From 7e0dfa7494026f770f67d439bca322fa39ff23a3 Mon Sep 17 00:00:00 2001 From: czz <862977248@qq.com> Date: Tue, 3 Jun 2025 09:34:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A3=89=E8=8A=B1app=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 + assets/images/active_bluetooth.png | Bin 0 -> 645 bytes assets/images/bar_control.svg | 1 + assets/images/bar_heart.svg | 6 + assets/images/bar_home.svg | 13 + assets/images/bar_mine.svg | 22 + assets/images/bed_control.png | Bin 0 -> 2674 bytes assets/images/bed_name.png | Bin 0 -> 2312 bytes assets/images/device_bed.png | Bin 0 -> 32805 bytes assets/images/edit.svg | 11 + assets/images/electric_bed.png | Bin 0 -> 45125 bytes assets/images/new_background.png | Bin 0 -> 186088 bytes assets/images/new_empty.png | Bin 0 -> 1143 bytes assets/images/people_avatar.png | Bin 0 -> 61111 bytes assets/images/read_message.svg | 1 + assets/img/icon/bluetooth_edit.svg | 10 + assets/img/icon/expand.svg | 1 + assets/img/icon/history_store.svg | 10 + assets/img/icon/message.svg | 1 + assets/img/icon/people_info.svg | 1 + assets/img/icon/return_buttom.svg | 1 + assets/img/icon/xiaoe.svg | 1 + lib/common/util/FitTool.dart | 5 +- lib/common/util/MyUtils.dart | 33 + lib/component/img/img_default_widget.dart | 77 + lib/component/img/img_preview_controller.dart | 23 + .../img/img_preview_controller.g.dart | 15 + lib/component/img/img_preview_widget.dart | 80 + lib/component/tool/CustomCard.dart | 145 +- .../main_bottom/main_page_b_controller.dart | 31 + .../main_bottom/main_page_b_controller.g.dart | 15 + lib/controller/mh/address_controller.dart | 155 ++ lib/controller/mh/address_controller.g.dart | 33 + .../mh/address_list_controller.dart | 64 + .../mh/address_list_controller.g.dart | 20 + .../mh/apply_repair_controller.dart | 198 ++ .../mh/apply_repair_controller.g.dart | 60 + lib/controller/mh/book_info_controller.dart | 74 + .../mh/experience_store_list_page.dart | 125 ++ .../mh/experience_store_list_page.g.dart | 19 + lib/controller/mh/issue_controller.dart | 55 + lib/controller/mh/issue_controller.g.dart | 26 + .../mh/issue_preview_controller.dart | 20 + .../mh/issue_preview_controller.g.dart | 15 + lib/controller/mh/message_controller.dart | 198 ++ lib/controller/mh/message_controller.g.dart | 20 + lib/controller/mh/muser_info_controller.dart | 177 ++ .../mh/muser_info_controller.g.dart | 36 + .../mh/my_experience_list_controller.dart | 115 + lib/controller/mh/people_info_controller.dart | 111 + .../mh/people_info_controller.g.dart | 30 + lib/controller/mh/repair_info_controller.dart | 68 + .../mh/repair_info_controller.g.dart | 37 + lib/controller/mh/repair_list_controller.dart | 83 + .../mh/repair_list_controller.g.dart | 26 + lib/controller/mh/repair_process.dart | 18 + lib/controller/mh/repair_process.g.dart | 26 + lib/controller/mh/score_controller.dart | 20 + lib/controller/mh/score_controller.g.dart | 15 + .../mh/sleeping_habit_controller.dart | 94 + .../mh/sleeping_habit_controller.g.dart | 40 + lib/controller/mh/user_data.dart | 22 + lib/controller/mh/user_data.g.dart | 32 + lib/main.dart | 168 +- .../common/bezier_bottom_navigation_bar.dart | 151 ++ lib/pages/device_control/BackMovement.dart | 228 ++ .../device_control/ColorChangeOnTap.dart | 94 + lib/pages/device_control/Empty.dart | 54 + .../device_control/EmptyMessageWidget.dart | 37 + lib/pages/device_control/HomeDeviceType.dart | 245 +++ lib/pages/device_control/LanguagePage.dart | 158 ++ lib/pages/device_control/MattressControl.dart | 352 +++ .../device_control/address_list_page.dart | 206 ++ .../device_control/address_module_widget.dart | 264 +++ .../device_control/app_map_location.dart | 46 + .../device_control/apply_repair_page.dart | 1936 +++++++++++++++++ lib/pages/device_control/bluetooth.dart | 188 ++ .../device_control/book_date_widget.dart | 87 + lib/pages/device_control/book_info_page.dart | 796 +++++++ .../device_control/book_success_page.dart | 210 ++ lib/pages/device_control/delete_account.dart | 328 +++ .../device_control/device_people_info.dart | 266 +++ .../device_control/edit_address_page.dart | 1333 ++++++++++++ lib/pages/device_control/edit_bed.dart | 203 ++ .../device_control/edit_userinfo_page.dart | 205 ++ .../device_control/experience_store_page.dart | 454 ++++ .../experience_store_widget.dart | 306 +++ lib/pages/device_control/issue_list_page.dart | 187 ++ .../device_control/issue_preview_widget.dart | 104 + lib/pages/device_control/message_page.dart | 418 ++++ .../device_control/my_experience_page.dart | 152 ++ .../device_control/my_experience_widget.dart | 424 ++++ lib/pages/device_control/new_Home_page.dart | 854 ++++++++ .../device_control/new_message_page copy.dart | 304 +++ lib/pages/device_control/new_mine_page.dart | 416 ++++ lib/pages/device_control/new_settingPage.dart | 618 ++++++ lib/pages/device_control/people_info.dart | 815 +++++++ .../device_control/repair_history_page.dart | 797 +++++++ .../device_control/repair_history_widget.dart | 144 ++ lib/pages/device_control/repair_list.dart | 575 +++++ .../device_control/repair_process_widget.dart | 121 ++ lib/pages/device_control/room_picker.dart | 185 ++ lib/pages/device_control/score_page.dart | 468 ++++ lib/pages/device_control/searchWidget.dart | 268 +++ lib/pages/device_control/sleep_habit.dart | 106 + lib/pages/device_control/smys.dart | 380 ++++ .../component/MessageWidgetWidget.dart | 4 +- .../component/main_page_b_bottom_change.dart | 246 +++ lib/pages/main_bottom/message_page.dart | 1 + lib/pages/main_bottom/mine_page.dart | 1 + lib/routers/mh_routers.dart | 110 + lib/routers/routers.dart | 1 + 112 files changed, 18479 insertions(+), 73 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 assets/images/active_bluetooth.png create mode 100644 assets/images/bar_control.svg create mode 100644 assets/images/bar_heart.svg create mode 100644 assets/images/bar_home.svg create mode 100644 assets/images/bar_mine.svg create mode 100644 assets/images/bed_control.png create mode 100644 assets/images/bed_name.png create mode 100644 assets/images/device_bed.png create mode 100644 assets/images/edit.svg create mode 100644 assets/images/electric_bed.png create mode 100644 assets/images/new_background.png create mode 100644 assets/images/new_empty.png create mode 100644 assets/images/people_avatar.png create mode 100644 assets/images/read_message.svg create mode 100644 assets/img/icon/bluetooth_edit.svg create mode 100644 assets/img/icon/expand.svg create mode 100644 assets/img/icon/history_store.svg create mode 100644 assets/img/icon/message.svg create mode 100644 assets/img/icon/people_info.svg create mode 100644 assets/img/icon/return_buttom.svg create mode 100644 assets/img/icon/xiaoe.svg create mode 100644 lib/component/img/img_default_widget.dart create mode 100644 lib/component/img/img_preview_controller.dart create mode 100644 lib/component/img/img_preview_controller.g.dart create mode 100644 lib/component/img/img_preview_widget.dart create mode 100644 lib/controller/main_bottom/main_page_b_controller.dart create mode 100644 lib/controller/main_bottom/main_page_b_controller.g.dart create mode 100644 lib/controller/mh/address_controller.dart create mode 100644 lib/controller/mh/address_controller.g.dart create mode 100644 lib/controller/mh/address_list_controller.dart create mode 100644 lib/controller/mh/address_list_controller.g.dart create mode 100644 lib/controller/mh/apply_repair_controller.dart create mode 100644 lib/controller/mh/apply_repair_controller.g.dart create mode 100644 lib/controller/mh/book_info_controller.dart create mode 100644 lib/controller/mh/experience_store_list_page.dart create mode 100644 lib/controller/mh/experience_store_list_page.g.dart create mode 100644 lib/controller/mh/issue_controller.dart create mode 100644 lib/controller/mh/issue_controller.g.dart create mode 100644 lib/controller/mh/issue_preview_controller.dart create mode 100644 lib/controller/mh/issue_preview_controller.g.dart create mode 100644 lib/controller/mh/message_controller.dart create mode 100644 lib/controller/mh/message_controller.g.dart create mode 100644 lib/controller/mh/muser_info_controller.dart create mode 100644 lib/controller/mh/muser_info_controller.g.dart create mode 100644 lib/controller/mh/my_experience_list_controller.dart create mode 100644 lib/controller/mh/people_info_controller.dart create mode 100644 lib/controller/mh/people_info_controller.g.dart create mode 100644 lib/controller/mh/repair_info_controller.dart create mode 100644 lib/controller/mh/repair_info_controller.g.dart create mode 100644 lib/controller/mh/repair_list_controller.dart create mode 100644 lib/controller/mh/repair_list_controller.g.dart create mode 100644 lib/controller/mh/repair_process.dart create mode 100644 lib/controller/mh/repair_process.g.dart create mode 100644 lib/controller/mh/score_controller.dart create mode 100644 lib/controller/mh/score_controller.g.dart create mode 100644 lib/controller/mh/sleeping_habit_controller.dart create mode 100644 lib/controller/mh/sleeping_habit_controller.g.dart create mode 100644 lib/controller/mh/user_data.dart create mode 100644 lib/controller/mh/user_data.g.dart create mode 100644 lib/pages/common/bezier_bottom_navigation_bar.dart create mode 100644 lib/pages/device_control/BackMovement.dart create mode 100644 lib/pages/device_control/ColorChangeOnTap.dart create mode 100644 lib/pages/device_control/Empty.dart create mode 100644 lib/pages/device_control/EmptyMessageWidget.dart create mode 100644 lib/pages/device_control/HomeDeviceType.dart create mode 100644 lib/pages/device_control/LanguagePage.dart create mode 100644 lib/pages/device_control/MattressControl.dart create mode 100644 lib/pages/device_control/address_list_page.dart create mode 100644 lib/pages/device_control/address_module_widget.dart create mode 100644 lib/pages/device_control/app_map_location.dart create mode 100644 lib/pages/device_control/apply_repair_page.dart create mode 100644 lib/pages/device_control/bluetooth.dart create mode 100644 lib/pages/device_control/book_date_widget.dart create mode 100644 lib/pages/device_control/book_info_page.dart create mode 100644 lib/pages/device_control/book_success_page.dart create mode 100644 lib/pages/device_control/delete_account.dart create mode 100644 lib/pages/device_control/device_people_info.dart create mode 100644 lib/pages/device_control/edit_address_page.dart create mode 100644 lib/pages/device_control/edit_bed.dart create mode 100644 lib/pages/device_control/edit_userinfo_page.dart create mode 100644 lib/pages/device_control/experience_store_page.dart create mode 100644 lib/pages/device_control/experience_store_widget.dart create mode 100644 lib/pages/device_control/issue_list_page.dart create mode 100644 lib/pages/device_control/issue_preview_widget.dart create mode 100644 lib/pages/device_control/message_page.dart create mode 100644 lib/pages/device_control/my_experience_page.dart create mode 100644 lib/pages/device_control/my_experience_widget.dart create mode 100644 lib/pages/device_control/new_Home_page.dart create mode 100644 lib/pages/device_control/new_message_page copy.dart create mode 100644 lib/pages/device_control/new_mine_page.dart create mode 100644 lib/pages/device_control/new_settingPage.dart create mode 100644 lib/pages/device_control/people_info.dart create mode 100644 lib/pages/device_control/repair_history_page.dart create mode 100644 lib/pages/device_control/repair_history_widget.dart create mode 100644 lib/pages/device_control/repair_list.dart create mode 100644 lib/pages/device_control/repair_process_widget.dart create mode 100644 lib/pages/device_control/room_picker.dart create mode 100644 lib/pages/device_control/score_page.dart create mode 100644 lib/pages/device_control/searchWidget.dart create mode 100644 lib/pages/device_control/sleep_habit.dart create mode 100644 lib/pages/device_control/smys.dart create mode 100644 lib/pages/main_bottom/component/main_page_b_bottom_change.dart create mode 100644 lib/routers/mh_routers.dart diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4039166 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.sourceDirectory": "D:/flutter/vbvs_app-1/linux" +} diff --git a/assets/images/active_bluetooth.png b/assets/images/active_bluetooth.png new file mode 100644 index 0000000000000000000000000000000000000000..d2b37a7c8f152f5b11f3d37f0f28a4173c1dfb06 GIT binary patch literal 645 zcmeAS@N?(olHy`uVBq!ia0vp^+91rq3?#2LH+}+AlLLH0T-^(N{^JJOf7c*O0=aMm z6o;@O3XsJiQgCrN1E>bhhA=QmpqkfDc`AU;(=Q3~3ub88aN&S}!G{8c0|5^vID9Z@ zNOZJIkI29@hH<~&66v49%+!_(G{zUXV2YW{CD@fqio8Pyp1~^Wlp^~OSam{S4v-N z+s~aDu^U`hh*YmQw<1mb*WuGe^#PGGgo%p`8cs>N!W?Yxe{&X zUng}gm$mm#`mRJLslw(P<{4r#jUQ=Vve6{lhCXhVIS0g_``ytyw(r1_g_l^koPD literal 0 HcmV?d00001 diff --git a/assets/images/bar_control.svg b/assets/images/bar_control.svg new file mode 100644 index 0000000..a42c2d0 --- /dev/null +++ b/assets/images/bar_control.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/bar_heart.svg b/assets/images/bar_heart.svg new file mode 100644 index 0000000..1f2ea46 --- /dev/null +++ b/assets/images/bar_heart.svg @@ -0,0 +1,6 @@ + + + + diff --git a/assets/images/bar_home.svg b/assets/images/bar_home.svg new file mode 100644 index 0000000..0411b21 --- /dev/null +++ b/assets/images/bar_home.svg @@ -0,0 +1,13 @@ + + 资源 485 + + + + + + + diff --git a/assets/images/bar_mine.svg b/assets/images/bar_mine.svg new file mode 100644 index 0000000..3cc9e92 --- /dev/null +++ b/assets/images/bar_mine.svg @@ -0,0 +1,22 @@ + + 资源 486 + + + + + + + + + + diff --git a/assets/images/bed_control.png b/assets/images/bed_control.png new file mode 100644 index 0000000000000000000000000000000000000000..7149ac782df81b2313df3550f804edd9ec369647 GIT binary patch literal 2674 zcmcIlc~DbH9)9sLCNh$kFq{J+Ag32Fq6SGIfhY-b1VKhnF>+tSp`sj)<^W7k9Pr>! zkT~Luy5iu7_kan?r8owZ03swLgaF|PAsm9jzFoI!tM>n`>i+sy-}m};e_wZ1^XUHG zdb*~%008LGsFd9RumTR%LIen5QlOj%5#e;-;2qwnzGwM0v^ch6bbNOH6NFH0L=0z~M()Mx{ea_C7p zpB5IAa!Qt#mY{lic79>;b9wbM{{$AqN1r<1*(dW)U=OLrr9-1LbMvhtu}nGk`u&He zFJC(b9fnqcT3~YSj>t?LExt`G`RWTIEvRwWozajH3-8!3OG}1sdk06xu--A|JE9;v z>*&eE0~ydit$h=5)HqR(tXDQ7?pHYNIlL`2eLy*e-5KK*k*!pz$JEobn3EdqTtEW* zd-6dGYOIO-e)+KKqfGg|=OM_{8?j{m)57b{zLt(&{cS;wZ@UDq-a*@jHfc=UXX0^S zPfBh`O5UIK%}-wbJ@;t=G8mMc8=R7>otuZwQKOxOj6-RRsWnhgP%HEzpIFKDygK2#_+F z3q?gL<;;NEY0Vn7sGUJ42?}fYsW>S^YT-op5J(4qH8N4jkIX--F;Y!&NzyOVn)!^u z?t^ltanb1N8V?5ZwT0A|D`#8!Ob-QW3WYXz&Bf;48 z-tFxUsHBRqV^rs0Urs|QcUQ9EwBTx0_KQX3OI=sgPVYO3<>l}_cGP6)-A$P3s6suZ)Lt+lt%^X>H1y!_QH&yn3n7_ z+fsmhim|{IVL>@Iaz_{~sIQ)vby8keYUPRo#N>7j&#M6Fgly|A25Pai97UzSk)FnYqJm zH<$c<^%s9vYBo8#dG;D2?IHzyf>ag~AV)y!h6{!6IIh5Fd<)jk3Hcs6$MbBjc_({cB~VbP8Qo*jq4W+j#0*2SO=jIL7@<(JbUu-q=l;|#;D^UqUzBc#Fh83;E=ROl z_`0eWQS8qP-jki$S;547_6^+f(nUHLtAB_Ti$qNrMMg>*+Ij{mk|wi z?PsL+s1w3gO5q9jRqsI~eX{yiXT($&IENuGuyP{Q-C!3+D8Z|H|1*9BA7O-Yyt)r8 z!3dRjbw79oSvyiANec>{mE@LHG*>gb~Y>O?MjTgySQC4wWa0|A@hMkWW$yvcx!(5PvrP{F1 z;pu}cUn_ea=!d0Rvy1U`1$maow?zhL7XEB?lLsEaMpYoPWTY~9k1hLGyl9AA%;P&C zYcmU@t>W^*bZk@!;dVU5l=5VkMw_DiH~C(j)i{f1SEC{zp!SEn9}C zPmtsF$!TVBbNq`uzAN&5HvK7uZVq1{*4X&y^rZn(;o}Z#_5>bK3&fW^K}8x<%Bpq@ z2glQZ0rC`&?~ZgL*l$O_Z-(W;8*SN3cwmbEm;!LY?@;+Pog6%KiqEBxxS%m=WhG)w z8dEN0=)=|`nFQngR?L^M^Kg!jP9dJ8VL0)a7&slfnt*1=fY%(B?FxT0W~P&XBH)2e zsFlSCQW|qeNW#DzkWvEmDuSNIRFY*BWPVg_UtZa|xwb(bZvrg1bY7gi&z z3O>c7^9xrv)#V z!EHc0$$@Upl0M7@$s`VYphpOg4GBH{J-a@(o9| zxjtitih?-t7M7dkUQxDY?NaR#kDW11@Rstfj%uNHT5>w3KU=h6bXLkfey?l}xivOD z-buAFHB2IiS(JI1zQ3y3imy ~sDq++rdgl0ND2t=K+|PYp3c{jImFxb#g`JIlzy=S5~j zwi~fVOdt=l9+a;?eyjsbd=uu0y0Zm^$zp7r+*}>j`8cmMy=uy#VX?s6yx@xT$=|+x zD+4}-WPE5V3wRN rj!S`U3)RJsfhTe*xi)JH<-r3Gj^{3&-m8SH-o+Fcxp literal 0 HcmV?d00001 diff --git a/assets/images/bed_name.png b/assets/images/bed_name.png new file mode 100644 index 0000000000000000000000000000000000000000..3a30c963a415ed372980978f902969d1fc323021 GIT binary patch literal 2312 zcmb7FX;hPE77jGk;4%iSRIAbm4p>T&rHUvZAe5zuD4;;GQc++KD~JLG7go`N3Kj$u z1XQFJkE}vK!KiEjLLd$()Qx8Br{#rlti0V@$}08C=p39qJ=YF2u#9B^D1M4>K8@X@znDa%2X`6oBLk z#A7UuT(LlBBhZC$XiQCuCfNL$S=nFWMN8_}GLTR5gafoG@(6Q`HO=G-2F9o6=H;+5 zXqL+4q`%hZ@P#WYDNu6g8W?AF_K$)Oqf8E0AfmH*@_{>z@aRNeKJMX#^0Xs}d$9z93TK)bXjhyNQOUrn zV(}4&T$1||;V@y+j^&(5%XIa%!`(mAKP2D3 zyhIr8_~>=YrK_cv`@u1B%R_0$$pwAWOh!U6uHD()-NVSO^4vrxwpib(_PcOcVJyfKA&0`AJLfF zV~s=>r1X|&b1c)YztAT?Klpqj@xifEuh)=mcl9?uyF0FIH>|_>6*cduobs@K#N6`z z&qmy}K8?>Yk7J9|O^YR@5(9Y~!}xO5QFFidNzdIl)ub)$dhWReUCKyd)o z-JEl@(fQ(ixVVYCU%MS2`mJs5r1A$$f;cinITV#@=oMY+SKDFEUA_1HhSv{XeNCd2 z6|!%vY!Qb}XT7PjHd%>!I92BVeP0g8P)EF` zeBBA^sS6q6Yp>l-egs5_Cwcy*veAeuU7oJE}e10`tZ7# z%GiK%`hndhG1{7W-`v34=;3)&QrT>sj8(@rNm>j?Y<@ILCZj7VkDv2_|<3!N4IVmGAe~tu=&;Mp(9r6p|Whyq37)Y zN{{icLX6~JhM2{VfY`?mg{Y0F_b@}$<{U$OA!Z?-5c?2!h!RBYgBH&YqHCUd_I6%4 z#20yLJTcE3qE@~dXIXqSDb8qD(G^e&auZs()QQFnihDfW*#keS;dEm%DIX$HWN*5_7J;AB|;XxhEwG|d2 zCaZLcf<*qB#to!^N|bNJn~@5wZ_BDNq171p?I4`d4y?jd`l5Y}HH~#Nbkb4jP6@65 zZ~0+ZkH5xCJl&dbIwg)2EY+2Ma0_HhIaD9QAC{!_@VMsBCd78@1~UdMLY$mqHm&AYAN9IB1uSOsM$ aKi^ZbHQi%mtuFjYpj@3i9A7yECjAL^CkAr> literal 0 HcmV?d00001 diff --git a/assets/images/device_bed.png b/assets/images/device_bed.png new file mode 100644 index 0000000000000000000000000000000000000000..7089767af70db04dbde504580b8a7bb63a319c0b GIT binary patch literal 32805 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 z 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 Q;fI2fl~k0d7BdX~Kkjm*7XSbN literal 0 HcmV?d00001 diff --git a/assets/images/edit.svg b/assets/images/edit.svg new file mode 100644 index 0000000..244e842 --- /dev/null +++ b/assets/images/edit.svg @@ -0,0 +1,11 @@ + + 资源 494 + + + + + + + diff --git a/assets/images/electric_bed.png b/assets/images/electric_bed.png new file mode 100644 index 0000000000000000000000000000000000000000..670fe82697e38e2ad6060d9e1414221bd871b26f GIT binary patch literal 45125 zcmd3N^;eW_)b)@KB|}I{ry$ZT-60K9Qc8Ct-JnBvNrMPTmq@oXNQ1P9bR+p)^L*=F z>-`g6evpyH+{}IMbDgu#-upzUy^_PhB*TP2AUF#0(i#v5k`;Kp1Vsn`8Vw2~gKtQ# z8gi15ucH(@;6JFYk_uW-@Z}4A8wr6>LlmSXw7jzRTJ_4G_ItBmYioN}nvR_^HutKy zXc96-6*4F#+0EnIJ!*OtY);3I1c!7A4oH~@NMu2rSFe73q;@u;Z)3V-;DDia4r)>c zQws)BAzx)(y`KFM&8$Zxqe08^DszdhdE2^TT1tC4;!FFt_wi)%9}8|!B1c+1Di8kt z{aSf{eV-SI&!CvZte!6&^?&z;C;IP){Q7(RK)TD)=ZKGcd>Ye8YW|SzkFjunl>@om z_F2gK@8e5c2}5FX|J~Wj{dYT8)O7~qu@rSP2M_RST!EUN?EJlrme`uuLs7~eQTFG5 z5O4AlKOP`B3*jP20b%IbUyn}~pzPWDQ4m@aa47miwC%=g{N^gYF;@wMY28#tVVvOr zikn{#ezzc8PG_ANWAmT@T=gU3*D25b_f_@B5g%5l6WVCb+Yn%EyMOQOuqS-2x4t0< zuA(SnHm)DS>7nFu@$lna+MSO3TdbHoluSUh9b>xa#9?3$m&IJ8GP8 z-XC&d!YtLZPnSySJt4{y9VT%V2F}tDD%+cm1eZ~l5gZ*N7d_3OX zLOqtS=Rr>p$|DXAj=<5;SD~iRzB!c?&w`1L!~26nv&)0!tGks4zn?a|voQ&UhtPn2 zlA9N2O8-UT?NJdHtzr@3B#%tlbl30Sj5@ly&Raj843CbQfgqHXm08v6gIg#lC?KJr z=(*Tm0zru^&I{CPWCY$uq53*>Z1;b9dU`syu;B8|$t5N$@FdC>V-!~;~*~V>gozYC_hCg z0TYNImr%s$BSA+;=iuTB&dZ~5^Y93Ez2_#tH^r2t%dDutXc7(P!SB-N1e%UCI6Ma;$FbO6}xG?cmZbjvGq4JLG{$I`msblLoQ4E#X zo2E*9&u|cg+a*bsu-)0pjmaXV*Lr$L=GY-2Azpjc{o~8a(fSp?p|O$QC#+1|-JgIo z74STuV1M&HGAIZM@rRw9#s|?o6&2x}-%oz93iw`e+#lgSz+S$5$u6|s&4^T!c8ErL zlZ%mGR)%GK_gD9rKj4(#>tv8=nck&x(baZIX!B^MstiZxHlqdYkQ)c5!YVo8;oru$ zmH$3ihv#Q|JG<4r`PwG`JE3pizEuT0_`_pjei4o>ijIG4Y2g$S`dfZbTFS!4#-M_xL8$HDh@;tJgZvYNL=L@qJ05bVl(&4R-LO&sxt+3U>nFMsM)lqH?gV z28lr$2>4y|6ei8J2Z(v>FN86FfRL137f?fy&(6>D8XJif5>`Pxo4k%`Ei5gMhq=d0 zOiXff)dRHhf9jjt*VtOsi8;bl>tvz?k^gT zvD%NY{_N~Duc-JKU+KmF^xud?dz&G_62>+ZM~^{7L|j$#4PHO3-Qx_GEiheq5jc~antEb=IXEb;VFLxq}(L9Q{1 zMZq@pA2_g)aydRDnOIw6IJV#MCD3=Sbw^bD-FPs?FFlq>GpgK*DJH|;g%!89brfkn(Ei+g8rg*@u$`8c*0EOd3H4Ekg{N=j zI|>kXG3Fwte<$z0-yF1%kdbw1s=m~Y>{-n!n71=CHASket$l4|6qZy2>&>f|Ez)p) z+y$zh=i`pJZcwdWWebI!pSx2Cx&3KS$bg2M#T$EXJ@I|GS?SNY9n8snQ;Fi`WNUo& zc(6>ja=kI&rtx?-;BI!V%}*Gzbg_Bjzu?}|i`5ZE#YcvdC|)})UQivR%wWZ5Ae*4S zB3&@iv#>z6F5pqd@GW?lK1~B6pi$I8lIw;}BcNZA;tq4QvOi#eBD;BB=C(UROi3ga zqf+0z#{l&n(!LQ@NB;+3Oe|MIgqJsLszlY?%Zo%VhC+fQJO;HWsmWuX?CYD>51>jQ zN~x6<6r8QkT5xyiHBUrs%*>RkotM_tCH6S{6%FdGWf)2axZ%+(!H}XN29dk7DbP~d zo_lv0doU>kI|ke=3cNpKZoA!j(IT+*X#PX7_P}M^Y(W*z)-aYh2>=XsGmMIP5K6#eWP5sRLIEcQ@!*Ff$_X7Pl& z4sUkNbd1gc6}^D*3z@x?4@76X&05`@%KnEKYtH=xVYgl0l+2V;VQ zxWn00@=Si=Zd_?z{IaU=rIrrVuRtGduKg4S8z;M3+7^x27w$V4DE-KlSk*H|P?&@$ zt#vct@qBhg=jubCjK*K@vGh{bRy#vT$jMz@9y#r5Wb508nnv0$Hkdj&!4eY_5e4Q= zz@59u=`i=7zkiXt=dnXpBiP*~f32@C&FZjlP0g9m^SVy_ z;PXh$u+>RA>IUO=ICr?R;_PFo4-0?Ve!$vhuuZAs7+B2G15Z0-UXS-=z9S8$4%GOP zdlO+ANk7zqCdbGiIZ6{MUQ0^+H-6mDWi*~10~{L+Wy`U)k9li&p0{Jcpze!Irsd@H z1BCRLQY7-=z=7XnW_H&3WK#ijOFFq26DzAfjP|;UJ1OImk&-S@6ZD&3tv(ae(_xw= zuhuFWe|1f%ibVs21L+tahxPUMJD>m6CT8*zK6+kde7|Mfry6jrnI+(ioO6Fx5-{V? zETu-Tj1GxYG&5h;>a?xb2Zbu8d|d}C^@TBd?(v518;RGY)G-F*&!iZi@VGopk4zIs zO?#J~h;MZ+=|T`^JHd{g&dI@%X;MfXD&E5?UyH5GVnt#`BuR}eWp3|7fLRgKG|){p zvV!eA^%fQ$fBJGn&aXx-{=X?-V0`PL!yvl?s8X`^O+Ua< zPuCP!od5o0k!Lv`RQ1PiZEYP*&`>n>_9mU0ngZ>*^Y`y!y6~8o$7h$9=KV2GEe0P; zF?M%%3%LD({qn!DN7PHN>z$IP@t`d{;^yW~%gT~AHeRvUYrl7%wt3QiZqOd~UtIui z04Vm*4Z{es%%2@`9qqOZYNk|^GZuN~u2nsm$7Dj^wS7YzeblZn3xf&9Zp6cdl<(hv z+ttnWXft+_JJ?kjRZ(!xvqbtRIx&DP(K2tZsUZ~Bt`IKH#1a7R6)+U?5-?XAoDyM3 zTrZ|3nS9?H-+G}KGGpdsV?2JTE_rJzj4 zQbe+WTrlE6Qy|y3HEeQ1!otE5@YqYE6QV(#9w8hS!Le;*lw|5M8=Oo)R!bPGZR3sWW}wRL)-1qY_Egn z?W4buf4#@WCCn<&x970?lcvSFY@scJ7Y6wk9<{Eld4FygLoMelV zd?*POqOW19XVx z^VpaeBFRG%^SK85%$tWX7cqKw-wpDW4#(R*$22E)!jFginJRYn_B2CW0Ek%BMuA%1 z+bcsHZn6H|AS}&MDh3;bjk%ExDNy1EAsId-1V*Mvnt!>Q%v^+rj?M3|)G^Jfdz3!r z+h^5EE1p4b5=?_l=hWAc9tuOML#Gd$;*92iLTr1vIZ(6cR*@BLoknw$*k4ZuLHDWy zS1DjfsQlZThF&$H&YLWyYNc8f$BAE`LXnuM?HR^{j-Vp0sFdL}T^!P|PyjZ#L4w_v zfyQL;+_jCmXLy(=JUpVa<3PZ<=)V+`Z#OhF?CIzb&x^bTMW~^n!RgOF!bDP4CV6--O%?Q5Twf93 zbmeNeiqXPkYtciXDB>i@#qXJAX*tK}hq&JA{T>}6LD`^C$jBcJJl!5!JMO<+@C>fM zyRpKE0L|QsUSd&T|5xjxo|nGuQj;?Z=su&SCG~v(5Pdal4mN7>K+Lg+wmZLWy>AYC zX)I&L+_n0wqGB>@CgH9XVdS%w1@rI;JHBx%JDMn!G`-q+$&7biH=7C^=(n3pj)9$Q zwXEu)78EGsaTIxw;E(PvjWS*oX!d292=+`Ci2Ossf>Lj*f83``#n)NhYFhrSrbTca`f+m3ntx-p8n?g~MW0VFN z$)1TGC(xkZD5HoS9#d|az~;NdG6eU<3#CcZlAprXc;;k^uU*JB<6%;SLwloBw#CSj z5FAYH)IRkkj5EB}a?I@TS1Z5KLqYz3r_c)KJc{K!rWKj<7TN*Z`SAl&NJwaWeqIl{ zobOuyKrfe}fv=ZBJ7UJfSzc+MKW$@bZH=dxxyPT*Qm2mriKZr$Pax4_>@4>&h9VWg zL-Xpx6UfxaR>hf7C)p$t3I)7Ro{K!(I!h-*f=tGL6jE{*BUQj;kO~vV!F+{L#7(b& z*$1g0MI{czk>Zvv$xE+M#|VFo+!w7w5sGF>M$+MJk{!x1`Vu`f50V?lh)?{&up^#M zZvU8q3>(g^^+mgagn@*1odVW5}GbQ{$fb*PY{r;*XagFi;s_Q zd}_+v{bJE4RVkSLSUx!AlmE<99BO@?L?+P~b8KvEU#sYk&CP;Y!k(l1f%f!a*j!3+ zg)B*0Fo{TI3pJe=Pr6>01ZNI}S(G8s3^czhpW)%&93c%cp^)TemPgH_>ETg1zTR~- z0Uh}B^p{l%H4VLdF3yfDaz7FXDm)b5B}kfaoJ{8p=POagagH`t3wQ0uqbLLPXd7LH zF9{4VGE=(X1*3(cw#?ajGRYfD^PZd{JfSaJJn|YVafeu0&b2>Z9@bXf$s==Y0FM6b@3MC9DJC7Q^*3MVOpF<(sG-q1 zM$C`_%y6}a8xT1%q7tVZSHw~{tgL}bY_dco$aRrA%}O9XwGFYP2!f8hjb}j(3Y=lQ zXq>hQwnb;bnNUo#in5(8Rx8u4c3dIogP4=yladfHp3o`;ayZS;W^fJ+3-o@WMQ%jR zqUWregc?R>OyJjP#T>~naP7=aO1pD7KnZ3r`LC;^8lYZ*JcCsYZNWv!?{0G*`X9oS zQrRV>=%Ar`MujZ-pM!^sUAYaUnX6J*&Hsf;s1wn0%ru63Ov;ml!)Ag#rTYUbWKpuS zv*jm$Qc$7m@Xx3{t9?9-Xs&%w?8aic$$4tnwuy_*BM5s%W8FntpnonX>JLEVDXtD_UAB{)PvFDTVI zjBR8pGw;bHeS`iN$XK*7x*7r_o_ zQ+Y+mUaR&)Clf~|Gtb%7*DV8Q$m;b+w8iOKt2IhF7vNo!X_3w;SmDM@nDj=l@oJdkpRP8^KX+*{=?rrjMi%1_F5M_rl&%X{e+ z3^S88pwe+nAEA#O2!#Kh3w`oEfyy@6yYePv$;J;XE~Lu7y~TWJR>)<>l9}UpwjN zYhVHnE+h$GQ&Tf07hrV|n*08TTO^C^;tuN0@>kfIY?_TpZ;V04bEw$4HwC^3Jb(?qEV}yRx6u@Sbab4BY&;;Mk0eTPG5?X zx?BrF-YhZJ$I!_f#*B>@#%T8#c{Rvc!=^iVoE~?XHouQP;ff%Trh|=}m5`=sDlu6j zPEjzQP%;oB=(7&*EIu|IMZ)Bo8h&Eqem4A>UCBrIR!wvzo)i`7z0Wm*w&Y+eKQ}}u z4!M9DIe-6@m6i2?n+7#JBBHvc1{^JSNMFY8&Q9mR0Q9SI`$5+Rh|$AU<3m(Ykqp6$ zECu;=2`7hg?q^+Ng3>VYP^6}0ZTLnM3Lk0L3v~KWC(ar|IotAS5^J)Jbjwc?fRAo_ zxH|-7(j3Ex(`YBDRO_2dHX{QmNvO2?Td6soLcT+1cz8nJx5lvQ ze$5?wKO?v;;Iau#psz+@?pVKOxSJE{JIdO!W=sNUVGd+DY;v30P*ftE?Npknvo zNk0)++J@0B8`@6YQ=7bES4-0VT(88A!Dfxp%OC>L%pMJ2Pk(J4M9;nEAH*?JZDA2i zgFj5idva4SfF-toq9~yh#qlN0%gQ!Lli?dRERL&QBie)PeL``d#f6v4D2r{p<}&=d zIR19forn{GW{Lt+Vm!8HodECvb*7la2d)OwD?f^&g3^%iye9O5vv$S-*GkWv+F*Mqs>`Zm%p+6At1>Tg~p)_(ua zG{~7g+z}>j;qFA4w&lYb(-|6Q!3eLy*QQQmF)PeP>Wp6MBK3l$6()&`&s&LFdy1?n zH%$lr9vFwRQ%tyi zN)=)F7h#i*8svNhYS=a72U^WUeZ`-)*#aJCBwgd-Xk0kKMxrJIqRJyHHAeY^1BVn_8zjDHf)pdf{$RgWS!*Q#}T6 zKC{P(wkQi?OPskLtz}1A(t0zs^HmaD?}xyD<|P4+TdJ0Hv3y{lf%I#( zg?plzx%t$fTGkdpxzh8-O_iLfp3?e0z?9lYJ11u4I~p%@-1*)Zdta$5Pd`6q4rc2- zK6XaXsvaIQcNH3?tA8d6z(hJ?F_rMCE9`P~qn_Y_iiaM#)2I%~d?^_NCl~@>F?8&H zAt3#5S+Tv;Rhw?%5k(aB?gibW)b1nSFhHi=c&>R{>KY2Ym8DCT2(r=R3;+#$(s!R zI|sv@yEhy)|MR+a0-3(jwwq#hVvO+63l$Bk-mI`!KD(s;oI|D+DrXQA`De94e0ZpS z4$ut2=uEet7e{<7+)z_4+!0F(buFZgs>^Oeibkb^hC;cGJ}NPdACgZoUE7QABsx?Y zXoh09hu^AkaTF?8@IM;BdaO>xQWRfE*!}qMQ2Lj}Iw5V{Y<^BqB7Ij!p;bf>%lEgE z7$_wQQwOX+WA8T=?`*jwN4PPNkw%dSjF-ROWe$)!#cYg;#oAO@pm7icj5=Ai_=<78 zl3cMy+N>^b+rsbXOi4+ps;dhH92d~I*E)hw0K@j0=JEL}p_-l$wD;lagoqz{-JQ=m z0|JRc(4|K&tB!XXFirlq5BGC#H|L9-89v1Ae5cK5hcm$NU=qkqgV@auSZeR0F4@j2q_!3v(g>sZ`{oB+uEV7bT zhZMo5Qm%V$>+q--q^rkYhSNF;d1NSZe44!gx&-?d#+VJs-#JN`60n6EPSX6WM+YRd z=S(@i_!}*rPjvKtQb#Xtr$nUW-Z4Bx7evDW%505)v5WTHIM;Tz_9Th6-Y@$)h=rz)$P#4iWu@ac*aF za~xG7W-8zE+-&1j|0s&W`2IEN$VDB^JHR>u$q%UL&Ue@DS)zVqKP9@3^Dh}QZ4)Fva2AE5)s)Ai(qM|S?NhctNZ{GAFW)}J=(bC%oQsy_e5K^0T$tsa!GZq_-8qK1yS6|b->5DNZ^wx_PZEPA0l_Pnq=~KV z(7R6>IhpzQ7|dS{Z1vN(T594%?{`$&BY*w!w@Sl-iar)mLsh{*28ITpboL@*N<_rL z&mYma;!h5`8X~5EV9LIjo}G=Dm{5nq;fR_J&MpbU0|Eql&;gq|`~#XLU(8IG=~g#1 zps%jgKNiF0NlQ&lb>3g#Wqa|WrS+J(xwElKzk&#GSu{n`a&nIVW6Z(F7k+SXfXl{w zmK*%342FDjdFV;s*xVeYYwY)AXh;c)df8PfX?yp?GybCD4J|IDu`YbaRZK)>elnL3 zS4CPyT3pE8A;`563mT8tdx)>lbY*&Y$5@i5`n!!gmNT3hTRAIa`UgvVx1q6k+3ly# zkfbAzZ|Eo5tazy!fk~yiC@Xp_(hfzFJ?n>Pf2id4=|83{WLfIjc=~+{m}M^$RbOPD z55JD-+V)k5%(sn9DoqKea#WcSF=513G;}V@VC!z!Uv&O6P9wbI=j&wx6^b#x-CwzX z?tc_QW#Zs4`lN>vI7NWqQti6^ibBK-1~e3e*4WVj0ltIrm6gLcY5`8Zu(e4nUm!&R z5svAT*Sb{uX;sjhaogFiYbRSnz}SOOG<$kbfp!Tz2y13WcQ=f<7bhoNpr$$jzl`#$ zS7vYDqQ;8d3xKS}@;m1^OJC7h`27drT{z#J#hVMV$|qPInAh{wYdij|s`&OfLFZNI zdZoMzezf78NzPGJd06C|n?m>zW9u9RYqaPWQ`Vh$ zw46?KU2*O&Jr+{KUavmwXRuampp9iG-`_|`%U;T8#H}#?HOBNjWguL%@_ga1r~X%| z^4%ST#-GCqqPwL~dV1QwpxQaqn+(DafNsaDmb<3t-%fkryz=fm5( zgwv_U$(<$t_DOeZb0e|qu!C9Si5X->`W2rEueQUwEjSKyZUIZ z(UHpkls}-h%AmSZqH%Xp^mauIbN-d8>c-j5)YT8&HjO#0Gt&qSi`_iWU*3;^Abhme zjSz(CQF2YT>f}(bOyGG11z=2|>;Z(%(J!CFwe{YQ2yGCUB)0OYDT%BqjuUfkQNid9 zR52j2nW`mm`0l2&If!8fM@C$8F|BOL(rBtcK?RVB>lgf3q zbz@Z9Q32m)q3nlSdC}a4>&>@pZydO{T+9j@)G4YecgXZ4#Y;to$J;+eJ>z~XQxT{* zophv}&}3pwz}a9s+vcv)v-oS}--ekhDG6metvRJX&uf;2H6FxIcV|A%5e91W2z#r3R{!WS@g2 zLFS^Plc5)4_%qyiy}RWD=RC_L3#D#$Cd&PF~T|@GG(Ar z{O213Ee8=&#F!LAAsGDW)2E28sLx4V2)o(uVN%_#RdL+^2eOzNsrZUbc+i(=n_JY-7U>()$`?9 z_mMGfTdFnTy1dT#;Vo-!!Dl$$03$3JA>|hy_=Byy_`ET0w?nICU8f8)gF4WV^7y%1 z&4-<)r4AFdXWXXm8_bMhX;HyC$QPKejElFoE{UhZFPNTQw@ejH)j5gP)%=(wq{Tii z-FT5(Quc_QTqfYVi2Djg24^@hDuSA`9((^M_JEA0aRVd#F^nbN9{xO@^X-+2w~F867imltC=ib^|hj~NcfBAL$ozQ#N|M%w4%?T6o2m! zIq^CKiFjNQDGN!5>Qw@&MtUUjy9&8rDza1pa)!V(*bC~}E?m>(B9pFXqy3X@%1}S%F zqk)ZsgMh`LWIY=Y);je73OzV)KxUwS|NcD(Cub1o$(|LRof0B9d$nGtBm4+eAMx6u z`6{<#_VtR-;Y;9Ixs4#t4T621dFHWLIvmf6Bfc`fJu6$>KE;)V&Z#$iKbhU;=z%#1 zQFF1g`>P7ESp=1m z%GlT?r(}J$(BGLlz@+znl9!ov3Tnb(GP?rY%84CdoX}S zFTb+#@RMQfyxsbK<4WJr(GgvqSfl>)EU^GezzQM^PWAfkAr9u|C?%>neL!dJ>+7rX zxpZJssuOPcJnCRisNBo|^R=nNMB$^Kf4%UZn50LzC(-Y}4_?d>y&?O6vgh zH{}Ej!G}NB>V!1d$UQnAi<23GvJwDyGx_S9Tr6cTaH*(4zqEwB&!-B$Q5-)@XubU9 zGuP_Vh-KfrsHSLYYl{WwWZW?SYl++~AAqNs#QqI-vBQ8skH{myN;?BR7}zma+}iIU z=Xl{XlsA^FyCAHg%&fu-Mk8OF$A&wOZ=+?U7v$MX7BcUN+Ho-}hib3^;*B|~ zW#i_pY2}c~P{Rzu)Q~7mmpyCb zOJ6m)5RPgLff^MUZJ@ghC2LWc9SvQcEmp9|^N5>D zyNf#3oHrNTMUp&ee|=b+!B%4RXtvQJdC9ceR!HjgUQXJet|QBPk6bF6Vlkkg~9M zp)y0eAGQ5rH^}Uz)yj_C{y7%u1b#MDL`74s&!60PC@1C4-?vKD?kqiLV*3)MKJQH> zap4mPd&B(7Rr08+yYlVn#M=#nadFBWi4-x0RyDTTfc84YVxvWcwvQWg6-jk7VQMei z`!LT1P3WaZl}l&+ZZ1sC%wo%q?d<-vT(+%vMisQQkOLytIQ&;g=hJW+FakJj^hJOF z-60jpHUtE)5YPYs0D*AaH8wRxf=t}|)!Gsln)r?sVNV5GZ41F^V#DVq(nx0tbANwI zP|y%0!$g5xHSp`mi6d&>^|cVf+NtXIS94TozSV~xVX^?TFEAZ1r=k++X8?n$rJ(1} z-AHrIJa$;u%nWaV;@~jO>-Sr}FJ9t!2vz1}t;+S)?RL{IB3Yc{p?W7lEoI~isg5OF zko8In>l+Nh+uX$MX;>2_Z$BG}Hsjx#N6NDl#E6ssRb4 zbI!Qbr@72T?PF2YrDA_5ku;-U`RF_PAjAAt+L^A~G=A)>3JM8*0Hb5D;g(z%gmEG? z%9mC-0oB030JvcO?Cy4de9;EQOEWS*VB{n?V3nBSDyyxX8hLy6ZyDWMT_Hih#V1WX zo?MY-Z>f2z)kH%PvEWdzj{`=ird_3?B-UrVqM|Y2Y0OJ*^&%glpr8PF(!DcP;tT*B zq+@Q51R^B>@Q#4{UqS@s09?UP8a0rmU_Swf3ysQcRDkwGAV3`*9k>V$w{%{q9Z@7i zQC|ZGRg#GGs}9ntM-WjA2~raSZ~W6iO6fppH#c~7$FQh3VKzj+#)rt->=KJ!<9x-h zeGZS|lU2pjC`Fd1%}BjhhP0kF#e-kYKMEoRYGMA+|ELv^uU|@Co1<=(C8$FS^Ipbi zk0zWJzmy?r5KC7xc$WNK$D^g;)ynzeA7Lwn*zj}mae4_aF(x`11$agzKX!i!yt(+-K;6X^L(7C zWUVSV#l#MuT}=3aBZ=UC$3DFb>j?v?hzKgMfb|0I%BUTs7lRXuOe}YYklU7;T@k0Y zhy9)(!Kjbu$E3lU^*}wh!_xFrhM(wPH z2B!^lcB3{pK>omi#-qXs8VySwmpIi6qw+&0RCv%^1=@nqUq#f zArxvE_4{sS1^lA-)G;?y763f~v*yW(i>bE@eI;cB5=^U0lWdjO4!!b(h>!U zIeS}XB*Mn*=jR6u?oKERhr1X4CCWVrBPwFcWg}MXafh-UU>?#kG9=5Ufd%x@HU&Uf z5ariYf~Q|E_GyF_5m5G__PWMRs}pd!WKgu4$E z>8I)Ow^f#7ln9^WpgDMEptuLlI1vE0&egelQ@XH0L&b$AG?6cG2}6ObW@cfUv*hrR zL?B}2$h{>2bj3Wd`0@Vzf=n)KKEBtuRO`E)2)Eup{8tqH4*7YPQH;q?g*}=sZU!0M zsHCmha0@j`o9;+<$TkVjvZsIY>E~U6p4YPP7&;Ezxd2Rm^C`G5x-YmytYaY70jigf zA+wdna)4w4?jFM(Jq}IEpE=`NjPcggwK1K*F;JjWNxnAENa1W*xbl+qx{aU?)+M<2 z;W)`N_A{wDXi&1io~|>|ZK0rPzX8BCL{KjtZFh(dIK>gm227&IQJH_Ae5WEY2YX4< z2vX6~vKoZM()|+nWnEk*pA#T8Asa)7q?0wkJGIo!M5>k_Kiy=_gt}JUv^q(bU*JOMi2oK*y`*JlcNM{h}2Kfg|f2%?50Chm6$k- zTD>%kL%xNO9V))787c|eeP{-oI12;Fei&*HPWi(hz)1p!x#eh<1Vw)gTv%8*TPo%{ z_RWb-nY(Tdoe_{ZfU{Uwz~{mU8XwX0RK%+ahK7{p+>^H4p}E}~7Yd8vVW#QA?WJ}3 zp;^ei?MC-9qg<}03MumliNtpK{_JVUz3ZvFovYOwscx}fV@_w?NISxtO{X^lvA0%@ z@I^n-duc^!1@gCX$*QlU{t~;OCcN7hz8v03V|sAnpBdD@I1DNz788kML|WneOHb-Z zOQ%uNW`o#5o2xjwJ(4aWOi4`zr1Di;Cz8G`GfTWeRNk5?;H_Q&6n?d7dvM5ZMP`o( z#|se|=W$CZf-a6`xhb#MD&C=;&zIWEBwnYyu%mlWtyKS26fOfD8oqP_61s zC`Zdz7|Uef{^6l#x*63rH`{AIebBcbZ~yX}Wxx4|cCuI@xcWQT;2u)qfBIbdTH#V| zmdT8s>*A@GXuPdGk3)irz|hnezu>|)dfT|j@P!>=$Lz0<2^UZ|6M3^&Dht;7ISE*< zt#|y}Cz_KcM<=%BuC7844VM00x(xQLNZ}2fpI>Hn?0k1XzNn$!xhJWe47N{w@D1bO z&9;80a3WK$F9X;};13t}1WS7eE34zm!SzRq-*tcE(nD8~bFP1ujH?HcZj=qksDHJ)wBD_~@sXJ_oOb$jHdP z4W1nQ`O^V<_-ks3(dNat^Nmo)mknUf6TW0;H~tQJ&JDHTH6Z-hp4o||){0(RukL(_ zb1lcf5>@A?G*daGOymu0$KP*ltonjC!bEA-As^y#A(+mih5U)3YX(04zbTe;UNl~f zzA+BQkPZ}x!rG?B`l;n>j`ndO_W9#(+Ui7^-H3^Q>cnmJyN!#U5FzW1U)*}Xc&e|q z^D-vee!sf>efac`Y6AjEL~qRX$|Q1DS68oH%d><5^+A^^`>~)tR^`r#&LuKuLYJnL90HT;t#2?RTYPdE+G|=43)%D&%68XY&qzp@piyL+5(7K?ir>(sP71|Sx%L|(V^O5do#}gLXNm%y zvL`94ZMWj?91A(m@$mH~MNKFF-Kp{GlTL7#sPX)5p;y6VrFfr0xE06LhZ+{umm1(w zVNCSv$wRZ6@i^*gyTO^>jnAtDXuR!BwMGA7{+EZajoJ%o2iHuZeIMZ0G^t>q^_CY zL_GV!PE!iQ7pG3R@*)1PBtG(Li&E)?o_~HF>?29fu->C&25qn1|d}#kUZgQay zcQ$yVBgKkSI-GKD3d^W7wZBOC_$+=tJ|q1w%oJLY6lGoX_f1xMb~Nd}l_`2v)g}XK z<0m^LcIA5BjUE0ORGtn26iW)l%(&-$f=PuMi5}grDsrtNwgXWz=G*5TG#7enxGc(_ zj4HR9(tfoVdM#SV5;oZ}xsFdnUh0vq=)X~EsvNInaiyW#E3HzJeC&(`e6u(*L!2SsRb|e)T zyL;q6s7B@kF?_iTcJRO+E3vxd{)E0c7}P=Q{~Bw}&?DHt)~#wb$LPE~lPp_Lc6u>NDf4?uI0{Nq5o|2L&6Nuo*dQ#Ek4& z984>Vs58{qYY%Wmaa3j4+0asTq?KCYLERpo>5chOzFaf-*LI#tA65JFHf>#`v&U_E zB;~tD&do2shvhRmv`FbYQHGl4>6<-+kJ7hoz7j{N=Y^z=1`~CmmlzYX(SAxf<*s5g z3psYcCSNl)?iXXhnQfH{->PzKsRvyise(catk__syQ;c6NWekD`olgvFG zCr18}_~teeTPWq1f>>0cpSBBY>%3!&Bh9uw!5aft`wV2s2hg#A{l@oq?^tfh_OB$-dyXZ~;2He_F#A0xUbNJF z5O^qgz?W~yinaI9O)0ioP$MUkw$8|Sr&bolqu{)=E(7)-5bQHx75cauiV zYCk}|TdrJ*GsyeLef*s1A${WQ>I=WcdfkT-)j~;V>bPl}r4G4+0o_Q42^P)7zrE_8 zx@`=K!{m^o5D?5HlLxt%VG4SjItsHP=O~+FWLi32Z*+K({ zxulb!`dedB2P0>6`&mYN=ElKC(Ma5!{b5n*Y_q^1rbyPT$ZBP+%RewU&1AbmcDblL zw&EFi?EGfB`J zP=R~tX-$Lt&h1Xd!1D6e=ly$FKPOqVtSOyFd*bZu>~c-`fG)@2BwGE?zVJ|e(a-VwgVA5} zmEh5vq|B3C4>Xj%+`4dCb%V|CX}3;gqPezszLWNiN!G!I8@~2JjeB%p-WB?o$!7Fd z>Pr!D6;3QK+m{=$I$j-Oq%Ff{Zpy2^NU}efIHjhI-nc5JJ-@dZ4A6xnGBAOim*L!c z=?9DDo-$LA|QK;&#}5?{Dpjph0!6pNnVz}|=J+cqK>o-!${)AD{k-0}T616G!p zKV;F%o3{a~&)vPg>YL&eHkeKN!A3bC5s&w3$1=1}P=aHX$HP+pgv5k2=nRka|1K<~ zE^-M~LcVWy-LCrneUB2^+Cq_~F%-zAgzCh|io3qztPmh`B%cXv&2_u%dpY;h7GxVr~}I}0HM3vPGvRoyE7@Mmjhp4p!6(?@JcmEGw~ zt#kOCj)hZ~%w`=02Y*CL*k^G)`!>Az%-FdZh%@2u8SyVyh_j4B?<>;i#yngn%&*)0vl{Xk4$S;_p9r3q78u(O1G!aY@mY z$myD{!j?&a@?q!X+_8pe#SsRB_sM6!_jP-F`0aL>t5hE%y}FvpZZkt{@g!F8PZ?g@ z6sg~W;v#gEt}Ol24sJ#SF*@qsy08ok$=SIMkx_|aM#YYR^}KFLo&aY~s8V*we?f~_ z=}9QvezDkoCH!*`0rYABOk!YS5|zGi=7nwtFLfLfYr@?e(Yi3E>vGwK7w+nQKk4u; zqQ*GtviE$n?JE`9!Ls^yhD@$^c#G%Gg#2oZz+%Aen?qptkJ*vyS;O>LP!7v??M8UW zw0wmZ`AvoE!y|Mzfu?Dh@J7HIGZ#Ej!eETIuKGQ{y`Zq=cjYISHn0nw$%67Aw={80 zSgR!77{Dl4US0;2ZkmuEs)5KKR%C5R<`~iDu5aj+pC$fMc)ga(pIy^&9*d*9Nuc$2 z(3#zJMRHeP(o^u*Jacst@2j0l{O6f#75Kp5`}0U1RgLwPwYA%HJf_TdP-rb+HHy)w zLNS=I7@5KHqI{-F39lPDBG%}n%F@pY8QAy15utZbd<-5ZX@`pi0F-~yKQ*2A)Qpq7 z^zI45O3Bu-v1)RK|H-a?JTn*lyC4PE`&j!X_IgS6hVwRS`ns}Vp>4zFzYraP4J@FL z2eAP>PYU}VFM9oJqJ@30M*=j&6vd${IJ(#ouYm@y^`Q`2b{ z>II}~ul$eP)UgGJ`Sw7?{__tqxNu#7@uwhKPfG%g6a>`9o#7H+Q0@P+le_ca53B^R zaiYttWCg9~mnHXSR-?~v{y>>u-QALVCo;^`GO|o4C?p6Ro$A>hn1U8NGU%$H^RJj% zd(ZsAhvmQd0k!#sz30pT(o?5hO?|76`Kmm>Eu8r{Q}nE4bII}W{NMNs$!ik#-voZp z$v6o_fAWUxKid|Iy~t1239E^wbWFk7o^S~)<@QmpuR#GPDyGe8X&438=s+|1KYn%X ziYgh&_mhI}rp&F9jxXDQJIDXZLP1P&4>WSra+M$+h?4 zM9gU*Om^pkWDwQE&}jqcxqWw|I(@X|s5~Pr_niAL1A38ebtYGTgZxpN00yV%7gv%; z(yq7X0K=$1@yZ$t<)v-6`@X12tiP~626=G=S4fo~;B~(B0K3mTdf|5@w15=@(Dng5 zoYq=}mR0uSmJDTrghO0XOLSUfO^7bGT*_iC(8Ir1St2AYlhkr4?fJ`en3q6@|6aR? zp}xzOJ;JcW0aRk_em|s^R`l*`pv+_u@!ER_QpS&f5KZK)0G)adPg%BPJZVj>8MS*f zAq8P3dCiJ~<+{0)tM{3=FzASc2u4<2E4)-9s0jHHkk-CM20bVe@^@=~QSVMnoYwnH zJvCS(FF&@T47Xut2!{TswbLZtWNREpd62x}s|A*&s7+b?iqE0=a#|&*B;C5QQ?jL? zWb5hzIoD;yGUkEvx2^Miz&6O`y%Q^rVeJn9)YO9L&2O)qYfFbyyDf`h3~{4x4oMb1 z0&D(ef|Cl`Fly-%qJ-pC?7n|&b%bJwgvK&9hWzzxGBXID0ikH=S)xSh&q^vN4hM57 z>y_^sr3kUbH4vrWd@nl3b11jpD&KJFz12$!K~U{@NIBO#^H2xlRy>BlUJI1zmF(&+ zMjT|w-tz%Q^F{Ts4ggj?^){%94W!}@fTQvM+c~XYYWV9i{|>AM=q&v22&`E9!@G!a zT34Inak>79zB5F7FR(U)pFXKsekm9`>FjBeE%qJ6LMV41Ch>gavz$6ayI=Vtcz-iG z4L@Go1$8Y{nE!Q?i29N7Lmt_yb+R?dzfZy8W~uNeln!ae#E50${6m=#?y0jAgWE3* zH83!0UC37YI`Q^rRP>2=^krCq){b_)t&M;`_XBmH;3RKL1~y!APJG4>QbpbqAK6=9 zLu!oW*_J!g*82K->8^(0z=hZn2fptnOmG9L7M|?&7DqP+0 z)I}MwF#)_+-Mg~#BD;*->wUJIGFBzT(m5XGlVsR5n&%V|Shp85lu!Buq8F6WW?LA}LGUs?7lPRs0 z&_&m)i(nqM(a$HHsuf4Y)Bv=~o12>fkG0^hJ%@6c6ywH!zx_`_3+zJxI-rk^cGULg za$_M<45$+=5_yJU1$MVMPFZ_b!;09Pg8*7>gsRfTRH{y{^hf>Ik&(CAtvrF%46DPi zq9@83VoyaJR3$@YEfL*RJp^O^xjD&|;i^yl#Z;WjBY3Wx%giPcXXMbLHUOO7P_an+#YdDo%{vnS5t@`e6~_N<3rR z2%=An{z#0DtEuv;2V1nw951|OJQ0)RU!TVgD6OO1X(u(De*Z?MqsuBMu!lH{TmkK^ z$-$hu0-G#LWV5QS25N~Xvj-R3^-gQna$7@7L3)H@WF*hQL+gwgB-Fbn%zSBiSH_iW zai`z5$lO@(7(-eI1p(Aa@bjWGgzv%<ZW!N_2 zTY3-(gz9(Qh&$xRy;(EN1@pdvm_(HlhXVu$eX9Nlf7O0MW>+xmG{EUiAeI&*-?F(- zb`=BwTUVta3#5}~a&Fg^k-y&kmKKQ^%JNLeRvf+|vF3(n6AyYOCQ3u8$3lV-C$5CL zZh3Xl4#U_%G*>X1*`o#2#>yu_XjZIf`CzQmPH9V6v*=?q2cMDbK0PvOm2otFHYGGW z$cIEmm?1w!!(ja=0i|ozk691j%5|Rks>jkM!5v-oT~U9PRr(p)aep(*Cblb3UxxpV zW)!d+Z_s%{2p}$9CRsiOBa4L0rA>!>!7w`O>LI|ZgoDO0X29X4it(Xn_20*}(DvFr zyO50*Sc{{Ld`Qi4{2EppI1R}Yh-22idyY+ZRiMm3uZ0zwslS)U`t^*3Iz$FBYqlD& z@7*zzflu4bwbiZLbIV~6!=;|{W+{a-%(`JhX5eOX9~47^de0|eiO~u^b&#MVjY+^8QMhXy|@DyZ3s*B;Mjj&dGNEwB$bR=t_nyf_8#*(M$U)2sh89^ zEG0^5+3@)A1119gpP(5w--JGKGJQ_AWmIgQXXqCbsSauWJshcKo>}6`D;E298vu3nA;9i>6|>5E``)#0JzfxN4|mk-~5 z=&@RwX1BZKeFoLxaVQIGQ$q8Z8AfMUTJ$UIaJlU2dhc<`i#F%FOsZDEzy8M)8(;WM zGS4;>ADM&Pr4YWw<*CAD)7pjJqt5?LT&T@A47r-SBA}LEn}pnUnI_Y0<~5=_Xgj=l zAw++yPOi|}?iXUBqclf)@g`E^du5tg?ODk!x(BnIsiDi9X`A`zfln37>eoeA8a2_L z!)_W$LZiKt1lK0_3F-fZ@dTIav7vGObI2e8b_;IjTmPvtrZJ-dH~ruK`SB$vA!zSo z>+=1*)mgkH3D4(^3wi+->k4~P_DmIG%f{~R#P06@y41z5)t!2M+)7k zS!y0oCX8`($?L|(-2@6qT7o`yXRrQAM!JQR`u}e&=%e}7_epQ%U z=@q$uN|}pzRYRD(V*-M1v*N*vqS{w6Q^O+_c@KAw{ojwGRXG#>W@F?p#LsGM&fLVU z_a7Hb)D~rHCIuNyTINVpV|uEV9qkHeW?PP_s!vHp(T@DwXd7x#-Fix?uqIMHFh?rE z^W7%1Yz&I?n7n&Y$}<5H3VM1e1FLImaTOZXW^St2;-di)SXVz<58|3eb^Yi^)eKAP z6p>hj;AaRpdh09nGZ}90?f?|~pN|<<<%~s#(cbej`RM2<$Hp!>R~~~|T5qU_l40BO z2-F&0(RhX18)K3G_~z*zvi-;b><6whc+R&U{j5U-)xw*Z8(X?DbcDDoFC*(Rq-E0H z+n*c%D2%u4tk-5;CXa!5){y#hWp7#xycCV|ZJq((22Y2jidxKbrcr`;d0IFr{F|Cv z@vZ6Y#BpPJTIv!E5#I@!Xi`<6kQ&}#O^rihzZr3nlBl9T*JeAoP$p{a0a^tn!%*uQ zs1R*W4caAkE87b@(N+o|6tPK=W|_n#A|h(~L9p`#v+SKXZ@1)8HSy`kn(NPi`r&|G zosz5`O668XX&(AYs4}$BDP;&F0aE$XH>G%3*i~ZRqRDQ2*iG0e5d$U?E$<439wGFK z`qTY9tCyk{Z@P?$jt@tQx@eI8g6Y@G)yB!gg;{4kI<8bfMbg0>SsbN!tX&CuhCXP% z`WK#;{O!XVr4EQbo9dTE6;i%giUMcO%btbQ{lGEGBole<7lK!g70PoZ$3&w~2&cdS zJUu-f-#ul|LOFu*tkDK&D@tWTj$RJ@qlRhqI>=m|ck{NN8H0c^uT93W9pg>kk0Mn! zgbJ>BUmA^NZN$)OqJ&vlw^rb)E22pvM0^qrztavQH{Spv;E{riO(AcwQ(dhU50m;J zmy{MyO<-zoD=HtyU^(wY^?mwuLXLhGi`o#`oClj5B~FqTYJG(`ZGkW(I&2c}T#6_a zlCm4N;pN9+pQ=)r6_2fWLywHR#Q%MU+JVUZ~so zQA31aA0s+#Ohv7EhtgR&QJE9wLxbz&Oo|7O1tVStW6I5Aih4c!Sk`i{0F&rE>J^5=AddNv8NQDa*Y#6g;%^SdA{)2Fo+@RI5}&)6el0}}VO-!OC14p7|< zz7)5>zR-?-?3Q-cc4AhAEBM5;;-Du-J=rpKEg$wx$FL^suptF8QCdnT@jKr%v!P#9 zEQ3c@)<9aRZ~zi!SoGggo%Q0Q;ZMcbN+usfZ;&-xQQMPGMbnuv;!Rkn!hY%skYQj2fg#zcvRSJX#IK9~kUsvnI0VXXVx;2%S4DElfcTJT|(* z<>a7ww+Lk~Mj1ULo|{Wbi>Q{;bF`Y*57ziF)#ypJt1v_8eoizM=Rb(3dMI6# z9!l1JK9zBJ_3F8z6wVynZA6$Lw?!$0m#{?7t&uk&(SH{5YuA@&gYL0lqa%OZ{GmGDbLvx&UdTZJ!?X zIxRj)7eUSFq|bnz&~2m=F{Qf@D~X8Gfy;?gbfT(6)6(+Jl#`jId?TmAMgb4|f;9YK z8Tl0*tyF$mZo^=40pDM}8b<{jW~i=L73>J>XT2ttqyIyc(~MJe^`VS8j#yxyNFhpZ zuH5iU4J?GKdM_G3;kIwyESq_ftz2YF;#DXI`Obq_dxJVt*=kc@%?#I=I*~l9q7or4 z7;k+^ZKvd4wW8RVNnWIh&lXax$A0uUKwm9CTQLm4o*Vmp? zHZ91@GY>yqYzIe(!$7&6N?J@|P{EQk%FI}wkh*N-^1I9!aTi5km^V|MtZjqHbs+Q^CvcMJK7tQ8(sM<)S}V%pO26% z=9lh=qb05}RYx^%$CIk*t@L#36vKjC&{+=bxQYEFW-9<3UABGDoJPpfS+uT4- zAOjuEeW22!EE0V{CG+Sy(WRgMJRBeHP|~4nDf84Yf!j93!&f8c4npbX8PB4)e&#U$>6l(r*)N0b;4)7dFb?*h7 z>ZC}N5heW}t6dzd%w^)dLYI#-7;1{y-RR)4MS`ni1k~V&@HvqDsG?F|2xMfH$Tdvs z639|jRnz`j6k0P+SUn7Tlh{$5lHcCmT^7AvQ|+;xzXoWwnnZatKrfX+(=b1`R>PJ< zbKLo(8I@Db$8wD_T*R$T5Xim_iN3(xz~ zC7E;rYOu{bh(KS&srX=s8dJvxTTXmJyqsa(Xm`Dh|ErW)GXjBFt#u&!Zan#&gKrm8 zp=F1WyseY*N{Bjj8M&GBuXJgeq(WcI!153^sV8#2BrGAF-0urGlW}1q_jO`Xytw>j zX?zI^hMCNA3m~Y{0y54R+$J|^VyPh037kBqo4S(glJ|u2X-1Gc97xxrM;^&~XHevi zhlxFkrn)shWg*;_u5@5xggyX^d9iRUyEhqbFn)wblbRm~_ZhZ5IdPhhUVKn~SN z1>qHokmeTEEcB4h@awY^8~y^Zfn^iETzWeRzj?inkIw~QN!+`8=DQ`8`7of!<#PA@ zNZCM%1i>HqU@2_-0k)_by(7l5(r^Glp|8ZVl6{gmVOEN1ceY(0#Bot^n@rAlmhK!> zh_>P_2%^pzyUwti&BD1irS%9-Af9G zG%s93RS(lHKh)6hzz`E@Wp8Ys(F!AuT^3&0R4ga>TB7b|IOssyE|*cha!iw}BSmiX zGph3m0@7K211jUR1{hztdJOIfp=f{4Vhwf*;0CMND6Njw@yOrXNueo`5The7d;BkyY`zcckuiFHx(q#@F#<5Bbc5Zi@WoA|GOg^_k zKYJ}_nR~g9MHT{xYJDy$zmD57Uy&~x=&H=#oc;doccFkfO-t++(4LaAw_Cc`fwBOP zzbrxH`ls0kis2YIS<*JfS^n%s_j7esj=-+PMH@9(cq_e3JbO%;W&~xDnYc0!kDHjG zUrjU0wJAPT} z4mL6ipZ15N>%~|D2-|&v4grL^+F3{qZk^alE+!50Za|>RV5-TezR`$1Kxwy8#IyS& z#;Vu=qz$MI{aL-w)(LR$yTP317yyPt8r_K}2OOKVy_gLc>)wQ@~3>YpOp5MPZOKTlq(oj%lq(7;h=! ziDid-73-Z&pk=A$eB4?>FLCq7+}Bp5q2NJRD813bkM!L`P^+#d`}^2U$lR!gJsQ13 zS76D%O9!Rm=Xq5FSWpU#0>t}^&tz$FcJt3nqhpTRgQVz>g`bVzYvv^Nz`7j!XAX*< zwtQ%d5@5N_0}-`MlEP&$OvaW(q$=-rs1+v)-)*Sgi{o^)efiox&NLyTuu7wd`50JN z&C;pcAnhV;B$Unt!YM|!0XSzi_&$Rwhw_qV-~P?IXm%NLIa!z6U4`2haLn+D+wi|G z%RUFioOrFR6&rp`zn*y#8Zqn1-d~1%kWk-@np-cHy$CuSK>{g1h;I02Qrk-uSrX?G z`&A5xomauvuhbGc-=4X?^#YdN=s6S8yMjd=*&z=%F;n;MNz)*X!a@120+;fFQQuy3vkuFe6f@XlWf}xwg8B5Rxga ziKNoMq}Ez`+*%o>xE7rkU5>(1tNc*TWmpz|w+2y?DnhJ-<0UE+71q$!GPkpehkY+PJSdiRZwX~j0+e7k$$l^5tZWOYM|_V@%9v}F^*|p3xB=V< zM+G_mfE0&T);ED0F0tNj-UjzaH3sr^g8xt!ak(MZ!`fYv!`l+%Q$2n9Bpi4JFM3T8 zLuLtP0Zc?kYUP>C#fy*+6i}~hX%qBoe!OXDGkHag(W7xnI+%8wP|ZAC#ndZ(uZ0hS z8cnh8Tg0f3cFJ>sh=gz!D7KtTN>|vp7-olJB1Vc)w=Njj$+4PQCVbip$)12b~Jr%Wpv zyJ$u+)4FRA=N-X~vMp#{#(>58q>Z*5lv+`sJ?IlDMz-WnCJoW6PJ|~U624m~DN9l&s>OUt z0&2E=0Z;4O@_J2C?Oc0DU-WEHd_vAVJ-Ybg=&tfF(mr}z+rZNoSaXzws0{mCrNXpP zGP24x)VeXJ&X(Fw2)`G_7pcDTT-cT2Tg{SmBBDzr#hINY)aRw8pKLzgvV1M!a zXVQ9&oj#7?S!O;)BE;^X{99K`k6^-t#4g(k@$`rg7*IY-X+yRAzx# zlJ&L4q@m28BaNdS#de^G#vb*NwY?qUsrCKHo5V$a=fIcc%M12|!m4=y=XwrIp^KRp z4vcDTU$^K=9A*mUaCUuzK;0FF3f~!@UiZ4J7w{3fE9x*;z8(Ovi=X$4`0&kj7#j%Fz{JA((31c!$ZM^{@@0(rGk^5hI{#EB-Lb+Nn*|a)I&)})Y zO2xw@f|_};BwmcY0}pEmOLMuLV(`T_?|!mP4G-c-lv*+7EJ2}^h@>s0UBxPD1O{46 zuI0fwM2;)_yV~NA8*_%gLP;Q4U$#k+blwX0U~X9l}W5nerZBSDFxI;ncQx4$6cUUSrH?FHkD8)h#=U1Cm^L z`Fp5X;Nub!CO(3`qiJ5(%IOzm94Rt+B-fyhSkPfao~H3iQyQv}x;`c_Z{45vzB=X? z6qJkw9@U@)A`;LGuszs5+(Gy6n_xb^?SMu^jZ``3(Bd%^BYlv^(DzfooN7Ln>yfeP z%DSP=thw3VX}{jr`PZ`(Ofn&_dlXe~@xz{9>(N)B(lnQdw7q>zQ+ zyCq2l1m%%tEGM3e%6wrd;>(=~Eoz;SqWe*tY~-2)tqQY&A(--pbPuv51RCpUiV`qp z?GHw>w~12A1zrdwQS|x9Z~0p$#v(x4N!-arOn4tdGLy*HiEnMuuiAG6j4X?d7HYhY zYCCYO@;&FTQs;TZ+m*(qmj;F}#K89A#J9vOEQ|FkQY5hx;cBrW<+gqePN8}Yr*?9R zqwI%CP{0Cy5(G);6H}r| z9x35H+@V`)W{=;E&OzNR(2En*Hvf+eIv3#&*ggPOfWoZSkr#`Kj>}?!GNV`Q-J^-p zj)@Ne^AjHtLdLDaf*-#GqwX6;CFn&kHiqb6YH|uoP~Z{?tauSn@_{7w9Fp`;2tQ-VLo*(T=jjn_rzYEEsjkH7!Y zuFkasua(8bQK!U>gP#+{4c-zGFyX25Ljq!$ZN5ZXPFU84h0@&5o)Pd7(U5uq4L>vn zns!vIjjA5KkEK(}?w`-KSmKdDHE z(sW#$PyjE{j}&oH6wiX3?(DuF`_yxhqJL&Z)?SPisYuA_FoDZKl6$oC6ZP8Us;fy~ zM$cS)YrvrcKA)?;1k<>cp|Me3;fy2W|X(N0J}(9GLbLnz1Jt*6Fr=AFM^|(rBIJMTw@d z(p{614-r0g&XYIYg-G6YW3JR?=7O~05zf;rCF|XV$>q(I zyfi()sd(ihBhXuOQ(zAU@?PvCArq1fL#JaX&mz$E$JN zE?;ObpFnCqsgFTl$~a)9M@ii< z8)t^F-_0<6cVA@PHyT@`Y~>WLFBh0-{%c-tNJtUSIfs#s)G@Byi^&1+Qrg7?Y9h#M zLJaRQRY>F+OYZd0p=`g@*NX%aSl&sp9G)h^+gcfBZp9L#zBI@L@RqR>UU%3AhZBGy zY*zjgOY{ZpCJo_lAsbEc{8S+JMALV`SP7u%_v^hc>+QGJszLF-J|>r1m@)nSMKW%P zL9ikE7rMiMSP9UsY6UoZxQ7BxKl}58(SDDAStum}VgMz6vAuq_x{gPPHfeVuk%3RB zVs19psyU)T1M|GWz5t7*j3SuOUxC`Xiz7>=f#Js)m`b04k66+E6kbQ0s;jqCsV%vn zZA$N=)*J-jpuywdii^cSgI@y&s-`^NRgdxw^pUBCz| z=>foAW~PCs@~DT@ypm6{!XOaLD^W983`|*1-NYQ)kmWh4^~^kt1U{@aK@J&t-?3>R zX9V9L#x}scMSPA#`C-XFszCd?ZFz64&2fI$NKbDH$zVkw)1b6zS!|$|)L*MF@+P5} z!qJZkJz4sjMzUVcbCunz5awWOf{Vcxmtqdcs>3ml(?Cu>lUi@ z^^$#C}MJ`VUnV6UWRQ!KgS^*dRNb@DCIW-6c{SP*G?k-aR01|#k>(IGzQAJ<3 z;+QVCE5w!etD4N#EKe7+k3VtNLC<~>&~^Yl^JvCe?{+bVS4mmL`*eoP_(;&3+mn9w}JGG`SteKMx zz#m~eg3Yx^jpk5nNoVgvUT^HX`|x*tcKid|&(qsO52=J-zhGowjl*}*Zo)!A8@NsH zknCRY;9A8~<Cnoo*bVDNjPe|VE0W1>`cm2JO$ zZX<1gji?L$1BAcM(KjG7iGNF|K|{@`l0l_#1M!s@RpNX7r53Wa)(AW;NeAr-xwabk z>44Uj{g*d_Q%w2JNTIbMJ6SH0NYipSD6|R1Yw}}9*g{ZRmO3-ZDs5WU$Ucute*Vt! zG4eN;&4Ep!?V+tL6ZW;?Cm`1A%{#xSX#dmp6Xidbubpr#i9Wz#4!o~A9Lh2WcGO6l z{zXjq^Zd^8nDP_q#|Lx<6jjuHCy2;?-eG-h+lr=~F4793kdMOvJGova!(+GvZ^1Bz z7}}|70Qx$-Tpz^ z-yFIiG9rhy51}x6*BROn{6b_7Nd(`PDSUQ&dky?Yi23)s9d@FOT+53lHJtN_Hz5(Q z?4V{gLd2ZOMdno%KY`6ylJ~}DK204BXaf)T1w_3L&mtkw;$d4k*1H&eQAI83P;&Dq z9CDH~!WOmybI#gBFiN60BVDW0mpMeViwlzbdaX++N%%M&V-+!Cx8v{7aJ&cQ%JPL) z+Xgya=C~e@k)p{uG)2D%6aFsAp0Fe>!Yp{Y{yE~?VS`M&gC;j@7cJfv2^-?A*Drub zh&fqI;YpV=qqzVmRzLh)UmtvZl>p3+{}*&*+UbeZZ9;M&wS@eBqSk66El)0I_i-NM z-^Fh~n!dsTtcib?#`{HY4@H-|(Nuf?!hHJp;r2n+f$5>Od9ATXA7dc}iVA-xaKnSB zx{KWsO(cWJ(i325RYis28R`6d8&rgt7%PRWf3I4w`13V_f zG~T`7Yf!!$8MYvtpsJ*xlEmk%#!!Y57SN}Df$I|KHei4LTb-`18ggwdZS1umVrem? zaKMP8oWC$w&wph?>ByLzS1Hr9eO^{yV-SOQVXi!XNiy(_92*iRKG|5sYGB!jiGvap zTKVddaZ@3e=uA`$t8E2WRM6$J-mxbX@xy~ah|q;}<^i2AtZLchpl$Bg3HssFLg-+) zWexfBNEWm)kxQMwX!d2qTs7h6+(fjp4R~~gBY=km%#uz*xLPeePfud17H=OMO!Y4< z&Skp?XdBes03SiBSnRqC@mcc}(vGze9ZI0l7R1OMF%!+(+uMT$?t!hX?Z0*qusCZ1 zL%4HP-Q3+n7Z-Ja!3-X#x0s)&KyFkxMfLyu73IQ$ufL&X{3^|7368X@K%iQH-rTd; z&AmmmHSXM-`t<2wGXZWIHN>9^yIqAC=T`wwkVye9je@@_kg%wBOO z#hGk_tJsm_R5^;G=IB0J_-?c=h7P+M30LgbXbRQK768IBN;q1T7epr0qq<%_j$lm4 zkRVW%D8=REwfvLNZ}IXc+vGiaD}PtfR+g0a$ndWK9L)^r`SU^kk*pRk%+nvJr$0!S zMV3Zf<4*OeOql*`ifFU}Mal`FQ5+u=yLP`2x)g2<0WXio7ntTLU)+Wo(!~?>&s3kR z&3HR5b{>DDV^K;B9XylAKagJ!!^TH`-m9wBJ6l-7jEas3m+Hp64t0N7-IT^=5yObTC_2uw#Ui(~%6 z>yIwYi67$K*duOTA&Dl*0?JA9wo5lKHTp1hU!lizLI~#JT`R9~Gj+=aIU^?0653CzNVBZH|%KJaQ zz48CEYQ4Sn;Wvemea+plZ$Llk%DFuxuzq%*TU(xbd0(=b#>4YF-URA>D3;89^L6`t zRI}M*?z2g-EgqH)1S5rct4l2wP0)&j)~b)eMG%G*7Q-T7PsOj^g&(0mt_`alW=s)5 zn~#@7{wfwVq*7*~^Z1Y}4)%w`**ZTAkG9O!!u*M0ra{B9T|z9)=L82Wa~@v*eo<)m zt7!ZUr_~`pb00rr=H@}zw`JdLgXoyV&g#q6eTDmXZ+CBSzCB(@YQigJ(O8$hZ-?jq zxMTo6VJ>)0p^`aCpkK?7KqEKcj~dG(8{7C^#Zjh%{)={0MRWfhXy}m{x`<|XD5ic+ zL235M5v{Br+q!{>JvM!swVg|@pY;Pw!R&C;vt3q@?^PkN{v z6p02Lt+0SB%ifUQx2Im$O}K{MmX>hWz|#+=puZaX_ezM#&&Ivmqw|+MNv<1x^Yb{b zzh_^kqV+M5ev-QGUR+>@_fzM_qKnWfHrX`fE8>L=fYI>!5^2=Cd@}u+7zE5j8=jwH zjI$s&_I-kyxHDiYxwxSi912l}{d?(?$k~W6ESc*{v4CdDv{Y3qasN!~u@-VQolnWW zD5(KQ)_kmv5C-XD@e)E5 z&61j^dd8J`+z6O|q!^P%f9dz}+(N=M1}PYL#G@uWI);XaBhRDupAE>M7tr8W==`e6 zq%3S~Ty6=Fd7HX(s?xzqO{{U-%)0_(iy|+M)gOkhsw&uoh=^JH12_H<7OPFZVFhr5 zE7DD0=pc4_=OWMRB8rKoN|(xuK-=$ zI^oW)j!S;%aiSI5Le-;tB$-J!iNT$+@zt7IiZGDkkdv7pX5r3^Iq~&Wcj`1e;yJ5GgZ}V%j6{VN9px<;x=^HAt zv}w+zyjePMN#QEGcNtb?oaM{3nUt|BAMYT1VL>i01Sq@NS7=$Pi|xY3H6Z!jG9SGa zfo5KgTvehiCq!_3EQtBRE-II2p>+E++_|FMb20i;q+*P<;u)s7R))*;Nh^foJ^RL^4c0!Wpl|&QeA{Co35aIrQ1TOk)cV~zC zw*R^I4f-~M^zI%86nSZv(EPh(3 zBb}N@Iwkd_#Lgvc!xkL_7EN(Gb?F0Eyi$ulv3bAjm}#wGIK`AU*2_24xbqa0)=2x( zpRzG(zouJ2aEUS!%M+h?L0e!BfF8g@`MI&BCBDD-^W`$(t&cAcc_Q$C_+U8P@85rb zdql&9N`?7_037~?`pQ1R(QmLSi-Aj1)%W~K#KbWKu{^V&>-%r^LWwdNUA3w?LSPbx zHX1-0gP!5BsQw%I)^k&Ip%DC6L0C*|@a5_5Vvs5*0_)u~XtwC7JPdM4s9!rF<{h`8 zz-UGC_#c&+Ljsq19J{>+e+Nk^{C(;d_#y-9txDKmIk$!>th2O5)$J@*_#X*j{MzL4 z2Cm11R1!7qi_CNmB3B+@1qP-i3CBu6&@i$}$xjnBt#jJr)yjVwYL>S?P)Qa>+NWQ6 zhZ=IpIc|gcJkt`P`HA+CBP6z34X4>s03E(Ddzz;s+ss4aGBPMZE?E z-8MN|H|Avb`Kg&PW5UX0Ifx_Q5+jor_S8(c&rf`0*$)jM84`aU{RtqEzzbo6yW+FV zf&%a9+1=~n`QE$NnQtJ!__5JVTVjl8zrQ;vuF7-g`)udk(RVEkBgj~SEH-e~_Hxui zE@B{WOIih!IQA7)s3yWBLqw8@cjAaaoxa}B_JAs-bh!)}Tal~MJ~Qs2-CY{MH3m2- zJO^hd^G~110D~3aD@edHOp1ei>tv}}X!Cehy|?^$00=%{{oBm*2Pimmtv7nV4e9uH zSH`(B8orJ&kec5u_Zr}+{_}ngdWCL>xAleta4B?l_Tpe1FW|Y1YWLst!zs;+!L$~= z>7Q6_YQ?;YuRG+8o7|$RFiHtxh8Cx*+yC^Z%XU{n!Mi%7^1UqxdXH zV2G4lh$q>wtw11to~S05aIBhcMBkeiscXS$aHz$0o2#R2-VGkEY&7vyP9fFPD;e`- zC+s&rO2u1>nBui{MvuO}t8X-zvJkyEIk9JDFS0YGny<_-I2eyprhH494cnH_evWLQIm$Rqdv)72g+J|HXSGwdB3v6)U4ltJg;I;+^Bfz6 zi5F)vvh_*uI_Oup0_MA-Q42G-?v{}@R3ohybg?egN%`5=C-xm$yR%dLg9%4(ERX^#5X+ zdp+FAsi^k&mS0@CLjH>mczMK0`s~`bM#`8Snl_Fg@pvq=(R;^re_Zz2?c>L| z%FE%tz)H*5=8O2A_vxVyZgVA1%7vdk3mZPU#73nz^iyb@aY^H;Ae!z^55gSU2jaW$=#pzxi0`P2R-JJN86 zZh5_jfqSAw7X7xj@70cdG*${Q>|FWR6t?+XSSW{s#Mc8%PUuK7e?JBOhQH1Y znQT;k1Z6jkUD8F;O&g0qyL{K1l>Nr0jbSSTu-efXuexhho&9J2bmPQW8KaVD%v}3! zXPMg?OQzp}@yGk8+4VB7b>nDqs(XEZ$I%(4E zB7v?y)Fp(z`hphTI6+_*0y?Hnv1`Uq#8e`KwyF1$jve;_giCJ6ryl^uI=bx}6FVVV zexbxLV9j;ek3_Wt*uS;6XYX0~!+@Aow(Y_8i6$`vc1+6$J!YT1gJ9F4MTVW)gVz)O zfAEm%mVq~H|7AA+d1}Fb&AOm!lv!0}g-kkY{~2NR(8ubC*e(P1F3-<1)!1B<*;YRO zhU|nr>xz2j9VYw07#OeF5IWN~Qi07z@liHYE*4OO#M!?zM+a^D-XCK;0%%^ponrz( zxdeLCwf7IiUKN42=0tUV7&*Ke@#c8UV=`Ce=~ja8k{NuWO#t|(_@o}JJ5&%dYM zUqekFHX|U(PQbe=>QDPvIAK=T>>mL?XP1w-5r=I;p>B6348^{^qo-ZR0ne)9MOP9S zj2m?? z`w^~^8djk1-ffwc7{uy%g9`wxaI zhgsde&wS+kX%NpkG%_)U0}1pgut%RT`L)wO%j4+|XvKINYJW_8*+KNo8ujQv2Y-y~ ztHqfp%9!+Gy5uQof%e15}?!tE>@7vKKzmClB10Za6#L7blF!*6bPe`d|w zz`GCEP@coP-@nl{iX?_Dcw~$}nfL?duvzO&<

Kbg>oH&6wC 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 JtCBYh`5#td?q~o2 literal 0 HcmV?d00001 diff --git a/assets/images/new_background.png b/assets/images/new_background.png new file mode 100644 index 0000000000000000000000000000000000000000..974ec90b186331db4afc4810114ef6e5cb9eadaa GIT binary patch literal 186088 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 YJNJ(I8VwsRM#ubmsSV|##io$|18*8p)c^nh literal 0 HcmV?d00001 diff --git a/assets/images/new_empty.png b/assets/images/new_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..47b9a235da27e6584337e643bfed79ec49de7780 GIT binary patch literal 1143 zcmeAS@N?(olHy`uVBq!ia0vp^A3&Ic4M^IBzMKT47>k44ofy`glX(f`uoOFahHwBu z4M$1`kgMqF;uumf=k4wFMJcWl#~yCi^hrvNlvcTM)UB9*qr%PC9Ac+!8)A2Fj7Vzk zJ$uUSOrrColh5v-DXF(UA8h(>?X1tM-^~i13^bV(uwnVF7mQQC-s^YEzcK0cwOhw8 zDp$;Dn7`tC-JB=wD)&_^y^1W#E{4Ub|J=H@%(9AOzWM|AFZb@N{WM&i@x8NyTi^rp zwAUXqCp|tG>?ZW_3Co^iLhpCKxxaFEUx&Kd1M4HZr*)`*z50UD_~l-Cm7kiA_P#ba zslWHT`QrA1*$w&Do{tn`{f`I>eMqvb^>=$eV@`*<@&jr0pPTN#&Fkt=S9&0QzfUfp zqeETsLCvqHmG|#`kJFn!UFahV%brdB{0~bfZSL4%!nj_hN6z5Tr*>9BakU3i_tw7G zesqhar-NJAz|$pWYQs;LBVRdYM7zXvH|%sjQpz!7t4mCCL*;~y=jsV|-bads4f=&X z?qNAIxue35>Dfsa8+pdhI!g1p8!F8N&pRL3)6wxPnb(osstIO(M|LYGY;!uYTQOmq+mYMq3ERAm+*VE4=6B?_azdHY zk=u$1Wo}1it0$CYH4D~npXs`lbH?1;0Y_X8@F+bxD`0TANfcfuluRjx5O`ea$omtea60~wc-Ert>4n; z95UYBbNRa%<@Wt~$( F69C9f%VGck literal 0 HcmV?d00001 diff --git a/assets/images/people_avatar.png b/assets/images/people_avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..07122c80c3231c2fbbe268173b4d2306941874eb GIT binary patch literal 61111 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�yr>xyIb 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 literal 0 HcmV?d00001 diff --git a/assets/images/read_message.svg b/assets/images/read_message.svg new file mode 100644 index 0000000..5aa3c6b --- /dev/null +++ b/assets/images/read_message.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/bluetooth_edit.svg b/assets/img/icon/bluetooth_edit.svg new file mode 100644 index 0000000..36ed11f --- /dev/null +++ b/assets/img/icon/bluetooth_edit.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/assets/img/icon/expand.svg b/assets/img/icon/expand.svg new file mode 100644 index 0000000..a0eae77 --- /dev/null +++ b/assets/img/icon/expand.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/history_store.svg b/assets/img/icon/history_store.svg new file mode 100644 index 0000000..326df56 --- /dev/null +++ b/assets/img/icon/history_store.svg @@ -0,0 +1,10 @@ + + 资源 530 + + + + + + + + diff --git a/assets/img/icon/message.svg b/assets/img/icon/message.svg new file mode 100644 index 0000000..6956b9f --- /dev/null +++ b/assets/img/icon/message.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/people_info.svg b/assets/img/icon/people_info.svg new file mode 100644 index 0000000..860629a --- /dev/null +++ b/assets/img/icon/people_info.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/return_buttom.svg b/assets/img/icon/return_buttom.svg new file mode 100644 index 0000000..4788c77 --- /dev/null +++ b/assets/img/icon/return_buttom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/img/icon/xiaoe.svg b/assets/img/icon/xiaoe.svg new file mode 100644 index 0000000..f996a3d --- /dev/null +++ b/assets/img/icon/xiaoe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/lib/common/util/FitTool.dart b/lib/common/util/FitTool.dart index 212c2b0..3c83270 100644 --- a/lib/common/util/FitTool.dart +++ b/lib/common/util/FitTool.dart @@ -1,5 +1,3 @@ - - class FitTool { static double rpx = 0; static bool isInit = false; @@ -9,7 +7,8 @@ class FitTool { } if (isInit == false) { isInit = true; - rpx = v / 750.0; + // rpx = v / 750.0; + rpx=v/1624.0; } } diff --git a/lib/common/util/MyUtils.dart b/lib/common/util/MyUtils.dart index 76c1121..97620dc 100644 --- a/lib/common/util/MyUtils.dart +++ b/lib/common/util/MyUtils.dart @@ -2,10 +2,12 @@ import 'dart:async'; import 'package:ef/ef.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:intl/intl.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; import 'package:vbvs_app/controller/setting/language/language_controller.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/language/AppLanguage.dart'; @@ -361,6 +363,37 @@ var returnIconButtom = IconButton( icon: Icon(Icons.navigate_before, size: 60.rpx), ); +var returnIconButtomNew = ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(right: 0), + onTap: () => Get.back(), + child: Container( + // height: 42.rpx, + // width: 42.rpx, + child: SvgPicture.asset( + 'assets/img/icon/return_buttom.svg', + width: 42.rpx, + height: 42.rpx, + ), + // SvgPicture.asset( + // 'assets/img/icon/expand.svg', + // color: Colors.white, + // ) + )); + +// IconButton( +// padding: EdgeInsets.zero, // 去除默认 padding +// constraints: BoxConstraints(), // 去除最小尺寸限制 +// onPressed: () => Get.back(), +// icon: SvgPicture.asset( +// 'assets/img/icon/return_buttom.svg', +// width: 42.rpx, +// height: 42.rpx, +// ), +// ); + +var returnIconButtomAddCallback = (returnCallBack) { var returnIconButtomAddCallback = ( VoidCallback? returnCallBack, { bool enableBack = true, diff --git a/lib/component/img/img_default_widget.dart b/lib/component/img/img_default_widget.dart new file mode 100644 index 0000000..e16d5a7 --- /dev/null +++ b/lib/component/img/img_default_widget.dart @@ -0,0 +1,77 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; + +import '../../controller/mh/apply_repair_controller.dart'; + + +class ImgPreviewDefaultWidget extends GetView { + ApplyRepairController applyRepairController; + + ImgPreviewDefaultWidget({required this.applyRepairController}) {} + + @override + Widget build(BuildContext context) { + return InkWell( + // onTap: applyRepairController.uploadImg, + onTap: ()async{}, + child: Container( + width: MediaQuery.sizeOf(context).width * 0.25, + height: MediaQuery.sizeOf(context).height * 0.15, + constraints: BoxConstraints( + minHeight: 152, + ), + decoration: BoxDecoration( + color: Colors.white, + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.116, + constraints: BoxConstraints( + minHeight: 152, + ), + decoration: BoxDecoration( + color: Color(0xFFF3F5F6), + borderRadius: BorderRadius.circular(16), + ), + child: Align( + alignment: AlignmentDirectional(0, 0), + child: Container( + width: 35, + height: 35, + decoration: BoxDecoration( + image: DecorationImage( + fit: BoxFit.cover, + image: Image.asset( + 'assets/images/camera.png', + ).image, + ), + ), + ), + ), + ), + ), + Align( + alignment: AlignmentDirectional(0, 0), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(0, 8, 0, 13), + child: Text( + ' ', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 11, + letterSpacing: 0, + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/component/img/img_preview_controller.dart b/lib/component/img/img_preview_controller.dart new file mode 100644 index 0000000..5652db0 --- /dev/null +++ b/lib/component/img/img_preview_controller.dart @@ -0,0 +1,23 @@ +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'img_preview_controller.g.dart'; + +@JsonSerializable() +class ImgPreviewModel { + //版本id + String? url; //图片地址 + + + ImgPreviewModel(); + + static ImgPreviewModel fromJson(Map json) => + _$ImgPreviewModelFromJson(json); + Map toJson() => _$ImgPreviewModelToJson(this); +} + +class ImgPreviewController extends GetControllerEx { + ImgPreviewController() { + attr = GetModel(ImgPreviewModel()).obs; + } +} diff --git a/lib/component/img/img_preview_controller.g.dart b/lib/component/img/img_preview_controller.g.dart new file mode 100644 index 0000000..869e00e --- /dev/null +++ b/lib/component/img/img_preview_controller.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'img_preview_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ImgPreviewModel _$ImgPreviewModelFromJson(Map json) => + ImgPreviewModel()..url = json['url'] as String?; + +Map _$ImgPreviewModelToJson(ImgPreviewModel instance) => + { + 'url': instance.url, + }; diff --git a/lib/component/img/img_preview_widget.dart b/lib/component/img/img_preview_widget.dart new file mode 100644 index 0000000..af5c52a --- /dev/null +++ b/lib/component/img/img_preview_widget.dart @@ -0,0 +1,80 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import '../../common/color/appFontsize.dart'; +import '../../controller/mh/apply_repair_controller.dart'; + +class ImgPreviewWidget extends GetView { + String imgUrl; + int index; + ApplyRepairController applyRepairController; + bool isDel; + + ImgPreviewWidget( + {required this.imgUrl, + required this.index, + required this.applyRepairController, + required this.isDel}) {} + + @override + Widget build(BuildContext context) { + return Container( + width: MediaQuery.sizeOf(context).width * 0.25, + height: MediaQuery.sizeOf(context).height * 0.15, + constraints: BoxConstraints( + minHeight: 140, + ), + decoration: BoxDecoration( + color: Colors.white, + ), + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.116, + decoration: BoxDecoration( + color: Color(0xFFF3F5F6), + borderRadius: BorderRadius.circular(8), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Image.network( + 'https://picsum.photos/seed/73/600', + // applyRepairController.getPublicUrl(imgUrl), + + width: 300, + height: 200, + fit: BoxFit.cover, + ), + ), + ), + ), + Visibility( + visible: isDel, + child: Align( + alignment: AlignmentDirectional(0, 0), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(0, 8, 0, 13), + child: InkWell( + onTap: () { + applyRepairController.model.issue_img!.removeAt(index); + applyRepairController.updateAll(); + }, + child: Text( + '删除', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: AppFontsize.small_text_size, + letterSpacing: 0, + ), + ), + )), + )), + ], + ), + ); + } +} diff --git a/lib/component/tool/CustomCard.dart b/lib/component/tool/CustomCard.dart index 69b649f..2da20f7 100644 --- a/lib/component/tool/CustomCard.dart +++ b/lib/component/tool/CustomCard.dart @@ -1,6 +1,102 @@ +// import 'package:flutter/material.dart'; +// import 'package:vbvs_app/common/util/FitTool.dart'; + +// class CustomCard extends StatefulWidget { +// final double borderRadius; // 圆角 +// final VoidCallback onTap; // 点击回调 +// final List colors; // 背景颜色列表 +// final Widget child; // 子组件 +// final bool enableAnimation; // 是否启用动画效果 +// final bool enableGradient; // 是否启用渐变 + +// const CustomCard({ +// Key? key, +// required this.borderRadius, +// required this.onTap, +// required this.colors, +// required this.child, +// this.enableAnimation = true, // 默认启用动画效果 +// this.enableGradient = true, // 默认启用渐变效果 +// }) : super(key: key); + +// @override +// State createState() => _CustomCardState(); +// } + +// class _CustomCardState extends State +// with SingleTickerProviderStateMixin { +// double _scale = 1.0; +// final Duration _animationDuration = const Duration(milliseconds: 50); + +// Future _handleTap() async { +// if (widget.enableAnimation) { +// setState(() { +// _scale = 0.95; +// }); + +// await Future.delayed(_animationDuration); + +// setState(() { +// _scale = 1.0; +// }); +// } + +// widget.onTap(); +// } + +// @override +// Widget build(BuildContext context) { +// final bool isGradient = widget.enableGradient && widget.colors.length > 1; +// final Color baseColor = widget.colors.first; + +// return Material( +// color: Colors.transparent, +// borderRadius: BorderRadius.circular(widget.borderRadius), +// child: InkWell( +// onTap: _handleTap, +// borderRadius: BorderRadius.circular(widget.borderRadius), +// splashColor: widget.colors.first.withOpacity(0.2), +// child: widget.enableAnimation +// ? AnimatedScale( +// scale: _scale, +// duration: _animationDuration, +// curve: Curves.easeInOut, +// child: _buildContent(isGradient, baseColor), +// ) +// : _buildContent(isGradient, baseColor), +// ), +// ); +// } + +// Widget _buildContent(bool isGradient, Color baseColor) { +// return Container( +// decoration: BoxDecoration( +// color: isGradient ? null : baseColor, +// gradient: isGradient +// ? LinearGradient( +// colors: widget.colors, +// begin: Alignment.topLeft, +// end: Alignment.bottomRight, +// ) +// : null, +// borderRadius: BorderRadius.circular(widget.borderRadius), +// ), +// child: Padding( +// padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 5.rpx), +// child: widget.child, +// ), +// ); +// } +// } import 'package:flutter/material.dart'; import 'package:vbvs_app/common/util/FitTool.dart'; +/// 枚举控制渐变方向 +enum GradientDirection { + horizontal, + vertical, +} + class CustomCard extends StatefulWidget { final double borderRadius; // 圆角 final VoidCallback onTap; // 点击回调 @@ -8,6 +104,8 @@ class CustomCard extends StatefulWidget { final Widget child; // 子组件 final bool enableAnimation; // 是否启用动画效果 final bool enableGradient; // 是否启用渐变 + final GradientDirection gradientDirection; // 渐变方向 + final EdgeInsetsGeometry? margin; // 外部间距 const CustomCard({ Key? key, @@ -15,8 +113,10 @@ class CustomCard extends StatefulWidget { required this.onTap, required this.colors, required this.child, - this.enableAnimation = true, // 默认启用动画效果 - this.enableGradient = true, // 默认启用渐变效果 + this.enableAnimation = true, + this.enableGradient = true, + this.gradientDirection = GradientDirection.horizontal, + this.margin, }) : super(key: key); @override @@ -49,21 +149,24 @@ class _CustomCardState extends State final bool isGradient = widget.enableGradient && widget.colors.length > 1; final Color baseColor = widget.colors.first; - return Material( - color: Colors.transparent, - borderRadius: BorderRadius.circular(widget.borderRadius), - child: InkWell( - onTap: _handleTap, + return Container( + margin: widget.margin, // 应用外部间距 + child: Material( + color: Colors.transparent, borderRadius: BorderRadius.circular(widget.borderRadius), - splashColor: widget.colors.first.withOpacity(0.2), - child: widget.enableAnimation - ? AnimatedScale( - scale: _scale, - duration: _animationDuration, - curve: Curves.easeInOut, - child: _buildContent(isGradient, baseColor), - ) - : _buildContent(isGradient, baseColor), + child: InkWell( + onTap: _handleTap, + borderRadius: BorderRadius.circular(widget.borderRadius), + splashColor: widget.colors.first.withOpacity(0.2), + child: widget.enableAnimation + ? AnimatedScale( + scale: _scale, + duration: _animationDuration, + curve: Curves.easeInOut, + child: _buildContent(isGradient, baseColor), + ) + : _buildContent(isGradient, baseColor), + ), ), ); } @@ -75,14 +178,18 @@ class _CustomCardState extends State gradient: isGradient ? LinearGradient( colors: widget.colors, - begin: Alignment.topLeft, - end: Alignment.bottomRight, + begin: widget.gradientDirection == GradientDirection.vertical + ? Alignment.topCenter + : Alignment.centerLeft, + end: widget.gradientDirection == GradientDirection.vertical + ? Alignment.bottomCenter + : Alignment.centerRight, ) : null, borderRadius: BorderRadius.circular(widget.borderRadius), ), child: Padding( - padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 5.rpx), + padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 0.rpx), child: widget.child, ), ); diff --git a/lib/controller/main_bottom/main_page_b_controller.dart b/lib/controller/main_bottom/main_page_b_controller.dart new file mode 100644 index 0000000..ae22364 --- /dev/null +++ b/lib/controller/main_bottom/main_page_b_controller.dart @@ -0,0 +1,31 @@ +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart'; +part 'main_page_b_controller.g.dart'; + +@JsonSerializable() +class MainPageBModel { + int currentIndex = 0; + MainPageBModel(); + factory MainPageBModel.fromJson(Map json) { + try { + return _$MainPageBModelFromJson(json); + } catch (e) { + // 在实际应用中,应该有更细致的异常处理策略和错误日志 + return MainPageBModel(); // 或者返回一个带有错误信息的特定DeviceInfoModel实例 + } + } + + // 序列化为JSON时的异常处理 + Map toJson() => _$MainPageBModelToJson(this); +} + +class MainPageBController extends GetControllerEx { + MainPageBController() { + attr = GetModel(MainPageBModel()).obs; + } + + resetParm() { + model.currentIndex = 0; + } +} diff --git a/lib/controller/main_bottom/main_page_b_controller.g.dart b/lib/controller/main_bottom/main_page_b_controller.g.dart new file mode 100644 index 0000000..390ec91 --- /dev/null +++ b/lib/controller/main_bottom/main_page_b_controller.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'main_page_b_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +MainPageBModel _$MainPageBModelFromJson(Map json) => + MainPageBModel()..currentIndex = (json['currentIndex'] as num).toInt(); + +Map _$MainPageBModelToJson(MainPageBModel instance) => + { + 'currentIndex': instance.currentIndex, + }; diff --git a/lib/controller/mh/address_controller.dart b/lib/controller/mh/address_controller.dart new file mode 100644 index 0000000..63b2f10 --- /dev/null +++ b/lib/controller/mh/address_controller.dart @@ -0,0 +1,155 @@ +import 'package:ef/ef.dart'; +import 'package:flutter_city_picker/model/address.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/controller/mh/user_data.dart'; +import 'package:vbvs_app/controller/mh/muser_info_controller.dart'; + +part 'address_controller.g.dart'; + +@JsonSerializable() +class AddressModel { + //版本id + String? province; //省份 + String? city; //市 + String? county; //区 + String? street; //街道 + String? detail; //详细信息 + String? name; //名字 + String? phone; //手机号 + bool? ischecked = false; //是否默认 + + int currentType = 0; + String? all_address; + @JsonKey(ignore: true) + List? addressList = []; + + AddressModel(); + + static AddressModel fromJson(Map json) => + _$AddressModelFromJson(json); + Map toJson() => _$AddressModelToJson(this); +} + +class AddressController extends GetControllerEx { + AddressController() { + attr = GetModel(AddressModel()).obs; + } + + Future updateAddress( + Map address, AddressModel model) async { + if (model.addressList != null && model.addressList!.isNotEmpty) { + if (model.addressList!.length > 0) { + address["province"] = model.addressList![0].name; // 第一个元素为省 + } + if (model.addressList!.length > 1) { + address["city"] = model.addressList![1].name; // 第二个元素为市 + } + if (model.addressList!.length > 2) { + address["county"] = model.addressList![2].name; // 第三个元素为区 + } + if (model.addressList!.length > 3) { + address["street"] = model.addressList![3].name; // 第四个元素为街道 + } + } + address['detail'] = model.detail; + address['name'] = model.name; + address['phone'] = model.phone; + address['isChecked'] = model.ischecked; + + try { + final data = await ef.client.rpc("get_now_datetime"); + final response = await ef.client.from("app_user_address").update({ + 'province': address["province"], + 'city': address["city"], + 'county': address["county"], + 'street': address["street"], + 'detail': address["detail"], + 'name': address["name"], + 'phone': address["phone"], + 'ischecked': address['isChecked'] ? 1 : 0, + 'update_time': + DateFormat("yyyy-MM-dd HH:mm:ss").parse("$data").toString(), + }).eq("id", address['id']); + } catch (e) { + print('Error fetching repairs: $e'); + return e.toString(); + } + return ''; + } + + addAddress(AddressModel model) async { + try { + final MUserInfoController userInfoController = + Get.find(); + UserModel user = userInfoController.model.user!; + + // 设置省市区街道名称 + if (model.addressList != null && model.addressList!.isNotEmpty) { + if (model.addressList!.length > 0) + model.province = model.addressList![0].name; // 第一个元素为省 + if (model.addressList!.length > 1) + model.city = model.addressList![1].name; // 第二个元素为市 + if (model.addressList!.length > 2) + model.county = model.addressList![2].name; // 第三个元素为区 + if (model.addressList!.length > 3) + model.street = model.addressList![3].name; // 第四个元素为街道 + } + + // 查询数据库是否已有该用户的地址 + final existingAddresses = await ef.client + .from('app_user_address') + .select() + .eq('user_id', user.uid!); + + // 如果没有地址,将新增地址默认选中 + if (existingAddresses.isEmpty) { + model.ischecked = true; + } else if (model.ischecked == true) { + // 如果新地址被选中,将其他地址的 `ischecked` 字段设为 `0` + await ef.client + .from('app_user_address') + .update({'ischecked': 0}).eq('user_id', user.uid!); + } + + // 添加新地址 + final response = await ef.client.from('app_user_address').insert({ + 'province': model.province, + 'city': model.city, + 'county': model.county, + 'street': model.street, + 'detail': model.detail, + 'name': model.name, + 'phone': model.phone, + 'ischecked': model.ischecked! ? 1 : 0, + 'user_id': user.uid, + }); + } catch (e) { + print(e); + } + } + + Future> getData({int? level, int? pid}) async { + // 构建查询 + var query = ef.from("app_area_city").select(); + + // 如果 pid 不为 null,添加 pid 的条件 + if (pid != null) { + query = query.eq("pid", pid); + } + if (level != null) { + query = query.eq("deep", level); + } + List arr = await query; + + List addressNodes = arr.map((item) { + return AddressNode.fromJson({ + "name": item["ext_name"], // ext_name 对应 name + "code": item["id"], // id 对应 code + "letter": item["pinyin_prefix_upper"], // pinyin_prefix_upper 对应 letter + }); + }).toList(); + + return addressNodes; + } +} diff --git a/lib/controller/mh/address_controller.g.dart b/lib/controller/mh/address_controller.g.dart new file mode 100644 index 0000000..2e0927c --- /dev/null +++ b/lib/controller/mh/address_controller.g.dart @@ -0,0 +1,33 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'address_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +AddressModel _$AddressModelFromJson(Map json) => AddressModel() + ..province = json['province'] as String? + ..city = json['city'] as String? + ..county = json['county'] as String? + ..street = json['street'] as String? + ..detail = json['detail'] as String? + ..name = json['name'] as String? + ..phone = json['phone'] as String? + ..ischecked = json['ischecked'] as bool? + ..currentType = (json['currentType'] as num).toInt() + ..all_address = json['all_address'] as String?; + +Map _$AddressModelToJson(AddressModel instance) => + { + 'province': instance.province, + 'city': instance.city, + 'county': instance.county, + 'street': instance.street, + 'detail': instance.detail, + 'name': instance.name, + 'phone': instance.phone, + 'ischecked': instance.ischecked, + 'currentType': instance.currentType, + 'all_address': instance.all_address, + }; diff --git a/lib/controller/mh/address_list_controller.dart b/lib/controller/mh/address_list_controller.dart new file mode 100644 index 0000000..25b0456 --- /dev/null +++ b/lib/controller/mh/address_list_controller.dart @@ -0,0 +1,64 @@ +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; + + +part 'address_list_controller.g.dart'; + +@JsonSerializable() +class AddressListModel { + List addressList = []; + Map address = {}; //之前控制的设备 + + int? type = 1; //1添加,2编辑 + + AddressListModel(); + + static AddressListModel fromJson(Map json) => + _$AddressListModelFromJson(json); + Map toJson() => _$AddressListModelToJson(this); +} + +class AddressListController extends GetControllerEx { + AddressListController() { + attr = GetModel(AddressListModel()).obs; + } + + // getAddressList() async { + // await ApiService.request.get("/api/address/info/list").then((d) { + // model.addressList = d.data["data"] ?? []; + // updateAll(); + // }).catchError((e) { + // print("$e"); + // }); + // } + + // //更新默认 + // Future updateDefault(address) async { + // var id = address['id']; + // var uid = address['userId']; + // try { + // await ef.client + // .from("app_user_address") + // .update({ + // 'ischecked': 0, + // }) + // .eq("user_id", address['userId']) + // .eq("ischecked", 1); + // await ef.client.from("app_user_address").update({ + // 'ischecked': 1, + // }).eq("id", address['id']); + // } catch (e) { + // print('Error fetching repairs: $e'); + // } + // } + + // // 删除地址 + // Future deleteAddress(String id) async { + // try { + // await ef.client.from("app_user_address").delete().eq("id", id); + // print("Address with ID $id has been successfully deleted."); + // } catch (e) { + // print("Error deleting address with ID $id: $e"); + // } + // } +} diff --git a/lib/controller/mh/address_list_controller.g.dart b/lib/controller/mh/address_list_controller.g.dart new file mode 100644 index 0000000..316d37c --- /dev/null +++ b/lib/controller/mh/address_list_controller.g.dart @@ -0,0 +1,20 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'address_list_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +AddressListModel _$AddressListModelFromJson(Map json) => + AddressListModel() + ..addressList = json['addressList'] as List + ..address = json['address'] as Map + ..type = (json['type'] as num?)?.toInt(); + +Map _$AddressListModelToJson(AddressListModel instance) => + { + 'addressList': instance.addressList, + 'address': instance.address, + 'type': instance.type, + }; diff --git a/lib/controller/mh/apply_repair_controller.dart b/lib/controller/mh/apply_repair_controller.dart new file mode 100644 index 0000000..f3e2acc --- /dev/null +++ b/lib/controller/mh/apply_repair_controller.dart @@ -0,0 +1,198 @@ +import 'dart:io'; + +import 'package:ef/ef.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:img_picker/img_picker.dart'; +import 'package:json_annotation/json_annotation.dart'; + +import 'package:path/path.dart' as p; +import 'package:uuid/uuid.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +import 'muser_info_controller.dart'; + +part 'apply_repair_controller.g.dart'; + +@JsonSerializable() +class ApplyRepairModel { + int? id; //报修id + String? apply_name; //申请人名称 + String? tel; //手机号 + String? address; //地址 + String? desc; //问题描述 + DateTime? create_time; //创建时间 + + String? device_type; //类型 床,床垫 不能为空 + String? device_category; //型号 不能为空 + String? device_id; //序列号 设备id 不能为空 + + String? device_name; //名称 可为空 + + List? issue_img = []; //图片 + int? imagesLImit = 3; //图片限制上传数量 + String? img_bucket = 'mianhuatang_repair'; + + String? status; //维修状态 + + String? select_device; + // String? select_type; + // List? device_list = ['床垫/BY-H/智能床垫', '床垫/BY-A/智能床垫', '床垫/BY-C/智能床垫']; + List? device_list = []; + int? score; + DateTime? score_time; //创建时间 + + int? messageType = 1; //消息类型 + int? repairId; //消息类型 + + ApplyRepairModel(); + static ApplyRepairModel fromJson(Map json) => + _$ApplyRepairModelFromJson(json); + Map toJson() => _$ApplyRepairModelToJson(this); +} + +class ApplyRepairController extends GetControllerEx { + // RepairRepository repairRepository = RepairRepository(); + ApplyRepairController() { + attr = GetModel(ApplyRepairModel()).obs; + } + + // //上传图片 + // Future uploadImg() async { + // final ImagePicker picker = ImagePicker(); + // final XFile? image = await picker.pickImage(source: ImageSource.gallery); + // final user = Supabase.instance.client.auth.currentUser; + // try { + // if (image != null) { + // int fileSize = await image.length(); // 获取图片大小,单位为字节 + // if (fileSize > 1024 * 1024 * 5) { + // // 1 MB = 1024 * 1024 bytes + // showToast("上传图片不能超过5MB"); + // return; + // } + // final filePath = image.path; // 获取文件路径 + // final fileExtension = p.extension(filePath); // 获取文件扩展名,包括点(.) + // // 获取当前日期并格式化为 yyyy-MM-dd + // final String folderName = + // DateFormat('yyyy-MM-dd').format(DateTime.now()); + // final file = File(image.path); + // // 构造文件路径,文件会被上传到 record_img 文件夹下的当天日期文件夹 + // var response = await ef.client.storage + // .from(model.img_bucket!) + // .upload('$folderName/${Uuid().v4()}$fileExtension', file); + // if (response != null) { + // String publicUrl = + // ef.client.storage.from(model.img_bucket!).getPublicUrl(response); + + // print('文件上传成功: $response'); + // print('文件上传成功: $publicUrl'); + // String prefixToRemove = 'mianhuatang_repair/'; + // model.issue_img!.add(response.startsWith(prefixToRemove) + // ? response.substring(prefixToRemove.length) + // : response); + // updateAll(); + // } + // print('/$model.img_bucket'); + // } else { + // print('未选择图片'); + // return; + // } + // } catch (e) { + // print('上传失败: $e'); + // } + // } + + // //提交 + // Future submitRepair(BuildContext context) async { + // //tmp + // // return ''; + // String message = ''; + // final MyDialogController myDialogController = + // Get.find(); + // if (model.device_type == null || model.device_type!.isEmpty) { + // message = '请选择设备类型!'; + // showToast(message); + // return message; + // } + // if (model.device_category == null || model.device_category!.isEmpty) { + // message = '请输入设备型号!'; + // showToast(message); + // return message; + // } + // if (model.device_id == null || model.device_id!.isEmpty) { + // message = '请输入设备序列号id!'; + // showToast(message); + // return message; + // } + // if (model.apply_name == null || model.apply_name!.isEmpty) { + // message = '请输入姓名!'; + // showToast(message); + // return message; + // } + // RegExp nameRegExp = RegExp(r'^[\u4e00-\u9fa5]{2,4}$'); + + // if (!nameRegExp.hasMatch(model.apply_name!)) { + // message = '姓名必须为2到4个汉字!'; + // showToast(message); + // return message; + // } + // if (model.tel == null || model.tel!.isEmpty) { + // message = '请输入手机号!'; + // showToast(message); + // return message; + // } + // if (!MyUtils.isValidPhoneNumber(model.tel!)) { + // message = '无效的手机号!'; + // showToast(message); + // return message; + // } + // if (model.address == null || model.address!.isEmpty) { + // message = '请输入地址!'; + // showToast(message); + // return message; + // } + // if (model.desc == null || model.desc!.isEmpty) { + // message = '请输入问题描述!'; + // showToast(message); + // return message; + // } + // if (model.issue_img == null || model.issue_img!.isEmpty) { + // message = '请至少上传一张问题图片!'; + // showToast(message); + // return message; + // } + // model.status = RepairStatus.pending; + // await repairRepository.saveRepair(model); + // return message; + // } + + // Future getDeviceList() async { + // final UserInfoController userInfoController = + // Get.find(); + // // UserModel loginUser = userInfoController.model.user!; + // DeviceListController deviceListController = Get.find(); + // await deviceListController.getDeviceList(); + // var aa = deviceListController.model.deviceListWyf; + // ApplyRepairController applyRepairController = Get.find(); + // applyRepairController.model.device_list = aa; + // } + + // String getPublicUrl(String path) { + // try { + // String bucketPath = '${model.img_bucket}/'; + // if (path.contains(bucketPath)) { + // int firstIndex = path.indexOf(bucketPath); + // // int secondIndex = + // // response.indexOf(bucketPath, firstIndex + bucketPath.length); + // if (firstIndex != -1) { + // // 去掉第一个存储桶路径 + // path = path.replaceFirst(bucketPath, '', firstIndex); + // } + // } + // String publicUrl = + // ef.client.storage.from(model.img_bucket!).getPublicUrl(path); + // return publicUrl; + // } catch (e) {} + // return ''; + // } +} diff --git a/lib/controller/mh/apply_repair_controller.g.dart b/lib/controller/mh/apply_repair_controller.g.dart new file mode 100644 index 0000000..8a5b4d0 --- /dev/null +++ b/lib/controller/mh/apply_repair_controller.g.dart @@ -0,0 +1,60 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'apply_repair_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ApplyRepairModel _$ApplyRepairModelFromJson(Map json) => + ApplyRepairModel() + ..id = (json['id'] as num?)?.toInt() + ..apply_name = json['apply_name'] as String? + ..tel = json['tel'] as String? + ..address = json['address'] as String? + ..desc = json['desc'] as String? + ..create_time = json['create_time'] == null + ? null + : DateTime.parse(json['create_time'] as String) + ..device_type = json['device_type'] as String? + ..device_category = json['device_category'] as String? + ..device_id = json['device_id'] as String? + ..device_name = json['device_name'] as String? + ..issue_img = (json['issue_img'] as List?) + ?.map((e) => e as String) + .toList() + ..imagesLImit = (json['imagesLImit'] as num?)?.toInt() + ..img_bucket = json['img_bucket'] as String? + ..status = json['status'] as String? + ..select_device = json['select_device'] as String? + ..device_list = json['device_list'] as List? + ..score = (json['score'] as num?)?.toInt() + ..score_time = json['score_time'] == null + ? null + : DateTime.parse(json['score_time'] as String) + ..messageType = (json['messageType'] as num?)?.toInt() + ..repairId = (json['repairId'] as num?)?.toInt(); + +Map _$ApplyRepairModelToJson(ApplyRepairModel instance) => + { + 'id': instance.id, + 'apply_name': instance.apply_name, + 'tel': instance.tel, + 'address': instance.address, + 'desc': instance.desc, + 'create_time': instance.create_time?.toIso8601String(), + 'device_type': instance.device_type, + 'device_category': instance.device_category, + 'device_id': instance.device_id, + 'device_name': instance.device_name, + 'issue_img': instance.issue_img, + 'imagesLImit': instance.imagesLImit, + 'img_bucket': instance.img_bucket, + 'status': instance.status, + 'select_device': instance.select_device, + 'device_list': instance.device_list, + 'score': instance.score, + 'score_time': instance.score_time?.toIso8601String(), + 'messageType': instance.messageType, + 'repairId': instance.repairId, + }; diff --git a/lib/controller/mh/book_info_controller.dart b/lib/controller/mh/book_info_controller.dart new file mode 100644 index 0000000..4b4420d --- /dev/null +++ b/lib/controller/mh/book_info_controller.dart @@ -0,0 +1,74 @@ +import 'dart:convert'; + +import 'package:ef/ef.dart'; + + +class BookInfoModel { + // DateTime? dateTime; //预约时间 + String? userName; //预约人 + String? userPhone; //预约电话 + List time_period = []; //预约时段 + // String? select_time; //选择时间 + int? select_time_index; //选择时间 + + List datetimes = []; + int? datetimes_index; + Map dataT = {}; + + BookInfoModel(); +} + +class BookInfoController extends GetControllerEx { + BookInfoController() { + attr = GetModel(BookInfoModel()).obs; + } + + // get userInfoController => Get.find(); + + // getData(id) { + // model.datetimes = []; + // model.datetimes_index = null; + // model.dataT = {}; + // updateAll(); + // ApiService.reservation.get("/agent/userBook/config/detailConfigByStore?storeId=$id") + // .then((d) { + // model.datetimes = d.data["dateList"]; + // model.datetimes_index = 0; + // model.dataT = d.data; + // time_periodChange(); + // }); + // } + + // time_periodChange() { + // if(model.datetimes_index == null) { + // return; + // } + // model.select_time_index = null; + // model.time_period = model.dataT[model.datetimes?[model.datetimes_index!]["day"]]; + // updateAll(); + // } + + // submitData(id) { + // String tel = userInfoController.model?.user?.tel ?? ""; + // if(tel.isEmpty) { + // showToast("用户未存在手机号"); + // return; + // } + // return ApiService.reservation.post("/agent/userBook/submitBook", data: { + // "extUserId": tel, + // "storeId": id, + // "realName": model.userName, + // "userPhone": model.userPhone, + // "bookDateId": model.time_period[model.select_time_index!]["id"] + // }); + // } + + // messageAdd(Map data) { + // return ApiService.request.post("/api/message/info", data: { + // "type": 0, + // "status": 1, + // "read": 1, + // "data": jsonEncode(data) + // }); + // } +} diff --git a/lib/controller/mh/experience_store_list_page.dart b/lib/controller/mh/experience_store_list_page.dart new file mode 100644 index 0000000..c856721 --- /dev/null +++ b/lib/controller/mh/experience_store_list_page.dart @@ -0,0 +1,125 @@ +import 'dart:ui'; + +import 'package:ef/ef.dart'; + + +import 'package:json_annotation/json_annotation.dart'; + +part 'experience_store_list_page.g.dart'; + +@JsonSerializable() +class ExperienceStoreListModel { + List experienceStoreModelList = []; //体验店列 + + @JsonKey(ignore: true) + String? keyword = ''; + @JsonKey(ignore: true) + Color? color = Color(0xFFFFFFFF); + + ExperienceStoreListModel(); + // static ExperienceStoreListModel fromJson(Map json) => + // _$ExperienceStoreListModelFromJson(json); + // Map toJson() => _$ExperienceStoreListModelToJson(this); +} + +class ExperienceStoreListController + extends GetControllerEx { + ExperienceStoreListController() { + attr = GetModel(ExperienceStoreListModel()).obs; + } + + // Position? position; + // double latitude = 31.8512; + // double longitude = 117.26061; + + // int total = 0; + // int page = 0; + // bool lock = false; + + + // resetParm() { + // position = null; + // total = 0; + // page = 0; + // lock = false; + // model.experienceStoreModelList = []; + // updateAll(); + // } + + // getData({int count = 10}) async { + // if (page != 0 && page * count > total) { + // return; + // } + // if (lock) { + // return; + // } + // if (page == 0) { + // position = await locationCheck(); + // } + // lock = true; + // int page_ = page; + // ApiService.reservation + // .get( + // "/agent/userBook/config/getBookStoreList?storeName=${"${model.keyword}".isNotEmpty ? model.keyword : ''}&latitude=${position == null ? latitude : position?.latitude}&longitude=${position == null ? longitude : position?.longitude}&page=$page&size=$count&sort=distance") + // .then((d) { + // lock = false; + // if (page == 0) { + // model.experienceStoreModelList = d.data["records"]; + // } else { + // int index = 0; + // d.data["records"]?.forEach((item) { + // if (model.experienceStoreModelList + // .indexWhere((item2) => item2["id"] == item["id"]) == + // -1) { + // model.experienceStoreModelList.add(item); + // } else { + // model.experienceStoreModelList[index] = item; + // } + // index++; + // }); + // } + // page = page_ + 1; + // total = d.data["total"]; + // updateAll(); + // }).catchError((d) { + // lock = false; + // }); + // } + + determinePosition() async { + // bool serviceEnabled; + // LocationPermission permission; + + // // Test if location services are enabled. + // serviceEnabled = await Geolocator.isLocationServiceEnabled(); + // if (!serviceEnabled) { + // // Location services are not enabled don't continue + // // accessing the position and request users of the + // // App to enable the location services. + // return Future.error('Location services are disabled.'); + // } + + // permission = await Geolocator.checkPermission(); + // if (permission == LocationPermission.denied) { + // permission = await Geolocator.requestPermission(); + // if (permission == LocationPermission.denied) { + // // Permissions are denied, next time you could try + // // requesting permissions again (this is also where + // // Android's shouldShowRequestPermissionRationale + // // returned true. According to Android guidelines + // // your App should show an explanatory UI now. + // return Future.error('Location permissions are denied'); + // } + // } + + // if (permission == LocationPermission.deniedForever) { + // // Permissions are denied forever, handle appropriately. + // return Future.error( + // 'Location permissions are permanently denied, we cannot request permissions.'); + // } + + // // When we reach here, permissions are granted and we can + // // continue accessing the position of the device. + // position = await Geolocator.getCurrentPosition(); + } +} diff --git a/lib/controller/mh/experience_store_list_page.g.dart b/lib/controller/mh/experience_store_list_page.g.dart new file mode 100644 index 0000000..6c658c4 --- /dev/null +++ b/lib/controller/mh/experience_store_list_page.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'experience_store_list_page.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ExperienceStoreListModel _$ExperienceStoreListModelFromJson( + Map json) => + ExperienceStoreListModel() + ..experienceStoreModelList = + json['experienceStoreModelList'] as List; + +Map _$ExperienceStoreListModelToJson( + ExperienceStoreListModel instance) => + { + 'experienceStoreModelList': instance.experienceStoreModelList, + }; diff --git a/lib/controller/mh/issue_controller.dart b/lib/controller/mh/issue_controller.dart new file mode 100644 index 0000000..222a666 --- /dev/null +++ b/lib/controller/mh/issue_controller.dart @@ -0,0 +1,55 @@ +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; + +part 'issue_controller.g.dart'; + +@JsonSerializable() +class IssueListModel { + List issueList = []; + + int limit = AppConstants.limit; + int offset = 0; + bool isLoading = false; + bool hasMore = true; + + int? selectedIndex; + + IssueListModel(); + static IssueListModel fromJson(Map json) => + _$IssueListModelFromJson(json); + Map toJson() => _$IssueListModelToJson(this); +} + +class IssueListController extends GetControllerEx { + // HelpRepository helpRepository = HelpRepository(); + IssueListController() { + attr = GetModel(IssueListModel()).obs; + } + + + // //初始化列表数据 + // Future initData() async { + // if (model.isLoading) { + // return; + // } + // model.isLoading = true; + // final List fetchedRepairs = await helpRepository.findHelpInfos( + // limit: model.limit, offset: model.offset); + // if (fetchedRepairs != null) { + // List infos = []; + // List tmp = fetchedRepairs as List; + // try { + // // infos = tmp.map((repair) => IssueModel.fromJson(repair)).toList(); + // // model.issueList!.addAll(infos); + // model.issueList.addAll(tmp); + // } catch (e) { + // print('Error parsing JSON: $e'); + // } + // } + // model.offset += model.limit; // 更新 offset,下一次查询跳过当前已经加载的记录 + // model.hasMore = fetchedRepairs.length == model.limit; // 判断是否还有更多数据 + // model.isLoading = false; + // updateAll(); + // } +} diff --git a/lib/controller/mh/issue_controller.g.dart b/lib/controller/mh/issue_controller.g.dart new file mode 100644 index 0000000..ac15cea --- /dev/null +++ b/lib/controller/mh/issue_controller.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'issue_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +IssueListModel _$IssueListModelFromJson(Map json) => + IssueListModel() + ..issueList = json['issueList'] as List + ..limit = (json['limit'] as num).toInt() + ..offset = (json['offset'] as num).toInt() + ..isLoading = json['isLoading'] as bool + ..hasMore = json['hasMore'] as bool + ..selectedIndex = (json['selectedIndex'] as num?)?.toInt(); + +Map _$IssueListModelToJson(IssueListModel instance) => + { + 'issueList': instance.issueList, + 'limit': instance.limit, + 'offset': instance.offset, + 'isLoading': instance.isLoading, + 'hasMore': instance.hasMore, + 'selectedIndex': instance.selectedIndex, + }; diff --git a/lib/controller/mh/issue_preview_controller.dart b/lib/controller/mh/issue_preview_controller.dart new file mode 100644 index 0000000..c436572 --- /dev/null +++ b/lib/controller/mh/issue_preview_controller.dart @@ -0,0 +1,20 @@ +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'issue_preview_controller.g.dart'; + +@JsonSerializable() +class IssuePreviewInfoModel { + + IssuePreviewInfoModel(); + + static IssuePreviewInfoModel fromJson(Map json) => + _$IssuePreviewInfoModelFromJson(json); + Map toJson() => _$IssuePreviewInfoModelToJson(this); +} + +class IssuePreviewInfoController extends GetControllerEx { + IssuePreviewInfoController() { + attr = GetModel(IssuePreviewInfoModel()).obs; + } +} diff --git a/lib/controller/mh/issue_preview_controller.g.dart b/lib/controller/mh/issue_preview_controller.g.dart new file mode 100644 index 0000000..c6cfbd1 --- /dev/null +++ b/lib/controller/mh/issue_preview_controller.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'issue_preview_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +IssuePreviewInfoModel _$IssuePreviewInfoModelFromJson( + Map json) => + IssuePreviewInfoModel(); + +Map _$IssuePreviewInfoModelToJson( + IssuePreviewInfoModel instance) => + {}; diff --git a/lib/controller/mh/message_controller.dart b/lib/controller/mh/message_controller.dart new file mode 100644 index 0000000..f4389dd --- /dev/null +++ b/lib/controller/mh/message_controller.dart @@ -0,0 +1,198 @@ +import 'dart:convert'; + +import 'package:EasyDartModule/EasyDartModule.dart'; +import 'package:ef/ef.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/common/color/ServiceConstant.dart'; +import 'package:vbvs_app/common/color/app_uri_status.dart'; +import 'package:vbvs_app/common/util/DailyLogUtils.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/model/api_response.dart'; + +part 'message_controller.g.dart'; // 由json_serializable自动生成的部分 + +@JsonSerializable() +class MhMessageModel { + int? type = 1; //设备类型 1:体征消息 2.系统消息 + int? body_message_read = 0; //体征消息 0:已读 1:未读 + int? system_message_read = 0; //系统消息 0:已读 1:未读 + + MhMessageModel(); + + // 从JSON反序列化时的异常处理 + + factory MhMessageModel.fromJson(Map json) { + try { + return _$MhMessageModelFromJson(json); + } catch (e) { + // 在实际应用中,应该有更细致的异常处理策略和错误日志 + return MhMessageModel(); // 或者返回一个带有错误信息的特定DeviceInfoModel实例 + } + } + + // 序列化为JSON时的异常处理 + Map toJson() => _$MhMessageModelToJson(this); +} + +class MhMessageController extends GetControllerEx { + MhMessageController() { + attr = GetModel(MhMessageModel()).obs; + } + + RxList messageList = [].obs; + + Future getMessageList({String? key}) async { + try { + ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败".tr); + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.server_service; + String serviceApi = ServiceConstant.message_list; + String messageType = "app_system"; + if (model.type == 1) { + messageType = "app_body"; + } else { + messageType = "app_system"; + } + String queryUrl = + "${serviceAddress}${serviceName}${serviceApi}?type=${messageType}"; + String? language = ""; + if (languageController.selectLanguage != null) { + language = languageController.selectLanguage.value!.language_code; + } + if (language != null && language.isNotEmpty) { + if (queryUrl.contains("?")) { + queryUrl += "&lang=$language"; + } else { + queryUrl += "?lang=$language"; + } + } + var response = await EasyDartModule.dio.get(queryUrl); + if (response != null) { + var responseData = + response.data is String ? jsonDecode(response.data) : response.data; + ApiResponse res = + ApiResponse.fromJson(responseData, (object) => object); + MyUtils.formatResponse(res, "请求成功".tr, "请求失败".tr); + if (res.code == HttpStatusCodes.ok) { + updateAll(); + messageList.value = res.data; + return res; + } + } else { + return ApiResponse(code: -1, msg: "服务器.失败".tr); + } + return apiResponse; + } catch (e) { + EasyDartModule.logger.info("设备请求列表: $e"); + DailyLogUtils.writeLog("设备请求列表: $e"); + } + return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement + } + + //获取消息已读未读 + Future getMessageStatus() async { + try { + ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败".tr); + // return apiResponse; + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.server_service; + String serviceApi = ServiceConstant.message_read; + + String queryUrl = "${serviceAddress}${serviceName}${serviceApi}"; + String? language = ""; + if (languageController.selectLanguage != null) { + language = languageController.selectLanguage.value!.language_code; + } + if (language != null && language.isNotEmpty) { + if (queryUrl.contains("?")) { + queryUrl += "&lang=$language"; + } else { + queryUrl += "?lang=$language"; + } + } + var response = await EasyDartModule.dio.get(queryUrl); + if (response != null) { + var responseData = + response.data is String ? jsonDecode(response.data) : response.data; + ApiResponse res = + ApiResponse.fromJson(responseData, (object) => object); + MyUtils.formatResponse(res, "请求成功".tr, "请求失败".tr); + if (res.code == HttpStatusCodes.ok) { + updateAll(); + List dataList = res.data; + + // 查找 type 为 app_vsm 的项 + var vsmItem = dataList.firstWhere( + (e) => e['type'] == 'app_vsm', + orElse: () => null, + ); + model.body_message_read = vsmItem?['count'] ?? 0; + + // 查找 type 为 app_system 的项 + var systemItem = dataList.firstWhere( + (e) => e['type'] == 'app_system', + orElse: () => null, + ); + model.system_message_read = systemItem?['count'] ?? 0; + + updateAll(); + return res; + } + } else { + return ApiResponse(code: -1, msg: "服务器.失败".tr); + } + return apiResponse; + } catch (e) { + EasyDartModule.logger.info("获取消息已读未读: $e"); + DailyLogUtils.writeLog("获取消息已读未读: $e"); + } + return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement + } + + //更新消息已读 + Future updateMessageStatus({String? type}) async { + EasyDartModule.logger.info("更新消息已读状态"); + DailyLogUtils.writeLog("更新消息已读状态"); + try { + ApiResponse apiResponse = ApiResponse(code: -1, msg: "操作失败".tr); + String serviceAddress = ServiceConstant.service_address; + String serviceName = ServiceConstant.server_service; + String serviceApi = ServiceConstant.message_read; + + // 拼接 URL,添加 type 参数 + String queryUrl = "$serviceAddress$serviceName$serviceApi"; + if (type != null && type.isNotEmpty) { + queryUrl += "?type=$type"; + } + + String? language = ""; + if (languageController.selectLanguage != null) { + language = languageController.selectLanguage.value!.language_code; + } + if (language != null && language.isNotEmpty) { + if (queryUrl.contains("?")) { + queryUrl += "&lang=$language"; + } else { + queryUrl += "?lang=$language"; + } + } + var response = await EasyDartModule.dio.post(queryUrl); + + if (response != null) { + var responseData = + response.data is String ? jsonDecode(response.data) : response.data; + ApiResponse res = + ApiResponse.fromJson(responseData, (object) => object); + MyUtils.formatResponse(res, "操作成功".tr, "操作成功".tr); + return res; + } else { + return ApiResponse(code: -1, msg: "服务器.失败".tr); + } + } catch (e) { + EasyDartModule.logger.info("更新消息已读状态->$e"); + DailyLogUtils.writeLog("更新消息已读状态->$e"); + return ApiResponse(code: -1, msg: "服务器.失败".tr); + } + } +} diff --git a/lib/controller/mh/message_controller.g.dart b/lib/controller/mh/message_controller.g.dart new file mode 100644 index 0000000..564e51f --- /dev/null +++ b/lib/controller/mh/message_controller.g.dart @@ -0,0 +1,20 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'message_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +MhMessageModel _$MhMessageModelFromJson(Map json) => + MhMessageModel() + ..type = (json['type'] as num?)?.toInt() + ..body_message_read = (json['body_message_read'] as num?)?.toInt() + ..system_message_read = (json['system_message_read'] as num?)?.toInt(); + +Map _$MhMessageModelToJson(MhMessageModel instance) => + { + 'type': instance.type, + 'body_message_read': instance.body_message_read, + 'system_message_read': instance.system_message_read, + }; diff --git a/lib/controller/mh/muser_info_controller.dart b/lib/controller/mh/muser_info_controller.dart new file mode 100644 index 0000000..96fb747 --- /dev/null +++ b/lib/controller/mh/muser_info_controller.dart @@ -0,0 +1,177 @@ +import 'dart:io'; + +import 'package:ef/ef.dart'; +import 'package:fluwx/fluwx.dart'; +import 'package:json_annotation/json_annotation.dart'; + +import 'package:path/path.dart' as p; + +import 'package:vbvs_app/controller/mh/user_data.dart'; +part 'muser_info_controller.g.dart'; + +@JsonSerializable() +class MUserInfoModel { + int? message = 0; //消息数量 + + UserModel? user; //用户信息 + String? token; //token值 + String? runSystem; //运行系统 + String? phoneVersion; //手机版本 + String? deviceId; //手机唯一 + String? deviceModel; //设备可见型号(如 "iPhone","iPad") + String? appVersion; //app版本信息 + + @JsonKey(ignore: true) + Session? superbase_session; + @JsonKey(ignore: true) + User? superbase_user; + + String? img_bucket = 'user'; + int? login = 0; //是否登录0:未登录 1:已登录 + + MUserInfoModel(); + static MUserInfoModel fromJson(Map json) => + _$MUserInfoModelFromJson(json); + Map toJson() => _$MUserInfoModelToJson(this); +} + +class MUserInfoController extends GetControllerEx { + // 初始化实例 + final Fluwx fluwx = Fluwx(); + + MUserInfoController() { + attr = GetModel(MUserInfoModel()).obs; + } + + // Future uploadImg() async { + // final ImagePicker picker = ImagePicker(); + // final XFile? image = await picker.pickImage(source: ImageSource.gallery); + // final user = Supabase.instance.client.auth.currentUser; + // try { + // if (image != null) { + // int fileSize = await image.length(); // 获取图片大小,单位为字节 + // if (fileSize > 1048576) { + // // 1 MB = 1024 * 1024 bytes + // showToast("头像图片不能超过1MB"); + // return; + // } + // final filePath = image.path; // 获取文件路径 + // final fileExtension = p.extension(filePath); // 获取文件扩展名,包括点(.) + // // 获取当前日期并格式化为 yyyy-MM-dd + // final String folderName = + // DateFormat('yyyy-MM-dd').format(DateTime.now()); + // final file = File(image.path); + // // 构造文件路径,文件会被上传到 record_img 文件夹下的当天日期文件夹 + // var response = await ef.client.storage + // .from(model.img_bucket!) + // .upload('$folderName/${Uuid().v4()}$fileExtension', file); + // if (response != null) { + // String publicUrl = + // ef.client.storage.from(model.img_bucket!).getPublicUrl(response); + + // print('文件上传成功: $response'); + // print('文件上传成功: $publicUrl'); + // String prefixToRemove = 'user/'; + // // model.user!.tmpHead = model.user!.head; + // model.user!.tmpHead = publicUrl.startsWith(prefixToRemove) + // ? response.substring(prefixToRemove.length) + // : response; + // updateAll(); + // } + // print('/$model.img_bucket'); + // } else { + // print('未选择图片'); + // return; + // } + // } catch (e) { + // print('上传失败: $e'); + // } + // } + + // updateData() { + // UserInfoController controller = Get.find(); + // UserRepository userRepository = UserRepository(); + // return userRepository.updateInfo(controller.model.user!); + // } + + // autoLogin(String token) async { + // final UserInfoController userInfoController = Get.find(); + // try { + // final Map requestBody = { + // 'token': token, + // }; + + // var response = await ApiService.request + // .post("/api/auth/account/info/autoLogin", data: requestBody); + // if (response.statusCode == 200) { + // if (response.data != null) { + // ApiResponse apiResponse = ApiResponse.fromJson( + // response.data, + // (json) => UserModel.fromJson(json as Map)); + // if (apiResponse.code == HttpStatusCodes.ok) { + // userInfoController.model.user = apiResponse.data; + // userInfoController.model.token = response.headers['token']!.first; + // userInfoController.model.login = 1; + + // final box = GetStorage(); + // box.write( + // 'user', userInfoController.model.user!.toJson()); // 存储用户信息 + // box.write('token', userInfoController.model.token); // 存储 token + // String efPd = await getValueBySysConfigKey(CommonVariables.efKey); + // if (efPd != null && efPd.isNotEmpty) { + // await initDataEf(key: efPd); + // } else { + // print("efPD为空,无法初始化"); + // // 清除本地缓存 + // final box = GetStorage(); + // box.remove('user'); + // box.remove('token'); + // userInfoController.model.token = null; + // userInfoController.model.user = null; + // // 设置成未登录 + // userInfoController.model.login = 0; + // return; + // } + + // final AuthResponse res = await ef.client.auth.signInWithPassword( + // phone: userInfoController.model.user!.tel, + // password: userInfoController.model.user!.exp1!, + // ); + // userInfoController.model.superbase_session = res.session; + // userInfoController.model.superbase_user = res.user; + // userInfoController.updateAll(); + // // 登录成功移出网络检查监听 + // Checknetwork.subscription?.cancel(); + // } + // } + // } else { + // // 处理非 200 响应 + // print('Failed to sign in. Status code: ${response.statusCode}'); + // print('Response data: ${response.data}'); + // } + // } catch (e) { + // e.printError(); + // // 清除本地缓存 + // final box = GetStorage(); + // box.remove('user'); + // box.remove('token'); + // userInfoController.model.token = null; + // userInfoController.model.user = null; + // // 设置成未登录 + // userInfoController.model.login = 0; + // } + // } + + // // 拉起微信企业客服 + // Future openWeChatCustomerService() async { + // bool isWeChatInstalled = await fluwx.isWeChatInstalled; + // if (!isWeChatInstalled) { + // showToast("请先安装微信APP,再联系客服", color: color_error); + // return; + // } + // showToast('正在打开微信客服...', color: color_success); + // await fluwx.open( + // target: CustomerServiceChat( + // corpId: CommonVariables.wxCorpId, url: CommonVariables.wxKfUrl)); + // } +} diff --git a/lib/controller/mh/muser_info_controller.g.dart b/lib/controller/mh/muser_info_controller.g.dart new file mode 100644 index 0000000..1dc29be --- /dev/null +++ b/lib/controller/mh/muser_info_controller.g.dart @@ -0,0 +1,36 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'muser_info_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +MUserInfoModel _$MUserInfoModelFromJson(Map json) => + MUserInfoModel() + ..message = (json['message'] as num?)?.toInt() + ..user = json['user'] == null + ? null + : UserModel.fromJson(json['user'] as Map) + ..token = json['token'] as String? + ..runSystem = json['runSystem'] as String? + ..phoneVersion = json['phoneVersion'] as String? + ..deviceId = json['deviceId'] as String? + ..deviceModel = json['deviceModel'] as String? + ..appVersion = json['appVersion'] as String? + ..img_bucket = json['img_bucket'] as String? + ..login = (json['login'] as num?)?.toInt(); + +Map _$MUserInfoModelToJson(MUserInfoModel instance) => + { + 'message': instance.message, + 'user': instance.user, + 'token': instance.token, + 'runSystem': instance.runSystem, + 'phoneVersion': instance.phoneVersion, + 'deviceId': instance.deviceId, + 'deviceModel': instance.deviceModel, + 'appVersion': instance.appVersion, + 'img_bucket': instance.img_bucket, + 'login': instance.login, + }; diff --git a/lib/controller/mh/my_experience_list_controller.dart b/lib/controller/mh/my_experience_list_controller.dart new file mode 100644 index 0000000..b4b7c41 --- /dev/null +++ b/lib/controller/mh/my_experience_list_controller.dart @@ -0,0 +1,115 @@ +import 'dart:convert'; + +import 'package:ef/ef.dart'; + + +class BookExperienceListModel { + List bookInfoList = []; //预约列表 + List experienceStoreModelList = []; +} + +class BookExperienceListController + extends GetControllerEx { + BookExperienceListController() { + attr = GetModel(BookExperienceListModel()).obs; + } + + // resetParm() { + // model.bookInfoList = []; + // model.experienceStoreModelList = []; + // total = 0; + // page = 0; + // lock = false; + // updateAll(); + // } + + // getAllBook() { + // ApiService.reservation + // .get( + // "/agent/userBook/config/getBookStoreList?storeName=&latitude=31.8512&longitude=117.26061&page=0&size=20000&sort=distance") + // .then((d) { + // model.experienceStoreModelList = d.data["records"]; + // updateAll(); + // }); + // } + + // int total = 0; + // int page = 0; + // bool lock = false; + + // getData({int count = 10, Function? finished}) { + // if (page != 0 && page * count > total) { + // finished?.call(); + // return; + // } + // if (lock) { + // finished?.call(); + // return; + // } + // lock = true; + // int page_ = page; + // String tel = Get.find().model.user?.tel ?? ""; + // if (tel.isEmpty) { + // showToast("用户未存在手机号"); + // finished?.call(); + // return; + // } + // ApiService.reservation + // .get( + // "/agent/userBook/list?extUserId=$tel&page=$page_&size=$count&sort=create_time,desc") + // .then((d) { + // lock = false; + // finished?.call(); + // if (page == 0) { + // model.bookInfoList = d.data["records"]; + // } else { + // int index = 0; + // d.data["records"]?.forEach((item) { + // if (model.bookInfoList + // .indexWhere((item2) => item2["id"] == item["id"]) == + // -1) { + // model.bookInfoList.add(item); + // } else { + // model.bookInfoList[index] = item; + // } + // index++; + // }); + // } + // page = page_ + 1; + // total = d.data["total"]; + // updateAll(); + // }).catchError((d) { + // lock = false; + // finished?.call(); + // }); + // } + + // cancelBook(id, {Function? success}) { + // String tel = Get.find().model.user?.tel ?? ""; + // if (tel.isEmpty) { + // showToast("用户未存在手机号"); + // return; + // } + // LoadingDialog.show("提交中..."); + // ApiService.reservation + // .post("/agent/userBook/cancel?extUserId=$tel&id=$id") + // .then((d) { + // page = 0; + // getData(finished: () { + // LoadingDialog.hide(); + // }); + // success?.call(); + // }).catchError((d) { + // LoadingDialog.hide(); + // }); + // } + + // messageAdd(Map data) { + // return ApiService.request.post("/api/message/info", data: { + // "type": 0, + // "status": 1, + // "read": 1, + // "data": jsonEncode(data) + // }); + // } +} diff --git a/lib/controller/mh/people_info_controller.dart b/lib/controller/mh/people_info_controller.dart new file mode 100644 index 0000000..14a36be --- /dev/null +++ b/lib/controller/mh/people_info_controller.dart @@ -0,0 +1,111 @@ +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; + +part 'people_info_controller.g.dart'; // 由json_serializable自动生成的部分 + +class PeopleInfoModel { + List peopleList = [PeopleInfoPojo(), PeopleInfoPojo()]; +} + +@JsonSerializable() +class PeopleInfoPojo { + String? name; + String sex = "男"; + String? height; + String? weight; + DateTime? birthday; + String? tel; + String? emergencyContact; + + PeopleInfoPojo(); + + // // 从JSON反序列化时的异常处理 + + factory PeopleInfoPojo.fromJson(Map json) { + try { + return _$PeopleInfoPojoFromJson(json); + } catch (e) { + // 在实际应用中,应该有更细致的异常处理策略和错误日志 + return PeopleInfoPojo(); // 或者返回一个带有错误信息的特定PeopleInfoModel实例 + } + } + + // 序列化为JSON时的异常处理 + Map toJson() => _$PeopleInfoPojoToJson(this); +} + +class PeopleInfoController extends GetControllerEx { + PeopleInfoController() { + attr = GetModel(PeopleInfoModel()).obs; + } + + GlobalController get glcontroller => Get.find(); + + // getPeoples() async { + // var arr = []; + // String bindMacA = + // glcontroller.getUpperCaseMac(glcontroller.model.deviceMain["bindMacA"]); + // String bindMacB = + // glcontroller.getUpperCaseMac(glcontroller.model.deviceMain["bindMacB"]); + // arr.add(bindMacA); + // if (bindMacB.length > 6) { + // arr.add(bindMacB); + // } else { + // model.peopleList[1] = PeopleInfoPojo(); + // } + // model.peopleList[0] = PeopleInfoPojo(); + // print("getuser $arr"); + // var data = await ef.from("app_personnel").select().inFilter("mac", arr); + // print("getuser $data"); + // data?.forEach((d) { + // PeopleInfoPojo peopleInfoPojo = PeopleInfoPojo(); + // peopleInfoPojo.name = d["name"]; + // peopleInfoPojo.sex = d["gender"] == 1 ? "男" : "女"; + // peopleInfoPojo.height = d["height"] == null ? null : "${d["height"]}"; + // peopleInfoPojo.weight = d["weight"] == null ? null : "${d["weight"]}"; + // if (d["birthday"] != null) { + // peopleInfoPojo.birthday = DateTime.parse(d["birthday"]).toLocal(); + // } + // peopleInfoPojo.tel = d["tel"]; + // peopleInfoPojo.emergencyContact = d["contact"]; + // if (glcontroller.getUpperCaseMac(d['mac']) == bindMacA) { + // model.peopleList[0] = peopleInfoPojo; + // } + // if (glcontroller.getUpperCaseMac(d['mac']) == bindMacB) { + // model.peopleList[1] = peopleInfoPojo; + // } + // }); + // updateAll(); + // attr.value.updateAll(); + // } + + // savePeoples() async { + // String bindMacA = + // glcontroller.getUpperCaseMac(glcontroller.model.deviceMain["bindMacA"]); + // String bindMacB = + // glcontroller.getUpperCaseMac(glcontroller.model.deviceMain["bindMacB"]); + // List arr = []; + // for (var i = 0; i < 2; i++) { + // if (i == 1 && bindMacB.length < 6) { + // break; + // } + // arr.add(ef.from("app_personnel").update({ + // "name": model.peopleList[i].name, + // "gender": model.peopleList[i].sex == "男" ? 1 : 0, + // "height": int.tryParse("${model.peopleList[i].height}"), + // "weight": int.tryParse("${model.peopleList[i].weight}"), + // "birthday": model.peopleList[i].birthday == null + // ? null + // : model.peopleList[i].birthday.toString(), + // "tel": model.peopleList[i].tel, + // "contact": model.peopleList[i].emergencyContact + // }).eq("mac", i == 0 ? bindMacA : bindMacB)); + // } + // return Future.wait(arr); + // } + + // Future saveOnePeople(mac, data) async { + // return ef.from("app_personnel").update(data).eq("mac", mac); + // } +} diff --git a/lib/controller/mh/people_info_controller.g.dart b/lib/controller/mh/people_info_controller.g.dart new file mode 100644 index 0000000..1c66eb4 --- /dev/null +++ b/lib/controller/mh/people_info_controller.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'people_info_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PeopleInfoPojo _$PeopleInfoPojoFromJson(Map json) => + PeopleInfoPojo() + ..name = json['name'] as String? + ..sex = json['sex'] as String + ..height = json['height'] as String? + ..weight = json['weight'] as String? + ..birthday = json['birthday'] == null + ? null + : DateTime.parse(json['birthday'] as String) + ..tel = json['tel'] as String? + ..emergencyContact = json['emergencyContact'] as String?; + +Map _$PeopleInfoPojoToJson(PeopleInfoPojo instance) => + { + 'name': instance.name, + 'sex': instance.sex, + 'height': instance.height, + 'weight': instance.weight, + 'birthday': instance.birthday?.toIso8601String(), + 'tel': instance.tel, + 'emergencyContact': instance.emergencyContact, + }; diff --git a/lib/controller/mh/repair_info_controller.dart b/lib/controller/mh/repair_info_controller.dart new file mode 100644 index 0000000..b21eae7 --- /dev/null +++ b/lib/controller/mh/repair_info_controller.dart @@ -0,0 +1,68 @@ +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/controller/mh/apply_repair_controller.dart'; +import 'package:vbvs_app/controller/mh/repair_process.dart'; + +part 'repair_info_controller.g.dart'; + +@JsonSerializable() +class RepairInfoModel { + String? id; //记录id + DateTime? create_time; //提交时间 + String? status; //状态 + String? desc; //描述 + int? record_id; //归属记录id + + List repairProcessList = []; //审核流程 + String? device_name; + ApplyRepairModel? applyRepairModel; + + RepairInfoModel(); + + static RepairInfoModel fromJson(Map json) => + _$RepairInfoModelFromJson(json); + Map toJson() => _$RepairInfoModelToJson(this); +} + +class RepairInfoController extends GetControllerEx { + // RepairRepository repairRepository = RepairRepository(); + RepairInfoController() { + attr = GetModel(RepairInfoModel()).obs; + } + + // Future initData(ApplyRepairModel applyRepairModel) async { + // if (applyRepairModel != null) { + // final List fetchedRepairs = + // await repairRepository.findData(applyRepairModel.id!); + // RepairListController repairListController = Get.find(); + // final List info = await repairListController.repairRepository + // .findRecordData(applyRepairModel.id!); + // if (info.isNotEmpty) { + // List infos = []; + // List tmp = info as List; + // try { + // infos = + // tmp.map((repair) => ApplyRepairModel.fromJson(repair)).toList(); + // model.applyRepairModel = infos.first; + // updateAll(); + // } catch (e) { + // print('Error parsing JSON: $e'); + // } + // // model.applyRepairModel = applyRepairModel; + // } + + // if (fetchedRepairs != null) { + // List infos = []; + // List tmp = fetchedRepairs as List; + // try { + // infos = + // tmp.map((repair) => RepairProcessModel.fromJson(repair)).toList(); + // model.repairProcessList = infos; + // updateAll(); + // } catch (e) { + // print('Error parsing JSON: $e'); + // } + // } + // } + // } +} diff --git a/lib/controller/mh/repair_info_controller.g.dart b/lib/controller/mh/repair_info_controller.g.dart new file mode 100644 index 0000000..0ef35b6 --- /dev/null +++ b/lib/controller/mh/repair_info_controller.g.dart @@ -0,0 +1,37 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'repair_info_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +RepairInfoModel _$RepairInfoModelFromJson(Map json) => + RepairInfoModel() + ..id = json['id'] as String? + ..create_time = json['create_time'] == null + ? null + : DateTime.parse(json['create_time'] as String) + ..status = json['status'] as String? + ..desc = json['desc'] as String? + ..record_id = (json['record_id'] as num?)?.toInt() + ..repairProcessList = (json['repairProcessList'] as List) + .map((e) => RepairProcessModel.fromJson(e as Map)) + .toList() + ..device_name = json['device_name'] as String? + ..applyRepairModel = json['applyRepairModel'] == null + ? null + : ApplyRepairModel.fromJson( + json['applyRepairModel'] as Map); + +Map _$RepairInfoModelToJson(RepairInfoModel instance) => + { + 'id': instance.id, + 'create_time': instance.create_time?.toIso8601String(), + 'status': instance.status, + 'desc': instance.desc, + 'record_id': instance.record_id, + 'repairProcessList': instance.repairProcessList, + 'device_name': instance.device_name, + 'applyRepairModel': instance.applyRepairModel, + }; diff --git a/lib/controller/mh/repair_list_controller.dart b/lib/controller/mh/repair_list_controller.dart new file mode 100644 index 0000000..edd58ce --- /dev/null +++ b/lib/controller/mh/repair_list_controller.dart @@ -0,0 +1,83 @@ +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'apply_repair_controller.dart'; +part 'repair_list_controller.g.dart'; + +@JsonSerializable() +class RepairListModel { + int limit = AppConstants.limit; + int offset = 0; + bool isLoading = false; + bool hasMore = true; + + List repairList = []; + + RepairListModel(); + static RepairListModel fromJson(Map json) => + _$RepairListModelFromJson(json); + Map toJson() => _$RepairListModelToJson(this); +} + +class RepairListController extends GetControllerEx { + // RepairRepository repairRepository = RepairRepository(); + // RepairListController() { + // attr = GetModel(RepairListModel()).obs; + // } + + // //初始化列表数据 + // Future initData() async { + // if (model.isLoading) { + // return; + // } + // model.isLoading = true; + // final List fetchedRepairs = await repairRepository.fetchRepairs( + // limit: model.limit, offset: model.offset); + // if (fetchedRepairs != null) { + // List infos = []; + // List tmp = fetchedRepairs as List; + // try { + // infos = tmp.map((repair) => ApplyRepairModel.fromJson(repair)).toList(); + // model.repairList.addAll(infos); + // } catch (e) { + // print('Error parsing JSON: $e'); + // } + // } + // model.offset += model.limit; // 更新 offset,下一次查询跳过当前已经加载的记录 + // model.hasMore = fetchedRepairs.length == model.limit; // 判断是否还有更多数据 + // model.isLoading = false; + // updateAll(); + // } + + // Future addScore(int id, int score) async { + // return await repairRepository.addScore(id, score); + // } + @override + void onInit() { + super.onInit(); + loadMockRepairList(); + } + + void loadMockRepairList() { + model.repairList = [ + ApplyRepairModel() + ..id = 1001 + ..device_category = '智能床垫 BY-H' + ..status = '待维修' + ..create_time = DateTime.now().subtract(Duration(days: 1)) + ..device_id = 'BYH-001', + ApplyRepairModel() + ..id = 1002 + ..device_category = '智能床垫 BY-A' + ..status = '维修中' + ..create_time = DateTime.now().subtract(Duration(days: 2)) + ..device_id = 'BYA-002', + ApplyRepairModel() + ..id = 1003 + ..device_category = '智能床垫 BY-C' + ..status = '已完成' + ..create_time = DateTime.now().subtract(Duration(days: 3)) + ..device_id = 'BYC-003', + ]; + } +} diff --git a/lib/controller/mh/repair_list_controller.g.dart b/lib/controller/mh/repair_list_controller.g.dart new file mode 100644 index 0000000..0e260c6 --- /dev/null +++ b/lib/controller/mh/repair_list_controller.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'repair_list_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +RepairListModel _$RepairListModelFromJson(Map json) => + RepairListModel() + ..limit = (json['limit'] as num).toInt() + ..offset = (json['offset'] as num).toInt() + ..isLoading = json['isLoading'] as bool + ..hasMore = json['hasMore'] as bool + ..repairList = (json['repairList'] as List) + .map((e) => ApplyRepairModel.fromJson(e as Map)) + .toList(); + +Map _$RepairListModelToJson(RepairListModel instance) => + { + 'limit': instance.limit, + 'offset': instance.offset, + 'isLoading': instance.isLoading, + 'hasMore': instance.hasMore, + 'repairList': instance.repairList, + }; diff --git a/lib/controller/mh/repair_process.dart b/lib/controller/mh/repair_process.dart new file mode 100644 index 0000000..de3e16d --- /dev/null +++ b/lib/controller/mh/repair_process.dart @@ -0,0 +1,18 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'repair_process.g.dart'; + +@JsonSerializable() +class RepairProcessModel { + String? status; //审核状态 + DateTime? create_time; //审核时间 + String? desc; //审核意见 + int? record_id; //归属记录 + + int? deal_user; //处理人 + + RepairProcessModel(); + static RepairProcessModel fromJson(Map json) => + _$RepairProcessModelFromJson(json); + Map toJson() => _$RepairProcessModelToJson(this); +} diff --git a/lib/controller/mh/repair_process.g.dart b/lib/controller/mh/repair_process.g.dart new file mode 100644 index 0000000..d55573e --- /dev/null +++ b/lib/controller/mh/repair_process.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'repair_process.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +RepairProcessModel _$RepairProcessModelFromJson(Map json) => + RepairProcessModel() + ..status = json['status'] as String? + ..create_time = json['create_time'] == null + ? null + : DateTime.parse(json['create_time'] as String) + ..desc = json['desc'] as String? + ..record_id = (json['record_id'] as num?)?.toInt() + ..deal_user = (json['deal_user'] as num?)?.toInt(); + +Map _$RepairProcessModelToJson(RepairProcessModel instance) => + { + 'status': instance.status, + 'create_time': instance.create_time?.toIso8601String(), + 'desc': instance.desc, + 'record_id': instance.record_id, + 'deal_user': instance.deal_user, + }; diff --git a/lib/controller/mh/score_controller.dart b/lib/controller/mh/score_controller.dart new file mode 100644 index 0000000..f804a70 --- /dev/null +++ b/lib/controller/mh/score_controller.dart @@ -0,0 +1,20 @@ +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'score_controller.g.dart'; + +@JsonSerializable() +class ScoreModel { + int? score = 5; + + ScoreModel(); + static ScoreModel fromJson(Map json) => + _$ScoreModelFromJson(json); + Map toJson() => _$ScoreModelToJson(this); +} + +class ScoreController extends GetControllerEx { + ScoreController() { + attr = GetModel(ScoreModel()).obs; + } +} diff --git a/lib/controller/mh/score_controller.g.dart b/lib/controller/mh/score_controller.g.dart new file mode 100644 index 0000000..fb345f6 --- /dev/null +++ b/lib/controller/mh/score_controller.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'score_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ScoreModel _$ScoreModelFromJson(Map json) => + ScoreModel()..score = (json['score'] as num?)?.toInt(); + +Map _$ScoreModelToJson(ScoreModel instance) => + { + 'score': instance.score, + }; diff --git a/lib/controller/mh/sleeping_habit_controller.dart b/lib/controller/mh/sleeping_habit_controller.dart new file mode 100644 index 0000000..85e590b --- /dev/null +++ b/lib/controller/mh/sleeping_habit_controller.dart @@ -0,0 +1,94 @@ +import 'dart:convert'; + +import 'package:dio/src/form_data.dart' as formdata; +import 'package:ef/ef.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'sleeping_habit_controller.g.dart'; // 由json_serializable自动生成的部分 + +@JsonSerializable() +class SleepingHabitModel { + bool rxhxIsStart = false; + List rxhxWakeTime = [0, 0]; + bool rxhxIsBell = false; + bool rxhxIsAnMo = false; + int rxhxLocation = 0; + List rxhxWeeks = [0, 0, 0, 0, 0, 0, 0]; + + bool dhgyIsStart = false; + + bool smysIsStart = false; + List smysStartTime = [20, 0]; + List smysEndTime = [9, 0]; + + String get rxhxWakeTimeToString { + return '${rxhxWakeTime[0]}'.padLeft(2, "0") + + ":" + + '${rxhxWakeTime[1]}'.padLeft(2, "0"); + } + + String get smysStartTimeToString { + return '${smysStartTime[0]}'.padLeft(2, "0") + + ":" + + '${smysStartTime[1]}'.padLeft(2, "0"); + } + + String get smysEndTimeToString { + return '${smysEndTime[0]}'.padLeft(2, "0") + + ":" + + '${smysEndTime[1]}'.padLeft(2, "0"); + } + + SleepingHabitModel(); + + factory SleepingHabitModel.fromJson(Map json) { + try { + return _$SleepingHabitModelFromJson(json); + } catch (e) { + print("$e"); + // 在实际应用中,应该有更细致的异常处理策略和错误日志 + return SleepingHabitModel(); // 或者返回一个带有错误信息的特定AboutModel实例 + } + } + Map toJson() => _$SleepingHabitModelToJson(this); +} + +class SleepingHabitController extends GetControllerEx { + SleepingHabitController() { + attr = GetModel(SleepingHabitModel()).obs; + } + + // saveDataApi() { + // String mac = Get.find().model.deviceMain["mac"]; + // ApiService.request.post("/api/device/info/config", + // data: formdata.FormData.fromMap({ + // "mac": mac, + // "type": "sleepHabit", + // "data": jsonEncode(model.toJson()) + // })); + // } + + // loadDataApi({int time = 3}) { + // String mac = Get.find().model.deviceMain["mac"]; + + // ApiService.request + // .get("/api/device/info/config?type=sleepHabit&mac=${mac}") + // .then((d) async { + // if (d.data["data"] != null && d.data["data"]["data"] != null) { + // attr.value.model = + // SleepingHabitModel.fromJson(jsonDecode(d.data["data"]["data"])); + // print("load ${model.toJson()}"); + // } else { + // attr.value.model = SleepingHabitModel(); + // print("load error"); + // } + // updateAll(); + // }).catchError((d) { + // if (time > 0) { + // loadDataApi(time: time - 1); + // } else { + // attr.value.model = SleepingHabitModel(); + // } + // }); + // } +} diff --git a/lib/controller/mh/sleeping_habit_controller.g.dart b/lib/controller/mh/sleeping_habit_controller.g.dart new file mode 100644 index 0000000..2cde832 --- /dev/null +++ b/lib/controller/mh/sleeping_habit_controller.g.dart @@ -0,0 +1,40 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'sleeping_habit_controller.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +SleepingHabitModel _$SleepingHabitModelFromJson(Map json) => + SleepingHabitModel() + ..rxhxIsStart = json['rxhxIsStart'] as bool + ..rxhxWakeTime = (json['rxhxWakeTime'] as List) + .map((e) => (e as num).toInt()) + .toList() + ..rxhxIsBell = json['rxhxIsBell'] as bool + ..rxhxIsAnMo = json['rxhxIsAnMo'] as bool + ..rxhxLocation = (json['rxhxLocation'] as num).toInt() + ..rxhxWeeks = json['rxhxWeeks'] as List + ..dhgyIsStart = json['dhgyIsStart'] as bool + ..smysIsStart = json['smysIsStart'] as bool + ..smysStartTime = (json['smysStartTime'] as List) + .map((e) => (e as num).toInt()) + .toList() + ..smysEndTime = (json['smysEndTime'] as List) + .map((e) => (e as num).toInt()) + .toList(); + +Map _$SleepingHabitModelToJson(SleepingHabitModel instance) => + { + 'rxhxIsStart': instance.rxhxIsStart, + 'rxhxWakeTime': instance.rxhxWakeTime, + 'rxhxIsBell': instance.rxhxIsBell, + 'rxhxIsAnMo': instance.rxhxIsAnMo, + 'rxhxLocation': instance.rxhxLocation, + 'rxhxWeeks': instance.rxhxWeeks, + 'dhgyIsStart': instance.dhgyIsStart, + 'smysIsStart': instance.smysIsStart, + 'smysStartTime': instance.smysStartTime, + 'smysEndTime': instance.smysEndTime, + }; diff --git a/lib/controller/mh/user_data.dart b/lib/controller/mh/user_data.dart new file mode 100644 index 0000000..ea76499 --- /dev/null +++ b/lib/controller/mh/user_data.dart @@ -0,0 +1,22 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'user_data.g.dart'; + +@JsonSerializable() +class UserModel { + String? uid; + String? userName; + String? nickName; + String? tel; + String? avatar; + String? exp1; + String? exp2; + String? head; + String? tmpHead; + String? tmpNickName; + + UserModel(); + static UserModel fromJson(Map json) => + _$UserModelFromJson(json); + Map toJson() => _$UserModelToJson(this); +} diff --git a/lib/controller/mh/user_data.g.dart b/lib/controller/mh/user_data.g.dart new file mode 100644 index 0000000..89d1e4c --- /dev/null +++ b/lib/controller/mh/user_data.g.dart @@ -0,0 +1,32 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user_data.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +UserModel _$UserModelFromJson(Map json) => UserModel() + ..uid = json['uid'] as String? + ..userName = json['userName'] as String? + ..nickName = json['nickName'] as String? + ..tel = json['tel'] as String? + ..avatar = json['avatar'] as String? + ..exp1 = json['exp1'] as String? + ..exp2 = json['exp2'] as String? + ..head = json['head'] as String? + ..tmpHead = json['tmpHead'] as String? + ..tmpNickName = json['tmpNickName'] as String?; + +Map _$UserModelToJson(UserModel instance) => { + 'uid': instance.uid, + 'userName': instance.userName, + 'nickName': instance.nickName, + 'tel': instance.tel, + 'avatar': instance.avatar, + 'exp1': instance.exp1, + 'exp2': instance.exp2, + 'head': instance.head, + 'tmpHead': instance.tmpHead, + 'tmpNickName': instance.tmpNickName, + }; diff --git a/lib/main.dart b/lib/main.dart index fa8d3d4..6f33c56 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -31,6 +31,20 @@ import 'package:vbvs_app/controller/message/common_message_setting_controller.da import 'package:vbvs_app/controller/message/message_controller.dart'; import 'package:vbvs_app/controller/message/message_review_controller.dart'; import 'package:vbvs_app/controller/message/message_setting_controller.dart'; +import 'package:vbvs_app/controller/mh/address_controller.dart'; +import 'package:vbvs_app/controller/mh/address_list_controller.dart'; +import 'package:vbvs_app/controller/mh/book_info_controller.dart'; +import 'package:vbvs_app/controller/mh/experience_store_list_page.dart'; +import 'package:vbvs_app/controller/mh/issue_controller.dart'; +import 'package:vbvs_app/controller/mh/issue_preview_controller.dart'; +import 'package:vbvs_app/controller/mh/message_controller.dart'; +import 'package:vbvs_app/controller/mh/muser_info_controller.dart'; +import 'package:vbvs_app/controller/mh/my_experience_list_controller.dart'; +import 'package:vbvs_app/controller/mh/people_info_controller.dart'; +import 'package:vbvs_app/controller/mh/repair_info_controller.dart'; +import 'package:vbvs_app/controller/mh/repair_list_controller.dart'; +import 'package:vbvs_app/controller/mh/score_controller.dart'; +import 'package:vbvs_app/controller/mh/sleeping_habit_controller.dart'; import 'package:vbvs_app/controller/person/person_controller.dart'; import 'package:vbvs_app/controller/repair/repair_controller.dart'; import 'package:vbvs_app/controller/setting/language/language_controller.dart'; @@ -43,7 +57,13 @@ import 'package:vbvs_app/controller/weather/weather_controller.dart'; import 'package:vbvs_app/language/AppLanguage.dart'; import 'package:vbvs_app/model/CustomThemeColor.dart'; import 'package:vbvs_app/model/user_data.dart'; +import 'package:vbvs_app/pages/device_control/BackMovement.dart'; +import 'package:vbvs_app/pages/device_control/MattressControl.dart'; +import 'package:vbvs_app/pages/device_control/people_info.dart'; +import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart'; +import 'package:vbvs_app/routers/mh_routers.dart'; +import 'controller/mh/apply_repair_controller.dart'; import 'controller/user_info_controller.dart'; import 'routers/routers.dart'; @@ -198,55 +218,87 @@ class MyApp extends StatelessWidget { MyApp({super.key}); final ThemeController themeController = Get.put(ThemeController()); - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - themeController.changeTheme(CustomThemeColor.dark); - UserInfoController userInfoController = Get.find(); - return LayoutBuilder(builder: (contxt, cons) { - double width = cons.maxWidth; - double height = cons.maxHeight; - if (width < 1) { - return Container(); - } - FitTool.init(width < height ? width : height); - return GetMaterialApp( - translations: AppLanguage(), - // locale: const Locale("zh", "CN"), - locale: AppLanguage().currentLocale, // ✅ 动态读取当前语言 - fallbackLocale: const Locale("zh", "CN"), - localizationsDelegates: [ - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - SfGlobalLocalizations.delegate, - ], - supportedLocales: [ - const Locale('zh', 'CN'), // 中文 - const Locale('en', 'US'), // ⚠️ 添加你支持的语言 - ], - debugShowCheckedModeBanner: false, - title: '', - theme: themeController.currentTheme, - // home: const MyHomePage(title: '智慧眠花糖 Home Page'), - initialRoute: "/mianPageBottomChange", - onGenerateRoute: onGenerateRoute, - initialBinding: BindingsBuilder(() => [ - // Get.lazyPut(() => UserInfoController()), - Get.put(GlobalController()), + Widget buildmht(BuildContext context, BoxConstraints cons) { + return GetMaterialApp( + translations: AppLanguage(), + debugShowCheckedModeBanner: false, + title: '', + theme: themeController.currentTheme, + home: MainPageBBottomChange(), + onGenerateRoute: mhonGenerateRoute, + initialBinding: BindingsBuilder(() => [ + // Get.lazyPut(() => UserInfoController()), + Get.put(GlobalController()), + Get.lazyPut(() => ControlCardController()), + Get.lazyPut(() => RepairListController()), + Get.lazyPut(() => RepairInfoController()), + Get.lazyPut(() => MUserInfoController()), + Get.lazyPut(() => MhMessageController()), + Get.lazyPut(() => ScoreController()), + Get.lazyPut(() => ExperienceStoreListController()), + Get.lazyPut(() => BookExperienceListController()), + Get.lazyPut(() => IssuePreviewInfoController()), + Get.lazyPut(() => IssueListController()), + Get.lazyPut(() => ApplyRepairController()), + Get.lazyPut(() => SleepingHabitController()), + Get.lazyPut(() => PeopleInfoController()), + Get.lazyPut(() => MainPageController()), + Get.lazyPut(() => AddressListController()), + Get.lazyPut(() => AddressController()), + Get.lazyPut(() => BlueteethBindController()), + Get.lazyPut(() => BookInfoController()), + Get.lazyPut(() => PersonController()), + Get.lazyPut(() => CountdownController()), + Get.lazyPut(() => LoginController()), + Get.lazyPut(() => DeviceTypeController()), + Get.lazyPut(() => BodyDeviceController()), + Get.lazyPut(() => HomeController()), + Get.lazyPut(() => DeviceShareController()), + Get.lazyPut(() => DeviceShareListController()), + Get.lazyPut(() => DeviceCalibrationController()), + Get.lazyPut(() => RepairController()), + Get.lazyPut(() => PdfController()), + ])); + } + + Widget buildth(BuildContext context, BoxConstraints cons) { + return GetMaterialApp( + translations: AppLanguage(), + // locale: const Locale("zh", "CN"), + locale: AppLanguage().currentLocale, // ✅ 动态读取当前语言 + fallbackLocale: const Locale("zh", "CN"), + localizationsDelegates: [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + SfGlobalLocalizations.delegate, + ], + supportedLocales: [ + const Locale('zh', 'CN'), // 中文 + const Locale('en', 'US'), // ⚠️ 添加你支持的语言 + ], + debugShowCheckedModeBanner: false, + title: '', + theme: themeController.currentTheme, + // home: const MyHomePage(title: '智慧眠花糖 Home Page'), + initialRoute: "/mianPageBottomChange", + onGenerateRoute: onGenerateRoute, + initialBinding: BindingsBuilder(() => [ + // Get.lazyPut(() => UserInfoController()), + Get.put(GlobalController()), Get.put(WeatherModelController()), - Get.lazyPut(() => MainPageController()), - Get.lazyPut(() => BlueteethBindController()), - Get.lazyPut(() => PersonController()), - Get.lazyPut(() => CountdownController()), - Get.lazyPut(() => LoginController()), - Get.lazyPut(() => DeviceTypeController()), - Get.lazyPut(() => BodyDeviceController()), - Get.lazyPut(() => HomeController()), - Get.lazyPut(() => DeviceShareController()), - Get.lazyPut(() => DeviceShareListController()), - Get.lazyPut(() => DeviceCalibrationController()), - Get.lazyPut(() => RepairController()), + Get.lazyPut(() => MainPageController()), + Get.lazyPut(() => BlueteethBindController()), + Get.lazyPut(() => PersonController()), + Get.lazyPut(() => CountdownController()), + Get.lazyPut(() => LoginController()), + Get.lazyPut(() => DeviceTypeController()), + Get.lazyPut(() => BodyDeviceController()), + Get.lazyPut(() => HomeController()), + Get.lazyPut(() => DeviceShareController()), + Get.lazyPut(() => DeviceShareListController()), + Get.lazyPut(() => DeviceCalibrationController()), + Get.lazyPut(() => RepairController()), Get.lazyPut(() => UserPdfController()), Get.lazyPut(() => PrivacyPdfController()), Get.lazyPut(() => CalendarController()), @@ -254,7 +306,25 @@ class MyApp extends StatelessWidget { Get.lazyPut(() => MessageReviewController()), Get.lazyPut(() => MessageSettingController()), Get.lazyPut(() => CommonMessageSettingController()), - ])); + ])); + } + + final selectapp = "mht"; + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + var co = MediaQuery.sizeOf(context); + FitTool.init(co.height); + themeController.changeTheme(CustomThemeColor.dark); + return LayoutBuilder(builder: (contxt, cons) { + switch (selectapp) { + case "th": + return buildth(context, cons); + case "mht": + return buildmht(contxt, cons); + default: + return buildth(context, cons); + } }); } } diff --git a/lib/pages/common/bezier_bottom_navigation_bar.dart b/lib/pages/common/bezier_bottom_navigation_bar.dart new file mode 100644 index 0000000..77672be --- /dev/null +++ b/lib/pages/common/bezier_bottom_navigation_bar.dart @@ -0,0 +1,151 @@ +// bezier_bottom_navigation_bar.dart +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; + +class BezierBottomNavigationBar extends StatelessWidget { + final int selectedIndex; + final double animatedPosition; + final ValueChanged onTap; + final List path; + final List titles; + + const BezierBottomNavigationBar({ + Key? key, + required this.selectedIndex, + required this.animatedPosition, + required this.onTap, + required this.path, + required this.titles, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final itemCount = path.length; + return SizedBox( + height: 130.rpx, + child: Stack( + children: [ + Positioned.fill( + child: CustomPaint( + size: Size(MediaQuery.of(context).size.width, 130.rpx), + painter: BezierPainter( + position: animatedPosition, + itemCount: itemCount, + ), + ), + ), + Row( + children: path.asMap().entries.map((entry) { + final i = entry.key; + final icon = entry.value; + return Expanded( + child: GestureDetector( + // 用 InkWell 替换 GestureDetector,支持点击反馈 + onTap: () => onTap(i), + // splashColor: Colors.transparent, // 可选:关闭 splash 效果 + // highlightColor: Colors.transparent, // 可选:关闭高亮效果 + child: SizedBox.expand( + child: Padding( + padding: EdgeInsets.only(top: 14.rpx), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 11.rpx), + child: SvgPicture.asset(icon, + width: 42.rpx, + height: 42.rpx, + color: selectedIndex == i + ? Colors.white + : Color(0XFF929699)), + ), + SizedBox(height: 3), + Text( + titles[i], + style: TextStyle( + fontSize: 22.rpx, + color: selectedIndex == i + ? Colors.white + : Colors.grey.shade400, + ), + ), + ], + ), + ) + // 关键点:撑满 Expanded 区域 + + ), + ), + ); + }).toList(), + ), + ], + ), + ); + } +} + +class BezierPainter extends CustomPainter { + final double position; + final int itemCount; + + BezierPainter({required this.position, required this.itemCount}); + + @override + void paint(Canvas canvas, Size size) { + final paint = Paint() + ..color = Colors.white + ..style = PaintingStyle.stroke + ..strokeWidth = 1.0; + + final path = Path(); + final itemWidth = size.width / itemCount; + final curveWidth = itemWidth * 0.8; + double curveHeight = 8.5; + + final centerX = itemWidth * position + itemWidth / 2; + final left = centerX - curveWidth / 2; + final right = centerX + curveWidth / 2; + + // 控制点偏移比例(越小越平滑) + final controlOffsetX = curveWidth * 0.2; + final controlOffsetY = curveHeight * 0.9; + + // 起点 + path.moveTo(0, 0); + + // 到左侧前的一段直线 + path.lineTo(left, 0); + + // 凸起贝塞尔曲线 + path.cubicTo( + left + controlOffsetX, + 0, + centerX - controlOffsetX, + -controlOffsetY, + centerX, + -controlOffsetY, + ); + path.cubicTo( + centerX + controlOffsetX, + -controlOffsetY, + right - controlOffsetX, + 0, + right, + 0, + ); + + // 右边剩余直线 + path.lineTo(size.width, 0); + + // 向下平移,保证凸起在容器内部 + canvas.translate(0, controlOffsetY); + canvas.drawPath(path, paint); + } + + @override + bool shouldRepaint(covariant BezierPainter oldDelegate) { + return oldDelegate.position != position; + } +} diff --git a/lib/pages/device_control/BackMovement.dart b/lib/pages/device_control/BackMovement.dart new file mode 100644 index 0000000..1c6432f --- /dev/null +++ b/lib/pages/device_control/BackMovement.dart @@ -0,0 +1,228 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'dart:math' as math; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +class BackMovementPage extends StatefulWidget { + const BackMovementPage({super.key}); + + @override + State createState() => _BackMovementPageState(); +} + +class _BackMovementPageState extends State { + double intensity = 4; + int selectedTime = 10; + + final List timeOptions = [10, 20, 30]; + + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, bodysize) { + final double totalWidth = bodysize.maxWidth - 40.rpx * 2; // 减去左右 padding + final double spacing = 34.rpx; + final double buttonHeight = 101.rpx; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + child: Scaffold( + appBar: AppBar( + iconTheme: IconThemeData(color: themeController.currentColor.sc3), + backgroundColor: const Color(0xFF011C33), // 统一背景色 + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '背部律动', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + backgroundColor: const Color(0xFF011C33), + body: Padding( + padding: EdgeInsets.fromLTRB(0.rpx, 0, 0.rpx, 0), + child: Column( + // crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SingleChildScrollView( + child: Column( + children: [ + SizedBox(height: 30.rpx), + Text( + '力度调节', + style: TextStyle(color: Colors.grey, fontSize: 30.rpx), + ), + SizedBox(height: 148.rpx), + Text( + intensity.toInt().toString(), + style: + TextStyle(color: Colors.white, fontSize: 160.rpx), + ), + SizedBox(height: 41.rpx), + SizedBox( + height: 451.rpx, // 外部容器高度固定 + child: Stack( + children: [ + // 左边的 强/弱 文本 + Positioned( + left: 0, + top: 0, + bottom: 0, + child: SizedBox( + width: 60.rpx, + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text('强', + style: TextStyle( + color: Colors.grey, + fontSize: 30.rpx)), + Text('弱', + style: TextStyle( + color: Colors.grey, + fontSize: 30.rpx)), + ], + ), + ), + ), + + // 右侧 slider,27.rpx 后居中 + Positioned( + left: 60.rpx - 27.rpx, // 60 是文字宽度,27 是间隔 + right: 0, + top: 0, + bottom: 0, + child: Center( + child: Transform.rotate( + angle: -math.pi / 2, + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: 451.rpx, + maxHeight: 451.rpx, + ), + child: SliderTheme( + data: SliderTheme.of(context).copyWith( + trackHeight: 60.rpx, + thumbShape: RoundSliderThumbShape( + enabledThumbRadius: 45.rpx), + overlayShape: + const RoundSliderOverlayShape( + overlayRadius: 20), + ), + child: Slider( + value: intensity, + min: 1, + max: 6, + divisions: 7, + activeColor: Colors.cyanAccent, + inactiveColor: Colors.blue.shade900, + onChanged: (value) { + setState(() { + intensity = value; + }); + }, + ), + ), + ), + ), + ), + ), + ], + ), + ), + SizedBox(height: 118.rpx), + Padding( + padding: EdgeInsets.only( + left: 47.rpx), // 👈 控制间隔大小(也可以是 all / symmetric) + child: Align( + alignment: Alignment.centerLeft, + child: Text( + '按摩定时', + style: TextStyle( + color: Colors.white70, fontSize: 30.rpx), + ), + ), + ), + SizedBox(height: 74.rpx), + Padding( + padding: EdgeInsets.fromLTRB(40.rpx, 0, 40.rpx, 0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: + List.generate(timeOptions.length, (index) { + final min = timeOptions[index]; + final isSelected = selectedTime == min; + return SizedBox( + height: buttonHeight, + child: ElevatedButton( + onPressed: () { + setState(() { + selectedTime = min; + }); + }, + style: ElevatedButton.styleFrom( + backgroundColor: isSelected + ? Colors.cyanAccent + : Colors.blue.shade900, + foregroundColor: isSelected + ? Colors.black + : Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + ), + child: Text('$min分钟'), + )); + }), + )), + ], + )), + Padding( + padding: EdgeInsets.fromLTRB(30.rpx, 0, 30.rpx, + 81.rpx), // 👈 控制上方间隔(也可以用 all / symmetric) + child: OutlinedButton( + onPressed: () { + setState(() { + intensity = 4; + selectedTime = 10; + }); + }, + style: OutlinedButton.styleFrom( + side: const BorderSide(color: Color(0XFF74DAE5)), + foregroundColor: Colors.cyanAccent, + minimumSize: Size(bodysize.maxWidth, 92.rpx), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + ), + child: const Text('恢复到默认设置'), + ), + ), + ], + ), + ), + ))); + }); + } +} diff --git a/lib/pages/device_control/ColorChangeOnTap.dart b/lib/pages/device_control/ColorChangeOnTap.dart new file mode 100644 index 0000000..8af73e6 --- /dev/null +++ b/lib/pages/device_control/ColorChangeOnTap.dart @@ -0,0 +1,94 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +class ColorChangeOnPress extends StatefulWidget { + final Color? initialColor; // 初始颜色 + final Color pressColor; // 按下时的颜色 + final bool shouldNavigate; // 是否需要跳转 + final String? routeName; // 路由名称 + final Widget child; // 子组件 + final String? toastMessage; // Toast 消息 + final ToastColor? toastColor; // Toast 颜色 + final double topLeft; // 左上圆角 + final double topRight; // 右上圆角 + final double bottomRight; // 右下圆角 + final double bottomLeft; // 左下圆角 + final VoidCallback? onTap; // 点击回调 + + const ColorChangeOnPress({ + Key? key, + this.initialColor = Colors.white, // 默认初始颜色为白色 + this.pressColor = Colors.grey, // 默认按下颜色为灰色 + this.shouldNavigate = false, // 默认不跳转 + this.routeName, + required this.child, + this.toastMessage, // Toast 消息 + this.toastColor, // Toast 颜色 + this.topLeft = 0.0, // 左上圆角 + this.topRight = 0.0, // 右上圆角 + this.bottomRight = 0.0, // 右下圆角 + this.bottomLeft = 0.0, // 左下圆角 + this.onTap, // 点击回调 + }) : super(key: key); + + @override + _ColorChangeOnPressState createState() => _ColorChangeOnPressState(); +} + +class _ColorChangeOnPressState extends State { + Color? _currentColor; + + @override + void initState() { + super.initState(); + _currentColor = widget.initialColor; // 初始化为初始颜色 + } + + void _handleTap() { + // 如果提供了 onTap 回调,调用它 + if (widget.onTap != null) { + widget.onTap!(); // 执行自定义逻辑 + } + + setState(() { + _currentColor = widget.pressColor; // 改变为按下的颜色 + }); + + // 显示 Toast 消息 + if (widget.toastMessage != null) { + showToast(widget.toastMessage!, color: widget.toastColor!); + } + + // 在0.5秒后恢复颜色 + Future.delayed(const Duration(milliseconds: 100), () { + setState(() { + _currentColor = widget.initialColor; // 恢复为初始颜色 + }); + + // 如果需要跳转,则执行路由跳转 + if (widget.shouldNavigate && widget.routeName != null) { + Get.toNamed(widget.routeName!); // 在颜色恢复后执行跳转 + } + }); + } + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: _currentColor, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(widget.topLeft), // 左上圆角 + topRight: Radius.circular(widget.topRight), // 右上圆角 + bottomRight: Radius.circular(widget.bottomRight), // 右下圆角 + bottomLeft: Radius.circular(widget.bottomLeft), // 左下圆角 + ), + ), + child: InkWell( + onTap: _handleTap, + child: widget.child, + ), + ); + } +} diff --git a/lib/pages/device_control/Empty.dart b/lib/pages/device_control/Empty.dart new file mode 100644 index 0000000..311a512 --- /dev/null +++ b/lib/pages/device_control/Empty.dart @@ -0,0 +1,54 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; + +class Empty extends StatefulWidget { + Empty({super.key}); + + @override + State createState() => _EmptyState(); +} + +class _EmptyState extends State { + String empty = ""; + bool closepage = false; + + @override + void initState() { + // TODO: implement initState + super.initState(); + Timer(const Duration(milliseconds: 1200), () { + if (empty.isEmpty && closepage == false) { + setState(() { + empty = "assets/images/new_empty.png"; + }); + } + }); + } + + @override + void dispose() { + // TODO: implement dispose + super.dispose(); + closepage = true; + } + + @override + Widget build(BuildContext context) { + if (empty.isEmpty) { + return Container(); + } else { + return Container( + width: double.infinity, + margin: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.3), + alignment: Alignment.center, + child: Container( + width: 164.rpx, + height: 230.rpx, + child: Image.asset(empty), + ), + ); + } + } +} diff --git a/lib/pages/device_control/EmptyMessageWidget.dart b/lib/pages/device_control/EmptyMessageWidget.dart new file mode 100644 index 0000000..e62d9f4 --- /dev/null +++ b/lib/pages/device_control/EmptyMessageWidget.dart @@ -0,0 +1,37 @@ +import 'dart:async'; + +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; + +class EmptyMessageWidget extends StatelessWidget { + final String imagePath; + final double width; + final double height; + var empty = "".obs; + + EmptyMessageWidget({ + Key? key, + this.imagePath = 'assets/images/new_empty.png', // 默认图片路径 + double? width, // 默认宽度 + double? height, // 默认高度 + }) : width = 164.rpx, // 初始化宽度 + height = 230.rpx, // 初始化高度变为原来的三分之二 + super(key: key); + + @override + Widget build(BuildContext context) { + Timer(Duration(milliseconds: 5000), () { + empty.value = "assets/images/new_empty.png"; + }); + return Center( + child: Image.asset( + imagePath, + width: width, + height: height, + color: Colors.white, + ), + + ); + } +} diff --git a/lib/pages/device_control/HomeDeviceType.dart b/lib/pages/device_control/HomeDeviceType.dart new file mode 100644 index 0000000..91a66aa --- /dev/null +++ b/lib/pages/device_control/HomeDeviceType.dart @@ -0,0 +1,245 @@ +import 'dart:async'; + +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + + +class HomeDeviceType extends StatefulWidget { + HomeDeviceType({super.key}); + @override + State createState() => _HomeDeviceTypeState(); +} + +class _HomeDeviceTypeState extends State { + bool isExec = false; + + @override + Widget build(BuildContext context) { + // if (isExec == false) { + // Timer(const Duration(milliseconds: 10), () { + // controller.getDeviceType(); + // }); + // isExec = true; + // } + return LayoutBuilder( + builder: (context, boxConstraints) => GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: const IconThemeData(color: Colors.white), + titleSpacing: 0, + // leading: returnIconButtom, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '添加设备', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtom, + ), + ], + ), + ), + + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1.123, + // decoration: const BoxDecoration( + // image: DecorationImage( + // image: AssetImage("assets/images/new_background.png"), + // fit: BoxFit.cover, + // ), + // ), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 48.rpx, 24.rpx, 0, 0), + child: Text( + '选择类型', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + ), + _buildControlCard(context), + ], + ), + ), + ), + ), + ), + )), + ); + } +} + +Widget _buildControlCard(BuildContext context) { + final List> deviceTypeList = [ + { + "id": 1, + "name": "智能床垫", + "desc": "SWES01 MHT01 SWES01 MHT01 SWES01 MHT01 ", + "img": "assets/images/device_bed.png", + "page": 1, + }, + { + "id": 2, + "name": "智能电动床", + "desc": "M300", + "img": "assets/images/electric_bed.png", + "page": 2, + }, + ]; + + return SizedBox( + // height: 221.rpx, + child: Padding( + padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx, top: 7.rpx), + child: Column( + children: List.generate( + deviceTypeList.length, + (index) => _buildDeviceItem(context, deviceTypeList[index]), + ), + ))); +} + +Widget _buildDeviceItem(BuildContext context, Map dtype) { + return Padding( + padding: EdgeInsetsDirectional.fromSTEB(0, 25.rpx, 0, 0), + child: InkWell( + onTap: () { + // Get.offAndToNamed("/bindDevice", arguments: dtype["id"]); + }, + child: Container( + height: 221.rpx, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context).secondaryBackground, + borderRadius: BorderRadius.circular(6), + ), + constraints: BoxConstraints(minHeight: 221.rpx), + child: Row( + children: [ + Padding( + padding: EdgeInsetsDirectional.only(start: 59.rpx), + child: Container( + child: ClipRRect( + borderRadius: BorderRadius.circular(6.rpx), + child: Image.asset( + dtype["img"], + width: 180.rpx, + height: 109.rpx, + fit: BoxFit.cover, + ), + ), + ), + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.fromLTRB(0, 59.rpx, 0, 0), + child: Text( + dtype["name"], + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + fontSize: 30.rpx, + fontWeight: FontWeight.bold, + ), + ), + ), + SizedBox(height: 35.rpx), + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 80.rpx, right: 80.rpx), + child: SizedBox( + height: 40.rpx, // 固定高度(两行高度 + 行间距) + child: LayoutBuilder( + builder: (context, constraints) { + final items = (dtype["desc"] as String) + .split(RegExp(r'\s+')) + .where((e) => e.trim().isNotEmpty) + .toList(); + final limitedItems = items.take(6).toList(); + + final isSingleLine = limitedItems.length <= 3; + + return Align( + alignment: isSingleLine + ? Alignment.topCenter + : Alignment.topLeft, + child: Wrap( + spacing: 20.rpx, + runSpacing: 10.rpx, + alignment: isSingleLine + ? WrapAlignment.center + : WrapAlignment.start, + children: limitedItems.map((item) { + return Container( + width: 75.rpx, + // height: 40.rpx, + alignment: Alignment.center, + child: Text( + item, + style: TextStyle( + fontSize: 20.rpx, + color: const Color(0xFF9AA0B3), + height: 1, + ), + // overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ); + }).toList(), + ), + ); + }, + ), + ), + )) + ], + ), + ), + ], + ), + ), + ), + ); +} diff --git a/lib/pages/device_control/LanguagePage.dart b/lib/pages/device_control/LanguagePage.dart new file mode 100644 index 0000000..d51684b --- /dev/null +++ b/lib/pages/device_control/LanguagePage.dart @@ -0,0 +1,158 @@ +import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart'; +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +class LanguagePage extends StatefulWidget { + @override + _LanguagePageState createState() => _LanguagePageState(); +} + +BoxConstraints? bodysize; +List languageList = [ + '简体中文', + '繁體中文', + 'English', +]; +final Map languageMap = { + '简体中文': 'zh_CN', + '繁體中文': 'zh_TW', + 'English': 'en_US', +}; + +class _LanguagePageState extends State { + RxBool checkboxValue = false.obs; + RxString? selectLanguage = ''.obs; + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () { + FocusScope.of(context).requestFocus(FocusNode()); + }, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '切换语言', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Padding( + padding: EdgeInsets.only( + top: 30.rpx, left: 30.rpx, right: 30.rpx), + child: Container( + decoration: BoxDecoration( + color: Color(0XFF003058), + borderRadius: BorderRadius.circular(16.rpx)), + child: Padding( + padding: EdgeInsets.only( + left: 40.rpx, + top: 20.rpx, + bottom: 20.rpx, + right: 30.rpx), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListView.builder( + padding: EdgeInsets.zero, + shrinkWrap: true, + scrollDirection: Axis.vertical, + itemCount: languageList.length, + itemBuilder: + (BuildContext context, int index) { + return _buildItem( + context, index, languageList[index]); + }, + ), + Container(height: bodysize!.maxHeight * 0.12) + ], + ), + ))))), + )); + }); + } + + Widget _buildItem(BuildContext context, int index, String text) { + return Container( + // width: bodysize!.maxWidth * 1, + height: bodysize!.maxHeight * 0.055, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + text, + style: TextStyle(color: Colors.white, fontSize: 30.rpx), + ), + Theme( + data: ThemeData( + checkboxTheme: CheckboxThemeData( + visualDensity: VisualDensity.compact, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + ), + ), + unselectedWidgetColor: FlutterFlowTheme.of(context).alternate, + ), + child: Obx(() { + return Checkbox( + value: selectLanguage!.value == languageMap[text], + onChanged: (newValue) async { + if (newValue!) { + selectLanguage!.value = languageMap[ + text]!; // Set selectLanguage to the current text value + } else { + selectLanguage!.value = + ''; // Clear selection if unchecked + } + }, + shape: CircleBorder(), + side: BorderSide( + width: 2, + color: FlutterFlowTheme.of(context).alternate, + ), + activeColor: Color(0XFF6BFDAC), + checkColor: FlutterFlowTheme.of(context).info, + ); + })), + ], + ), + ); + } +} diff --git a/lib/pages/device_control/MattressControl.dart b/lib/pages/device_control/MattressControl.dart new file mode 100644 index 0000000..3eeda78 --- /dev/null +++ b/lib/pages/device_control/MattressControl.dart @@ -0,0 +1,352 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutter_switch/flutter_switch.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; + +class MattressControlPage extends StatefulWidget { + const MattressControlPage({super.key}); + + @override + State createState() => _MattressControlPageState(); +} + +class _MattressControlPageState extends State { + final controller = Get.put(ControlCardController()); + + int selectedIndex = 1; // 当前选中的tab索引 + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, bodySize) => GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: + AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + // 顶部返回 + 设备选择 + 蓝牙图标 + 设置按钮 + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + titleSpacing: 0, + elevation: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox(width: 20.rpx), + returnIconButtomNew, + SizedBox(width: 26.rpx), + Container( + decoration: BoxDecoration( + color: Color(0xFF003058), + borderRadius: BorderRadius.circular(30.rpx), + ), + constraints: BoxConstraints( + minHeight: 60.rpx, + maxHeight: 60.rpx, + maxWidth: 260.rpx, + minWidth: 260.rpx), + padding: EdgeInsets.symmetric( + horizontal: 20.rpx), // 加左右边距 + child: DropdownButton( + value: 'Eason Chan', + underline: const SizedBox(), + dropdownColor: Colors.blueGrey, + iconEnabledColor: Colors.white, + style: const TextStyle(color: Colors.white), + isExpanded: true, + items: const [ + DropdownMenuItem( + value: 'Eason Chan', + child: Text('Eason Chan'), + ), + DropdownMenuItem( + value: 'Anna', + child: Text('Anna'), + ), + ], + onChanged: (_) {}, + ), + ), + ], + )), + actions: [ + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(right: 69.rpx), + onTap: () {}, + child: Icon( + Icons.bluetooth, + color: Colors.white, + size: 42.rpx, + ), + ), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(right: 38.rpx), + onTap: () { + Get.toNamed('/bluetoothPage'); + }, + child: Icon(Icons.tune, + color: Colors.white, size: 42.rpx)) + ], + centerTitle: false, + ), + body: SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _buildBedImageSection(context), + _buildModeSelector(context), + Expanded(child: _buildControlCards(context)), + ], + ), + ), + )))); + } + + // 床体图示 + Widget _buildBedImageSection(BuildContext context) { + return Padding( + padding: EdgeInsets.fromLTRB(0, 38.rpx, 0, 63.rpx), + child: Image.asset( + 'assets/images/bed_control.png', + width: MediaQuery.of(context).size.width * 0.7, // 你需要准备这个图像资源 + height: 193.rpx, + ), + ); + } + + Widget _buildModeSelector(BuildContext context) { + final screenWidth = MediaQuery.of(context).size.width - 60.rpx; // 左右各30 + final spacing = 20.0.rpx; + final thirdWidth = 215.rpx; // 三个卡片两个间距 + final tabCount = 3; + final tabWidth = screenWidth / tabCount; + final sideMargin = (tabWidth - thirdWidth) / 2; + + final labels = ['左', '全局', '右']; + + return Padding( + padding: EdgeInsets.symmetric(horizontal: 30.rpx), + child: Stack( + children: [ + Row( + children: List.generate(tabCount, (index) { + return Expanded( + child: GestureDetector( + onTap: () { + selectedIndex = index; + }, + child: _selectorTab( + labels[index], + isSelected: selectedIndex == index, + sideMargin: sideMargin, + ), + ), + ); + }), + ), + // 白线指示器 + Positioned( + bottom: 0, + left: selectedIndex * tabWidth + sideMargin, + child: AnimatedContainer( + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + width: thirdWidth, + height: 3.rpx, + color: Colors.white, + ), + ), + ], + ), + ); + } + + Widget _selectorTab(String label, + {bool isSelected = false, double sideMargin = 0}) { + return Container( + margin: EdgeInsets.symmetric(horizontal: sideMargin), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Center( + child: Text( + label, + style: TextStyle( + color: isSelected ? Colors.white : Colors.grey, + fontSize: 30.rpx, + fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, + ), + ), + ), + if (isSelected) SizedBox(height: 15.rpx), // 保留间距,避免文字和线重叠 + ], + ), + ); + } + + Widget _buildControlCards(BuildContext context) { + final spacing = 20.0.rpx; + + final List> allCards = [ + {'title': '一键助眠', 'time': '30:00'}, + {'title': '疲劳缓解', 'time': '20:00'}, + {'title': '全身放松', 'time': '20:00'}, + {'title': '背部律动', 'time': '10:00'}, + {'title': '腿部律动', 'time': '30:00'}, + {'title': '垂直律动', 'time': ''}, + {'title': '加热', 'time': '30:00'}, + {'title': '柔性唤醒', 'time': 'PM 08:00'}, + {'title': '记忆', 'time': ''}, + ]; + + final firstRow = allCards.sublist(0, 3); + final restCards = allCards.sublist(3); + + // 后续每行两个 + List>> chunkedRows = []; + for (int i = 0; i < restCards.length; i += 2) { + int end = (i + 2 < restCards.length) ? i + 2 : restCards.length; + chunkedRows.add(restCards.sublist(i, end)); + } + + return SingleChildScrollView( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 30.rpx, vertical: 30.rpx), + child: Column( + children: [ + // 第一行:三个卡片 + Row( + children: List.generate(firstRow.length * 2 - 1, (index) { + if (index.isOdd) { + return SizedBox(width: spacing); // 卡片间距 + } else { + final item = firstRow[index ~/ 2]; + return Expanded( + flex: 1, + child: _buildControlCard( + index ~/ 2, + item['title'], + item['time'], + // null, // 不再使用固定宽度 + ), + ); + } + }), + ), + SizedBox(height: spacing), + // 其余每行两个卡片 + ...chunkedRows.map((row) { + return Padding( + padding: EdgeInsets.only(bottom: spacing), + child: Row( + children: List.generate(row.length * 2 - 1, (index) { + if (index.isOdd) { + return SizedBox(width: spacing); + } else { + final item = row[index ~/ 2]; + return Expanded( + flex: 1, + child: _buildControlCard( + index ~/ 2, + item['title'], + item['time'], + // null, + ), + ); + } + }), + ), + ); + }).toList(), + ], + ), + ), + ); + } + + Widget _buildControlCard( + int index, + String title, + String time, + // double width, + ) { + final controller = Get.find(); + + return Container( + // width: width, + height: 241.rpx, + decoration: BoxDecoration( + color: const Color(0xFF003058), + borderRadius: BorderRadius.circular(8), + ), + padding: EdgeInsets.all(15.rpx), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + children: [ + SvgPicture.asset( + 'assets/img/icon/group.svg', + width: 60.rpx, + height: 60.rpx, + color: Colors.white, + ), + SizedBox(height: 22.rpx), + Text( + title, + style: TextStyle(color: Colors.white, fontSize: 30.rpx), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + time, + style: TextStyle( + color: const Color(0XFF929699), + fontSize: 26.rpx, + fontFamily: 'PingFang SC', + ), + ), + Obx(() => FlutterSwitch( + width: 71.rpx, + height: 36.rpx, + toggleSize: 30.rpx, + activeColor: const Color(0XFF6BFDAC), + inactiveColor: const Color(0XFF011D33), + value: controller.switchStates[index].value, + onToggle: (val) { + controller.switchStates[index].value = val; + }, + )), + ], + ), + ], + ), + ); + } +} + +class ControlCardController extends GetxController { + // 共9个卡片,每个卡片有自己的开关状态 + final List switchStates = List.generate(9, (index) => false.obs); +} diff --git a/lib/pages/device_control/address_list_page.dart b/lib/pages/device_control/address_list_page.dart new file mode 100644 index 0000000..cb40322 --- /dev/null +++ b/lib/pages/device_control/address_list_page.dart @@ -0,0 +1,206 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/color/appFontsize.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/controller/mh/address_list_controller.dart'; +import 'package:vbvs_app/pages/device_control/EmptyMessageWidget.dart'; +import 'package:vbvs_app/pages/device_control/address_module_widget.dart'; + +class AddressListPage extends GetView { + final scaffoldKey = GlobalKey(); + BoxConstraints? bodysize; + + // AddressListPage() { + // controller.getAddressList(); + // } + + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: Colors.white), + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '地址管理', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + body: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Obx(() { + if (controller.model.addressList!.isEmpty) { + // 如果地址列表为空,显示 EmptyMessageWidget + return Expanded( + child: EmptyMessageWidget(), + ); + } else { + // 如果地址列表不为空,显示地址列表 + return Expanded( + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + decoration: BoxDecoration( + color: Color(0xFFF6F6F6), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: AlignmentDirectional(-1, 0), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 31, 27, 0, 26), + child: Text( + '我的地址', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: AppFontsize.title_size, + letterSpacing: 0, + fontWeight: FontWeight.w600, + ), + ), + ), + ), + Expanded( + child: Obx(() => ListView( + shrinkWrap: true, + scrollDirection: Axis.vertical, + children: (controller.model.addressList! + .asMap() + .entries + .map((e) => AddressModuleWidget( + index: e.key, + addressListController: + controller, + )) + .toList() as List) + .divide(const SizedBox(height: 10)) + .addToEnd(const SizedBox( + height: AppConstants + .list_end_height)), + )), + ), + ], + ), + ), + ); + } + }), + Align( + alignment: AlignmentDirectional(0, 1), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(15, 15, 15, + AppConstants.page_button_bottom_padding), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.056, + decoration: BoxDecoration( + // color: Color(0xFFF6F6F6), + border: + Border.all(width: 0, color: Color(0XFF85F5FF)), + borderRadius: BorderRadius.circular(12), + ), + child: TextButton( + onPressed: () { + controller.model.address = {'isChecked': false}; + controller.model.type = 1; + Get.toNamed("/editAddressPage"); + }, + style: TextButton.styleFrom( + backgroundColor: Colors.transparent, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + padding: + EdgeInsets.symmetric(horizontal: 24), // 按钮内边距 + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Baseline( + baselineType: TextBaseline.alphabetic, + baseline: AppFontsize.normal_text_size * + 1.6, // 调整基线位置 + child: Text( + '+', + style: FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF85F5FF), + fontSize: + AppFontsize.normal_text_size + + 12, // 让加号比文字稍大 + letterSpacing: 0, + ), + ), + ), + SizedBox(width: 10), // 加号和文字间距 + Text( + '添加新地址', + style: FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF85F5FF), + fontSize: AppFontsize.normal_text_size, + letterSpacing: 0, + ), + ), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ), + )); + }); + } +} diff --git a/lib/pages/device_control/address_module_widget.dart b/lib/pages/device_control/address_module_widget.dart new file mode 100644 index 0000000..462bf62 --- /dev/null +++ b/lib/pages/device_control/address_module_widget.dart @@ -0,0 +1,264 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:flutter_slidable/flutter_slidable.dart'; +import 'package:vbvs_app/controller/mh/address_list_controller.dart'; + +import '../../common/color/appFontsize.dart'; + +class AddressModuleWidget extends GetView { + final int index; + final AddressListController addressListController; + + AddressModuleWidget({ + required this.index, + required this.addressListController, + }) {} + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: SlidableAutoCloseBehavior( + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(15, 0, 15, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + constraints: BoxConstraints( + minHeight: 100, + ), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + ), + child: Slidable( + endActionPane: ActionPane( + extentRatio: 0.26, + motion: ScrollMotion(), + children: [ + Expanded( + child: InkWell( + onTap: () async { + // await addressListController.deleteAddress( + // addressListController.model.addressList[index] + // ['id']); + // addressListController.model.addressList.removeAt(index); + + // addressListController.updateAll(); + }, + child: Container( + margin: EdgeInsets.only(left: 30), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.red, + ), + alignment: Alignment.center, + child: Icon( + Icons.delete, + color: Colors.white, + ), + ), + ), + ) + ], + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(15, 13, 15, 10), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.123, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.08, + constraints: BoxConstraints( + minHeight: 112, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: MediaQuery.sizeOf(context).width * 0.7, + height: + MediaQuery.sizeOf(context).height * 0.08, + constraints: BoxConstraints( + minHeight: 112, + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + child: Align( + alignment: AlignmentDirectional(-1, 0), + child: Text( + [ + addressListController.model + .addressList[index]['province'], + addressListController.model + .addressList[index]['city'], + addressListController.model + .addressList[index]['county'], + addressListController.model + .addressList[index]['street'] + ] + .where((element) => + element != null && + element.isNotEmpty) + .join(' '), + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF333333), + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + ), + ), + ), + Flexible( + child: Align( + alignment: AlignmentDirectional(-1, 0), + child: Text( + addressListController + .model + .addressList[index] + ['detail'] + ?.isEmpty ?? + true + ? '无详细地址' + : addressListController.model + .addressList[index]['detail'], + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF333333), + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + ), + ), + ), + Flexible( + child: Align( + alignment: AlignmentDirectional(-1, 0), + child: Text( + '${addressListController.model.addressList[index]['name']} ' + + '${addressListController.model.addressList[index]['phone']} ', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF333333), + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + ), + ), + ), + ].divide(SizedBox(height: 5)), + ), + ), + Align( + alignment: AlignmentDirectional(1, -1), + child: Theme( + data: ThemeData( + checkboxTheme: CheckboxThemeData( + visualDensity: VisualDensity.compact, + materialTapTargetSize: + MaterialTapTargetSize.shrinkWrap, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(64), + ), + ), + unselectedWidgetColor: Color(0xFFD3D3D3), + ), + child: Obx(() { + return Checkbox( + value: addressListController + .model.addressList[index] + ['isChecked'] ?? + false, + onChanged: (newValue) async { + // if (newValue == true) { + // for (var i = 0; + // i < + // addressListController + // .model.addressList.length; + // i++) { + // addressListController + // .model.addressList[i] + // ['isChecked'] = false; + // } + // addressListController + // .model.addressList[index] + // ['isChecked'] = newValue; + // addressListController.updateDefault( + // addressListController + // .model.addressList[index]); + // } + // addressListController.updateAll(); + }, + side: BorderSide( + width: 1.5, + color: FlutterFlowTheme.of(context) + .secondaryText, + ), + activeColor: const Color(0xFFd3b684), + checkColor: + FlutterFlowTheme.of(context).info, + ); + }), + ), + ) + ], + ), + ), + ), + Align( + alignment: AlignmentDirectional(1, 0), + child: InkWell( + onTap: () { + addressListController.model.address = + addressListController.model.addressList[index]; + addressListController.model.type = 2; + Get.toNamed("/editAddressPage"); + }, + child: Container( + width: 100, + height: MediaQuery.sizeOf(context).height * 0.03, + child: Align( + alignment: AlignmentDirectional(1, 0), + child: Text( + '编辑', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: AppFontsize.small_text_size, + letterSpacing: 0, + ), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/device_control/app_map_location.dart b/lib/pages/device_control/app_map_location.dart new file mode 100644 index 0000000..93a38ac --- /dev/null +++ b/lib/pages/device_control/app_map_location.dart @@ -0,0 +1,46 @@ +// import 'package:map_launcher/map_launcher.dart'; + +// class AppMapLocation { +// static List availableMaps = []; +// static List availableMapsToNames = []; + +// static Future checkInstalledApps() async { +// availableMaps = await MapLauncher.installedMaps; +// availableMapsToNames = availableMaps.map((AvailableMap m) { +// String v = ""; +// switch (m.mapType) { +// case MapType.baidu: +// v = '百度地图'; +// break; +// case MapType.tencent: +// v = '腾讯地图'; +// break; +// case MapType.amap: +// v = '高德地图'; +// break; +// case MapType.apple: +// v = 'Apple地图'; +// break; +// case MapType.google: +// v = 'Google地图'; +// break; +// case MapType.googleGo: +// v = 'Google地图Go'; +// break; +// case MapType.petal: +// v = 'Petal地图'; +// break; +// default: +// v = m.mapName; +// } +// return v; +// }).toList(); +// } + +// static void launchMap(index, title, double latitude, double longitude) async { +// await availableMaps[index].showMarker( +// coords: Coords(latitude, longitude), +// title: title, +// ); +// } +// } diff --git a/lib/pages/device_control/apply_repair_page.dart b/lib/pages/device_control/apply_repair_page.dart new file mode 100644 index 0000000..b110517 --- /dev/null +++ b/lib/pages/device_control/apply_repair_page.dart @@ -0,0 +1,1936 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/color/appFontsize.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/img/img_default_widget.dart'; +import 'package:vbvs_app/component/img/img_preview_widget.dart'; +import 'package:vbvs_app/component/tool/CustomCard.dart'; +import 'package:vbvs_app/controller/mh/apply_repair_controller.dart'; + +class ApplyRepairPage extends GetView { + final scaffoldKey = GlobalKey(); + BoxConstraints? bodysize; + + // ApplyRepairPage() { + // controller.attr.value.listenlists.clear(); + // controller.getDeviceList(); + // controller.model.device_type = ""; + // controller.model.select_device = ""; + // controller.model.device_category = ""; + // controller.model.device_name = ""; + // controller.model.device_id = ""; + // } + + @override + Widget build(BuildContext context) { + var tmpcontroller = + FormFieldController(controller.model.select_device); + var typecontroller = + FormFieldController(controller.model.device_type); + controller.model.address; + List deviceTypeNames = ['床', '床垫']; + List deviceTypeIds = ['床', '床垫']; + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '申请报修', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + body: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + // TitleComponentWidget( + // titleName: '申请保修', + // ), + Flexible( + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 0, 30.rpx, 30.rpx), + child: Container( + width: bodysize!.maxWidth, + height: 1000, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 27.rpx, 0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * + 0.247, + constraints: BoxConstraints( + minHeight: 500.rpx, + maxHeight: 500.rpx, + ), + decoration: BoxDecoration( + color: Color(0XFF003058), + borderRadius: + BorderRadius.circular(16.rpx), + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 25.rpx, 27.rpx, 34.rpx, 0), + child: Container( + width: 100, + height: 100, + child: Container( + width: 100, + height: 100, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: + const AlignmentDirectional( + 0, 0), + child: Container( + width: + MediaQuery.sizeOf(context) + .width, + height: 44, + child: Align( + alignment: + const AlignmentDirectional( + 0, -1), + child: Text( + '选择需要报修的设备', + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: 0, + fontSize: + AppFontsize + .title_size, + fontWeight: + FontWeight + .bold, + color: Colors + .white // 加粗文字 + ), + ), + ), + ), + ), + Expanded( + child: Column( + mainAxisSize: + MainAxisSize.max, + children: [ + Flexible( + child: Container( + width: + MediaQuery.sizeOf( + context) + .width, + height: 10, + constraints: + BoxConstraints( + minHeight: 60.rpx, + ), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Container( + width: 105.rpx, + height: MediaQuery + .sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minWidth: 60, + ), + child: Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '已绑设备', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + color: Colors + .white), + ), + ), + ), + Expanded( + child: + Container( + width: + 300, // 可以根据需要调整宽度 + height: + 56, // 可以根据需要调整高度 + decoration: + BoxDecoration( + borderRadius: + BorderRadius.circular(8), + color: + Colors.white, + ), + child: Obx( + () { + List> deviceOptions = controller + .model + .device_list! + .map((device) => { + 'id': device['id'].toString(), // 提取设备 ID + 'name': device['name'].toString(), // 提取设备名称 + }) + .toList(); + + // 提取 optionsLabel 和 optionsValue + List deviceNames = deviceOptions + .map((device) => device['name']!) // 用于显示的名称列表 + .toList(); + + List deviceIds = deviceOptions + .map((device) => device['id']!) // 用于匹配的 ID 列表 + .toList(); + + return FlutterFlowDropDown< + String>( + controller: + tmpcontroller, + options: + deviceIds, // 下拉菜单选项为设备的 ID + optionLabels: + deviceNames, // 下拉菜单显示的内容为设备名称 + onChanged: + (val) { + var selectedDevice = controller.model.device_list!.firstWhere((device) => device['id'].toString() == val); + controller.model.select_device = val; + controller.model.device_type = selectedDevice['type'] == 1 ? '床' : '床垫'; + controller.model.device_category = selectedDevice['deviceSeries']['name'] ?? '未知型号'; // 获取设备型号 + controller.model.device_id = selectedDevice['mac'] ?? '未知设备ID'; // 获取设备ID + controller.model.device_name = selectedDevice['name'] ?? '未知设备'; // 获取设备名称 + controller.updateAll(); + }, + width: + 300, + height: + 56, + searchHintTextStyle: FlutterFlowTheme.of(context).labelMedium.override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + searchTextStyle: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + textStyle: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + hintText: + '请选择绑定设备', + searchHintText: + '查找', + icon: + Icon( + Icons.keyboard_arrow_down_rounded, + color: FlutterFlowTheme.of(context).secondaryText, + size: 24, + ), + // fillColor: + // FlutterFlowTheme.of(context).secondaryBackground, + elevation: + 2, + borderColor: + FlutterFlowTheme.of(context).alternate, + borderWidth: + 0, + borderRadius: + 8, + margin: const EdgeInsetsDirectional.fromSTEB( + 10, + 4, + 10, + 4), + hidesUnderline: + true, + isOverButton: + false, + isSearchable: + false, + isMultiSelect: + false, + ); + }))), + ].divide(SizedBox( + width: 26.rpx)), + ), + ), + ), + Flexible( + child: Container( + width: + MediaQuery.sizeOf( + context) + .width, + height: 10, + constraints: + BoxConstraints( + minHeight: 60.rpx, + ), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Container( + width: 105.rpx, + height: MediaQuery + .sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minWidth: 60, + ), + child: Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '设备系列', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + color: Colors + .white), + ), + ), + ), + Expanded( + child: Container( + width: 100, + height: 100, + decoration: + BoxDecoration( + color: Colors + .white, + borderRadius: + BorderRadius + .circular(8), + ), + child: + Obx(() { + return TextFormField( + // autofocus: true, + controller: + controller + .onReDraw( + TextEditingController( + text: + controller.model.device_category ?? ""), + (value) => + { + value.text = + controller.model.device_category ?? "" + }, + ), + onChanged: + (value) { + controller + .model + .device_category = value; + }, + // initialValue: + // controller + // .model + // .device_category, + obscureText: + false, + decoration: + InputDecoration( + labelStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + hintStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + contentPadding: const EdgeInsetsDirectional + .fromSTEB( + 10, + 0, + 10, + 18), + ), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + ); + })), + ), + ].divide(SizedBox( + width: 26.rpx)), + ), + ), + ), + Flexible( + child: Container( + width: + MediaQuery.sizeOf( + context) + .width, + height: 10, + constraints: + BoxConstraints( + minHeight: 60.rpx, + ), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Container( + width: 105.rpx, + height: MediaQuery + .sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minWidth: 60, + ), + child: Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '产品型号', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + color: Colors + .white), + ), + ), + ), + Expanded( + child: Container( + width: 100, + height: 100, + decoration: + BoxDecoration( + color: Colors + .white, + borderRadius: + BorderRadius + .circular(8), + ), + child: + Obx(() { + return TextFormField( + // autofocus: true, + controller: + controller + .onReDraw( + TextEditingController( + text: + controller.model.device_category ?? ""), + (value) => + { + value.text = + controller.model.device_category ?? "" + }, + ), + onChanged: + (value) { + controller + .model + .device_category = value; + }, + // initialValue: + // controller + // .model + // .device_category, + obscureText: + false, + decoration: + InputDecoration( + labelStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + hintStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + contentPadding: const EdgeInsetsDirectional + .fromSTEB( + 10, + 0, + 10, + 18), + ), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + ); + })), + ), + ].divide(SizedBox( + width: 26.rpx)), + ), + ), + ), + Flexible( + child: Container( + width: + MediaQuery.sizeOf( + context) + .width, + height: 10, + constraints: + BoxConstraints( + minHeight: 60.rpx, + ), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Container( + width: 105.rpx, + height: MediaQuery + .sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minWidth: 60, + ), + child: Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '序列号', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + color: Colors + .white), + ), + ), + ), + Expanded( + child: Container( + width: 100, + height: 100, + decoration: + BoxDecoration( + color: const Color( + 0xFFF3F5F6), + borderRadius: + BorderRadius + .circular(8), + ), + child: + Obx(() { + return TextFormField( + // autofocus: true, + controller: + controller + .onReDraw( + TextEditingController( + text: + controller.model.device_id ?? ""), + (value) => + { + value.text = + controller.model.device_id ?? "" + }, + ), + onChanged: + (value) { + controller + .model + .device_id = value; + }, + // initialValue: + // controller + // .model + // .device_id, + obscureText: + false, + decoration: + InputDecoration( + labelStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + hintStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + contentPadding: const EdgeInsetsDirectional + .fromSTEB( + 10, + 0, + 10, + 18), + ), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + ); + })), + ), + ].divide(SizedBox( + width: 26.rpx)), + ), + ), + ), + ].divide( + SizedBox(height: 30.rpx)), + ), + ) + ], + ), + ), + ), + ), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 26.rpx, 0, 0), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.17, + constraints: BoxConstraints( + minHeight: 345.rpx, + ), + decoration: BoxDecoration( + color: Color(0XFF003058), + borderRadius: + BorderRadius.circular(16.rpx), + ), + child: Obx(() { + return Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.17, + decoration: BoxDecoration( + color: Color(0XFF003058), + borderRadius: + BorderRadius.circular(16.rpx), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + if (controller.model.issue_img == + null || + controller + .model.issue_img!.isEmpty) + Flexible( + child: InkWell( + onTap: () { + // controller.uploadImg(); + }, + child: Container( + width: + MediaQuery.sizeOf(context) + .width, + height: + MediaQuery.sizeOf(context) + .height * + 0.186, + child: Column( + mainAxisSize: + MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment + .center, + crossAxisAlignment: + CrossAxisAlignment + .center, + children: [ + Flexible( + child: Align( + alignment: + const AlignmentDirectional( + 0, 0), + // child: Icon( + // Icons + // .linked_camera_outlined, + // color: + // Color(0xFF9EA4B7), + // size: 40, + // ), + child: Container( + width: 50, + height: 50, + decoration: + BoxDecoration( + image: + DecorationImage( + fit: BoxFit + .cover, + image: + Image.asset( + 'assets/images/camera.png', + ).image, + ), + ), + ), + ), + ), + Flexible( + child: Container( + width: 138, + height: 31, + decoration: + BoxDecoration( + borderRadius: + BorderRadius + .circular( + 50), + border: Border.all( + color: const Color( + 0xFF9EA4B7), + ), + ), + child: Align( + alignment: + const AlignmentDirectional( + 0, 0), + child: Text( + '上传设备故障照片', + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: const Color( + 0xFF9EA4B7), + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + ), + ), + ), + ), + ), + ], + ), + ), + )), + if (controller.model.issue_img != + null && + controller.model.issue_img! + .isNotEmpty) + Flexible( + child: Container( + width: + MediaQuery.sizeOf(context) + .width, + height: + MediaQuery.sizeOf(context) + .height * + 0.186, + constraints: + const BoxConstraints( + minHeight: 250, + ), + decoration: BoxDecoration( + color: FlutterFlowTheme.of( + context) + .secondaryBackground, + ), + child: Column( + mainAxisSize: + MainAxisSize.max, + children: [ + Align( + alignment: + const AlignmentDirectional( + 1, 0), + child: Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB( + 0, 7, 21, 7), + child: Container( + width: MediaQuery + .sizeOf( + context) + .width * + 0.2, + height: 21, + decoration: + BoxDecoration( + color: FlutterFlowTheme + .of(context) + .secondaryBackground, + ), + child: Container( + width: MediaQuery + .sizeOf( + context) + .width * + 0.2, + height: 21, + decoration: + BoxDecoration( + color: FlutterFlowTheme.of( + context) + .secondaryBackground, + ), + child: Row( + mainAxisSize: + MainAxisSize + .max, + mainAxisAlignment: + MainAxisAlignment + .end, + children: [ + Text( + // '2', + controller + .model + .issue_img! + .length + .toString(), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize.normal_text_size, + letterSpacing: + 0, + ), + ), + Text( + '/', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize.normal_text_size, + letterSpacing: + 0, + ), + ), + Text( + '3', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize.normal_text_size, + letterSpacing: + 0, + ), + ), + ], + ), + ), + ), + ), + ), + Flexible( + child: Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB( + 0, 0, 21, 0), + child: Container( + width: MediaQuery + .sizeOf( + context) + .width, + height: MediaQuery + .sizeOf( + context) + .height * + 0.15, + constraints: + const BoxConstraints( + minHeight: 152, + ), + decoration: + BoxDecoration( + color: FlutterFlowTheme + .of(context) + .secondaryBackground, + ), + child: Container( + width: 100, + height: 100, + decoration: + BoxDecoration( + color: FlutterFlowTheme.of( + context) + .secondaryBackground, + ), + child: Obx(() => ListView( + shrinkWrap: true, + scrollDirection: Axis.horizontal, + children: getImage() + .divide(const SizedBox( + width: + 12, + )) + .addToStart(const SizedBox( + width: + 21, + ))))), + ), + ), + ), + ], + ), + ), + ), + ], + ), + ); + }), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 25.rpx, 0, 0), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.17, + constraints: BoxConstraints( + minHeight: 345.rpx, + ), + decoration: BoxDecoration( + color: Color(0xFF003058), + borderRadius: + BorderRadius.circular(16.rpx), + ), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.19, + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(16.rpx), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: + const AlignmentDirectional( + 0, 0), + child: Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB(0, 15, 0, 16), + child: Text( + '请描述一下您的问题', + style: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + letterSpacing: 0, + fontWeight: + FontWeight.w600, + ), + ), + ), + ), + Expanded( + child: Padding( + padding: EdgeInsetsDirectional + .fromSTEB(34.rpx, 0, 34.rpx, + 34.rpx), + child: Container( + width: + MediaQuery.sizeOf(context) + .width, + height: + MediaQuery.sizeOf(context) + .height * + 1, + constraints: BoxConstraints( + minHeight: 181.rpx, + ), + decoration: BoxDecoration( + color: + const Color(0xFFF3F5F6), + borderRadius: + BorderRadius.circular(8), + ), + child: TextFormField( + // autofocus: true, + onChanged: (value) { + controller.model.desc = + value; + }, + initialValue: + controller.model.desc, + obscureText: false, + + decoration: InputDecoration( + hintText: '问题描述(100个字以内)', + labelStyle: FlutterFlowTheme + .of(context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + color: Color( + 0XFF929699)), + hintStyle: FlutterFlowTheme + .of(context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + color: Color( + 0XFF929699)), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + // contentPadding: + // EdgeInsetsDirectional + // .fromSTEB(0, 0, 0, 12), + contentPadding: + const EdgeInsetsDirectional + .fromSTEB( + 10, 5, 10, 5), + ), + maxLines: 4, + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 26.rpx, 0, 0), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.17, + constraints: const BoxConstraints( + minHeight: 222, + ), + decoration: BoxDecoration( + color: Color(0XFF003058), + borderRadius: BorderRadius.circular(16), + ), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: + const AlignmentDirectional( + 0, 0), + child: Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB(0, 15, 0, 15), + child: Text( + '联系方式', + style: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + letterSpacing: 0, + fontWeight: + FontWeight.w600, + ), + ), + ), + ), + Expanded( + child: Padding( + padding: EdgeInsetsDirectional + .fromSTEB( + 25.rpx, 0, 34.rpx, 0), + child: Container( + width: + MediaQuery.sizeOf(context) + .width, + height: + MediaQuery.sizeOf(context) + .height * + 1, + child: Column( + mainAxisSize: + MainAxisSize.max, + children: [ + Flexible( + child: Container( + width: + MediaQuery.sizeOf( + context) + .width, + height: + MediaQuery.sizeOf( + context) + .height * + 0.038, + constraints: + BoxConstraints( + minHeight: 61.rpx, + ), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Container( + width: 105.rpx, + height: MediaQuery + .sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minWidth: 60, + ), + // decoration: + // BoxDecoration( + // color: FlutterFlowTheme.of( + // context) + // .secondaryBackground, + // ), + child: Row( + mainAxisSize: + MainAxisSize + .max, + children: [ + Text( + '联系人', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .small_text_size, + letterSpacing: + 0, + color: Colors + .white), + ), + ], + ), + ), + Expanded( + child: Container( + width: MediaQuery + .sizeOf( + context) + .width, + height: 100, + decoration: + BoxDecoration( + color: Colors + .white, + borderRadius: + BorderRadius + .circular( + 8), + ), + child: + TextFormField( + // autofocus: true, + onChanged: + (value) { + controller + .model + .apply_name = + value; + }, + initialValue: + controller + .model + .apply_name, + obscureText: + false, + decoration: + InputDecoration( + contentPadding: + const EdgeInsetsDirectional + .fromSTEB( + 10, + 10, + 10, + 14), + labelStyle: FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + hintStyle: FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + ), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + ), + ), + ), + ].divide( + const SizedBox( + width: 13)), + ), + ), + ), + Flexible( + child: Container( + width: + MediaQuery.sizeOf( + context) + .width, + height: + MediaQuery.sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minHeight: 31, + ), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Container( + width: 105.rpx, + height: MediaQuery + .sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minWidth: 60, + ), + child: Row( + mainAxisSize: + MainAxisSize + .max, + children: [ + Text( + '手机号码', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .small_text_size, + letterSpacing: + 0, + color: Colors + .white), + ), + ], + ), + ), + Expanded( + child: Container( + width: 100, + height: 100, + decoration: + BoxDecoration( + color: Colors + .white, + borderRadius: + BorderRadius + .circular( + 8), + ), + child: + TextFormField( + // autofocus: true, + onChanged: + (value) { + controller + .model + .tel = + value; + }, + initialValue: + controller + .model + .tel, + obscureText: + false, + decoration: + InputDecoration( + contentPadding: + const EdgeInsetsDirectional + .fromSTEB( + 10, + 10, + 10, + 14), + labelStyle: FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + hintStyle: FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + ), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + ), + ), + ), + ].divide( + const SizedBox( + width: 13)), + ), + ), + ), + ].divide(const SizedBox( + height: 15)), + ), + ), + ), + ), + ], + ), + ), + ), + ), + ], + ), + ), + ), + ), + ), + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 15, 15, 15, AppConstants.page_button_bottom_padding), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.056, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context) + .secondaryBackground, + borderRadius: BorderRadius.circular(16.rpx), + ), + child: CustomCard( + borderRadius: 10, + gradientDirection: GradientDirection.vertical, + onTap: () { + // print('Button pressed ...'); + // controller.submitRepair(context).then((msg) { + // if (msg.isEmpty) { + // MessageListController messageListController = + // Get.find(); + // messageListController.addMessage(); + // Get.to(() => ApplyRepairSuccessPage(), + // arguments: {'model': controller.model}); + // controller.model = + // ApplyRepairModel(); // 在 submitRepair 完成后执行 + // controller.updateAll(); + // } + // }).catchError((error) { + // // 错误处理 + // print('Error: $error'); + // }); + }, + colors: const [ + Color(0xFFFCFCFC), + Color(0xFFF8FAF9), + Color(0XFFECF6F3), + Color(0XFFD9F0E9), + Color(0xFFCEECE3) + ], + child: Container( + width: double.infinity, + height: 90.rpx, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + ), + child: Text( + "提交申请", + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: stringToColor("#011D33"), + letterSpacing: 0, + fontSize: 30.rpx, + ), + ), + ), + ) + + // Container( + // width: bodysize!.maxWidth, + // height: bodysize!.maxHeight * 0.056, + // decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context) + // .secondaryBackground, + // borderRadius: BorderRadius.circular(16.rpx), + // ), + // child: FFButtonWidget( + // onPressed: () { + // print('Button pressed ...'); + // controller.submitRepair(context).then((msg) { + // if (msg.isEmpty) { + // MessageListController messageListController = + // Get.find(); + // messageListController.addMessage(); + // Get.to(() => ApplyRepairSuccessPage(), + // arguments: {'model': controller.model}); + // controller.model = + // ApplyRepairModel(); // 在 submitRepair 完成后执行 + // controller.updateAll(); + // } + // }).catchError((error) { + // // 错误处理 + // print('Error: $error'); + // }); + // }, + // text: '提交申请', + // options: FFButtonOptions( + // height: 40, + // padding: const EdgeInsetsDirectional.fromSTEB( + // 24, 0, 24, 0), + // iconPadding: const EdgeInsetsDirectional.fromSTEB( + // 0, 0, 0, 0), + // color: const Color(0xFFD3B684), + // textStyle: FlutterFlowTheme.of(context) + // .titleSmall + // .override( + // fontFamily: 'Readex Pro', + // color: Colors.white, + // fontSize: AppFontsize.normal_text_size, + // letterSpacing: 0, + // ), + // elevation: 0, + // borderSide: const BorderSide( + // color: Colors.transparent, + // width: 1, + // ), + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // ), + ), + ), + ], + ), + ), + ), + )); + }); + } + + List getImage() { + List images = []; + controller.model.issue_img!.forEach((element) async { + images.add(ImgPreviewWidget( + imgUrl: element, + index: controller.model.issue_img!.indexOf(element), + applyRepairController: controller, + isDel: true, + )); + }); + if (images.length < controller.model.imagesLImit!) { + images.add(ImgPreviewDefaultWidget( + applyRepairController: controller, + )); + } + return images; + } + + List> _getDropdownItems() { + List options = [ + '智能床垫AH-2型', + '智能床垫BY-H型', + '智能床垫BY-C型', + // 可以在这里添加更多选项 + ]; + + return options.map((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(); + } +} diff --git a/lib/pages/device_control/bluetooth.dart b/lib/pages/device_control/bluetooth.dart new file mode 100644 index 0000000..7ccc51c --- /dev/null +++ b/lib/pages/device_control/bluetooth.dart @@ -0,0 +1,188 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; + +class BluetoothPage extends StatefulWidget { + BluetoothPage({super.key}); + + @override + State createState() => _BluetoothState(); +} + +BoxConstraints? bodysize; + +class _BluetoothState extends State { + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '设置', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Padding( + padding: EdgeInsets.fromLTRB(0.rpx, 115.rpx, 0.rpx, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('TomFayer', + style: TextStyle( + color: Colors.white, + fontSize: 40.rpx, + )), + SizedBox(width: 27.rpx), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: const Color(0xFF055466), + padding: EdgeInsets.only(left: 0), + onTap: () { + Get.toNamed("/editBedPage"); + }, + child: Container( + width: 42.rpx, + height: 42.rpx, + child: SvgPicture.asset( + "assets/img/icon/bluetooth_edit.svg", + color: Colors.white, + ))) + ], + ), + + const SizedBox(height: 4), + Text('MAC:4645146546', + style: TextStyle( + color: Colors.white70, fontSize: 26.rpx)), + + const SizedBox(height: 16), + + // 蓝牙连接状态 + Column( + children: [ + Image.asset( + 'assets/images/active_bluetooth.png', + width: 42.rpx, + height: 42.rpx, + ), + SizedBox(height: 4), + Text('已连接', + style: TextStyle( + color: Colors.green, + fontSize: 26.rpx)), + ], + ), + ], + ), + + const SizedBox(height: 24), + + // 按钮列表 + Expanded( + child: ListView( + padding: EdgeInsets.symmetric(horizontal: 30.rpx), + children: [ + _buildMenuButton( + context, '详情', "/devicePeopleInfo"), + _buildMenuButton( + context, '人员资料', "/devicePeopleInfo"), + _buildMenuButton( + context, '房间选择', "/roomPickerPage"), + _buildMenuButton( + context, '设备校准', "/devicePeopleInfo"), + _buildMenuButton( + context, '体征传感器', "/devicePeopleInfo"), + _buildMenuButton( + context, 'WIFI配置', "/devicePeopleInfo"), + _buildMenuButton( + context, '睡眠习惯', "/sleepHabitPage"), + _buildMenuButton( + context, '分享设备', "/devicePeopleInfo"), + _buildMenuButton( + context, '解绑', "/devicePeopleInfo"), + ], + ), + ), + ], + ), + )), + ))); + }); + } + + Widget _buildMenuButton(BuildContext context, String title, String? path) { + return Padding( + padding: EdgeInsets.only(bottom: 19.rpx), // 将 margin 外移 + child: ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Color(0XFF055466), + padding: EdgeInsets.only(left: 0), + onTap: () { + if (path?.isNotEmpty == true) { + Get.toNamed(path!); + } + }, + child: Container( + height: MediaQuery.sizeOf(context).height * 0.0566, + decoration: BoxDecoration( + color: const Color(0xFF003058), + borderRadius: BorderRadius.circular(16.rpx), + ), + child: Center( + child: Text( + title, + style: const TextStyle(color: Colors.white, fontSize: 16), + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/device_control/book_date_widget.dart b/lib/pages/device_control/book_date_widget.dart new file mode 100644 index 0000000..f8335c3 --- /dev/null +++ b/lib/pages/device_control/book_date_widget.dart @@ -0,0 +1,87 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/controller/mh/book_info_controller.dart'; + +class BookDateWidget extends GetView { + // final String week; + // final String date; + + // const BookDateWidget({ + // super.key, + // String? week, + // String? date, + // }) : this.week = week ?? '周一', + // this.date = date ?? '07/10'; + + int index; + BookInfoController bookInfoController; + + BookDateWidget({required this.index, required this.bookInfoController}) {} + + @override + Widget build(BuildContext context) { + return InkWell(onTap: () { + // if(index == controller.model.datetimes_index) { + // return; + // } + // controller.model.datetimes_index = index; + // controller.time_periodChange(); + // controller.updateAll(); + }, child: Obx(() { + return Container( + width: 71.5, + height: 71.5, + constraints: BoxConstraints( + minHeight: 70, + ), + decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context).secondaryBackground, + color: controller.model.datetimes_index == index + ? stringToColor('#D3B684') + : FlutterFlowTheme.of(context).secondaryBackground, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Flexible( + child: Text( + "${bookInfoController.model.datetimes![index]?['dayName']}", + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + color: controller.model.datetimes_index == index + ? stringToColor('#FFFFFF') + : stringToColor('#333333'), + ), + ), + ), + Flexible( + child: Text( + "${bookInfoController.model.datetimes![index]?['day']}", + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + color: controller.model.datetimes_index == index + ? stringToColor('#FFFFFF') + : stringToColor('#333333'), + ), + ), + ), + Flexible( + child: Icon( + Icons.keyboard_arrow_down_rounded, + color: controller.model.datetimes_index == index + ? stringToColor('#FFFFFF') + : stringToColor('#333333'), + size: 12, + ), + ), + ], + ), + ); + })); + } +} diff --git a/lib/pages/device_control/book_info_page.dart b/lib/pages/device_control/book_info_page.dart new file mode 100644 index 0000000..46c23e0 --- /dev/null +++ b/lib/pages/device_control/book_info_page.dart @@ -0,0 +1,796 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appColors.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/color/appFontsize.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/CustomCard.dart'; +import 'package:vbvs_app/controller/mh/book_info_controller.dart'; +import 'package:vbvs_app/pages/common/selectDialog.dart'; +import 'package:vbvs_app/pages/device_control/book_date_widget.dart'; + +class BookInfoPage extends GetView { + final scaffoldKey = GlobalKey(); + Map data; + + BookInfoPage({required this.data}) { + // controller.getData(data["id"]); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + // key: scaffoldKey, + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: const IconThemeData(color: Colors.white), + titleSpacing: 0, + title: Container( + width: double.infinity, + height: 70.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '我要预约', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + actions: [], + centerTitle: false, + ), + body: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + // TitleComponentWidget( + // titleName: '我要预约', + // ), + Expanded( + child: Padding( + padding: + const EdgeInsetsDirectional.fromSTEB(28, 27, 28, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 0, 0, 0, 10), + child: Container( + width: MediaQuery.sizeOf(context).width, + constraints: const BoxConstraints( + minHeight: 50, + ), + child: Container( + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + '${data["name"]}', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: + AppFontsize.title_size, + letterSpacing: 0, + fontWeight: FontWeight.w600, + color: Colors.white), + ), + Text( + '地址:${data["addressDetail"]}', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + color: Colors.white), + ), + ], + ), + ), + ), + ), + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 0, 0, 0, 20), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: + MediaQuery.sizeOf(context).height * 0.01, + constraints: const BoxConstraints( + maxHeight: 1, + ), + decoration: const BoxDecoration( + color: Color(0xFF929699), + ), + ), + ), + Align( + alignment: const AlignmentDirectional(-1, 0), + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 0, 0, 0, 16), + child: Text( + '体验日期', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: AppFontsize.title_size, + letterSpacing: 0, + fontWeight: FontWeight.w600, + color: Color(0xFF929699)), + ), + ), + ), + Obx(() { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: getBuildItems(context), + ); + }), + + // Obx(() => ListView( + // shrinkWrap: true, + // scrollDirection: Axis.horizontal, + // children: getBuildItems(context))), + // Padding( + // padding: + // EdgeInsetsDirectional.fromSTEB(0, 59, 0, 0), + // child: Row( + // mainAxisSize: MainAxisSize.max, + // mainAxisAlignment: + // MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // '体验时段', + // style: FlutterFlowTheme.of(context) + // .bodyMedium + // .override( + // fontFamily: 'Readex Pro', + // fontSize: AppFontsize.title_size, + // letterSpacing: 0, + // ), + // ), + // Row( + // mainAxisSize: MainAxisSize.max, + // children: [ + // Padding( + // padding: EdgeInsetsDirectional.fromSTEB( + // 0, 0, 17, 0), + // child: Text( + // '09:30', + // style: FlutterFlowTheme.of(context) + // .bodyMedium + // .override( + // fontFamily: 'Readex Pro', + // fontSize: + // AppFontsize.title_size, + // letterSpacing: 0, + // ), + // ), + // ), + // Icon( + // Icons.keyboard_arrow_down_sharp, + // color: FlutterFlowTheme.of(context) + // .secondaryText, + // size: 12, + // ), + // ], + // ), + // ], + // ), + // ), + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 0, 59, 0, 0), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '体验时段', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: AppFontsize.title_size, + letterSpacing: 0, + color: Color(0xFF929699), + // 设置加粗 + ), + ), + Flexible(child: Obx(() { + return InkWell( + onTap: () { + showOneSelectionDialog(context, + arr: controller.model.time_period + .map((d) => + "${d['timeStr']} (${d['unBookAmount']}/${d['amount']})") + .toList()!, + checkIndex: controller.model + .select_time_index ?? + 0, checkChange: (index) { + controller.model.select_time_index = + index; + + controller.updateAll(); + }, title: '请选择时间'); + }, + child: Container( + width: 140, + height: 30, + child: Row( + mainAxisAlignment: + MainAxisAlignment.end, + crossAxisAlignment: + CrossAxisAlignment + .center, // 确保图标和文本垂直居中 + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB(0, 3, 17, 0), + child: Text( + controller.model + .select_time_index != + null + ? "${controller.model.time_period?[controller.model.select_time_index!]?["timeStr"]}" + : '请选择时间', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + color: (controller + .model + .select_time_index == + null) + ? stringToColor( + '#D0D0D0') + : stringToColor( + '#333333')), + ), + ), + Icon( + Icons.keyboard_arrow_down_sharp, + color: + FlutterFlowTheme.of(context) + .secondaryText, + size: 16, + ), + ], + ), + ), + ); + })), + ], + ), + ), + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 0, 25, 0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: + MediaQuery.sizeOf(context).height * 0.03, + constraints: BoxConstraints( + minHeight: 76.rpx, + ), + decoration: const BoxDecoration(), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * + 0.02, + decoration: const BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '体验人员', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: + AppFontsize.title_size, + letterSpacing: 0, + color: Color(0xFF929699), + // 设置加粗 + ), + ), + Flexible( + child: Align( + alignment: + const AlignmentDirectional( + 1, 0), + child: Container( + width: MediaQuery.sizeOf(context) + .width * + 0.3, + height: MediaQuery.sizeOf(context) + .height * + 1, + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(0), + ), + child: Align( + alignment: + const AlignmentDirectional( + 1, 0), + child: TextFormField( + // autofocus: true, + controller: + TextEditingController( + text: controller.model + .userName ?? + ""), + onChanged: (d) { + controller.model.userName = + d; + }, + obscureText: false, + decoration: InputDecoration( + labelStyle: + FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + hintText: '输入姓名', + hintStyle: FlutterFlowTheme + .of(context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + color: Color( + 0xFF929699)), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + contentPadding: + const EdgeInsetsDirectional + .fromSTEB( + 0, 0, 0, 12), + ), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + textAlign: TextAlign.end, + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 0, 25, 0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: + MediaQuery.sizeOf(context).height * 0.03, + constraints: BoxConstraints( + minHeight: 76.rpx, + ), + decoration: const BoxDecoration(), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * + 0.02, + decoration: const BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '手机号', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: + AppFontsize.title_size, + letterSpacing: 0, + color: Color(0xFF929699), + // 设置加粗 + ), + ), + Flexible( + child: Align( + alignment: + const AlignmentDirectional( + 1, 0), + child: Container( + width: MediaQuery.sizeOf(context) + .width * + 0.3, + height: MediaQuery.sizeOf(context) + .height * + 1, + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(0), + ), + child: Align( + alignment: + const AlignmentDirectional( + 1, 0), + child: TextFormField( + // autofocus: true, + controller: + TextEditingController( + text: controller.model + .userPhone ?? + ""), + onChanged: (d) { + controller.model.userPhone = + d; + }, + obscureText: false, + keyboardType: + TextInputType.phone, + decoration: InputDecoration( + labelStyle: + FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + hintText: '输入手机号', + hintStyle: FlutterFlowTheme + .of(context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + color: Color( + 0xFF929699)), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular( + 8), + ), + contentPadding: + const EdgeInsetsDirectional + .fromSTEB( + 0, 0, 0, 12), + ), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: AppFontsize + .normal_text_size, + letterSpacing: 0, + ), + textAlign: TextAlign.end, + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + ], + ), + )), + ), + ), + + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 15, 0, 15, AppConstants.page_button_bottom_padding), + child: CustomCard( + borderRadius: 10, + gradientDirection: GradientDirection.vertical, + onTap: () { + // if (controller.model.select_time_index == null) { + // showToast("请选择体验时间"); + // return; + // } + // if (controller.model.userName == null || + // controller.model.userName == "") { + // showToast("请输入姓名"); + // return; + // } + // if (controller.model.userPhone == null || + // controller.model.userPhone == "") { + // showToast("请输入手机号"); + // return; + // } + // if (MyUtils.isValidPhoneNumber( + // controller.model.userPhone!) == + // false) { + // showToast("请输入正确的手机号"); + // return; + // } + // controller.submitData(data["id"]).then((d) { + // if (d.data["status"] == 2) { + // d.data["addressDetail"] = data['addressDetail']; + // d.data["name"] = data["name"]; + // controller.messageAdd(d.data); + // Get.offAndToNamed("/bookSuccessPage", + // arguments: {"data": d.data}); + // } else { + // showToast("预约失败"); + // } + // }).catchError((d) { + // showToast("预约失败"); + // }); + Get.toNamed("/bookSuccessPage", arguments: { + "data": { + "id": "7fbfbd614ef5befa3d8a84730f666853", + "code": "10000114", + "orderSn": "2025051411302980610000114", + "userId": "09db8134288e8fb716c7acfdcca9f763", + "extUserId": null, + "deptId": 35, + "storeId": "962df2043ba06c99e6490616b37a60d4", + "customerId": "531ba6efe42d5e2cc3c8f219ebed4cee", + "idCard": null, + "realName": "江有龙", + "userPhone": "18956025450", + "province": "", + "city": "", + "district": "", + "addressDetail": "", + "bookType": 2, + "bookDateId": 104167, + "bookRoomNo": null, + "bookTimeStart": 1747281600000, + "bookTimeEnd": 1747303200000, + "payAmount": 0, + "transactionId": null, + "paid": 0, + "payTime": null, + "payType": null, + "status": 2, + "isVerify": false, + "verifyAdminId": null, + "verifyTime": null, + "giftAdminId": null, + "giftTime": null, + "createTime": 1747193430000, + "refundTime": null, + "isDel": false, + "audienceId": null, + "store": { + "id": "962df2043ba06c99e6490616b37a60d4", + "code": "55102", + "name": "合肥眠花糖共享会议华润大厦B座", + "deptId": 35, + "kingdeeId": "" + }, + "dateStr": "2025年05月15日周四", + "timeStr": "12:00~18:00", + "qrCode": "", + "payName": "未付款", + "statusName": "待体验", + "user": { + "id": "09db8134288e8fb716c7acfdcca9f763", + "nickName": "生陌", + "avatar": null, + "mobile": "18956025450" + }, + "verifyAdmin": null, + "giftAdmin": null, + "storeName": "合肥眠花糖共享会议华润大厦B座", + "storeAddress": null + }, + }); + }, + colors: const [ + Color(0xFFFCFCFC), + Color(0xFFF8FAF9), + Color(0XFFECF6F3), + Color(0XFFD9F0E9), + Color(0xFFCEECE3) + ], + child: Container( + width: double.infinity, + height: 90.rpx, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + ), + child: Text( + "提交预约", + style: + FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: stringToColor("#011D33"), + letterSpacing: 0, + fontSize: 30.rpx, + ), + ), + ), + )), + ], + ), + ), + ), + ), + ); + } + + List getBuildItems(BuildContext context) { + List images = []; + controller.model.datetimes!.forEach((element) async { + images.add(BookDateWidget( + index: controller.model.datetimes!.indexOf(element), + bookInfoController: controller, + )); + }); + return images; + } +} diff --git a/lib/pages/device_control/book_success_page.dart b/lib/pages/device_control/book_success_page.dart new file mode 100644 index 0000000..7c207e3 --- /dev/null +++ b/lib/pages/device_control/book_success_page.dart @@ -0,0 +1,210 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appColors.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +class BookSuccessPage extends GetView { + final scaffoldKey = GlobalKey(); + BoxConstraints? bodysize; + Map data; + BookSuccessPage({required this.data}); + final infoList = [ + {"label": "预约编号:", "value": "54648614654646"}, + {"label": "预约人员:", "value": "张大大"}, + {"label": "手机号码:", "value": "139****5699"}, + {"label": "体验时间:", "value": "2024-02-15 07:30"}, + {"label": "预约门店:", "value": "SWES眠花糖杭州南星桥旗舰店"}, + {"label": "门店地址:", "value": "浙江省杭州市上城区飞云江路45号一层"}, + ]; + + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + // key: scaffoldKey, + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: Colors.white), + titleSpacing: 0, + // leading: returnIconButtomAddCallback(() { + // controller.saveDataApi(); + // updateParm(isShowToast: false); + // }), + // leading: returnIconButtomNew, + title: Container( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '我要预约', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + + actions: [], + centerTitle: false, + ), + + body: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + width: bodysize!.maxWidth, + margin: EdgeInsets.only(top: 90.rpx), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + width: 148.rpx, + height: 148.rpx, + clipBehavior: Clip.antiAlias, + decoration: const BoxDecoration( + shape: BoxShape.circle, + ), + child: Image.asset( + 'assets/images/success.png', + fit: BoxFit.contain, + color: Color(0xFF84F5FF), + ), + ), + Align( + alignment: const AlignmentDirectional(0, 0), + child: Text( + '预约成功!', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + fontSize: 30.rpx, + color: Colors.white, + letterSpacing: 0, + fontWeight: FontWeight.w600, + ), + ), + ), + ].divide(SizedBox(height: 30.rpx)), + ), + ), + Container( + margin: EdgeInsets.only( + left: 30.rpx, right: 30.rpx, top: 55.rpx), + width: bodysize!.maxWidth, + decoration: BoxDecoration( + color: Color(0xFF003058), + borderRadius: BorderRadius.circular(16.rpx), + ), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 20), // 上间距 + for (var item in infoList) + Container( + height: 60.rpx, + padding: EdgeInsets.symmetric(horizontal: 35), + alignment: Alignment.centerLeft, + child: Row( + children: [ + Text( + item['label']!, + style: TextStyle( + color: Color(0XFF929699), + fontSize: 26.rpx, + ), + ), + SizedBox(width: 35.rpx), + Text( + item['value']!, + style: TextStyle( + color: Colors.white, + fontSize: 26.rpx, + ), + ), + ], + ), + ), + + SizedBox(height: 60.rpx), // 空间隔断 + Padding( + padding: EdgeInsets.symmetric(horizontal: 35), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 200.rpx, + height: 60.rpx, + child: ElevatedButton( + onPressed: () {}, + child: Text("关闭", + style: TextStyle( + color: Color(0XFF011D33), + fontSize: 26.rpx)), + style: ElevatedButton.styleFrom( + backgroundColor: Color(0xFF84F5FF), + // minimumSize: Size(0, 60), + ), + ), + ), + SizedBox(width: 60.rpx), + SizedBox( + width: 200.rpx, + height: 60.rpx, + child: ElevatedButton( + onPressed: () {}, + child: Text("我的预约", + style: TextStyle( + color: Color(0XFF011D33), + fontSize: 26.rpx)), + style: ElevatedButton.styleFrom( + backgroundColor: Color(0xFF84F5FF), + // minimumSize: Size(0, 60), + ), + ), + ) + ], + ), + ), + + SizedBox(height: 80), // 下间距 + ], + )), + ), + ], + ), + ), + ), + )); + }); + } +} diff --git a/lib/pages/device_control/delete_account.dart b/lib/pages/device_control/delete_account.dart new file mode 100644 index 0000000..84b7e29 --- /dev/null +++ b/lib/pages/device_control/delete_account.dart @@ -0,0 +1,328 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; + +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/color/appFontsize.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +class DeletedAccountPage extends GetView { + BoxConstraints? bodysize; + final scaffoldKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: const IconThemeData(color: Colors.white), + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '注销账号', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + key: scaffoldKey, + backgroundColor: Colors.transparent, + body: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + decoration: const BoxDecoration(), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Container( + width: MediaQuery.sizeOf(context).width, + height: 100, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 15, 33, 15, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + ), + child: Padding( + padding: + const EdgeInsetsDirectional.fromSTEB( + 21, 0, 22, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Container( + width: 50, + height: 50, + child: Image.asset( + 'assets/images/delete_account.png', + fit: BoxFit.cover, + color: Color(0XFF84F5FF), + ), + ), + const Text( + "注销智慧眠花糖账号", + style: TextStyle( + fontSize: 20, // 设置字体大小 + color: Color(0xFFFFFFFF), + // decoration: TextDecoration.underline, // 添加下划线 + ), + ), + Container( + child: Column( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + text: "账号注销后,你将无法使用以下功能,", + style: TextStyle( + fontSize: AppFontsize + .normal_text_size, // 设置字体大小 + color: Color( + 0xFF9AA0B3), // 默认颜色 + ), + children: [ + TextSpan( + text: + "并且当前有绑定以及被分享的智能床、智能床垫等设备的账号不能注销", + style: TextStyle( + fontSize: AppFontsize + .normal_text_size, + color: const Color( + 0xFFFF7159), // 设置为#E45E91的颜色 + ), + ), + TextSpan( + text: + ",可先进行解绑后再进行注销操作。", + style: TextStyle( + fontSize: AppFontsize + .normal_text_size, + color: + Color(0xFF9AA0B3), + ), + ), + ], + ), + ), + const SizedBox( + height: 24, + ), + Text( + "无法控制智能床、智能床垫等设备", + style: TextStyle( + fontSize: AppFontsize + .title_size, // 设置字体大小 + color: + const Color(0xFFFFFFFF), + ), + ), + const SizedBox( + height: 6, + ), + Text( + "你将无法控制你的智能床、智能床垫等设备,以及与其相关的各种操作。", + style: TextStyle( + fontSize: AppFontsize + .normal_text_size, // 设置字体大小 + color: Color(0xFF9AA0B3), + ), + ), + const SizedBox( + height: 24, + ), + Text( + "无法查询睡眠报告和体征数据", + style: TextStyle( + fontSize: AppFontsize + .title_size, // 设置字体大小 + color: + const Color(0xFFFFFFFF), + ), + ), + const SizedBox( + height: 6, + ), + Text( + "注销账号后你将查询不到你以前的睡眠报告和实时数据。", + style: TextStyle( + fontSize: AppFontsize + .normal_text_size, // 设置字体大小 + color: Color(0xFF9AA0B3), + ), + ), + const SizedBox( + height: 24, + ), + Text( + "无法使用的其他功能", + style: TextStyle( + fontSize: AppFontsize + .title_size, // 设置字体大小 + color: + const Color(0xFFFFFFFF), + ), + ), + const SizedBox( + height: 6, + ), + Text( + "包含设备报修、门店体验预约等。", + style: TextStyle( + fontSize: AppFontsize + .normal_text_size, // 设置字体大小 + color: Color(0xFF9AA0B3), + ), + ), + ], + )), + ] + .divide( + const SizedBox(height: 24)) + .addToStart( + const SizedBox(height: 14)) + .addToEnd( + const SizedBox(height: 17)), + ), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 15, 0, 15, AppConstants.page_button_bottom_padding), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.056, + // decoration: BoxDecoration( + // color: + // FlutterFlowTheme.of(context).secondaryBackground, + // ), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.056, + decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context) + // .secondaryBackground, + borderRadius: BorderRadius.circular(12), + ), + child: FFButtonWidget( + onPressed: () async { + // showCustomConfirmDialog(context, "是否确认注销?") + // .then((v) async { + // if (v != "confirm") { + // return; + // } + // LoginController loginController = Get.find(); + // UserInfoController userInfoController = + // Get.find(); + // var code = await loginController.deletedAccount(); + // if (code != null && code == 1) { + // final box = GetStorage(); + // box.remove('user'); + // box.remove('token'); + // userInfoController.model.token = null; + // userInfoController.model.user = null; + // userInfoController.model.login = 0; + // userInfoController.model.message = 0; + // GlobalController globalController = + // Get.find(); + // globalController.resetParmAll(); + // Get.offAllNamed("/loginPage"); + // } + // }); + }, + text: '注销账号', + options: FFButtonOptions( + height: 40, + padding: const EdgeInsetsDirectional.fromSTEB( + 24, 0, 24, 0), + iconPadding: const EdgeInsetsDirectional.fromSTEB( + 0, 0, 0, 0), + color: const Color(0xFFFF7159), + textStyle: FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: AppFontsize.normal_text_size, + letterSpacing: 0, + ), + elevation: 0, + borderSide: const BorderSide( + color: Colors.transparent, + width: 1, + ), + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ), + ], + ), + ), + ), + )); + }); + } + + Future _copyToClipboard(String text) async { + await Clipboard.setData(ClipboardData(text: text)); + } +} diff --git a/lib/pages/device_control/device_people_info.dart b/lib/pages/device_control/device_people_info.dart new file mode 100644 index 0000000..99d2cdc --- /dev/null +++ b/lib/pages/device_control/device_people_info.dart @@ -0,0 +1,266 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; + +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/base/THFlutterFlowDropDown.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; + +class DevicePeopleInfo extends StatelessWidget { + DevicePeopleInfo({super.key}); + + get glController => Get.find(); + get bodyData => glController.model.mainDevicePeople; + + getInfoRow(context, String str) { + return Container( + width: double.infinity, + height: 60.rpx, + decoration: BoxDecoration(), + alignment: Alignment.centerLeft, + child: Text( + '$str', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 26.rpx, + letterSpacing: 0, + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, boxConstraints) => GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: Colors.white), + titleSpacing: 0, + title: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '详情', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + actions: [], + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Obx( + () => Container( + padding: EdgeInsets.only( + left: 30.rpx, right: 30.rpx, top: 30.rpx), + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1.123, + // decoration: BoxDecoration( + // // color: AppColors.bg_color, + // image: DecorationImage( + // image: AssetImage("assets/images/background.png"), + // fit: BoxFit.cover, + // ), + // ), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + ClickableContainer( + backgroundColor: Color(0xFF003058), + highlightColor: Color(0xFF036060), + borderRadius: 16.rpx, + padding: EdgeInsets.fromLTRB( + 30.rpx, 20.rpx, 0, 20.rpx), + onTap: () {}, + child: Container( + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(16.rpx)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + alignment: Alignment.centerLeft, + child: Text( + '设备信息', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + ), + ), + ), + getInfoRow(context, + "名称:${glController.getDeviceGroupName2(glController.model.deviceMain)}"), + getInfoRow(context, + "房间:${glController.model.deviceMain["roomName"] ?? "-"}"), + getInfoRow(context, + "网络:${glController.model.deviceMain["status"] ?? "-"}"), + getInfoRow(context, + "MAC:${glController.model.deviceMain["mac"] ?? "-"}"), + ], + ), + )), + ...List.generate( + "${glController.model.deviceMain["bindMacB"]}" + .length > + 6 + ? 2 + : 1, (index) { + String location_ = ""; + if ("${glController.model.deviceMain["bindMacB"]}" + .length > + 6 && + (glController.model.mainDevicePeople[0] + ?["direction"] == + 1 || + glController.model.mainDevicePeople[1] + ?["direction"] == + 1)) { + location_ = + "${glController.model.mainDevicePeople[index]?["direction"] == 1 ? '左侧' : '右侧'}"; + } + // return Container( + // decoration: BoxDecoration( + // color: Color(0xFF003058), + // borderRadius: BorderRadius.circular(16.rpx), + // ), + // child: Padding( + // padding: EdgeInsets.symmetric( + // horizontal: 30.rpx), + // child: Column( + // children: [ + // Container( + // width: double.infinity, + // margin: EdgeInsets.only( + // bottom: 30.rpx, top: 50.rpx), + // decoration: BoxDecoration(), + // child: Text( + // '人员资料${index == 0 ? "A" : "B"}', + // style: FlutterFlowTheme.of(context) + // .bodyMedium + // .override( + // fontFamily: 'Readex Pro', + // color: Colors.white, + // fontSize: 32.rpx, + // letterSpacing: 0, + // ), + // ), + // ), + // if (location_.isNotEmpty) + // getInfoRow( + // context, "校准位置:$location_"), + // getInfoRow(context, + // "姓名:${bodyData[index]["name"] ?? "-"}"), + // getInfoRow(context, + // "性别:${bodyData[index]["gender"] == null ? "-" : (bodyData[index]["gender"] == 1 ? "男" : "女")}"), + // getInfoRow(context, + // "身高:${bodyData[index]["height"] == null ? "-" : "${bodyData[index]["height"]}cm"}"), + // getInfoRow(context, + // "体重:${bodyData[index]["weight"] == null ? "-" : "${bodyData[index]["weight"]}kg"}"), + // getInfoRow(context, + // "生日:${bodyData[index]["birthday"] == null ? "-" : (time_08_Formatter_pattern(bodyData[index]["birthday"], "yyyy年MM月dd日"))}"), + // getInfoRow(context, + // "电话:${bodyData[index]["tel"] ?? "-"}"), + // getInfoRow(context, + // "紧急联系人:${bodyData[index]["contact"] ?? "-"}"), + // ], + // ))); + + return ClickableContainer( + backgroundColor: Color(0xFF003058), + highlightColor: Color(0xFF036060), + borderRadius: 16.rpx, + padding: EdgeInsets.fromLTRB( + 30.rpx, 20.rpx, 30.rpx, 20.rpx), + onTap: () {}, + child: Column( + children: [ + Container( + width: double.infinity, + alignment: Alignment.centerLeft, + child: Text( + '人员资料${index == 0 ? "A" : "B"}', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 32.rpx, + letterSpacing: 0, + ), + ), + ), + if (location_.isNotEmpty) + getInfoRow(context, "校准位置:$location_"), + getInfoRow(context, + "姓名:${bodyData[index]["name"] ?? "-"}"), + getInfoRow(context, + "性别:${bodyData[index]["gender"] == null ? "-" : (bodyData[index]["gender"] == 1 ? "男" : "女")}"), + getInfoRow(context, + "身高:${bodyData[index]["height"] == null ? "-" : "${bodyData[index]["height"]}cm"}"), + getInfoRow(context, + "体重:${bodyData[index]["weight"] == null ? "-" : "${bodyData[index]["weight"]}kg"}"), + getInfoRow(context, + "生日:${bodyData[index]["birthday"] == null ? "-" : (time_08_Formatter_pattern(bodyData[index]["birthday"], "yyyy年MM月dd日"))}"), + getInfoRow(context, + "电话:${bodyData[index]["tel"] ?? "-"}"), + getInfoRow(context, + "紧急联系人:${bodyData[index]["contact"] ?? "-"}"), + ], + ), + ); + }) + ].divide(SizedBox( + height: 25.rpx, + )), + ), + ), + ), + ), + ), + ), + )), + ); + } +} diff --git a/lib/pages/device_control/edit_address_page.dart b/lib/pages/device_control/edit_address_page.dart new file mode 100644 index 0000000..e8ce5d8 --- /dev/null +++ b/lib/pages/device_control/edit_address_page.dart @@ -0,0 +1,1333 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_city_picker/city_picker.dart'; +import 'package:flutter_city_picker/model/address.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; + +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/color/appFontsize.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/CustomCard.dart'; +import 'package:vbvs_app/controller/mh/address_controller.dart'; +import 'package:vbvs_app/controller/mh/address_list_controller.dart'; + +class EditAddressPage extends GetView + implements CityPickerListener { + final scaffoldKey = GlobalKey(); + BoxConstraints? bodysize; + + /// 0: 省 + /// 1: 市 + /// 2: 地区 + /// 3: 街道 + + String _addressProvince = "请选择省"; + String _addressCity = "请选择市"; + String _addressArea = "请选择地区"; + String _addressStreet = "请选择街道"; + List _selectProvince = []; + List _selectCity = []; + List _selectArea = []; + List _selectStreet = []; + + @override + Widget build(BuildContext context) { + AddressListController addressListController = Get.find(); + var address = + Map.from(addressListController.model.address); + controller.model.ischecked = address['isChecked']; + controller.model.all_address = getAddressDesc(address); + controller.model.detail = address['detail']; + controller.model.name = address['name']; + controller.model.phone = address['phone']; + controller.model.ischecked = address['isChecked']; + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + // key: scaffoldKey, + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: Colors.white), + titleSpacing: 0, + // leading: returnIconButtomAddCallback(() { + // controller.saveDataApi(); + // updateParm(isShowToast: false); + // }), + // leading: returnIconButtomNew, + title: Container( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '编辑地址', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + + actions: [], + centerTitle: false, + ), + body: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + child: Column( + // mainAxisSize: MainAxisSize.max, + children: [ + // TitleComponentWidget( + // titleName: '编辑收货地址', + // ), + + Expanded( + child: Padding( + padding: + EdgeInsetsDirectional.fromSTEB(0, 28.rpx, 0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.907, + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 30.rpx), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + width: MediaQuery.sizeOf(context).width, + decoration: BoxDecoration( + color: Color(0xFF003058), + borderRadius: + BorderRadius.circular(16.rpx), + ), + child: Align( + alignment: + const AlignmentDirectional(0, -1), + child: Container( + width: MediaQuery.sizeOf(context).width, + child: Padding( + padding: const EdgeInsetsDirectional + .fromSTEB(15, 0, 15, 0), + child: Container( + width: MediaQuery.sizeOf(context) + .width, + // decoration: BoxDecoration( + // color: Color(0XFF003058), + // ), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + width: MediaQuery.sizeOf( + context) + .width, + height: MediaQuery.sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minHeight: 46, + ), + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular( + 16), + ), + child: Row( + mainAxisSize: + MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Expanded( + child: Container( + width: MediaQuery + .sizeOf( + context) + .width * + 0.1, + height: 100, + decoration: + BoxDecoration(), + child: Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '地址信息', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors + .white, + fontSize: + AppFontsize + .title_size, + letterSpacing: + 0, + fontWeight: + FontWeight + .w600, + ), + ), + ), + ), + ), + Container( + width: + MediaQuery.sizeOf( + context) + .width * + 0.17, + height: + MediaQuery.sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + maxWidth: 55, + ), + decoration: + BoxDecoration(), + child: Row( + mainAxisSize: + MainAxisSize + .max, + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Align( + alignment: + const AlignmentDirectional( + 0, 0), + child: Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB( + 0, + 3, + 0, + 0), + child: + Container( + width: 18, + height: 18, + decoration: + const BoxDecoration(), + child: + Align( + alignment: + const AlignmentDirectional( + 0, + 0), + child: Theme( + data: ThemeData( + checkboxTheme: + CheckboxThemeData( + visualDensity: VisualDensity.compact, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(64), + ), + ), + unselectedWidgetColor: + const Color(0xFFD3D3D3), + ), + child: Obx(() { + return Checkbox( + value: controller.model.ischecked, + onChanged: (newValue) async { + controller.model.ischecked = newValue; + controller.updateAll(); + }, + side: BorderSide( + width: 1.5, + color: FlutterFlowTheme.of(context).secondaryText, + ), + activeColor: const Color(0xFF84F5FF), + checkColor: Color(0xFF011D33), + ); + })), + ), + ), + ), + ), + Text( + '默认', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + color: Color( + 0XFF84F5FF)), + ), + ], + ), + ), + ].divide(const SizedBox( + width: 12)), + ), + ), + Container( + width: MediaQuery.sizeOf( + context) + .width, + height: MediaQuery.sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minHeight: 31, + ), + decoration: BoxDecoration(), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Container( + width: + MediaQuery.sizeOf( + context) + .width * + 0.17, + height: + MediaQuery.sizeOf( + context) + .height * + 0.038, + constraints: + BoxConstraints( + minWidth: + 105.rpx, + maxWidth: + 105.rpx), + decoration: + BoxDecoration(), + child: Row( + mainAxisSize: + MainAxisSize + .max, + children: [ + Text( + '收件人', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + color: Colors + .white), + ), + ], + ), + ), + Expanded( + child: Container( + width: 100, + height: 100, + decoration: + BoxDecoration( + color: + Colors.white, + borderRadius: + BorderRadius + .circular( + 8), + ), + child: + TextFormField( + // autofocus: true, + obscureText: + false, + onChanged: (val) { + controller.model + .name = val; + }, + initialValue: + address[ + 'name'], + decoration: + InputDecoration( + contentPadding: + const EdgeInsetsDirectional + .fromSTEB( + 10, + 0, + 10, + 18), + labelStyle: FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + hintStyle: FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular( + 8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular( + 8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular( + 8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular( + 8), + ), + ), + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + ), + ), + ), + ].divide(const SizedBox( + width: 15)), + ), + ), + Container( + width: MediaQuery.sizeOf( + context) + .width, + height: MediaQuery.sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minHeight: 31, + ), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Container( + width: + MediaQuery.sizeOf( + context) + .width * + 0.17, + height: + MediaQuery.sizeOf( + context) + .height * + 0.038, + constraints: + BoxConstraints( + minWidth: + 105.rpx, + maxWidth: + 105.rpx), + decoration: + BoxDecoration(), + child: Row( + mainAxisSize: + MainAxisSize + .max, + children: [ + Text( + '手机号', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + color: Colors + .white, + ), + ), + ], + ), + ), + Expanded( + child: Container( + width: 100, + height: 100, + decoration: + BoxDecoration( + borderRadius: + BorderRadius + .circular( + 8), + color: + Colors.white, + ), + child: + TextFormField( + // autofocus: true, + onChanged: (val) { + controller.model + .phone = + val; + }, + obscureText: + false, + initialValue: + address[ + 'phone'], + decoration: + InputDecoration( + contentPadding: + const EdgeInsetsDirectional + .fromSTEB( + 10, + 0, + 10, + 18), + labelStyle: FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + hintStyle: FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular( + 8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular( + 8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular( + 8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular( + 8), + ), + ), + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + ), + ), + ), + ].divide(const SizedBox( + width: 15)), + ), + ), + Container( + width: MediaQuery.sizeOf( + context) + .width, + height: MediaQuery.sizeOf( + context) + .height * + 0.038, + constraints: + const BoxConstraints( + minHeight: 31, + ), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Container( + width: + MediaQuery.sizeOf( + context) + .width * + 0.17, + height: + MediaQuery.sizeOf( + context) + .height * + 0.038, + constraints: + BoxConstraints( + minWidth: + 105.rpx, + maxWidth: + 105.rpx), + child: Row( + mainAxisSize: + MainAxisSize + .max, + children: [ + InkWell( + // onTap: () { + // CityPicker.show( + // context: + // context, + // cityPickerListener: + // this, + // ); + // }, + child: Text( + '所在地区', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize.normal_text_size, + letterSpacing: + 0, + color: Colors + .white, + ), + ), + ), + ], + ), + ), + Expanded( + child: InkWell( + onTap: () { + CityPicker.show( + context: + context, + cityPickerListener: + this, + ); + }, + child: Container( + width: 100, + height: 100, + decoration: + BoxDecoration( + color: const Color( + 0xFFF3F5F6), + borderRadius: + BorderRadius + .circular( + 8), + ), + child: Obx(() { + return TextFormField( + enabled: + false, + controller: controller.onReDraw( + TextEditingController( + text: + controller.model.all_address), + (val) { + val.text = controller + .model + .all_address; + }), + // autofocus: true, + obscureText: + false, + decoration: InputDecoration( + contentPadding: const EdgeInsetsDirectional.fromSTEB(10, 0, 10, 18), + labelStyle: FlutterFlowTheme.of(context).labelMedium.override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + hintStyle: FlutterFlowTheme.of(context).labelMedium.override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + enabledBorder: UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + disabledBorder: UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 0, + ), + borderRadius: + BorderRadius.circular(8), + ), + focusedBorder: UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + errorBorder: UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + focusedErrorBorder: UnderlineInputBorder( + borderSide: + const BorderSide( + color: + Color(0x00000000), + width: + 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + suffixIcon: Transform.rotate( + angle: + 1.5708, // 90 度相当于 pi / 2 弧度 + child: + Icon( + Icons.arrow_forward_ios, + color: + FlutterFlowTheme.of(context).secondaryText, + size: + 12, + ), + )), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + ); + })), + ), + ), + ].divide(const SizedBox( + width: 15)), + ), + ), + Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB( + 0, 0, 0, 15), + child: Container( + width: MediaQuery.sizeOf( + context) + .width, + height: MediaQuery.sizeOf( + context) + .height * + 0.093, + constraints: + const BoxConstraints( + minHeight: 76, + ), + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Align( + alignment: + const AlignmentDirectional( + -1, -1), + child: Container( + width: MediaQuery + .sizeOf( + context) + .width * + 0.17, + height: MediaQuery + .sizeOf( + context) + .height * + 0.038, + constraints: + BoxConstraints( + minWidth: 105 + .rpx, + maxWidth: + 105.rpx), + child: Row( + mainAxisSize: + MainAxisSize + .max, + children: [ + Text( + '详细地址', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize + .normal_text_size, + letterSpacing: + 0, + color: Colors + .white), + ), + // Align( + // alignment: + // AlignmentDirectional( + // 0, + // -0.1), + // child: Icon( + // Icons + // .star_rate_sharp, + // color: Color( + // 0xFFE50012), + // size: 8, + // ), + // ), + ], + ), + ), + ), + Expanded( + child: Container( + width: 100, + height: MediaQuery + .sizeOf( + context) + .height * + 0.093, + decoration: + BoxDecoration( + color: const Color( + 0xFFF3F5F6), + borderRadius: + BorderRadius + .circular( + 8), + ), + child: + TextFormField( + // autofocus: true, + onChanged: + (val) { + controller + .model + .detail = + val; + }, + initialValue: + address[ + 'detail'], + maxLines: 2, + obscureText: + false, + decoration: + InputDecoration( + contentPadding: + const EdgeInsetsDirectional + .fromSTEB( + 10, + 10, + 10, + 10), + labelStyle: FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + hintStyle: FlutterFlowTheme.of( + context) + .labelMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + enabledBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular(8), + ), + focusedBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular(8), + ), + errorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular(8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0x00000000), + width: 2, + ), + borderRadius: + BorderRadius + .circular(8), + ), + ), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + ), + ), + ), + ), + ].divide(const SizedBox( + width: 15)), + ), + ), + ), + ].divide( + const SizedBox(height: 15)), + ), + ), + ), + ), + ), + ), + ), + ], + ), + )), + ), + ), + ), + + Padding( + padding: const EdgeInsetsDirectional.fromSTEB(15, 0, + 15, AppConstants.page_button_bottom_padding), + child: CustomCard( + borderRadius: 10, + gradientDirection: GradientDirection.vertical, + onTap: () { + // if (controller.model.all_address == null || + // controller.model.all_address!.isEmpty) { + // showToast("地址不能为空"); + // return; + // } + // if (controller.model.name == null || + // controller.model.name!.isEmpty) { + // showToast("名字不能为空"); + // return; + // } + // if (controller.model.detail == null || + // controller.model.detail!.isEmpty) { + // showToast("详细地址不能为空"); + // return; + // } + // if (controller.model.phone == null || + // controller.model.phone!.isEmpty) { + // showToast("手机号不能为空"); + // return; + // } + // if (!MyUtils.isValidPhoneNumber( + // controller.model.phone!)) { + // showToast("无效的手机号码"); + // return; + // } + // if (addressListController.model.type == 1) { + // await controller.addAddress(controller.model); + // } else { + // await controller.updateAddress( + // address, controller.model); + // } + // await addressListController.getAddressList(); + // Get.back(); + // controller.model = AddressModel(); + // controller.updateAll(); + }, + colors: const [ + Color(0xFFFCFCFC), + Color(0xFFF8FAF9), + Color(0XFFECF6F3), + Color(0XFFD9F0E9), + Color(0xFFCEECE3) + ], + child: Container( + width: double.infinity, + height: 90.rpx, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + ), + child: Text( + "保存", + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: stringToColor("#011D33"), + letterSpacing: 0, + fontSize: 30.rpx, + ), + ), + ), + ) + + // Container( + // width: bodysize!.maxWidth, + // height: bodysize!.maxHeight * 0.056, + // decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context) + // .secondaryBackground, + // ), + // child: + + // Container( + // width: bodysize!.maxWidth, + // height: bodysize!.maxHeight * 0.056, + // decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context) + // .secondaryBackground, + // borderRadius: BorderRadius.circular(12), + // ), + // child: FFButtonWidget( + // onPressed: () async { + // // if (controller.model.all_address == null || + // // controller.model.all_address!.isEmpty) { + // // showToast("地址不能为空"); + // // return; + // // } + // // if (controller.model.name == null || + // // controller.model.name!.isEmpty) { + // // showToast("名字不能为空"); + // // return; + // // } + // // if (controller.model.detail == null || + // // controller.model.detail!.isEmpty) { + // // showToast("详细地址不能为空"); + // // return; + // // } + // // if (controller.model.phone == null || + // // controller.model.phone!.isEmpty) { + // // showToast("手机号不能为空"); + // // return; + // // } + // // if (!MyUtils.isValidPhoneNumber( + // // controller.model.phone!)) { + // // showToast("无效的手机号码"); + // // return; + // // } + // // if (addressListController.model.type == 1) { + // // await controller.addAddress(controller.model); + // // } else { + // // await controller.updateAddress( + // // address, controller.model); + // // } + // // await addressListController.getAddressList(); + // // Get.back(); + // // controller.model = AddressModel(); + // // controller.updateAll(); + // }, + // text: '确定', + // options: FFButtonOptions( + // height: 40, + // padding: const EdgeInsetsDirectional.fromSTEB( + // 24, 0, 24, 0), + // iconPadding: + // const EdgeInsetsDirectional.fromSTEB( + // 0, 0, 0, 0), + // color: const Color(0xFFD3B684), + // textStyle: FlutterFlowTheme.of(context) + // .titleSmall + // .override( + // fontFamily: 'Readex Pro', + // color: Colors.white, + // fontSize: AppFontsize.normal_text_size, + // letterSpacing: 0, + // ), + // elevation: 0, + // borderSide: const BorderSide( + // color: Colors.transparent, + // width: 1, + // ), + // borderRadius: BorderRadius.circular(6), + // ), + // ), + // ), + // ), + ), + ], + ), + ), + ))); + }); + } + + @override + Future> onDataLoad( + int index, String code, String name) async { + debugPrint("onDataLoad ---> $index $name"); + + if (index == 0) { + await Future.delayed(const Duration(milliseconds: 200)); + return HttpUtils.getCityData("", index); + } else { + if (controller.model.currentType == 0) { + return Future.value([]); + } else if (controller.model.currentType == 1) { + if (index == 2) { + return Future.value([]); + } + return HttpUtils.getCityData(code, index); + } else if (controller.model.currentType == 2) { + if (index == 3) { + return Future.value([]); + } + return HttpUtils.getCityData(code, index); + } else { + return HttpUtils.getCityData(code, index); + } + } + } + + @override + void onFinish(List data) { + debugPrint("onFinish"); + String add = ""; + for (var node in data) { + add += "${node.name} "; + } + if (controller.model.currentType == 0) { + _addressProvince = add; + _selectProvince = data; + } else if (controller.model.currentType == 1) { + _addressCity = add; + _selectCity = data; + } else if (controller.model.currentType == 2) { + _addressArea = add; + _selectArea = data; + } else { + _addressStreet = add; + _selectStreet = data; + } + controller.model.all_address = add; + controller.model.addressList = data; + controller.updateAll(); + } + + String getAddressDesc(Map address) { + // 提取地址的各个字段 + String? province = address['province']; + String? city = address['city']; + String? area = address['county']; + String? street = address['street']; + + // 使用 where 过滤掉 null 或空字符串的值,并用空格连接有效的字段 + return [province, city, area, street] + .where((element) => element != null && element.isNotEmpty) + .join(' '); + } +} + +class HttpUtils { + static Future> getCityData(String code, int index) async { + final AddressController addressController = Get.find(); + addressController.model.currentType = 1; + + if (code.isEmpty) { + addressController.updateAll(); + return addressController.getData(level: 0); + } + addressController.model.currentType = index + 1; + //控制选择区域层级 1.省 2.市 3.区 4.街道 + if (addressController.model.currentType > 3) { + return []; + } + return addressController.getData(pid: int.parse(code)); + } +} diff --git a/lib/pages/device_control/edit_bed.dart b/lib/pages/device_control/edit_bed.dart new file mode 100644 index 0000000..367b83e --- /dev/null +++ b/lib/pages/device_control/edit_bed.dart @@ -0,0 +1,203 @@ +import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart'; +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/CustomCard.dart'; + +class EditBedPage extends StatefulWidget { + const EditBedPage({Key? key}) : super(key: key); + @override + _EditBedPageState createState() => _EditBedPageState(); +} + +BoxConstraints? bodysize; +RxString _bedName = "".obs; + +class _EditBedPageState extends State { + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () { + FocusScope.of(context).requestFocus(FocusNode()); + }, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '智能床名称', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Padding( + padding: EdgeInsets.only(top: 40.rpx), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: bodysize!.maxHeight * 1, + height: bodysize!.maxHeight * 0.335, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + child: + Image.asset('assets/images/bed_name.png'), + width: bodysize!.maxWidth * 0.69, + height: 193.rpx, + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 60.rpx), + child: Container( + alignment: Alignment.center, + height: bodysize!.maxHeight * 0.076, + decoration: const BoxDecoration( + border: Border( + bottom: BorderSide( + color: Color(0xFF929699), + width: 0))), + child: TextFormField( + // autofocus: true, + obscureText: false, + onChanged: (val) { + // controller.model.name = val; + }, + textAlign: TextAlign.center, + initialValue: _bedName.value, + decoration: InputDecoration( + hintText: "请输入床的名称", + contentPadding: + const EdgeInsetsDirectional + .fromSTEB(10, 0, 10, 0), + labelStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + fontSize: 36.rpx, // 设置输入文字大小 + color: Colors.white, // 设置输入文字颜色 + ), + hintStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + color: Color(0xFF929699), + fontSize: 36.rpx, + ), + enabledBorder: UnderlineInputBorder( + borderSide: const BorderSide( + color: Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + focusedBorder: UnderlineInputBorder( + borderSide: const BorderSide( + color: Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + errorBorder: UnderlineInputBorder( + borderSide: const BorderSide( + color: Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + focusedErrorBorder: + UnderlineInputBorder( + borderSide: const BorderSide( + color: Color(0x00000000), + width: 2, + ), + borderRadius: + BorderRadius.circular(8), + ), + ), + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + letterSpacing: 0, + ), + ), + )) + ], + ), + ), + Padding( + padding: EdgeInsets.only( + left: 30.rpx, right: 30.rpx, bottom: 85.rpx), + child: CustomCard( + borderRadius: 10, + gradientDirection: GradientDirection.vertical, + onTap: () {}, + colors: const [ + Color(0xFFFCFCFC), + Color(0xFFF8FAF9), + Color(0XFFECF6F3), + Color(0XFFD9F0E9), + Color(0xFFCEECE3) + ], + child: Container( + width: double.infinity, + height: 90.rpx, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + ), + child: Text("完成", + style: TextStyle( + color: const Color(0xFF003058), + fontSize: 26.rpx)), + ), + )) + ], + ))), + ), + ), + ); + }); + } +} diff --git a/lib/pages/device_control/edit_userinfo_page.dart b/lib/pages/device_control/edit_userinfo_page.dart new file mode 100644 index 0000000..a9925cc --- /dev/null +++ b/lib/pages/device_control/edit_userinfo_page.dart @@ -0,0 +1,205 @@ +import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart'; +import 'package:flutter/material.dart'; + +import 'package:get/get.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/CustomCard.dart'; + +import '../../controller/mh/muser_info_controller.dart'; + +class EditUserInfoPage extends GetView { + final scaffoldKey = GlobalKey(); + + // EditUserInfoPage() { + // UserInfoController controller = Get.find(); + // controller.model.user!.tmpHead = controller.model.user!.head; + // } + + @override + Widget build(BuildContext context) { + // UserInfoController controller = Get.find(); + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + key: scaffoldKey, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: Colors.white), + titleSpacing: 0, + title: Container( + width: double.infinity, + height: 70.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '编辑资料', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + Positioned( + right: 30.rpx, + child: CustomCard( + borderRadius: 10, + gradientDirection: GradientDirection.vertical, + onTap: () {}, + colors: const [ + Color(0xFFFCFCFC), + Color(0xFFF8FAF9), + Color(0XFFECF6F3), + Color(0XFFD9F0E9), + Color(0xFFCEECE3) + ], + child: Container( + width: 120.rpx, + height: 60.rpx, + alignment: Alignment.center, + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(5), + // color: stringToColor("#182B7C"), + // ), + child: Text( + "保存", + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: stringToColor("#9EA4B7"), + letterSpacing: 0, + fontSize: 30.rpx, + ), + ), + ), + )) + ], + ), + ), + centerTitle: false, + ), + body: Container( + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 108.rpx), + child: Container( + width: 160.rpx, + height: 160.rpx, + clipBehavior: Clip.antiAlias, + decoration: const BoxDecoration( + shape: BoxShape.circle, + ), + child: Image.asset( + "assets/images/people_avatar.png", + fit: BoxFit.cover, + ), + ), + ), + Padding( + padding: EdgeInsets.only(top: 44.rpx), + child: Text( + '点击更换头像', + style: + TextStyle(color: Color(0XFF85F5FF), fontSize: 26.rpx), + ), + ), + Padding( + padding: + EdgeInsets.fromLTRB(60.rpx, 122.rpx, 60.rpx, 0.rpx), + child: Container( + width: double.infinity, + height: 88.rpx, + decoration: BoxDecoration( + border: Border( + top: BorderSide( + color: Color(0xFFD3D3D3), width: 2.rpx), // 上边线 + bottom: BorderSide( + color: Color(0xFFD3D3D3), width: 2.rpx), // 下边线 + ), + ), + alignment: Alignment(0, 0), + child: Text( + '玛利亚', + style: TextStyle( + color: Color(0XFFFFFFFF), fontSize: 26.rpx), + ), + ), + ), + ], + ), + ), + ), + )); + } + + // Widget getImageWidget(BuildContext context) { + // try { + // UserInfoController controller = Get.find(); + + // var head = controller.model.user!.tmpHead; + // return InkWell( + // onTap: () { + // controller.uploadImg(); + // }, + // child: Row( + // children: [ + // Container( + // width: 50, + // height: 50, + // decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context).secondaryBackground, + // ), + // child: Container( + // width: 120, + // height: 120, + // clipBehavior: Clip.antiAlias, + // decoration: BoxDecoration( + // shape: BoxShape.circle, + // ), + // child: head == null || head.isEmpty + // ? Image.asset( + // 'assets/images/avatar.png', + // fit: BoxFit.cover, + // ) + // : Image.network( + // "${getStorageResourceUrl(head)}", + // fit: BoxFit.cover, + // ), + // ), + // ), + // SizedBox(width: 10), + // Icon( + // Icons.arrow_forward_ios, + // color: Color(0xFF373737), + // size: 12, + // ), + // ], + // ), + // ); + // } catch (e) { + // print(e); + // } + // return Container(); + // } +} diff --git a/lib/pages/device_control/experience_store_page.dart b/lib/pages/device_control/experience_store_page.dart new file mode 100644 index 0000000..73c4d3c --- /dev/null +++ b/lib/pages/device_control/experience_store_page.dart @@ -0,0 +1,454 @@ +import 'dart:async'; + +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appColors.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/color/appFontsize.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/controller/mh/experience_store_list_page.dart'; +import 'package:vbvs_app/pages/device_control/Empty.dart'; +import 'package:vbvs_app/pages/device_control/experience_store_widget.dart'; +import 'package:vbvs_app/pages/device_control/searchWidget.dart'; + +class ExperienceStorePage extends GetView { + ExperienceStorePage({super.key}); + +// class _ExperienceStorePageState extends State { +// get controller => Get.find(); +// final scaffoldKey = GlobalKey(); + BoxConstraints? bodysize; + + ScrollController scrollController = ScrollController(); + ExperienceStoreListController controller = Get.find(); + int runTime = 0; + + // @override + // void initState() { + // // TODO: implement initState + // super.initState(); + // Timer(Duration(milliseconds: 100), () async { + // controller.resetParm(); + // await controller.determinePosition(); + // controller.page = 0; + // controller.getData(); + // scrollController.addListener(() { + // int ctime = DateTime.now().millisecondsSinceEpoch; + // if (ctime - runTime > 100 && + // scrollController.position.pixels + 80 > + // scrollController.position.maxScrollExtent) { + // runTime = ctime; + // print( + // "bottom get more data ${scrollController.position.pixels} ${scrollController.position.maxScrollExtent}"); + // controller.getData(); + // } + // }); + // }); + // } + + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + controller.model.experienceStoreModelList = [ + { + "id": "5b82d1d9c33c74647e7624ec1db7918f", + "enabled": true, + "code": "3401002", + "name": "SWES眠花糖合肥省委大院体验店", + "customerId": null, + "setNetCustomerKid": null, + "customer": null, + "kingdeeId": "", + "channel": null, + "salePersonId": "ed648f977422a9f32a05b4892a3cb529", + "salePerson": null, + "deptId": 3, + "deptName": null, + "dept": null, + "introduction": "", + "mobile": "18156022846", + "hotline": "0551-64464894", + "city": "合肥市", + "district": "庐阳区", + "addressDetail": "合肥市庐阳区逍遥津街道南含山路与红星路交汇处", + "image": "", + "latitude": "31.858934", + "longitude": "117.282166", + "isDel": false, + "isAppShow": true, + "business": true, + "authEndTime": null, + "createTime": 1701133326000, + "createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283", + "updateTime": 1709193588000, + "updateAdminId": null, + "distance": 2.2 + }, + { + "id": "97603deebb83f610f73acf5d0def2bce", + "enabled": true, + "code": "3401003", + "name": "SWES眠花糖合肥安粮国贸体验店", + "customerId": null, + "setNetCustomerKid": null, + "customer": null, + "kingdeeId": "", + "channel": null, + "salePersonId": "69297c65588adde4ee5de3c43a2c4033", + "salePerson": null, + "deptId": 3, + "deptName": null, + "dept": null, + "introduction": "", + "mobile": "18655643429", + "hotline": "0551-65156985", + "city": "合肥市", + "district": "政务新区", + "addressDetail": "安徽省合肥市蜀山区合作化南路16号", + "image": "", + "latitude": "31.82018", + "longitude": "117.25367", + "isDel": false, + "isAppShow": true, + "business": true, + "authEndTime": null, + "createTime": 1701133473000, + "createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283", + "updateTime": 1709193752000, + "updateAdminId": null, + "distance": 3.5 + }, + { + "id": "b6b588d7ff6b248115ee3e5951cf39a1", + "enabled": true, + "code": "3301001", + "name": "SWES眠花糖杭州南星桥旗舰店", + "customerId": null, + "setNetCustomerKid": null, + "customer": null, + "kingdeeId": "", + "channel": null, + "salePersonId": "f3a5e7935f65e94bc5aa6b2d63211e61", + "salePerson": null, + "deptId": 33, + "deptName": null, + "dept": null, + "introduction": "", + "mobile": "15222919097", + "hotline": "0571-86718606", + "city": "杭州市", + "district": "上城区", + "addressDetail": "浙江省杭州市上城区飞云江路45号一层102室", + "image": "", + "latitude": "30.21667", + "longitude": "120.17757", + "isDel": false, + "isAppShow": true, + "business": true, + "authEndTime": null, + "createTime": 1701135379000, + "createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283", + "updateTime": 1709194185000, + "updateAdminId": null, + "distance": 332.1 + }, + { + "id": "38fdbb715dc7bfddae3e32685c288e49", + "enabled": true, + "code": "3102001", + "name": "SWES眠花糖上海复兴荟旗舰店", + "customerId": null, + "setNetCustomerKid": null, + "customer": null, + "kingdeeId": "", + "channel": null, + "salePersonId": "4ae944badb423197bc54c0a6ec252944", + "salePerson": null, + "deptId": 32, + "deptName": null, + "dept": null, + "introduction": "", + "mobile": "13053037959", + "hotline": "021-63391962", + "city": "上海市", + "district": "黄浦区", + "addressDetail": "上海市黄浦区复兴东路1108号1层-1室", + "image": "", + "latitude": "31.22209", + "longitude": "121.494667", + "isDel": false, + "isAppShow": true, + "business": true, + "authEndTime": null, + "createTime": 1701135192000, + "createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283", + "updateTime": 1709194151000, + "updateAdminId": null, + "distance": 407.3 + }, + { + "id": "af908e6c5d1a2c8113b1c73117e15064", + "enabled": true, + "code": "3101001", + "name": "SWES眠花糖上海外滩九里体验店", + "customerId": null, + "setNetCustomerKid": null, + "customer": null, + "kingdeeId": "", + "channel": null, + "salePersonId": "1794f729f27ad4a44afad10061446dd5", + "salePerson": null, + "deptId": 31, + "deptName": null, + "dept": null, + "introduction": "", + "mobile": "13856414205", + "hotline": "021-63391208", + "city": "上海市", + "district": "黄浦区", + "addressDetail": "上海市黄浦区紫霞路103-107号1层103-12室", + "image": "", + "latitude": "31.218434", + "longitude": "121.502098", + "isDel": false, + "isAppShow": true, + "business": true, + "authEndTime": null, + "createTime": 1701134886000, + "createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283", + "updateTime": 1709194053000, + "updateAdminId": null, + "distance": 408.1 + }, + { + "id": "a5f1fc9a03ba827841c473e28a3fcdb2", + "enabled": true, + "code": "3101002", + "name": "SWES眠花糖上海尚悦湾旗舰店", + "customerId": null, + "setNetCustomerKid": null, + "customer": null, + "kingdeeId": "", + "channel": null, + "salePersonId": "d97ec48ee3b1060eb7ff5c81f0ffa37f", + "salePerson": null, + "deptId": 31, + "deptName": null, + "dept": null, + "introduction": "", + "mobile": "19523660595", + "hotline": "021-63336707", + "city": "上海市", + "district": "浦东新区", + "addressDetail": "上海市浦东新区银城路66号", + "image": "", + "latitude": "31.24103", + "longitude": "121.51045", + "isDel": false, + "isAppShow": true, + "business": true, + "authEndTime": null, + "createTime": 1701135694000, + "createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283", + "updateTime": 1709194087000, + "updateAdminId": null, + "distance": 408.4 + }, + { + "id": "21ddfb547060e930f841605dc4469bec", + "enabled": true, + "code": "1101001", + "name": "SWES眠花糖北京富力城旗舰店", + "customerId": null, + "setNetCustomerKid": null, + "customer": null, + "kingdeeId": "", + "channel": null, + "salePersonId": "b66028a628ce0fcb871ab7db5c17128e", + "salePerson": null, + "deptId": 11, + "deptName": null, + "dept": null, + "introduction": "", + "mobile": "15556119960", + "hotline": "010-58766288", + "city": "北京市", + "district": "朝阳区", + "addressDetail": "北京市朝阳区天力街3号楼1至2层商业12号", + "image": "", + "latitude": "39.89862", + "longitude": "116.45851", + "isDel": false, + "isAppShow": false, + "business": true, + "authEndTime": null, + "createTime": 1701134049000, + "createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283", + "updateTime": 1733193484000, + "updateAdminId": null, + "distance": 897.7 + }, + { + "id": "432bfdf508115827c5dca474b72dea68", + "enabled": true, + "code": "1102001", + "name": "SWES眠花糖北京英皇中心旗舰店", + "customerId": null, + "setNetCustomerKid": null, + "customer": null, + "kingdeeId": "", + "channel": null, + "salePersonId": "155848302d5b6f2768111574f0161816", + "salePerson": null, + "deptId": 12, + "deptName": null, + "dept": null, + "introduction": "", + "mobile": "18225602774", + "hotline": "010-53269059", + "city": "北京市", + "district": "朝阳区", + "addressDetail": "北京市朝阳区建国门外大街丁12号", + "image": "", + "latitude": "39.907911", + "longitude": "116.444584", + "isDel": false, + "isAppShow": true, + "business": true, + "authEndTime": null, + "createTime": 1701134158000, + "createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283", + "updateTime": 1710490644000, + "updateAdminId": null, + "distance": 898.9 + } + ]; + bodysize = cc; + + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + // key: scaffoldKey, + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: Colors.white), + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '预约体验', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + Positioned( + right: 30.rpx, + child: ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Color(0xFF055466), + padding: EdgeInsets.only(left: 0), + onTap: () { + Get.toNamed("/myExperiencePage"); + }, + child: SvgPicture.asset( + 'assets/img/icon/history_store.svg', + width: 35.rpx, + height: 35.rpx, + color: Colors.white, + ))) + ], + ), + ), + centerTitle: false, + ), + body: SingleChildScrollView( + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + //todo + + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 40.rpx, 0, 38.rpx), + child: SearchWidget( + keyword: controller.model.keyword, + color: controller.model.color, + hint: "请输入门店名称", + onChange: (d) { + controller.model.keyword = d; + }, + findCallback: () { + // controller.page = 0; + // controller.getData(); + }, + ), + ), + Obx(() { + if (controller + .model.experienceStoreModelList.length == + 0) { + return Empty(); + } else { + return Container(); + } + }), + Expanded( + child: Obx(() => ListView( + controller: scrollController, + shrinkWrap: true, + scrollDirection: Axis.vertical, + children: List.generate( + controller + .model + .experienceStoreModelList + .length, (index) { + return ExperienceStoreWidget( + index: index, + data: controller.model + .experienceStoreModelList[index]); + }) + .divide(const SizedBox( + height: 25, + )) + .addToStart(SizedBox( + height: AppConstants.list_start_height, + )) + .addToEnd(SizedBox( + height: AppConstants.list_ano_end_height, + ))))), + ], + ), + ), + )), + )); + }); + } +} diff --git a/lib/pages/device_control/experience_store_widget.dart b/lib/pages/device_control/experience_store_widget.dart new file mode 100644 index 0000000..cc49a78 --- /dev/null +++ b/lib/pages/device_control/experience_store_widget.dart @@ -0,0 +1,306 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/controller/mh/book_info_controller.dart'; +import 'package:vbvs_app/pages/common/selectDialog.dart'; +import 'package:vbvs_app/pages/device_control/app_map_location.dart'; + +import '../../common/color/appFontsize.dart'; +import '../../common/util/MyUtils.dart'; + +class ExperienceStoreWidget extends GetView { + int index; + Map data; + + ExperienceStoreWidget({required this.index, required this.data}) {} + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + // height: MediaQuery.sizeOf(context).height * 0.187, + decoration: BoxDecoration( + color: Color(0XFF003058), + borderRadius: BorderRadius.circular(16), + ), + + child: Container( + width: MediaQuery.sizeOf(context).width, + margin: EdgeInsetsDirectional.fromSTEB(26.rpx, 14, 14, 15), + height: 120, + decoration: BoxDecoration( + color: Color(0XFF003058), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsetsDirectional.fromSTEB(0, 0, 0, 4), + child: Container( + width: MediaQuery.sizeOf(context).width, + // height: MediaQuery.sizeOf(context).height * 0.018, + constraints: const BoxConstraints( + minHeight: 30, + ), + + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.018, + child: Align( + alignment: const AlignmentDirectional(0, 0), + child: Text( + // experienceStoreModel.name ?? '未命名', + data["name"] ?? '', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + fontWeight: FontWeight.bold, + letterSpacing: 0, + ), + ), + ), + ), + ), + ), + Container( + width: MediaQuery.sizeOf(context).width, + height: 1.rpx, + decoration: const BoxDecoration( + color: Color(0xFF929699), + ), + ), + Flexible( + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + // height: MediaQuery.sizeOf(context).height * 0.034, + constraints: const BoxConstraints( + minHeight: 55, + ), + + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.034, + constraints: const BoxConstraints( + minHeight: 55, + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + child: Align( + alignment: const AlignmentDirectional(-1, 0), + child: Text( + '地址:${data["addressDetail"]}', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: const Color(0xFF929699), + fontSize: 20.rpx, + letterSpacing: 0, + lineHeight: 1), + ), + ), + ), + Flexible( + child: Align( + alignment: const AlignmentDirectional(-1, 0), + child: Text( + '电话:${data["hotline"]}', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: const Color(0xFF929699), + fontSize: 20.rpx, + letterSpacing: 0, + lineHeight: 1), + ), + ), + ), + ], + ), + ), + ), + ), + ), + Flexible( + child: Container( + width: MediaQuery.sizeOf(context).width, + // height: MediaQuery.sizeOf(context).height * 0.038, + + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.038, + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Flexible( + child: InkWell( + onTap: () { + MyUtils.makePhoneCall("${data["hotline"]}"); + }, + child: Container( + width: MediaQuery.sizeOf(context).width * 0.105, + height: MediaQuery.sizeOf(context).height * 0.038, + constraints: const BoxConstraints( + minWidth: 50, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + // child: Icon( + // Icons.phone_in_talk, + // color: Color(0xFFD3B684), + // size: 12, + // ), + child: SvgPicture.asset( + 'assets/images/phone.svg', + width: 27.rpx, + height: 27.rpx, + color: const Color(0xFF84F5FF), + ), + ), + Text( + '咨询', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: AppFontsize.small_text_size, + letterSpacing: 0, + ), + ), + ].divide(const SizedBox(width: 13)), + ), + ), + )), + Flexible( + child: InkWell( + onTap: () async { + // //"latitude" -> "31.858934" "longitude" -> "117.282166" + // AppMapLocation.checkInstalledApps() + // .then((d) { + // if (AppMapLocation + // .availableMapsToNames.isEmpty) { + // showToast("未检测到导航软件"); + // } else { + // showOneSelectionDialog(context, + // title: "选择地图", + // arr: AppMapLocation + // .availableMapsToNames, + // checkChange: (index) { + // AppMapLocation.launchMap( + // index, + // data["name"], + // double.parse( + // "${data["latitude"]}"), + // double.parse( + // "${data["longitude"]}")); + // }); + // } + // }); + }, + child: Container( + width: MediaQuery.sizeOf(context).width * 0.105, + height: MediaQuery.sizeOf(context).height * 0.038, + constraints: const BoxConstraints( + minWidth: 50, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + // child: Icon( + // Icons.location_on, + // color: Color(0xFFD3B684), + // size: 12, + // ), + child: SvgPicture.asset( + 'assets/images/locationColor.svg', + width: 22.rpx, + height: 29.rpx, + color: Color(0xFF84F5FF), + ), + ), + Text( + '导航', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: AppFontsize.small_text_size, + letterSpacing: 0, + ), + ), + ].divide(const SizedBox(width: 13)), + ), + ), + ), + ), + Container( + width: MediaQuery.sizeOf(context).width * 0.208, + height: MediaQuery.sizeOf(context).height * 0.038, + constraints: BoxConstraints( + maxWidth: 156.rpx, + maxHeight: 60.rpx, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(30.rpx), + ), + child: FFButtonWidget( + onPressed: () { + BookInfoController bookInfoController = + Get.find(); + bookInfoController.model.userName = ""; + bookInfoController.model.userPhone = ""; + Get.toNamed("/bookInfoPage", + arguments: {"data": data}); + }, + text: '预约', + options: FFButtonOptions( + padding: const EdgeInsetsDirectional.fromSTEB( + 0, 0, 0, 0), + color: Color(0xFF84F5FF), + textStyle: FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF011D33), + fontSize: 26.rpx, + letterSpacing: 0, + ), + elevation: 0, + borderSide: const BorderSide( + color: Colors.transparent, + width: 1, + ), + borderRadius: BorderRadius.circular(30.rpx), + ), + ), + ), + ].divide(const SizedBox(width: 26)), + ), + ), + ), + ), + ], + ), + ), + + // ), + ), + ); + } +} diff --git a/lib/pages/device_control/issue_list_page.dart b/lib/pages/device_control/issue_list_page.dart new file mode 100644 index 0000000..50e9eef --- /dev/null +++ b/lib/pages/device_control/issue_list_page.dart @@ -0,0 +1,187 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/color/appFontsize.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/pages/device_control/issue_preview_widget.dart'; + +import '../../controller/mh/issue_controller.dart'; + +class IssueListPage extends GetView { + final scaffoldKey = GlobalKey(); + BoxConstraints? bodysize; + + final ScrollController scrollController = ScrollController(); + + // IssueListPage() { + // controller.model.limit = AppConstants.limit; + // controller.model.offset = 0; + // controller.model.isLoading = false; + // controller.model.hasMore = true; + // controller.model.issueList!.clear(); + // controller.initData(); + + // scrollController.addListener(() { + // if (scrollController.position.pixels == + // scrollController.position.maxScrollExtent && + // controller.model.hasMore) { + // controller.initData(); + // controller.updateAll(); + // } + // }); + // } + + // void initData() async {} + + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + controller.model.issueList = [ + {'title': 'APP如何连接我的智能床?'}, + {'title': '智能床如何连接网络?'}, + {'title': '跟换WIFI名称或密码,或者刚换了路由器后,我的智能床无法使用怎么办?'}, + {'title': '在APP中,如何查看我的睡眠报告?'}, + {'title': '在APP中,如何查看我的睡眠报告?'}, + {'title': '在APP中,如何查看我的睡眠报告?'} + ]; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: Colors.white), + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '问题与帮助', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + actions: [], + centerTitle: false, + ), + // backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + body: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + decoration: BoxDecoration( + // color: AppColors.bg_color, + // color: Color(0xFFF6F6F6), + ), + child: Obx(() { + return Visibility( + visible: controller.model.issueList != null && + controller.model.issueList!.isNotEmpty, + replacement: Container( + width: MediaQuery.sizeOf(context).width, + height: 100, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context).secondaryBackground, + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(31, 27, 0, 0), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: AlignmentDirectional(-1, 0), + child: Text( + '暂无内容!', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: AppFontsize.title_size, + letterSpacing: 0, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + ), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + // TitleComponentWidget( + // titleName: '问题与帮助', + // ), + Flexible( + child: Padding( + padding: + EdgeInsetsDirectional.fromSTEB(15, 13, 15, 15), + child: Container( + width: bodysize!.maxWidth, + decoration: BoxDecoration( + // color: Colors.white, + // borderRadius: BorderRadius.circular(16), + ), + child: Obx(() => ListView( + controller: scrollController, + padding: const EdgeInsets.fromLTRB( + 0, + 5, + 0, + 0, + ), + shrinkWrap: true, + scrollDirection: Axis.vertical, + children: (controller.model.issueList! + .asMap() + .entries + .map((e) => IssuePreviewWidget( + index: e.key, + issueListController: controller)) + .toList() as List) + // .divide(const SizedBox( + // height: 30, + // )) + // .addToEnd(const SizedBox( + // height: 26, + // )) + // .addToStart(SizedBox( + // height: 16, + // )) + )), + ), + ), + ), + ], + ), + ); + }), + ), + ), + )); + }); + } +} diff --git a/lib/pages/device_control/issue_preview_widget.dart b/lib/pages/device_control/issue_preview_widget.dart new file mode 100644 index 0000000..7ebf886 --- /dev/null +++ b/lib/pages/device_control/issue_preview_widget.dart @@ -0,0 +1,104 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/controller/mh/issue_controller.dart'; +import 'package:vbvs_app/controller/mh/issue_preview_controller.dart'; + +import '../../common/color/appFontsize.dart'; + +class IssuePreviewWidget extends GetView { + final int index; + final IssueListController issueListController; + + IssuePreviewWidget({ + required this.index, + required this.issueListController, + }); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () async { + // issueListController.model.selectedIndex = index; + // issueListController.updateAll(); + // await Future.delayed(Duration(milliseconds: 100)); + // issueListController.model.selectedIndex = -1; + // issueListController.updateAll(); + // var article = issueListController.model.issueList![index]; + // Get.toNamed("/helpArticle", arguments: article); + }, + child: Obx(() { + return Container( + alignment: Alignment.center, + width: double.infinity, + constraints: BoxConstraints( + // minWidth: 100, + minHeight: 119.rpx, + ), + decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(0), + // 整行的背景颜色 + color: index == issueListController.model.selectedIndex + ? Colors.grey[300] + : Colors.transparent, + border: Border( + bottom: BorderSide(color: const Color(0xFF929699), width: 0.rpx), + ), + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(16.rpx, 0, 41.rpx, 0), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Flexible( + flex: 9, + child: Align( + alignment: AlignmentDirectional(-1, -1), + child: Text( + issueListController.model.issueList![index]['title'] ?? + '', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Color(0xFFFFFFFF), + fontSize: AppFontsize.title_size, + letterSpacing: 0, + lineHeight: 1), + ), + ), + ), + Expanded( + flex: 1, + child: Align( + alignment: Alignment.centerRight, + child: ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(right: 0), + onTap: () {}, + child: Container( + height: 30.rpx, + width: 30.rpx, + child: SvgPicture.asset( + 'assets/img/icon/expand.svg', + color: Colors.white, + ) + // Icon( + // Icons.arrow_forward_ios, + // color: Colors.white, + // // size: 14.rpx, + // ), + )), + ), + ), + ], + ), + ), + ); + }), + ); + } +} diff --git a/lib/pages/device_control/message_page.dart b/lib/pages/device_control/message_page.dart new file mode 100644 index 0000000..ce3262a --- /dev/null +++ b/lib/pages/device_control/message_page.dart @@ -0,0 +1,418 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/color/appFontsize.dart'; +import 'package:vbvs_app/common/color/app_uri_status.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/NullDataComponentWidget.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; +import 'package:vbvs_app/controller/mh/message_controller.dart'; +import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; +import 'package:vbvs_app/pages/main_bottom/component/MessageWidgetWidget.dart'; + +class MessagePage extends StatefulWidget { + const MessagePage({super.key}); + + @override + State createState() => _MessagePageState(); +} + +class _MessagePageState extends State { + ThemeController themeController = Get.find(); + MhMessageController messageController = Get.find(); + late PageController _pageController; + + @override + void initState() { + super.initState(); + messageController.model.type = 1; + _pageController = + PageController(initialPage: messageController.model.type == 1 ? 0 : 1); + messageController.getMessageStatus(); + _fetchMessageData(); + } + + void _fetchMessageData() { + String type = messageController.model.type == 1 ? "app_vsm" : "app_system"; + messageController.updateMessageStatus(type: type); + messageController.getMessageList().then((response) { + if (response.code != HttpStatusCodes.ok) { + TopSlideNotification.show( + // Get.context!, + context, + text: response.msg ?? "服务器.失败".tr, + textColor: themeController.currentColor.sc9, + ); + } + }); + } + + void _onTabChanged(int index) { + messageController.model.type = index == 0 ? 1 : 2; + messageController.updateAll(); + _fetchMessageData(); + _pageController.animateToPage(index, + duration: const Duration(milliseconds: 300), curve: Curves.easeInOut); + } + + void _onPageChanged(int index) { + int newType = index == 0 ? 1 : 2; + if (messageController.model.type != newType) { + messageController.model.type = newType; + messageController.updateAll(); + _fetchMessageData(); + } + } + + @override + void dispose() { + _pageController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + messageController.messageList.value = [ + { + "_id": "6836c3ee4e626030c8000000", + "type": "app_vsm", + "data": { + "title": "实时监测通知", + "val": [ + {"k": "设备ID", "v": "48ca43b1b454"}, + {"k": "使用人员", "v": "bb"}, + {"k": "消息类型", "v": "呼吸异常"}, + {"k": "检测值", "v": '26'}, + {"k": "检测时间", "v": "2025-05-28 16:06:07"} + ] + }, + "level": 3, + "tid": "67f5d96e26ef310463000000", + "uid": "68319fe9702cc59bd1000000", + "status": 0, + "createTime": "1748419566651" + }, + { + "_id": "6836c3e84e625f30c8000000", + "type": "app_vsm", + "data": { + "title": "实时监测通知", + "val": [ + {"k": "设备ID", "v": "48ca43b1b454"}, + {"k": "使用人员", "v": "bb"}, + {"k": "消息类型", "v": "心率异常"}, + {"k": "检测值", "v": '115'}, + {"k": "检测时间", "v": "2025-05-28 16:06:00"} + ] + }, + "level": 3, + "tid": "67f5d96e26ef310463000000", + "uid": "68319fe9702cc59bd1000000", + "status": 0, + "createTime": "1748419560486" + }, + { + "_id": "6836bd0c4e625e30c8000000", + "type": "app_vsm", + "data": { + "title": "实时监测通知", + "val": [ + {"k": "设备ID", "v": "48ca43b1b454"}, + {"k": "使用人员", "v": "bb"}, + {"k": "消息类型", "v": "心率异常"}, + {"k": "检测值", "v": '107'}, + {"k": "检测时间", "v": "1748417761000"} + ] + }, + "level": 3, + "tid": "67f5d96e26ef310463000000", + "uid": "68319fe9702cc59bd1000000", + "status": 0, + "createTime": "1748417804381" + } + ]; + + SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarIconBrightness: Brightness.light, + )); + + return LayoutBuilder( + builder: (context, boxConstraints) => GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: themeController.currentColor.sc3), + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '消息中心', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + actions: const [], + centerTitle: false, + ), + backgroundColor: Colors.transparent, + body: SafeArea( + top: true, + child: Padding( + padding: EdgeInsets.only(top: 30.rpx), + child: Column( + children: [ + SizedBox( + height: 100.rpx, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + Row( + children: [ + // 第一个 Tab 占据屏幕一半 + bodyMessage(), + // 第二个 Tab 占据屏幕另一半 + systemMessage(), + ], + ), + Obx(() { + double screenWidth = + MediaQuery.of(context).size.width; + double tabWidth = screenWidth / 2; + double margin = 30.rpx; + double lineWidth = tabWidth - 2 * margin; + // 计算滑块左边距,保证滑块水平居中于对应tab的文字 + double left = (messageController.model.type == 1 + ? 0 + : tabWidth) + + margin; + return AnimatedPositioned( + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + bottom: 0, + left: left, + child: Container( + width: lineWidth, + height: 4.rpx, + decoration: BoxDecoration( + color: Color(0xFF84F5FF), + borderRadius: BorderRadius.circular(2.rpx), + ), + ), + ); + }), + ], + ), + ), + Expanded( + child: PageView( + controller: _pageController, + onPageChanged: _onPageChanged, + children: [ + Obx(() { + final list = messageController.messageList.value; + return list.isEmpty + ? const NullDataWidget() + : _buildMessageListView(list); + }), + Obx(() { + final list = messageController.messageList.value; + return list.isEmpty + ? const NullDataWidget() + : _buildMessageListView(list); + }), + ], + ), + ), + bottomIcon(context) + ], + ), + )), + ), + ), + ), + ); + } + + Container bottomIcon(BuildContext context) { + return Container( + height: 120.rpx, + decoration: BoxDecoration( + color: Color(0xFF003058), + ), + width: double.infinity, + child: TextButton( + onPressed: () {}, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Baseline( + baselineType: TextBaseline.alphabetic, + baseline: AppFontsize.normal_text_size * 1.6, // 调整基线位置 + child: SvgPicture.asset( + 'assets/images/read_message.svg', + width: 40.rpx, + height: 40.rpx, + )), + SizedBox(width: 14.rpx), // 加号和文字间距 + Text( + '全部已读', + style: FlutterFlowTheme.of(context).titleSmall.override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 26.rpx, + letterSpacing: 0, + ), + ), + ], + ), + ), + ); + } + + Expanded systemMessage() { + return Expanded( + child: Align( + alignment: Alignment.center, + child: Obx(() { + return ClickableContainer( + padding: EdgeInsets.zero, + backgroundColor: Colors.transparent, + highlightColor: themeController.currentColor.sc21, + borderRadius: 8.rpx, + onTap: () => _onTabChanged(1), + child: Stack( + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Text( + '系统消息'.tr, + style: TextStyle( + fontSize: AppConstants().title_text_fontSize, + color: messageController.model.type == 1 + ? Colors.white + : Color(0xFF84F5FF), + height: 1.0, + ), + ), + Obx(() { + return messageController.model.system_message_read == 1 + ? Positioned( + top: -4, + right: -14, + child: Container( + width: 8, + height: 8, + decoration: const BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + ), + ) + : const SizedBox.shrink(); + }), + ], + ), + ); + }), + ), + ); + } + + Expanded bodyMessage() { + return Expanded( + child: Align( + alignment: Alignment.center, + child: Obx(() { + return ClickableContainer( + padding: EdgeInsets.zero, + backgroundColor: Colors.transparent, + highlightColor: themeController.currentColor.sc21, + borderRadius: 8.rpx, + onTap: () => _onTabChanged(0), + child: Stack( + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Text( + '体征消息'.tr, + style: TextStyle( + fontSize: AppConstants().title_text_fontSize, + color: messageController.model.type == 2 + ? Colors.white + : Color(0xFF84F5FF), + height: 1.0, + ), + ), + Obx(() { + return messageController.model.body_message_read == 1 + ? Positioned( + top: -4, + right: -14, + child: Container( + width: 8, + height: 8, + decoration: const BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + ), + ) + : const SizedBox.shrink(); + }), + ], + ), + ); + }), + ), + ); + } + + Widget _buildMessageListView(List dataList) { + return Container( + width: double.infinity, + padding: EdgeInsets.symmetric(horizontal: 30.rpx), + child: SingleChildScrollView( + child: Column( + children: [ + SizedBox(height: 30.rpx), + ...dataList + .map((item) => MessageWidgetWidget(data: item)) + .toList() + .divide(SizedBox(height: 30.rpx)), + SizedBox(height: 30.rpx), + ], + ), + ), + ); + } +} diff --git a/lib/pages/device_control/my_experience_page.dart b/lib/pages/device_control/my_experience_page.dart new file mode 100644 index 0000000..48b6405 --- /dev/null +++ b/lib/pages/device_control/my_experience_page.dart @@ -0,0 +1,152 @@ +import 'dart:async'; + +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/color/appColors.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/controller/mh/my_experience_list_controller.dart'; +import 'package:vbvs_app/pages/device_control/Empty.dart'; +import 'package:vbvs_app/pages/device_control/my_experience_widget.dart'; + +class MyExperiencePage extends StatefulWidget { + const MyExperiencePage({super.key}); + + @override + State createState() => _MyExperiencePageState(); +} + +class _MyExperiencePageState extends State { + ScrollController scrollController = ScrollController(); + int runTime = 0; + @override + void initState() { + super.initState(); + Timer(Duration.zero, () { + controller.resetParm(); + controller.getAllBook(); + controller.page = 0; + controller.getData(); + scrollController.addListener(() { + print( + "${scrollController.position.pixels} ${scrollController.position.maxScrollExtent}"); + int ctime = DateTime.now().millisecondsSinceEpoch; + if (ctime - runTime > 100 && + scrollController.position.pixels + 80 > + scrollController.position.maxScrollExtent) { + runTime = ctime; + print( + "bottom get more data ${scrollController.position.pixels} ${scrollController.position.maxScrollExtent}"); + controller.getData(); + } + }); + }); + } + + get controller => Get.find(); + final scaffoldKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + // key: scaffoldKey, + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: Colors.white), + titleSpacing: 0, + // leading: returnIconButtomAddCallback(() { + // controller.saveDataApi(); + // updateParm(isShowToast: false); + // }), + // leading: returnIconButtomNew, + title: Container( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '我的预约', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + + actions: [], + centerTitle: false, + ), + + body: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1, + decoration: BoxDecoration( + color: Color(0xFFF6F6F6), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + // TitleComponentWidget( + // titleName: '我的预约', + // ), + Obx(() { + if (controller.model.bookInfoList.length == 0) { + return Empty(); + } else { + return Container(); + } + }), + Expanded( + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1, + decoration: BoxDecoration(), + child: Obx(() => ListView( + controller: scrollController, + shrinkWrap: true, + scrollDirection: Axis.vertical, + children: [ + const SizedBox( + height: AppConstants.list_start_height), + ...List.generate( + controller.model.bookInfoList.length, + (index) { + return MyExperienceWidget( + index: index, + bookExperienceListController: controller); + }), + SizedBox( + height: AppConstants.list_end_height, + ) + ], + ))), + ) + ], + ), + ), + ), + )); + } +} diff --git a/lib/pages/device_control/my_experience_widget.dart b/lib/pages/device_control/my_experience_widget.dart new file mode 100644 index 0000000..9967f06 --- /dev/null +++ b/lib/pages/device_control/my_experience_widget.dart @@ -0,0 +1,424 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +import 'package:vbvs_app/controller/mh/my_experience_list_controller.dart'; + +import '../../common/color/appFontsize.dart'; + +class MyExperienceWidget extends GetView { + int index; + BookExperienceListController bookExperienceListController; + + MyExperienceWidget( + {required this.index, required this.bookExperienceListController}) {} + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsetsDirectional.fromSTEB(15, 0, 15, 0), + child: Obx(() { + Map data = {}; + bookExperienceListController.model.experienceStoreModelList + .forEach((item) { + if (item["id"] == + bookExperienceListController.model.bookInfoList[index] + ["storeId"]) { + data = item; + } + }); + return Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.187, + margin: const EdgeInsets.only(bottom: 25), + constraints: const BoxConstraints( + minHeight: 170, + ), + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context).secondaryBackground, + borderRadius: BorderRadius.circular(16), + ), + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB(14, 14, 14, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.187, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context).secondaryBackground, + ), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.187, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context).secondaryBackground, + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: + const EdgeInsetsDirectional.fromSTEB(0, 0, 0, 17), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.018, + constraints: const BoxConstraints( + minHeight: 20, + ), + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context) + .secondaryBackground, + ), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.018, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context) + .secondaryBackground, + ), + child: Align( + alignment: const AlignmentDirectional(0, 0), + child: Text( + // widget!.name, + "体验时间:${DateFormat("yyyy-MM-dd HH:mm").format(DateTime.fromMillisecondsSinceEpoch(int.parse("${bookExperienceListController.model.bookInfoList[index]["bookTimeStart"]}")))}", + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: const Color(0xFF182B7C), + fontSize: AppFontsize.title_size, + letterSpacing: 0, + ), + ), + ), + ), + ), + ), + Container( + width: MediaQuery.sizeOf(context).width, + height: 1.rpx, + decoration: const BoxDecoration( + color: Color(0xFFAAAFC0), + ), + ), + Padding( + padding: + const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.034, + constraints: const BoxConstraints( + minHeight: 55, + ), + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context) + .secondaryBackground, + ), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.034, + constraints: const BoxConstraints( + minHeight: 55, + ), + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context) + .secondaryBackground, + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + child: Align( + alignment: + const AlignmentDirectional(-1, 0), + child: Text( + '门店:${data["name"] ?? ""}', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: const Color(0xFF9EA4B7), + fontSize: + AppFontsize.small_text_size, + letterSpacing: 0, + ), + ), + ), + ), + Flexible( + child: Align( + alignment: + const AlignmentDirectional(-1, 0), + child: Text( + '地址:${data['addressDetail'] ?? ""}', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: const Color(0xFF9EA4B7), + fontSize: + AppFontsize.small_text_size, + letterSpacing: 0, + ), + ), + ), + ), + Flexible( + child: Align( + alignment: + const AlignmentDirectional(-1, 0), + child: Text( + '电话:${data["hotline"]} ', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: const Color(0xFF9EA4B7), + fontSize: + AppFontsize.small_text_size, + letterSpacing: 0, + ), + ), + ), + ), + ], + ), + ), + ), + ), + Padding( + padding: + const EdgeInsetsDirectional.fromSTEB(0, 4, 0, 0), + child: Container( + constraints: const BoxConstraints( + minHeight: 40, + ), + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.038, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context) + .secondaryBackground, + ), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 0.038, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context) + .secondaryBackground, + ), + child: // Generated code for this Row Widget... + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Flexible( + child: InkWell( + onTap: () { + if (data["hotline"] != null) { + MyUtils.makePhoneCall(data["hotline"]); + } + }, + child: Container( + width: MediaQuery.sizeOf(context).width * + 0.105, + height: + MediaQuery.sizeOf(context).height * + 0.038, + constraints: const BoxConstraints( + maxWidth: 50, + ), + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context) + .secondaryBackground, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + const Flexible( + child: Icon( + Icons.phone_in_talk, + color: Color(0xFFD3B684), + size: 12, + ), + ), + Text( + '咨询', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + // color: Color(0xFF9EA4B7), + color: + const Color(0xFF333333), + fontSize: AppFontsize + .small_text_size, + letterSpacing: 0, + ), + ), + ].divide(const SizedBox(width: 13)), + ), + ), + )), + Flexible( + child: InkWell( + onTap: () { + // AppMapLocation.checkInstalledApps() + // .then((d) { + // if (AppMapLocation + // .availableMapsToNames.isEmpty) { + // showToast("未检测到导航软件"); + // } else { + // showOneSelectionDialog(context, + // title: "选择地图", + // arr: AppMapLocation + // .availableMapsToNames, + // checkChange: (index) { + // AppMapLocation.launchMap( + // index, + // data["name"], + // double.parse( + // "${data["latitude"]}"), + // double.parse( + // "${data["longitude"]}")); + // }); + // } + // }); + }, + child: Container( + width: MediaQuery.sizeOf(context).width * + 0.105, + height: + MediaQuery.sizeOf(context).height * + 0.038, + constraints: const BoxConstraints( + maxWidth: 50, + ), + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context) + .secondaryBackground, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + const Flexible( + child: Icon( + Icons.location_on, + color: Color(0xFFD3B684), + size: 12, + ), + ), + Text( + '导航', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + // color: Color(0xFF9EA4B7), + color: + const Color(0xFF333333), + fontSize: AppFontsize + .small_text_size, + letterSpacing: 0, + ), + ), + ].divide(const SizedBox(width: 13)), + ), + ), + )), + Container( + width: + MediaQuery.sizeOf(context).width * 0.22, + height: MediaQuery.sizeOf(context).height * + 0.038, + constraints: const BoxConstraints( + maxWidth: 78, + maxHeight: 100, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + ), + child: FFButtonWidget( + onPressed: () { + // if (bookExperienceListController + // .model.bookInfoList[index] + // ["status"] == + // 2) { + // showCustomConfirmAndCancelDialog( + // context, "取消预约") + // .then((d) { + // if (d == "confirm") { + // bookExperienceListController + // .cancelBook( + // bookExperienceListController + // .model + // .bookInfoList[ + // index]["id"], + // success: () { + // var rd = jsonDecode(jsonEncode( + // bookExperienceListController + // .model + // .bookInfoList[index])); + // rd["status"] = -1; + // rd["addressDetail"] = + // data['addressDetail']; + // rd["name"] = data["name"]; + // bookExperienceListController + // .messageAdd(rd); + // }); + // } + // }); + // } + }, + text: bookExperienceListController + .model.bookInfoList[index] + ["status"] == + 2 + ? '取消预约' + : bookExperienceListController + .model.bookInfoList[index] + ["statusName"], + options: FFButtonOptions( + height: 40, + padding: const EdgeInsetsDirectional + .fromSTEB(13, 0, 13, 0), + iconPadding: const EdgeInsetsDirectional + .fromSTEB(0, 0, 0, 0), + color: bookExperienceListController + .model + .bookInfoList[index] + ["status"] == + 2 + ? const Color(0xFFD3B684) + : stringToColor("#D3D3D3"), + textStyle: FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: + AppFontsize.small_text_size, + letterSpacing: 0, + ), + elevation: 0, + borderSide: const BorderSide( + color: Colors.transparent, + width: 1, + ), + borderRadius: BorderRadius.circular(32), + ), + ), + ), + ].divide(const SizedBox(width: 26)), + )), + ), + ), + ], + ), + ), + ), + ), + ); + })); + } +} diff --git a/lib/pages/device_control/new_Home_page.dart b/lib/pages/device_control/new_Home_page.dart new file mode 100644 index 0000000..7198c9f --- /dev/null +++ b/lib/pages/device_control/new_Home_page.dart @@ -0,0 +1,854 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; + +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/controller/device/body_device_controller.dart'; +import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; +import 'package:vbvs_app/controller/mh/muser_info_controller.dart'; + + +class NewHomePage extends StatefulWidget { + const NewHomePage({super.key}); + @override + State createState() => _NewHomePageState(); +} + +class _NewHomePageState extends State { + MUserInfoController userInfoController = Get.find(); + BodyDeviceController deviceController = Get.find(); + double borderRadius = 16.rpx; + + var formFieldController = FormFieldController(null); + + get gloablController => Get.find(); + + // get userInfoController => Get.find(); + + var sleepDays = [].obs; + + var sleep_mac = "".obs; + + Map scoreColor = { + "-1": "#d3d3d3", + "1": "#4e8408", + "2": "#7bbb33", + "3": "#e15b8d", + "4": "#ff0000", + }; + + Map scoreName = { + "-1": "暂无", + "1": "优秀", + "2": "良好", + "3": "合格", + "4": "注意", + }; + + @override + void initState() { + super.initState(); + } + + getWeekName(int i) { + String v = ""; + switch (i) { + case 1: + v = "周一"; + break; + case 2: + v = "周二"; + break; + case 3: + v = "周三"; + break; + case 4: + v = "周四"; + break; + case 5: + v = "周五"; + break; + case 6: + v = "周六"; + break; + case 7: + v = "周日"; + break; + } + return v; + } + + @override + Widget build(BuildContext context) { + int login = userInfoController.model.login!; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + iconTheme: IconThemeData(color: themeController.currentColor.sc3), + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + titleSpacing: 0, + title: Row( + children: [ + // 左侧头像 + SizedBox(width: 40.rpx), + CircleAvatar( + radius: 27.rpx, // 可根据需求调整 + backgroundImage: login == 1 + ? (userInfoController.model.user!.avatar == null || + userInfoController.model.user!.avatar!.isEmpty + ? const AssetImage( + "assets/images/people_avatar.png", + ) + : NetworkImage( + userInfoController.model.user!.avatar!, + )) + : const AssetImage( + "assets/images/people_avatar.png", + ), + ), + SizedBox(width: 23.rpx), // 左侧头像和文本之间的间距 + Text( + 'Eason Chan', + style: TextStyle(fontSize: 30.rpx, color: Colors.white), + ), + + const Spacer(), // 左右分隔 + // Container( + // width: 61.rpx, + // height: 78.rpx, + // alignment: const Alignment(0, 0), + // child: Image.asset( + // "assets/images/xiaoe.png", + // fit: BoxFit.cover, + // ), + // ), + // SizedBox(width: 46.rpx), // icon 之间的间距 + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(right: 0), + onTap: () {}, + child: Container( + height: 60.rpx, + width: 75.rpx, + child: SvgPicture.asset( + 'assets/img/icon/xiaoe.svg', + // color: Colors.white, + ))), + + // SizedBox(width: 40.rpx), + ], + ), + centerTitle: false, + ), + body: SafeArea( + child: Container( + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1.123, + // decoration: BoxDecoration( + // color: AppColors.bg_color, + // image: DecorationImage( + // image: AssetImage("assets/images/background.png"), + // fit: BoxFit.cover, + // ), + // ), + decoration: BoxDecoration( + + ), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + padding: + EdgeInsets.fromLTRB(26.rpx, 10.rpx, 26.rpx, 40.rpx), + width: double.infinity, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 30.rpx), + child: Column( + children: [ + Padding( + padding: + EdgeInsets.fromLTRB(17.rpx, 30.rpx, 0, 0), + child: Row( + children: [ + Text('上海 22° 多云', + style: TextStyle( + fontSize: 26.rpx, + color: Colors.white)), + Icon(Icons.cloud, + size: 30.rpx, color: Colors.white), + ], + ), + ), + ], + ))), + Container( + padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx), + child: Column( + children: [ + if (gloablController.model.deviceList.length > 0) + Container( + child: Column( + children: [ + Container( + width: MediaQuery.sizeOf(context).width, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: + BorderRadius.circular(borderRadius), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: + EdgeInsetsDirectional.fromSTEB( + 30.rpx, + 16.rpx, + 16.rpx, + 8.rpx), + child: Container( + width: MediaQuery.sizeOf(context) + .width, + height: MediaQuery.sizeOf(context) + .height * + 0.065, + decoration: BoxDecoration( + color: + FlutterFlowTheme.of(context) + .secondaryBackground, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + ValueListenableBuilder( + valueListenable: + formFieldController, + builder: (c, a, s) => + FlutterFlowDropDown< + String>( + controller: + formFieldController, + options: gloablController + .model.JunheDevices + .map((d) => + "${d["mac"]}") + .toList(), + optionLabels: + gloablController + .model.JunheDevices + .map((d) { + var s = + d["name"] ?? d["mac"]; + if (s == null) { + return ""; + } else { + return "$s"; + } + }).toList(), + onChanged: (val) { + // print("$val"); + // if (val == null) { + // sleepDays.value = []; + // } else { + // getSleeps( + // formFieldController + // .value); + // } + // // sleep_mac.value = val!; + }, + width: 360.rpx, + height: 72.rpx, + maxHeight: 200.rpx, + textStyle: TextStyle( + fontSize: 28.rpx, + overflow: TextOverflow + .ellipsis), + hintText: '', + icon: Icon( + Icons + .keyboard_arrow_down_rounded, + color: + FlutterFlowTheme.of( + context) + .secondaryText, + size: 48.rpx, + ), + fillColor: stringToColor( + "#F3F5F6"), + elevation: 2, + borderColor: stringToColor( + "#F3F5F6"), + borderWidth: 2, + borderRadius: 18, + margin: + EdgeInsetsDirectional + .fromSTEB( + 32.rpx, + 8.rpx, + 32.rpx, + 8.rpx), + hidesUnderline: true, + isOverButton: false, + isSearchable: false, + isMultiSelect: false, + ), + ), + InkWell( + onTap: () { + // if (formFieldController + // .value != + // null) { + // Get.toNamed( + // "/sleepWebview", + // arguments: [ + // formFieldController + // .value + // ]); + // } + }, + child: Row( + mainAxisSize: + MainAxisSize.max, + children: [ + Text( + '睡眠报告', + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + fontSize: + 30.rpx), + ), + SizedBox( + width: 12.rpx, + ), + SvgPicture.asset( + "assets/images/table.svg", + width: 28.rpx, + height: 28.rpx), + SizedBox( + width: 20.rpx, + ), + ], + ), + ), + ], + ), + ), + ), + Container( + padding: EdgeInsets.only( + top: 0.rpx, + bottom: 20.rpx, + left: 16.rpx, + right: 16.rpx), + width: double.infinity, + decoration: BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + ...List.generate( + sleepDays.value.length, + (index) { + var day = sleepDays[index]; + return Expanded( + child: Container( + padding: EdgeInsets.only( + top: 10.rpx, + bottom: 20.rpx), + width: 100, + // decoration: BoxDecoration( + // color: index == 2 + // ? stringToColor("#F3F5F6") + // : Colors.white, + // borderRadius: + // BorderRadius.circular( + // borderRadius), + // ), + child: Column( + mainAxisSize: + MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment + .start, + crossAxisAlignment: + CrossAxisAlignment + .center, + children: [ + Text( + day['week'], + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + 30.rpx, + letterSpacing: + 0, + ), + ), + Text( + day['date'], + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + fontSize: + 24.rpx, + ), + ), + SizedBox( + height: 6.rpx, + ), + Column( + children: [ + Row( + mainAxisSize: + MainAxisSize + .max, + mainAxisAlignment: + MainAxisAlignment + .center, + children: [ + Text( + '${day['score'] ?? "-"}', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + 48.rpx, + letterSpacing: + 0, + ), + ), + if (day['score'] != + null) + SizedBox( + width: + 2.rpx, + ), + if (day['score'] != + null) + Text( + '分', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + letterSpacing: + 0, + fontSize: + 26.rpx, + ), + ), + ], + ), + Container( + width: 120.rpx, + height: 52.rpx, + decoration: + BoxDecoration( + color: stringToColor( + day['scoreColor'] ?? + "#f3f5f6"), + borderRadius: + BorderRadius + .circular( + 26.rpx), + shape: BoxShape + .rectangle, + ), + alignment: + Alignment + .center, + child: Text( + '${day['scoreType'] ?? "暂无"}', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: day['scoreType'] != + null + ? Colors + .white + : stringToColor( + "#ced1d7"), + letterSpacing: + 0, + fontSize: + 28.rpx, + ), + ), + ) + ], + ) + ], + ), + ), + ); + }) + ], + ), + ), + ], + ), + ), + ...List.generate( + gloablController.model.deviceList.length, + (index) { + var device = gloablController + .model.deviceList[index]; + String rname = device['roomName']; + if (index != 0) { + String lrname = gloablController.model + .deviceList[index - 1]["roomName"]; + if (lrname == rname) { + rname = ""; + } + } + return Column(children: [ + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 20.rpx, 20.rpx, 0, 0), + child: Container( + decoration: BoxDecoration(), + alignment: + AlignmentDirectional(-1, 0), + child: rname.isNotEmpty + ? Text( + "$rname", + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors.white, + fontSize: 32.rpx, + letterSpacing: 0, + ), + ) + : SizedBox( + height: 10.rpx, + ), + ), + ), + // getDeviceList(context, device) + ]); + }), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 40.rpx, 0, 100.rpx), + child: Container( + width: MediaQuery.sizeOf(context).width, + height: 84.rpx, + decoration: BoxDecoration(), + child: FFButtonWidget( + onPressed: () { + // print('Button pressed ...'); + // Get.toNamed("/homeDeviceType"); + }, + text: '添加新设备', + icon: Icon( + Icons.add, + size: 60.rpx, + ), + options: FFButtonOptions( + height: 80.rpx, + padding: + EdgeInsetsDirectional.fromSTEB( + 48.rpx, 0, 48.rpx, 0), + iconPadding: + EdgeInsetsDirectional.fromSTEB( + 0, 0, 0, 0), + color: stringToColor("#182B7C"), + textStyle: + FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + letterSpacing: 0, + fontSize: 30.rpx), + elevation: 3, + borderSide: BorderSide( + color: Colors.transparent, + width: 1, + ), + borderRadius: BorderRadius.circular( + borderRadius), + ), + ), + ), + ), + ], + ), + ), + if (gloablController.model.deviceList.length == 0) + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0, 0, 0, 80.rpx), + child: Container( + width: MediaQuery.sizeOf(context).width, + padding: EdgeInsets.only( + top: 90.rpx, bottom: 80.rpx), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: + BorderRadius.circular(borderRadius), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '检测到您当前暂无设备!', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 32.rpx, + letterSpacing: 0, + ), + ), + SizedBox( + height: + MediaQuery.sizeOf(context).height * + 0.037, + ), + Container( + width: MediaQuery.sizeOf(context).width * + 0.54, + height: 90.rpx, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context) + .secondaryBackground, + borderRadius: BorderRadius.circular(0), + ), + child: FFButtonWidget( + onPressed: () { + // print('Button pressed ...'); + Get.toNamed("/homeDeviceType"); + }, + text: '立即添加一台', + icon: Icon( + Icons.add, + color: FlutterFlowTheme.of(context) + .primaryText, + size: 60.rpx, + ), + options: FFButtonOptions( + iconPadding: + EdgeInsetsDirectional.fromSTEB( + 0, 0, 0, 0), + color: Colors.white, + textStyle: + FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: 'Readex Pro', + color: + FlutterFlowTheme.of( + context) + .primaryText, + letterSpacing: 0, + fontSize: 30.rpx), + elevation: 3, + borderSide: BorderSide( + color: Color(0xFFABB0C0), + width: 1, + ), + borderRadius: + BorderRadius.circular(45.rpx), + ), + ), + ), + ], + ), + ), + ), + ], + ), + ) + ], + ), + ), + ) + + // Padding( + // padding: EdgeInsets.symmetric(horizontal: 30.rpx), + // child: Column( + // children: [ + // Padding( + // padding: EdgeInsets.fromLTRB(17.rpx, 30.rpx, 0, 0), + // child: Row( + // children: [ + // Text('上海 22° 多云', + // style: TextStyle( + // fontSize: 26.rpx, color: Colors.white)), + // Icon(Icons.cloud, + // size: 30.rpx, color: Colors.white), + // ], + // ), + // ), + // ], + // )) + ), + ), + )); + } +} + +class ScoreItem { + final String weekday; // 如“周四” + final String dateStr; // 如“07/03” + final int score; + final bool isToday; + + ScoreItem({ + required this.weekday, + required this.dateStr, + required this.score, + this.isToday = false, + }); +} + +class ScoreCard extends StatelessWidget { + final String selectedUser; + final List scoreList; + final ValueChanged? onUserChanged; + final VoidCallback? onChartPressed; + + const ScoreCard({ + super.key, + required this.selectedUser, + required this.scoreList, + this.onUserChanged, + this.onChartPressed, + }); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + color: const Color(0xff0F2B44), + borderRadius: BorderRadius.circular(16), + ), + padding: const EdgeInsets.all(12), + child: Column( + children: [ + // 顶部用户选择 + 图标按钮 + Row( + children: [ + DropdownButtonHideUnderline( + child: DropdownButton( + value: selectedUser, + borderRadius: BorderRadius.circular(12), + dropdownColor: const Color(0xff0F2B44), + iconEnabledColor: Colors.white, + style: const TextStyle(color: Colors.white), + items: ['Eason Chan', 'Jay Chou', 'G.E.M.'] + .map((user) => DropdownMenuItem( + value: user, + child: Text(user), + )) + .toList(), + onChanged: onUserChanged, + ), + ), + const Spacer(), + IconButton( + onPressed: onChartPressed, + icon: const Icon(Icons.bar_chart, color: Colors.white), + ), + ], + ), + const SizedBox(height: 12), + // 日期+分数 横向滚动展示 + SizedBox( + height: 70, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: scoreList.length, + separatorBuilder: (_, __) => const SizedBox(width: 12), + itemBuilder: (context, index) { + final item = scoreList[index]; + final isToday = item.isToday; + + return Container( + padding: + const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + decoration: BoxDecoration( + color: isToday + ? Colors.white.withOpacity(0.1) + : Colors.transparent, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(item.weekday, + style: const TextStyle( + color: Colors.white70, fontSize: 12)), + Text(item.dateStr, + style: const TextStyle( + color: Colors.white54, fontSize: 10)), + const SizedBox(height: 4), + Text( + item.score.toString(), + style: TextStyle( + color: Colors.white, + fontWeight: + isToday ? FontWeight.bold : FontWeight.normal, + fontSize: 16, + ), + ), + ], + ), + ); + }, + ), + ) + ], + ), + ); + } +} diff --git a/lib/pages/device_control/new_message_page copy.dart b/lib/pages/device_control/new_message_page copy.dart new file mode 100644 index 0000000..445ae72 --- /dev/null +++ b/lib/pages/device_control/new_message_page copy.dart @@ -0,0 +1,304 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/color/app_uri_status.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/component/NullDataComponentWidget.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; +import 'package:vbvs_app/controller/message/message_controller.dart'; +import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; +import 'package:vbvs_app/pages/main_bottom/component/MessageWidgetWidget.dart'; + +class MessagePage extends StatefulWidget { + const MessagePage({super.key}); + + @override + State createState() => _MessagePageState(); +} + +class _MessagePageState extends State { + ThemeController themeController = Get.find(); + MessageController messageController = Get.find(); + late PageController _pageController; + + @override + void initState() { + super.initState(); + _pageController = + PageController(initialPage: messageController.model.type == 1 ? 0 : 1); + messageController.getMessageStatus(); + _fetchMessageData(); + } + + void _fetchMessageData() { + String type = messageController.model.type == 1 ? "app_vsm" : "app_system"; + messageController.updateMessageStatus(type: type); + messageController.getMessageList().then((response) { + if (response.code != HttpStatusCodes.ok) { + TopSlideNotification.show( + Get.context!, + text: response.msg ?? "服务器.失败".tr, + textColor: themeController.currentColor.sc9, + ); + } + }); + } + + void _onTabChanged(int index) { + messageController.model.type = index == 0 ? 1 : 2; + messageController.updateAll(); + _fetchMessageData(); + _pageController.animateToPage(index, + duration: const Duration(milliseconds: 300), curve: Curves.easeInOut); + } + + void _onPageChanged(int index) { + int newType = index == 0 ? 1 : 2; + if (messageController.model.type != newType) { + messageController.model.type = newType; + messageController.updateAll(); + _fetchMessageData(); + } + } + + @override + void dispose() { + _pageController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarIconBrightness: Brightness.light, + )); + + return LayoutBuilder( + builder: (context, boxConstraints) => GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/img/bgNoImg.png'), + fit: BoxFit.fill, + ), + ), + child: Scaffold( + appBar: AppBar( + backgroundColor: themeController.currentColor.sc17, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: themeController.currentColor.sc3), + toolbarHeight: 140.rpx, + titleSpacing: 0, + title: Padding( + padding: EdgeInsetsDirectional.fromSTEB(40.rpx, 0, 0, 0), + child: Container( + width: double.infinity, + height: 140.rpx, + child: Column( + children: [ + SizedBox(height: 40.rpx), + Expanded( + child: Stack( + alignment: Alignment.bottomLeft, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Obx(() { + return ClickableContainer( + padding: EdgeInsets.all(0), + backgroundColor: Colors.transparent, + highlightColor: + themeController.currentColor.sc21, + borderRadius: 8.rpx, + onTap: () => _onTabChanged(0), + child: Container( + width: 160.rpx, + alignment: Alignment.center, + child: Stack( + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Text( + '体征消息'.tr, + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Inter', + fontSize: AppConstants() + .title_text_fontSize, + color: + messageController + .model.type == + 2 + ? themeController + .currentColor.sc3 + : themeController + .currentColor.sc2, + ), + ), + Obx(() { + return messageController.model + .body_message_read == + 1 + ? Positioned( + top: -4, + right: -14, + child: Container( + width: 8, + height: 8, + decoration: + const BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + ), + ) + : const SizedBox.shrink(); + }), + ], + ), + ), + ); + }), + Obx(() { + return ClickableContainer( + padding: EdgeInsets.all(0), + backgroundColor: Colors.transparent, + highlightColor: + themeController.currentColor.sc21, + borderRadius: 8.rpx, + onTap: () => _onTabChanged(1), + child: Container( + width: 160.rpx, + alignment: Alignment.center, + child: Stack( + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Text( + '系统消息'.tr, + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Inter', + fontSize: AppConstants() + .title_text_fontSize, + color: + messageController + .model.type == + 1 + ? themeController + .currentColor.sc3 + : themeController + .currentColor.sc2, + ), + ), + Obx(() { + return messageController.model + .system_message_read == + 1 + ? Positioned( + top: -4, + right: -14, + child: Container( + width: 8, + height: 8, + decoration: + const BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + ), + ) + : const SizedBox.shrink(); + }), + ], + ), + ), + ); + }), + ].divide(SizedBox(width: 10.rpx)), + ), + Obx(() { + double lineWidth = 170.rpx; + return AnimatedPositioned( + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + bottom: 0, + left: messageController.model.type == 1 + ? 0 + : 170.rpx, + child: Container( + width: lineWidth, + height: 4.rpx, + decoration: BoxDecoration( + color: themeController.currentColor.sc2, + borderRadius: BorderRadius.circular(2.rpx), + ), + ), + ); + }), + ], + ), + ), + SizedBox(height: 17.rpx), + ], + ), + ), + ), + actions: const [], + centerTitle: false, + ), + backgroundColor: Colors.transparent, + body: SafeArea( + top: true, + child: PageView( + controller: _pageController, + onPageChanged: _onPageChanged, + children: [ + Obx(() { + final list = messageController.messageList.value; + return list.isEmpty + ? const NullDataWidget() + : _buildMessageListView(list); + }), + Obx(() { + final list = messageController.messageList.value; + return list.isEmpty + ? const NullDataWidget() + : _buildMessageListView(list); + }), + ], + ), + ), + ), + ), + ), + ); + } + + Widget _buildMessageListView(List dataList) { + return Container( + width: double.infinity, + padding: EdgeInsets.symmetric(horizontal: 30.rpx), + child: SingleChildScrollView( + child: Column( + children: [ + SizedBox(height: 30.rpx), + ...dataList + .map((item) => MessageWidgetWidget(data: item)) + .toList() + .divide(SizedBox(height: 30.rpx)), + SizedBox(height: 30.rpx), + ], + ), + ), + ); + } +} diff --git a/lib/pages/device_control/new_mine_page.dart b/lib/pages/device_control/new_mine_page.dart new file mode 100644 index 0000000..d687b1b --- /dev/null +++ b/lib/pages/device_control/new_mine_page.dart @@ -0,0 +1,416 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; +import 'package:vbvs_app/controller/mh/muser_info_controller.dart'; +import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; + +import 'package:vbvs_app/enum/LoginStatus.dart'; + +class NewMinePage extends StatefulWidget { + const NewMinePage({super.key}); + + @override + State createState() => _MinePageState(); +} + +class _MinePageState extends State { + GlobalController globalController = Get.find(); + MUserInfoController userInfoController = Get.find(); + ThemeController themeController = Get.find(); + final GlobalKey _textKey = GlobalKey(); + + double _textHalfWidth = 0; + @override + void initState() { + super.initState(); + _calculateTextHalfWidth('Eason Chan'); + } + + void _calculateTextHalfWidth(String text) { + final textSpan = TextSpan( + text: text, + style: TextStyle( + fontSize: 30.rpx, + height: 1, + ), + ); + final textPainter = TextPainter( + text: textSpan, + textDirection: TextDirection.ltr, + ); + textPainter.layout(); // 计算文本宽度 + setState(() { + _textHalfWidth = textPainter.width / 2; + }); + } + + @override + Widget build(BuildContext context) { + SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, // 这里设置你希望的颜色 + statusBarIconBrightness: Brightness.light, // 状态栏图标的亮度 + )); + int login = userInfoController.model.login!; + return LayoutBuilder( + builder: (context, bodySize) => GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + actions: [ + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(right: 38.rpx), + onTap: () { + // if (userInfoController.model.login == + // LoginStatus.LOGIN.code) { + // TopSlideNotification.show( + // context, + // text: "待开发功能".tr, + // ); + // } else { + // TopSlideNotification.show( + // context, + // text: "必须登录提示".tr, + // textColor: themeController.currentColor.sc9, + // ); + // Get.toNamed("/loginPage"); + // } + Get.toNamed('/messagePage'); + }, + child: Container( + height: 42.rpx, + width: 42.rpx, + child: SvgPicture.asset( + 'assets/img/icon/message.svg', + color: Colors.white, + // color: Colors.white, + ))), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(right: 11.rpx), + onTap: () { + Get.toNamed("/peopleInfoPage"); + }, + child: Container( + height: 42.rpx, + width: 42.rpx, + child: SvgPicture.asset( + 'assets/img/icon/people_info.svg', + color: Colors.white, + ))), + ], + ), + body: SafeArea( + top: true, + child: Container( + height: bodySize.maxHeight, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: EdgeInsetsDirectional.only(top: 30.rpx), + child: Container( + width: 120.rpx, + height: 120.rpx, + clipBehavior: Clip.antiAlias, + decoration: const BoxDecoration( + shape: BoxShape.circle, + ), + child: login == 1 + ? (userInfoController.model.user!.avatar == null || + userInfoController + .model.user!.avatar!.isEmpty + ? Image.asset( + "assets/images/people_avatar.png", + fit: BoxFit.cover, + ) + : Image.network( + userInfoController.model.user!.avatar!, + fit: BoxFit.cover, + )) + : Image.asset( + "assets/images/people_avatar.png", + fit: BoxFit.cover, + ), + ), + ), + Padding( + padding: EdgeInsetsDirectional.only(top: 19.rpx), + child: Container( + width: double.infinity, + decoration: const BoxDecoration(), + child: Stack( + alignment: Alignment.center, // 使子组件在Stack中居中 + children: [ + Container( + // width: 194.rpx, + height: 63.rpx, + child: Column( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: + CrossAxisAlignment.center, // 文字水平居中 + children: [ + Text( + 'Eason Chan', + style: TextStyle( + fontSize: 30.rpx, + color: Colors.white, + height: 1), + ), + Text( + '135****2598', + style: TextStyle( + fontSize: 26.rpx, + color: const Color(0XFF929699), + height: 1), + ), + ], + ), + ), + Positioned( + left: MediaQuery.of(context).size.width / 2 + + _textHalfWidth + + 30.rpx, + top: -10.rpx, + child: ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: const Color(0xFF055466), + padding: EdgeInsets.zero, + onTap: () { + Get.toNamed("/editUserInfoPage"); + }, + child: Container( + width: 42.rpx, + height: 42.rpx, + alignment: Alignment.center, + child: SvgPicture.asset( + 'assets/images/edit.svg', + color: Colors.white, + width: 18.rpx, + height: 18.rpx, + ), + )), + ), + ], + ), + ), + ), + + Container( + margin: EdgeInsets.only( + left: 60.rpx, right: 60.rpx, top: 94.rpx), + child: Text( + '对已绑定的智能设备进行个性化配置,以获得更好的体验,', + style: TextStyle( + fontSize: 26.rpx, + color: const Color(0XFF929699), + height: 1), + )), + Padding( + padding: EdgeInsets.only(top: 46.rpx, bottom: 109.rpx), + child: ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + backgroundColor: const Color(0XFF85F5FF), + side: const BorderSide(color: Color(0XFF74DAE5)), + // foregroundColor: Colors.cyanAccent, + minimumSize: Size(260.rpx, 60.rpx), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + ), + child: Text( + '我的智能床', + style: TextStyle( + fontSize: 26.rpx, color: const Color(0xFF003058)), + ), + ), + ), + // 使用 Expanded 让滚动区域占据可用空间 + // SizedBox(height: 109.rpx), + Expanded( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.transparent, + ), + child: SingleChildScrollView( + // 直接使用 SingleChildScrollView + child: Column( + children: [ + _buildListTile( + Icons.receipt_long, '我的订单', '快捷查看我在网上的订单记录', + showTopLine: true), + _buildListTile(Icons.store_mall_directory, '门店体验', + '如果想免费体验智能设备,可在此进行提前预约', + path: "/experienceStorePage"), + _buildListTile( + Icons.build, + '设备报修', + '当您的智能设备需要报修时,可以通过该功能联系解决', + path: '/deviceRepairPage', + ), + _buildListTile( + Icons.shopping_cart, '网上商城', '最新的智能产品线上购买服务'), + _buildListTile( + Icons.location_on, '地址管理', '用于收货和报修时联系您', + path: "/addressListPage"), + _buildListTile(Icons.help_outline, '问题与帮助', + '常见的问题汇总,如:智能床连接流程、如何查看睡眠报告', + path: "/issueListpage"), + _buildListTile( + Icons.headset_mic, + '在线客服', + '购买和使用智能床过程中,如果遇到疑问可与客服进行联系', + ), + ], + ), + ), + ), + ), // 使用 Expanded 让滚动区域占据可用空间 + Padding( + padding: + EdgeInsets.fromLTRB(30.rpx, 24.rpx, 30.rpx, 50.rpx), + child: _buildSettingButton(), + ), + ], + ), + // Column( + // mainAxisSize: MainAxisSize.max, + // children: [ + + // ], + // ), + ), + ), + ), + ), + ), + ); + } + + /// 构建列表项(带分隔线) + Widget _buildListTile( + IconData icon, + String title, + String subtitle, { + // VoidCallback? onTap, + String? path, + bool showTopLine = false, + }) { + return ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.white, + padding: EdgeInsets.all(0.rpx), + onTap: () { + Get.toNamed(path!); + }, + child: Container( + decoration: BoxDecoration( + border: Border( + top: showTopLine + ? BorderSide(color: Color(0xFF929699), width: 2.rpx) + : BorderSide.none, + bottom: BorderSide(color: Color(0xFF929699), width: 2.rpx), + ), + ), + height: 116.rpx, + child: Padding( + padding: EdgeInsets.fromLTRB(40.rpx, 0.rpx, 40.rpx, 0.rpx), + child: Row( + children: [ + Icon(icon, color: const Color(0xFF85F5FF), size: 28.rpx), + SizedBox(width: 30.rpx), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, // 垂直方向居中对齐 + children: [ + Text( + title, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // SizedBox(height: 6.rpx), // 加点间距 + Text( + subtitle, + style: TextStyle( + color: Color(0xFF929699), + fontSize: 20.rpx, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + softWrap: true, // 允许换行 + ), + ], + ), + ), + ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Colors.transparent, + padding: EdgeInsets.only(right: 0), + onTap: () {}, + child: Container( + height: 30.rpx, + width: 30.rpx, + child: SvgPicture.asset( + 'assets/img/icon/expand.svg', + color: Colors.white, + ) + // Icon( + // Icons.arrow_forward_ios, + // color: Colors.white, + // // size: 14.rpx, + // ), + )), + ], + ), + ), + )); + } + + Widget _buildSettingButton() { + return Container( + width: double.infinity, + height: MediaQuery.sizeOf(context).height * 0.055, + constraints: BoxConstraints( + minHeight: 90.rpx, + ), + child: ElevatedButton( + onPressed: () { + Get.toNamed("/settingPage"); + }, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF04345E), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.rpx)), + ), + child: + Text('设置', style: TextStyle(fontSize: 26.rpx, color: Colors.white)), + ), + ); + } +} diff --git a/lib/pages/device_control/new_settingPage.dart b/lib/pages/device_control/new_settingPage.dart new file mode 100644 index 0000000..1906e4f --- /dev/null +++ b/lib/pages/device_control/new_settingPage.dart @@ -0,0 +1,618 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/component/tool/CustomCard.dart'; +import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; + +class SettingPage extends StatefulWidget { + @override + _SettingPageState createState() => _SettingPageState(); +} + +class _SettingPageState extends State { + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, bodySize) { + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + titleSpacing: 0, + automaticallyImplyLeading: false, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '设置', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 25.rpx, 0.rpx, 0), + child: Container( + width: double.infinity, + decoration: BoxDecoration( + color: Color(0xFF003058), + borderRadius: BorderRadius.circular( + AppConstants().normal_container_radius), + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 0, 0.rpx, 0), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + ClickableContainer( + backgroundColor: + Colors.transparent, // 容器背景色 + highlightColor: themeController + .currentColor.sc21, // 点击时的背景色 + padding: EdgeInsetsDirectional.fromSTEB( + 40.rpx, 0.rpx, 40.rpx, 0.rpx), + onTap: () { + TopSlideNotification.show(context, + text: "待开发功能".tr); + }, + child: Container( + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 30.rpx, 0.rpx, 30.rpx), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Text('修改密码', + style: TextStyle( + fontSize: 30.rpx, + color: Colors.white, + height: 1)), + ].divide(SizedBox(width: 22.rpx)), + ), + SvgPicture.asset( + 'assets/img/icon/arrow_right.svg', + width: 8.rpx, + height: 15 + .rpx, // 如果 SVG 中没有固定颜色,可以这样设置 + color: themeController + .currentColor.sc3, + ), + // Row( + // mainAxisSize: MainAxisSize.max, + // children: [ + // Text( + // '深色', + // style: FlutterFlowTheme.of( + // context) + // .bodyMedium + // .override( + // fontFamily: 'Inter', + // color: + // Color(0xFFD9E3EB), + // fontSize: 26.rpx, + // letterSpacing: 0.0, + // ), + // ), + + // ].divide(SizedBox(width: 28.rpx)), + // ), + ], + ), + ), + ), + ), + ClickableContainer( + backgroundColor: + Colors.transparent, // 容器背景色 + highlightColor: themeController + .currentColor.sc21, // 点击时的背景色 + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 0.rpx, 0.rpx, 0.rpx), + onTap: () { + print('点击了容器'); + Get.toNamed("/aboutUsPage"); + }, + child: Container( + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 40.rpx, 30.rpx, 40.rpx, 30.rpx), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Text( + '当前版本', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: 'Inter', + color: Colors.white, + fontSize: AppConstants() + .title_text_fontSize, + letterSpacing: 0.0, + lineHeight: 1.0, + ), + ), + ].divide(SizedBox(width: 22.rpx)), + ), + Text('SWES3.513.4', + style: TextStyle( + color: Colors.white, + fontSize: 26.rpx, + height: 1)), + // SvgPicture.asset( + // 'assets/img/icon/arrow_right.svg', + // width: 8.rpx, + // height: 14 + // .rpx, // 如果 SVG 中没有固定颜色,可以这样设置 + // color: themeController + // .currentColor.sc3, + // ), + ], + ), + ), + ), + ), + ClickableContainer( + backgroundColor: + Colors.transparent, // 容器背景色 + highlightColor: themeController + .currentColor.sc21, // 点击时的背景色 + padding: EdgeInsetsDirectional.fromSTEB( + 40.rpx, 0.rpx, 40.rpx, 0.rpx), + onTap: () { + // TopSlideNotification.show(context, + // text: "待开发功能".tr); + Get.toNamed("/languagePage"); + }, + child: Container( + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 30.rpx, 0.rpx, 30.rpx), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Text( + '切换语言', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: 'Inter', + color: Colors.white, + fontSize: AppConstants() + .title_text_fontSize, + letterSpacing: 0.0, + lineHeight: 1.0), + ), + ].divide(SizedBox(width: 22.rpx)), + ), + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Obx(() { + return Text( + languageController + .selectLanguage + .value! + .language_name!, + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: 'Inter', + color: + Color(0xFFD9E3EB), + fontSize: 26.rpx, + letterSpacing: 0.0, + lineHeight: 1.0, + ), + ); + }), + + // SvgPicture.asset( + // 'assets/img/icon/arrow_right.svg', + // width: 8.rpx, + // height: 15 + // .rpx, // 如果 SVG 中没有固定颜色,可以这样设置 + // color: themeController + // .currentColor.sc3, + // ), + ].divide(SizedBox(width: 28.rpx)), + ), + ], + ), + ), + ), + ), + ClickableContainer( + backgroundColor: + Colors.transparent, // 容器背景色 + highlightColor: themeController + .currentColor.sc21, // 点击时的背景色 + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 0.rpx, 0.rpx, 0.rpx), + onTap: () { + print('点击了容器'); + Get.toNamed("/aboutUsPage"); + }, + child: Container( + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 40.rpx, 30.rpx, 40.rpx, 30.rpx), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Text( + '设置页.关于我们'.tr, + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: 'Inter', + color: Colors.white, + fontSize: AppConstants() + .title_text_fontSize, + letterSpacing: 0.0, + lineHeight: 1.0, + ), + ), + ].divide(SizedBox(width: 22.rpx)), + ), + SvgPicture.asset( + 'assets/img/icon/arrow_right.svg', + width: 8.rpx, + height: 14 + .rpx, // 如果 SVG 中没有固定颜色,可以这样设置 + color: themeController + .currentColor.sc3, + ), + ], + ), + ), + ), + ), + ClickableContainer( + backgroundColor: + Colors.transparent, // 容器背景色 + highlightColor: themeController + .currentColor.sc21, // 点击时的背景色 + padding: EdgeInsetsDirectional.fromSTEB( + 40.rpx, 0.rpx, 40.rpx, 0.rpx), + onTap: () { + TopSlideNotification.show(context, + text: "待开发功能".tr); + }, + child: Container( + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 30.rpx, 0.rpx, 30.rpx), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Text( + '设置页.用户协议'.tr, + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: 'Inter', + color: Colors.white, + fontSize: AppConstants() + .title_text_fontSize, + letterSpacing: 0.0, + lineHeight: 1.0, + ), + ), + ].divide(SizedBox(width: 22.rpx)), + ), + SvgPicture.asset( + 'assets/img/icon/arrow_right.svg', + width: 8.rpx, + height: 15 + .rpx, // 如果 SVG 中没有固定颜色,可以这样设置 + color: themeController + .currentColor.sc3, + ), + ], + ), + ), + ), + ), + ClickableContainer( + backgroundColor: + Colors.transparent, // 容器背景色 + highlightColor: themeController + .currentColor.sc21, // 点击时的背景色 + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 0.rpx, 0.rpx, 0.rpx), + onTap: () { + TopSlideNotification.show(context, + text: "待开发功能".tr); + }, + child: Container( + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 40.rpx, 30.rpx, 40.rpx, 30.rpx), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Text( + '设置页.隐私协议'.tr, + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: 'Inter', + color: Colors.white, + fontSize: AppConstants() + .title_text_fontSize, + letterSpacing: 0.0, + lineHeight: 1.0, + ), + ), + ].divide(SizedBox(width: 22.rpx)), + ), + SvgPicture.asset( + 'assets/img/icon/arrow_right.svg', + width: 8.rpx, + height: 14 + .rpx, // 如果 SVG 中没有固定颜色,可以这样设置 + color: themeController + .currentColor.sc3, + ), + ], + ), + ), + ), + ), + ] + .divide(SizedBox(height: 0.rpx)) + .addToStart(SizedBox(height: 30.rpx)) + .addToEnd(SizedBox(height: 30.rpx)), + ), + ), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 174.rpx, 0.rpx, 0), + child: CustomCard( + borderRadius: 16.rpx, + + // 圆角半径 + onTap: () { + // ApiResponse apiResponse = + // userInfoController.logOut(); + // TopSlideNotification.show( + // context, + // text: apiResponse.msg!, + // textColor: + // apiResponse.code == HttpStatusCodes.ok + // ? themeController.currentColor.sc2 + // : themeController.currentColor.sc9, + // ); + // if (apiResponse.code == HttpStatusCodes.ok) { + // Get.offAllNamed("/mianPageBottomChange"); + // } + }, + colors: [ + Color(0XFF84F5FF), + ], // 渐变色是同一个色,也可以根据需要调整 + child: Container( + width: + // MediaQuery.sizeOf(context).width * 0.66, + bodySize.maxWidth, + height: MediaQuery.sizeOf(context).height * 0.055, + constraints: BoxConstraints( + minWidth: 500.rpx, + minHeight: 90.rpx, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '设置页.退出登录'.tr, + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + color: Color(0xFF003058), + fontFamily: 'Inter', + fontSize: AppConstants() + .normal_text_fontSize, + letterSpacing: 0.0, + ), + ), + ].divide(SizedBox( + width: 17.rpx, + )), + ), + ), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 100.rpx, 20.rpx, 100.rpx, 0), + child: CustomCard( + borderRadius: + AppConstants().button_container_radius, // 圆角半径 + onTap: () { + TopSlideNotification.show( + context, + text: "待开发功能".tr, + ); + }, + colors: [ + Colors.transparent, + ], // 渐变色是同一个色,也可以根据需要调整 + child: Container( + width: + // MediaQuery.sizeOf(context).width * 0.66, + bodySize.maxWidth, + height: MediaQuery.sizeOf(context).height * 0.055, + constraints: BoxConstraints( + minWidth: 500.rpx, + minHeight: 90.rpx, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '设置页.注销账号'.tr, + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + color: + themeController.currentColor.sc9, + fontFamily: 'Inter', + fontSize: AppConstants() + .normal_text_fontSize, + letterSpacing: 0.0, + ), + ), + ].divide(SizedBox( + width: 17.rpx, + )), + ), + ), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 135.rpx, 0.rpx, 0), + child: ClickableContainer( + borderRadius: + AppConstants().button_container_radius, // 圆角半径 + onTap: () {}, + backgroundColor: + Colors.transparent, // 渐变色是同一个色,也可以根据需要调整 + highlightColor: themeController.currentColor.sc5, + padding: EdgeInsetsDirectional.fromSTEB( + 0.rpx, 0.rpx, 0.rpx, 0), + child: Container( + width: + // MediaQuery.sizeOf(context).width * 0.66, + bodySize.maxWidth, + height: MediaQuery.sizeOf(context).height * 0.055, + constraints: BoxConstraints( + minWidth: 500.rpx, + minHeight: 90.rpx, + ), + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'ICP备案号:浙ICP备2023000785号-1'.tr, + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + color: themeController + .currentColor.sc4, + fontFamily: 'Inter', + fontSize: AppConstants() + .smaller_text_fontSize, + letterSpacing: 0.0, + ), + ), + Text( + 'Copyright © 202-2025 嘉兴太和信息技术有限责任公司 版权所有' + .tr, + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + color: themeController + .currentColor.sc4, + fontFamily: 'Inter', + fontSize: AppConstants() + .smaller_text_fontSize, + letterSpacing: 0.0, + ), + ), + ].divide(SizedBox( + height: 17.rpx, + ))), + ), + ), + ), + ], + ), + ), + ), + ), + )), + ); + }); + } +} diff --git a/lib/pages/device_control/people_info.dart b/lib/pages/device_control/people_info.dart new file mode 100644 index 0000000..6b1bbce --- /dev/null +++ b/lib/pages/device_control/people_info.dart @@ -0,0 +1,815 @@ +import 'dart:async'; + +import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart'; +import 'package:ef/ef.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/CustomCard.dart'; +import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; +import 'package:vbvs_app/controller/mh/people_info_controller.dart'; +import 'package:vbvs_app/pages/common/selectDialog.dart'; + +class PeopleInfoPage extends StatefulWidget { + const PeopleInfoPage({super.key}); + + @override + State createState() => _PeopleInfoState(); +} + +class _PeopleInfoState extends State { + get controller => Get.find(); + + get glcontroller => Get.find(); + + // @override + // void initState() { + // super.initState(); + // Timer(const Duration(milliseconds: 100), () { + // controller.getPeoples(); + // }); + // } + + getLine() { + return Container( + height: 1, + color: stringToColor("#152676"), + ); + } + + @override + Widget build(BuildContext context) { + return LayoutBuilder( + builder: (context, boxConstraints) => GestureDetector( + // onTap: () => FocusScope.of(context).unfocus(), + onTap: () { + // 触摸收起键盘 + FocusScope.of(context).requestFocus(FocusNode()); + }, + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: Colors.white), + titleSpacing: 0, + title: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '人员资料', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + Positioned( + right: 30.rpx, + child: CustomCard( + borderRadius: 10, + gradientDirection: GradientDirection.vertical, + onTap: () { + // bool isOk = true; + // for (var i = 0; i < 2; i++) { + // var d = controller.model.peopleList[i]; + // print("${d.toJson()}"); + // String before = "人员信息${i == 0 ? "A" : "B"}:"; + // if (isOk && + // d.height != null && + // d.height != "" && + // int.tryParse("${d.height}") == null) { + // showToast("$before身高请输入数字"); + // isOk = false; + // } + // if (isOk && + // d.weight != null && + // d.weight != "" && + // int.tryParse("${d.weight}") == null) { + // showToast("$before体重请输入数字"); + // isOk = false; + // } + // if (isOk && + // d.tel != null && + // d.tel != "" && + // MyUtils.isValidPhoneNumber("${d.tel}") == + // false) { + // showToast("$before请输入正确的电话"); + // isOk = false; + // } + // if (isOk && + // d.emergencyContact != null && + // d.emergencyContact != "" && + // MyUtils.isValidPhoneNumber( + // "${d.emergencyContact}") == + // false) { + // showToast("$before请输入正确的紧急联系人电话"); + // isOk = false; + // } + // if (isOk) { + // controller.savePeoples().then((d) { + // showToast("保存成功", color: color_success); + // }).catchError((d) { + // print("$d"); + // showToast("保存失败"); + // }); + // } + // } + // controller.model.peopleList.forEach((d) {}); + }, + colors: const [ + Color(0xFFFCFCFC), + Color(0xFFF8FAF9), + Color(0XFFECF6F3), + Color(0XFFD9F0E9), + Color(0xFFCEECE3) + ], + child: Container( + width: 120.rpx, + height: 60.rpx, + alignment: Alignment.center, + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(5), + // color: stringToColor("#182B7C"), + // ), + child: Text( + "保存", + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: stringToColor("#9EA4B7"), + letterSpacing: 0, + fontSize: 30.rpx, + ), + ), + ), + )) + ], + ), + ), + actions: [], + centerTitle: false, + ), + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Container( + padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx), + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1.123, + // decoration: BoxDecoration( + // color: Colors.transparent, + // image: DecorationImage( + // image: AssetImage("assets/images/background.png"), + // fit: BoxFit.cover, + // ), + // ), + child: SingleChildScrollView( + child: Column( + children: [ + ...List.generate( + "${glcontroller.model.deviceMain["bindMacB"]}" + .length > + 6 + ? 2 + : 1, (index) { + String location_ = ""; + if ("${glcontroller.model.deviceMain["bindMacB"]}" + .length > + 6 && + (glcontroller.model.mainDevicePeople[0] + ?["direction"] == + 1 || + glcontroller.model.mainDevicePeople[1] + ?["direction"] == + 1)) { + location_ = + "${glcontroller.model.mainDevicePeople[index]?["direction"] == 1 ? '左侧' : '右侧'}"; + } + return Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only( + top: index == 0 ? 30.rpx : 90.rpx, + bottom: 20.rpx), + child: Text( + "人员信息${index == 0 ? "A" : "B"}", + style: TextStyle( + color: Colors.white, fontSize: 30.rpx), + ), + ), + Container( + padding: + EdgeInsets.only(left: 30.rpx, right: 30.rpx), + child: Column( + children: [ + if (location_.isNotEmpty) + Container( + width: double.infinity, + height: + MediaQuery.sizeOf(context).height * + 0.064, + decoration: BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '校准位置', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + Text( + '$location_', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + ], + ), + ), + getLine(), + Container( + width: double.infinity, + height: MediaQuery.sizeOf(context).height * + 0.064, + decoration: BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '性名', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + Container( + width: 300.rpx, + child: TextField( + obscureText: false, + textAlign: TextAlign.right, + style: TextStyle( + fontSize: 30.rpx, + color: Colors.white), + decoration: const InputDecoration( + fillColor: Colors.transparent, + filled: true, + hintText: "请输入姓名", + hintStyle: TextStyle( + color: Colors.white), + border: InputBorder.none, + contentPadding: + EdgeInsets.all(0)), + onChanged: (value) { + controller.model.peopleList[index] + .name = value; + controller.updateAll(); + }, + controller: controller.onReDraw( + TextEditingController( + text: controller + .model + .peopleList[index] + .name ?? + ""), + (textEditingController) { + textEditingController.text = + controller + .model + .peopleList[index] + .name ?? + ""; + }, "people_name_$index"), + ), + ), + ], + ), + ), + getLine(), + Obx( + () => Container( + width: double.infinity, + height: + MediaQuery.sizeOf(context).height * + 0.064, + decoration: BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '性别', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + InkWell( + onTap: () { + // 触摸收起键盘 + FocusScope.of(context) + .requestFocus(FocusNode()); + Future.delayed( + const Duration( + milliseconds: 250), () { + // 延迟执行的代码 + showOneSelectionDialog(context, + arr: ["女", "男"], + checkIndex: controller + .model + .peopleList[ + index] + .sex == + "女" + ? 0 + : 1, + checkChange: (sindex) { + controller + .model + .peopleList[index] + .sex = + (sindex == 0 ? '女' : '男'); + controller.updateAll(); + print("sex $sindex"); + }).then((d) { + // Timer(Duration.zero, () { + // FocusScope.of(context).unfocus(); + // }); + }); + }); + }, + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + width: 200.rpx, + child: Text( + '${controller.model.peopleList[index].sex}', + textAlign: TextAlign.right, + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + ), + SizedBox( + width: 16.rpx, + ), + Icon( + Icons.expand_more, + color: Colors.white, + size: 48.rpx, + ), + ], + ), + ), + ], + ), + ), + ), + getLine(), + Container( + width: double.infinity, + height: MediaQuery.sizeOf(context).height * + 0.064, + decoration: BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '身高(cm)', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + Container( + width: 300.rpx, + child: TextField( + obscureText: false, + keyboardType: TextInputType.number, + textInputAction: + TextInputAction.done, + textAlign: TextAlign.right, + style: TextStyle( + fontSize: 30.rpx, + color: Colors.white), + decoration: InputDecoration( + fillColor: Colors.transparent, + filled: true, + hintText: "请输入身高(厘米)", + hintStyle: TextStyle( + color: Colors.white), + border: InputBorder.none, + contentPadding: + EdgeInsets.all(0)), + onChanged: (value) { + controller.model.peopleList[index] + .height = value; + controller.updateAll(); + }, + controller: controller.onReDraw( + TextEditingController( + text: controller + .model + .peopleList[index] + .height ?? + ""), + (textEditingController) { + textEditingController.text = + controller + .model + .peopleList[index] + .height ?? + ""; + }, "people_height_$index"), + ), + ) + ], + ), + ), + getLine(), + Container( + width: double.infinity, + height: MediaQuery.sizeOf(context).height * + 0.064, + decoration: BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '体重(kg)', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + Container( + width: 300.rpx, + child: TextField( + obscureText: false, + keyboardType: TextInputType.number, + textInputAction: + TextInputAction.done, + textAlign: TextAlign.right, + style: TextStyle( + fontSize: 30.rpx, + color: Colors.white), + decoration: InputDecoration( + fillColor: Colors.transparent, + filled: true, + hintText: "请输入体重(公斤)", + hintStyle: TextStyle( + color: Colors.white), + border: InputBorder.none, + contentPadding: + EdgeInsets.all(0)), + onChanged: (value) { + controller.model.peopleList[index] + .weight = value; + controller.updateAll(); + }, + controller: controller.onReDraw( + TextEditingController( + text: controller + .model + .peopleList[index] + .weight ?? + ""), + (textEditingController) { + textEditingController.text = + controller + .model + .peopleList[index] + .weight ?? + ""; + }, "people_weight_$index"), + ), + ), + ], + ), + ), + getLine(), + Obx( + () => Container( + width: double.infinity, + height: + MediaQuery.sizeOf(context).height * + 0.064, + decoration: BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '生日', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + InkWell( + onTap: () { + // 触摸收起键盘 + FocusScope.of(context) + .requestFocus(FocusNode()); + Future.delayed( + const Duration( + milliseconds: 250), () { + // 延迟执行的代码 + showDateSelectionDialog(context, + checkDate: controller + .model + .peopleList[index] + .birthday ?? + DateTime.now(), + checkChange: (DateTime d) { + controller + .model + .peopleList[index] + .birthday = d; + controller.updateAll(); + print("$d"); + }).then((d) { + // Timer(Duration.zero, () { + // FocusScope.of(context).unfocus(); + // }); + }); + }); + }, + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + constraints: BoxConstraints( + minWidth: 200.rpx), + child: Text( + controller + .model + .peopleList[ + index] + .birthday != + null + ? DateFormat( + "yyyy年MM月dd日") + .format(controller + .model + .peopleList[ + index] + .birthday!) + : '', + textAlign: TextAlign.right, + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + ), + SizedBox( + width: 16.rpx, + ), + Icon( + Icons.expand_more, + color: Colors.white, + size: 48.rpx, + ), + ], + ), + ), + ], + ), + ), + ), + // getLine(), + // Container( + // width: double.infinity, + // height: MediaQuery.sizeOf(context).height * + // 0.064, + // decoration: BoxDecoration(), + // child: Row( + // mainAxisSize: MainAxisSize.max, + // mainAxisAlignment: + // MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // '电话', + // style: FlutterFlowTheme.of(context) + // .bodyMedium + // .override( + // fontFamily: 'Readex Pro', + // color: Color(0xFF9EA4B7), + // fontSize: 30.rpx, + // letterSpacing: 0, + // ), + // ), + // Container( + // width: 300.rpx, + // child: TextField( + // obscureText: false, + // keyboardType: TextInputType.number, + // textInputAction: + // TextInputAction.done, + // textAlign: TextAlign.right, + // style: TextStyle( + // fontSize: 30.rpx, + // color: Colors.white), + // decoration: InputDecoration( + // fillColor: Colors.transparent, + // filled: true, + // hintText: "请输入电话", + // hintStyle: TextStyle( + // color: Colors.white), + // border: InputBorder.none, + // contentPadding: + // EdgeInsets.all(0)), + // onChanged: (value) { + // controller.model.peopleList[index] + // .tel = value; + // controller.updateAll(); + // }, + // controller: controller.onReDraw( + // TextEditingController( + // text: controller + // .model + // .peopleList[index] + // .tel ?? + // ""), + // (textEditingController) { + // textEditingController.text = + // controller + // .model + // .peopleList[index] + // .tel ?? + // ""; + // }, "people_tel_$index"), + // ), + // ), + // ], + // ), + // ), + getLine(), + Container( + width: double.infinity, + height: MediaQuery.sizeOf(context).height * + 0.064, + decoration: BoxDecoration(), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '联系人', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + Container( + width: 300.rpx, + child: TextField( + obscureText: false, + keyboardType: TextInputType.number, + textInputAction: + TextInputAction.done, + textAlign: TextAlign.right, + style: TextStyle( + fontSize: 30.rpx, + color: Colors.white), + decoration: InputDecoration( + fillColor: Colors.transparent, + filled: true, + hintText: "请输入联系人", + hintStyle: TextStyle( + color: Colors.white), + border: InputBorder.none, + contentPadding: + EdgeInsets.all(0)), + onChanged: (value) { + controller.model.peopleList[index] + .emergencyContact = value; + controller.updateAll(); + }, + controller: controller.onReDraw( + TextEditingController( + text: controller + .model + .peopleList[index] + .emergencyContact ?? + ""), + (textEditingController) { + textEditingController.text = + controller + .model + .peopleList[index] + .emergencyContact ?? + ""; + }, "people_emergencyContact_$index"), + ), + ), + ], + ), + ), + ], + ), + ) + ], + ); + }), + SizedBox( + height: 100.rpx, + ), + ], + )), + ), + ), + ), + )), + ); + } +} diff --git a/lib/pages/device_control/repair_history_page.dart b/lib/pages/device_control/repair_history_page.dart new file mode 100644 index 0000000..41325b7 --- /dev/null +++ b/lib/pages/device_control/repair_history_page.dart @@ -0,0 +1,797 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:timeline_tile/timeline_tile.dart'; +import 'package:vbvs_app/common/color/appColors.dart'; +import 'package:vbvs_app/common/color/appFontsize.dart'; +import 'package:vbvs_app/common/color/repair_status.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/controller/mh/repair_process.dart'; +import 'package:vbvs_app/pages/device_control/repair_process_widget.dart'; + +import '../../component/img/img_preview_widget.dart'; +import '../../controller/mh/apply_repair_controller.dart'; +import '../../controller/mh/repair_info_controller.dart'; + +class RepairHistoryListPage extends GetView { + final scaffoldKey = GlobalKey(); + BoxConstraints? bodysize; + + @override + Widget build(BuildContext context) { + controller.model.applyRepairModel = ApplyRepairModel() + ..id = 1001 + ..apply_name = '张三' + ..tel = '13812345678' + ..address = '北京市海淀区清华东路66号' + ..desc = '床垫传感器失灵,无法监测心率和呼吸' + ..create_time = DateTime.parse('2025-05-01 10:00:00') + ..device_type = '床垫' + ..device_category = 'BY-H' + ..device_id = 'BD202505011001' + ..device_name = '智能床垫 BY-H 型号' + ..issue_img = [ + 'https://example.com/img1.jpg', + 'https://example.com/img2.jpg' + ] + ..imagesLImit = 3 + ..img_bucket = 'mianhuatang_repair' + ..status = '待处理' + ..select_device = '床垫/BY-H/智能床垫' + ..device_list = ['床垫/BY-H/智能床垫', '床垫/BY-A/智能床垫', '床垫/BY-C/智能床垫'] + ..score = null + ..score_time = null + ..messageType = 1 + ..repairId = 1001; + + controller.model.repairProcessList = [ + RepairProcessModel() + ..status = '申请提交' + ..create_time = DateTime.parse('2025-05-01 10:05:00') + ..desc = '用户提交了维修申请' + ..record_id = 1001 + ..deal_user = null, + RepairProcessModel() + ..status = '客服受理' + ..create_time = DateTime.parse('2025-05-01 10:20:00') + ..desc = '客服已联系用户确认问题' + ..record_id = 1001 + ..deal_user = 2001, + RepairProcessModel() + ..status = '维修完成' + ..create_time = DateTime.parse('2025-05-02 15:30:00') + ..desc = '维修人员完成修复,等待用户确认' + ..record_id = 1001 + ..deal_user = 3001, + ]; + + final List events = controller.model.repairProcessList; + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return WillPopScope( + child: GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + // key: scaffoldKey, + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '详情', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + + body: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 30.rpx, 30.rpx, 0), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: + const EdgeInsetsDirectional.fromSTEB( + 0, 0, 0, 10), + child: Container( + width: MediaQuery.sizeOf(context).width, + decoration: BoxDecoration( + color: Color(0xFF003058), //true + borderRadius: BorderRadius.circular(8), + ), + child: Padding( + padding: const EdgeInsetsDirectional + .fromSTEB(17, 10, 0, 0), + child: Container( + decoration: const BoxDecoration(), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + // 'SWES01号智能一键入眠床', + controller + .model + .applyRepairModel! + .device_name ?? + '未命名', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: 30.rpx, + letterSpacing: 0, + color: Colors.white, + ), + ), + ), + Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '系列:' + + (controller + .model + .applyRepairModel! + .device_category ?? + '未命名'), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: const Color( + 0xFF929699), + fontSize: 26.rpx, + letterSpacing: 0, + ), + ), + ), + Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '类型:' + + (controller + .model + .applyRepairModel! + .device_type ?? + '未命名'), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: const Color( + 0xFF929699), + fontSize: 26.rpx, + letterSpacing: 0, + ), + ), + ), + Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '序列号:' + + (controller + .model + .applyRepairModel! + .device_id ?? + '未命名'), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: const Color( + 0xFF929699), + fontSize: 26.rpx, + letterSpacing: 0, + ), + ), + ), + Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '报修单号:' + + (controller + .model + .applyRepairModel! + .id + .toString() ?? + '未命名'), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: const Color( + 0xFF929699), + fontSize: 26.rpx, + letterSpacing: 0, + ), + ), + ), + Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '提交时间:' + + (MyUtils.formatDateTime( + controller + .model + .applyRepairModel! + .create_time!)), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: const Color( + 0xFF929699), + fontSize: 26.rpx, + letterSpacing: 0, + ), + ), + ), + Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '问题描述:' + + (controller + .model + .applyRepairModel! + .desc ?? + '未命名'), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: const Color( + 0xFF929699), + fontSize: 26.rpx, + letterSpacing: 0, + ), + ), + ), + Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB( + 0, 10, 0, 24), + child: Container( + width: MediaQuery.sizeOf( + context) + .width, + height: MediaQuery.sizeOf( + context) + .height * + 0.15, + constraints: + const BoxConstraints( + + // minHeight: 140, + ), + child: Container( + width: 100, + height: 100, + child: Obx(() => + ListView( + shrinkWrap: + true, + scrollDirection: + Axis + .horizontal, + children: getImage(controller + .model + .applyRepairModel!) + .divide( + const SizedBox( + width: + 12, + )) + .addToStart( + const SizedBox( + width: + 0, + ))))), + )), + ] + .divide( + const SizedBox(height: 5)) + .addToStart(const SizedBox( + height: 5, + )), + ), + )), + ), + ), + Padding( + padding: + const EdgeInsetsDirectional.fromSTEB( + 0, 25, 0, 25), // 设置上下间距为 34 + child: Align( + alignment: AlignmentDirectional + .centerStart, // 文字左对齐 + child: Text( + '报修状态', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 30.rpx, + letterSpacing: 0.0, + ), + ), + ), + ), + Container( + width: bodysize!.maxWidth, // 设置宽度自适应 + child: ListView.builder( + shrinkWrap: true, // 让ListView根据内容自适应高度 + physics: + const NeverScrollableScrollPhysics(), // 禁用内部滚动,交由外部滚动视图处理 + itemCount: events.length, + itemBuilder: (context, index) { + bool isLast = + index == events.length - 1; + return TimelineTile( + isFirst: index == 0, + isLast: isLast, + axis: + TimelineAxis.vertical, // 垂直方向时间轴 + alignment: + TimelineAlign.start, // 线条左对齐 + lineXY: 0.5, // 线条和圆圈相对位置 + indicatorStyle: IndicatorStyle( + width: 15, // 圆圈的宽度 + padding: const EdgeInsets.all( + 1), // 避免线条进入圆圈内部 + indicatorXY: 0.2, // 圆圈居中 + indicator: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: const Color( + 0xFFC8CBD2), // 最后一个元素为蓝色 + width: 1, + ), + color: stringToColor("#C8CBD2"), + ), + ), + ), + beforeLineStyle: LineStyle( + color: stringToColor( + "#C8CBD2"), // 上方线条颜色 + thickness: 1, // 线条厚度 + ), + afterLineStyle: LineStyle( + color: stringToColor( + "#C8CBD2"), // 最后一个节点的线条颜色 + thickness: 1, // 线条厚度 + ), + endChild: Padding( + padding: const EdgeInsets.all(8.0), + child: RepairStatusWidget( + index: index, + repairInfoController: controller, + ), + ), + ); + }, + ), + ), + Obx(() { + if (RepairStatus.completed == + controller.model.applyRepairModel! + .status && + controller.model.applyRepairModel! + .score == + null) + return Align( + alignment: + const AlignmentDirectional(1, 0), + child: Padding( + padding: const EdgeInsetsDirectional + .fromSTEB(17, 33, 0, 24), + child: Container( + width: 61, + height: MediaQuery.sizeOf(context) + .height * + 0.03, + constraints: const BoxConstraints( + minHeight: 24, + ), + decoration: const BoxDecoration(), + child: FFButtonWidget( + onPressed: () { + Get.toNamed("/scorePage"); + }, + text: '待评价', + options: FFButtonOptions( + height: 40, + padding: + const EdgeInsetsDirectional + .fromSTEB(0, 0, 0, 0), + iconPadding: + const EdgeInsetsDirectional + .fromSTEB(0, 0, 0, 0), + // color: FlutterFlowTheme.of(context) + // .secondaryBackground, + color: Colors.white, + textStyle: + FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: + 'Readex Pro', + // color: Color(0xFF333333), + // color: stringToColor("#D3B684"), + color: stringToColor( + "#117EFD"), + fontSize: 11, + letterSpacing: 0, + ), + elevation: 0, + borderSide: BorderSide( + // color: Color(0xFFC8CBD2), + // color: stringToColor("#D3B684"), + color: + stringToColor("#117EFD"), + width: 1, + ), + borderRadius: + BorderRadius.circular(50), + ), + ), + ), + ), + ); + return Container(); + }), + Obx(() { + if (RepairStatus.completed == + controller.model.applyRepairModel! + .status && + controller.model.applyRepairModel! + .score != + null) + return Padding( + padding: const EdgeInsetsDirectional + .fromSTEB(0, 0, 0, 5), + child: Container( + width: + MediaQuery.sizeOf(context).width, + decoration: BoxDecoration( + color: Colors.white, //true + borderRadius: + BorderRadius.circular(8), + ), + child: Padding( + padding: const EdgeInsetsDirectional + .fromSTEB(0, 0, 0, 0), + child: Container( + decoration: const BoxDecoration(), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB( + 17, 0, 30, 10), + child: Container( + width: MediaQuery.sizeOf( + context) + .width, + height: 30, + decoration: + const BoxDecoration(), + child: Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Text( + '评价状态', + style: FlutterFlowTheme + .of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + color: const Color( + 0xFF333333), + fontSize: 15, + letterSpacing: + 0.0, + ), + ), + ), + ), + ), + Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB( + 17, 0, 0, 0), + child: Container( + width: + MediaQuery.sizeOf( + context) + .width, + constraints: + const BoxConstraints( + minHeight: 24, + ), + decoration: + const BoxDecoration(), + child: // Generated code for this Column Widget... + Column( + mainAxisSize: + MainAxisSize.max, + children: [ + Align( + alignment: + const AlignmentDirectional( + -1, 0), + child: Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB( + 0, + 0, + 0, + 10), + child: Text( + // '2023-08-22 12:12:44', + MyUtils.formatDateTime( + controller + .model + .applyRepairModel! + .score_time!), + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize.normal_text_size, + letterSpacing: + 0.0, + ), + ), + ), + ), + Row( + mainAxisSize: + MainAxisSize + .max, + children: [ + Align( + alignment: + const AlignmentDirectional( + -1, + 0), + child: + Padding( + padding: + const EdgeInsetsDirectional + .fromSTEB( + 0, + 0, + 5, + 0), + child: Text( + '已评价', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: + AppFontsize.normal_text_size, + letterSpacing: + 0.0, + ), + ), + ), + ), + Icon( + Icons.star, + color: controller + .model + .applyRepairModel! + .score! >= + 1 + ? stringToColor( + "#F8AE00") + : stringToColor( + "#D0D0D0"), + size: 14, + ), + Icon( + Icons.star, + color: controller + .model + .applyRepairModel! + .score! >= + 2 + ? stringToColor( + "#F8AE00") + : stringToColor( + "#D0D0D0"), + size: 14, + ), + Icon( + Icons.star, + color: controller + .model + .applyRepairModel! + .score! >= + 3 + ? stringToColor( + "#F8AE00") + : stringToColor( + "#D0D0D0"), + size: 14, + ), + Icon( + Icons.star, + color: controller + .model + .applyRepairModel! + .score! >= + 4 + ? stringToColor( + "#F8AE00") + : stringToColor( + "#D0D0D0"), + size: 14, + ), + Icon( + Icons.star, + color: controller + .model + .applyRepairModel! + .score! >= + 5 + ? stringToColor( + "#F8AE00") + : stringToColor( + "#D0D0D0"), + size: 14, + ), + ], + ), + ], + ), + ), + ), + ), + ] + .divide(const SizedBox( + height: 0)) + .addToStart(const SizedBox( + height: 5, + )) + .addToEnd(const SizedBox( + height: 15, + )), + ), + ), + ), + ), + ); + return Container(); + }), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ), + )), + onWillPop: () async { + // 处理返回事件,比如弹出提示框等 + print("页面返回事件"); + return true; // 返回 true 允许页面返回,返回 false 阻止页面返回 + }, + ); + }); + } + + List getImage(ApplyRepairModel applyRepairModel) { + List images = []; + ApplyRepairController controller = Get.find(); + applyRepairModel.issue_img!.forEach((element) async { + images.add( + Container( + // height: 10, + // width: 10, + + child: ImgPreviewWidget( + imgUrl: element, + index: applyRepairModel.issue_img!.indexOf(element), + applyRepairController: controller, + isDel: false, + ), + ), + ); + }); + + return images; + } +} diff --git a/lib/pages/device_control/repair_history_widget.dart b/lib/pages/device_control/repair_history_widget.dart new file mode 100644 index 0000000..da96ecc --- /dev/null +++ b/lib/pages/device_control/repair_history_widget.dart @@ -0,0 +1,144 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appColors.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/controller/mh/repair_info_controller.dart'; +import 'package:vbvs_app/controller/mh/repair_list_controller.dart'; +import 'package:vbvs_app/pages/device_control/ColorChangeOnTap.dart'; + +import '../../common/color/appFontsize.dart'; + +class RepairHistoryWidget extends GetView { + int index; + RepairListController repairListController; + + RepairHistoryWidget( + {required this.index, required this.repairListController}) {} + + @override + Widget build(BuildContext context) { + int tmp = index; + index = tmp; + return ColorChangeOnPress( + pressColor: AppColors().press_color, // 按下时的颜色 + shouldNavigate: true, // 是否需要跳转 + routeName: "/repairHistoryListPage", // 路由名称 + topLeft: 16, + topRight: 16, + bottomLeft: 16, + bottomRight: 16, + onTap: () async { + // print("object"); + // final RepairInfoController repairInfoController = + // Get.find(); + // await repairInfoController + // .initData(repairListController.model.repairList[index]) + // .then((_) { + // repairInfoController.updateAll(); + // // Get.toNamed("/repairHistoryListPage"); // 这个在 ColorChangeOnPress 中已经处理 + // }); + }, + child: Container( + width: MediaQuery.sizeOf(context).width, + constraints: BoxConstraints( + minHeight: 70, + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(15, 14, 15, 13), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + width: MediaQuery.sizeOf(context).width * 0.5, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: AlignmentDirectional(-1, 0), + child: Text( + repairListController + .model.repairList[index].device_category ?? + '', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Color(0xFF333333), + fontSize: AppFontsize.title_size, + letterSpacing: 0, + ), + ), + ), + Align( + alignment: AlignmentDirectional(-1, 0), + child: Text( + "报修单号:${repairListController.model.repairList[index].id}", + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Color(0xFFC8CBD2), + fontSize: AppFontsize.small_text_size, + letterSpacing: 0, + ), + ), + ), + Align( + alignment: AlignmentDirectional(-1, 0), + child: Text( + "提交时间:" + + (MyUtils.formatDateTime(repairListController + .model.repairList[index].create_time!) ?? + ''), + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Color(0xFFC8CBD2), + fontSize: AppFontsize.small_text_size, + letterSpacing: 0, + ), + ), + ), + ], + ), + ), + Container( + width: MediaQuery.sizeOf(context).width * 0.2, + height: MediaQuery.sizeOf(context).height * 0.075, + constraints: BoxConstraints( + maxWidth: 130, + ), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Align( + alignment: AlignmentDirectional(0, 0), + child: Text( + repairListController.model.repairList[index].status ?? + '', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Color(0xFF333333), + fontSize: AppFontsize.normal_text_size, + letterSpacing: 0, + ), + ), + ), + Flexible( + child: Align( + alignment: AlignmentDirectional(0, 0.05), + child: Icon( + Icons.arrow_forward_ios, + color: FlutterFlowTheme.of(context).secondaryText, + size: 10, + ), + ), + ), + ].divide(SizedBox(width: 27)), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/device_control/repair_list.dart b/lib/pages/device_control/repair_list.dart new file mode 100644 index 0000000..4f89197 --- /dev/null +++ b/lib/pages/device_control/repair_list.dart @@ -0,0 +1,575 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; + +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; +import 'package:vbvs_app/component/tool/CustomCard.dart'; +import 'package:vbvs_app/controller/mh/apply_repair_controller.dart'; +import 'package:vbvs_app/controller/mh/repair_list_controller.dart'; + + +class DeviceRepairPage extends GetView { + final scaffoldKey = GlobalKey(); + BoxConstraints? bodysize; + + // final ScrollController scrollController = ScrollController(); + // final RepairListController controller = Get.find(); + + // DeviceRepairPage() { + // controller.model.limit = AppConstants.limit; + // controller.model.offset = 0; + // controller.model.isLoading = false; + // controller.model.hasMore = true; + // controller.model.repairList.clear(); + // controller.initData(); + // Get.put(RepairListController()); + + // scrollController.addListener(() { + // if (scrollController.position.pixels == + // scrollController.position.maxScrollExtent && + // controller.model.hasMore) { + // controller.initData(); + // controller.updateAll(); + // } + // }); + // } + final List mockData = List.generate(4, (index) { + return ApplyRepairModel() + ..device_name = "SWESO1号智能一键入眠床" + ..status = index == 0 ? "已提交" : "已完成" + ..create_time = DateTime(2024, 5, 12, 12, 5, 12); + }); + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + // key: scaffoldKey, + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '设备报修', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Padding( + padding: EdgeInsets.fromLTRB(30.rpx, 6.rpx, 30.rpx, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // 报修须知 + Container( + height: 412.rpx, + decoration: BoxDecoration( + border: Border.all( + color: Color(0XFFC8CBD2), width: 0.rpx), + borderRadius: BorderRadius.circular(10), + ), + child: Padding( + padding: EdgeInsets.fromLTRB( + 27.rpx, 49.rpx, 43.rpx, 39.rpx), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + // 固定的标题部分 + Text( + "报修须知", + style: TextStyle( + fontSize: 30.rpx, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + textAlign: TextAlign.center, + ), + SizedBox(height: 33.rpx), + // 可滚动的正文部分,限定高度 + Expanded( + child: SingleChildScrollView( + child: RichText( + text: TextSpan( + style: TextStyle( + color: Color(0XFF929699), + fontSize: 26.rpx, + ), + children: [ + TextSpan( + text: + "尊敬的用户,感谢您选择我司产品。在使用过程中,如果设备出现故障需要维修,请首先确认设备是否正确连接控制器或网络,检查设置是否正常,排除误操作问题。若问题依然存在,请记录下设备名称、设备编号、和具体故障内容,方便我们快速地为您提供帮助。您可以通过智慧棉花糖APP保修页面直接报修或拨打 ", + style: TextStyle( + color: + Color(0XFF929699), + fontSize: 26.rpx, + height: 1.3)), + TextSpan( + text: "400-8756-966", + style: TextStyle( + color: Colors.white, + // height: 1.3, + decoration: TextDecoration + .underline, // 添加下划线 + decorationColor: + Colors.white, + decorationThickness: 4.rpx, + ), + ), + TextSpan( + text: " 反馈。", + style: TextStyle( + color: + Color(0XFF929699), + fontSize: 26.rpx, + height: 1.3)), + ], + ), + ), + ), + ), + ], + ))), + + SizedBox(height: 24.rpx), + + InkWell( + onTap: () { + // bool isOk = true; + // for (var i = 0; i < 2; i++) { + // var d = controller.model.peopleList[i]; + // print("${d.toJson()}"); + // String before = "人员信息${i == 0 ? "A" : "B"}:"; + // if (isOk && + // d.height != null && + // d.height != "" && + // int.tryParse("${d.height}") == null) { + // showToast("$before身高请输入数字"); + // isOk = false; + // } + // if (isOk && + // d.weight != null && + // d.weight != "" && + // int.tryParse("${d.weight}") == null) { + // showToast("$before体重请输入数字"); + // isOk = false; + // } + // if (isOk && + // d.tel != null && + // d.tel != "" && + // MyUtils.isValidPhoneNumber("${d.tel}") == + // false) { + // showToast("$before请输入正确的电话"); + // isOk = false; + // } + // if (isOk && + // d.emergencyContact != null && + // d.emergencyContact != "" && + // MyUtils.isValidPhoneNumber( + // "${d.emergencyContact}") == + // false) { + // showToast("$before请输入正确的紧急联系人电话"); + // isOk = false; + // } + // if (isOk) { + // controller.savePeoples().then((d) { + // showToast("保存成功", color: color_success); + // }).catchError((d) { + // print("$d"); + // showToast("保存失败"); + // }); + // } + // } + // controller.model.peopleList.forEach((d) {}); + }, + child: CustomCard( + borderRadius: 10, + gradientDirection: GradientDirection.vertical, + onTap: () { + Get.toNamed("/applyRepairPage"); + }, + colors: const [ + Color(0xFFFCFCFC), + Color(0xFFF8FAF9), + Color(0XFFECF6F3), + Color(0XFFD9F0E9), + Color(0xFFCEECE3) + ], + child: Container( + width: double.infinity, + height: 90.rpx, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + ), + child: Text( + "我要报修", + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: stringToColor("#011D33"), + letterSpacing: 0, + fontSize: 30.rpx, + ), + ), + ), + )), + + SizedBox(height: 235.rpx), + + // 报修历史标题 + Container( + width: double.infinity, + child: Text("报修历史", + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + height: 1)), + ), + + SizedBox(height: 32.rpx), + + // 报修历史列表 + Expanded( + child: ListView.builder( + itemCount: mockData.length, + itemBuilder: (context, index) { + final item = mockData[index]; + return ClickableContainer( + backgroundColor: Colors.transparent, + highlightColor: Color(0XFF055466), + padding: EdgeInsets.only(top: 0), + onTap: () { + Get.toNamed("/repairHistoryListPage"); + }, + child: Container( + height: 119.rpx, + // margin: const EdgeInsets.only(bottom: 10), + // padding: const EdgeInsets.symmetric( + // vertical: 12, horizontal: 16), + decoration: BoxDecoration( + // color: const Color(0xFF06486F), + border: Border( + top: index == 0 + ? BorderSide( + color: + const Color(0xFF929699), + width: 1.rpx) + : BorderSide.none, + bottom: BorderSide( + color: const Color(0xFF929699), + width: 1.rpx), + ), + ), + child: Padding( + padding: EdgeInsets.fromLTRB( + 17.rpx, 0, 30.rpx, 0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + // 左侧设备信息 + Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + item.device_name ?? '', + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx), + ), + const SizedBox(height: 4), + Text( + "提交时间:${item.create_time?.toString().substring(0, 19) ?? ''}", + style: TextStyle( + color: Colors.white60, + fontSize: 20.rpx), + ), + ], + ), + // 右侧状态 + Row( + children: [ + Text( + item.status ?? '', + style: TextStyle( + color: Colors.white, + fontSize: 26.rpx), + ), + Icon(Icons.arrow_forward_ios, + color: Colors.white, + size: 30.rpx), + ], + ) + ], + ), + ))); + }, + ), + ), + ], + ), + )) + // Container( + // width: bodysize!.maxWidth, + // height: bodysize!.maxHeight * 1, + // decoration: BoxDecoration( + // color: Color(0xFFF6F6F6), + // ), + // child: Column( + // mainAxisSize: MainAxisSize.max, + // children: [ + // // TitleComponentWidget( + // // titleName: '设备报修', + // // ), + // Expanded( + // child: Padding( + // padding: EdgeInsetsDirectional.fromSTEB(15, 0, 15, 0), + // child: Container( + // width: bodysize!.maxWidth, + // height: bodysize!.maxHeight * 0.9, + // decoration: BoxDecoration( + // color: Color(0xFFF6F6F6), + // ), + // child: Column( + // mainAxisSize: MainAxisSize.max, + // children: [ + // Padding( + // padding: + // EdgeInsetsDirectional.fromSTEB(0, 14, 0, 13), + // child: Container( + // width: bodysize!.maxWidth, + // height: bodysize!.maxHeight * 0.186, + // constraints: BoxConstraints( + // minHeight: 170, + // ), + // decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context) + // .secondaryBackground, + // borderRadius: BorderRadius.circular(16), + // border: Border.all( + // color: Colors.white, + // ), + // ), + // child: Column( + // mainAxisSize: MainAxisSize.max, + // children: [ + // Padding( + // padding: EdgeInsetsDirectional.fromSTEB( + // 0, 14, 0, 18), + // child: Text( + // '报修须知', + // style: FlutterFlowTheme.of(context) + // .bodyMedium + // .override( + // fontFamily: 'Readex Pro', + // fontSize: AppFontsize.title_size, + // letterSpacing: 0, + // fontWeight: FontWeight.w600, + // ), + // ), + // ), + // Flexible( + // child: Padding( + // padding: EdgeInsetsDirectional.fromSTEB( + // 14, 0, 14, 14), // 应用 padding + // child: SingleChildScrollView( + // child: Column( + // mainAxisSize: MainAxisSize.max, + // children: [ + // Text( + // '尊敬的用户,感谢您选择我司产品。在使用过程中,如果设备出现故障或需要维修,请首先确认设备是否正确连接电源和网络,检查设置是否正常,排除基本操作问题。若问题依然存在,请记录下设备名称、设备型号、和具体故障情况等,方便我们更快速地为您提供帮助。您可以通过智慧眠花糖APP保修或者直接拨打400-8756-966反馈。', + // style: FlutterFlowTheme.of( + // context) + // .bodyMedium + // .override( + // fontFamily: 'Readex Pro', + // color: Color(0xFF333333), + // fontSize: AppFontsize + // .small_text_size, + // letterSpacing: 0, + // lineHeight: 1.5, + // ), + // ), + // // 如果需要,可以在 Text 下面添加其他小部件 + // ], + // ), + // ), + // ), + // ) + // ], + // ), + // ), + // ), + // Padding( + // padding: + // EdgeInsetsDirectional.fromSTEB(0, 0, 0, 42), + // child: Container( + // width: bodysize!.maxWidth, + // height: 46, + // decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context) + // .secondaryBackground, + // borderRadius: BorderRadius.circular(16), + // ), + // child: Container( + // width: bodysize!.maxWidth, + // height: bodysize!.maxHeight * 0.056, + // decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context) + // .secondaryBackground, + // borderRadius: BorderRadius.circular(16), + // ), + // child: FFButtonWidget( + // onPressed: () { + // Get.toNamed("/applyRepairPage"); + // }, + // text: '我要报修', + // options: FFButtonOptions( + // height: 46, + // padding: EdgeInsetsDirectional.fromSTEB( + // 24, 0, 24, 0), + // iconPadding: EdgeInsetsDirectional.fromSTEB( + // 0, 0, 0, 0), + // color: Color(0xFFE55E92), + // textStyle: FlutterFlowTheme.of(context) + // .titleSmall + // .override( + // fontFamily: 'Readex Pro', + // color: Colors.white, + // fontSize: AppFontsize.title_size, + // letterSpacing: 0, + // ), + // elevation: 0, + // borderSide: BorderSide( + // color: Colors.transparent, + // width: 1, + // ), + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // ), + // ), + // ), + // Expanded( + // child: Container( + // width: bodysize!.maxWidth, + // height: bodysize!.maxHeight * 1, + // decoration: BoxDecoration( + // color: Color(0xFFF6F6F6), + // ), + // child: Column( + // mainAxisSize: MainAxisSize.max, + // children: [ + // Align( + // alignment: AlignmentDirectional(-1, 0), + // child: Padding( + // padding: EdgeInsetsDirectional.fromSTEB( + // 14, 0, 0, 17), + // child: Text( + // '报修历史', + // style: FlutterFlowTheme.of(context) + // .bodyMedium + // .override( + // fontFamily: 'Readex Pro', + // color: Color(0xFF333333), + // fontSize: AppFontsize.title_size, + // letterSpacing: 0, + // fontWeight: FontWeight.w600, + // ), + // ), + // ), + // ), + // Obx(() { + // return Visibility( + // visible: + // controller.model.repairList != null && + // controller + // .model.repairList!.isNotEmpty, + // replacement: + // EmptyMessageWidget(), + // child: Expanded( + // // child: Obx(() => + // child: ListView( + // controller: + // scrollController, // 绑定 ScrollController + // shrinkWrap: true, + // scrollDirection: Axis.vertical, + // children: (controller + // .model.repairList + // .asMap() + // .entries + // .map((e) => + // RepairHistoryWidget( + // index: e.key, + // repairListController: + // controller)) + // .toList() as List) + // .divide(const SizedBox( + // height: 13, + // )) + // .addToEnd(SizedBox( + // height: AppConstants + // .list_end_height, + // ))) + // // ), + // ), + // ); + // }), + // ], + // ), + // ), + // ), + // ], + // ), + // ), + // ), + // ), + // ], + // ), + // ), + ), + )); + }); + } +} diff --git a/lib/pages/device_control/repair_process_widget.dart b/lib/pages/device_control/repair_process_widget.dart new file mode 100644 index 0000000..1c9391f --- /dev/null +++ b/lib/pages/device_control/repair_process_widget.dart @@ -0,0 +1,121 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/color/appColors.dart'; +import 'package:vbvs_app/common/color/repair_status.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/controller/mh/repair_info_controller.dart'; + +import '../../common/color/appFontsize.dart'; + +class RepairStatusWidget extends GetView { + int index; + RepairInfoController repairInfoController; + + RepairStatusWidget( + {required this.index, required this.repairInfoController}) {} + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 0), + child: Container( + width: MediaQuery.sizeOf(context).width, + decoration: BoxDecoration( + // color: Colors.white, + ), + child: Container( + width: MediaQuery.sizeOf(context).width, + decoration: BoxDecoration( + // color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: AlignmentDirectional(-1, 0), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 10), + child: Text( + // '2023-08-22 12:12:44', + MyUtils.formatDateTime(repairInfoController + .model.repairProcessList[index].create_time!) ?? + '未知时间', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + fontSize: AppFontsize.normal_text_size, + letterSpacing: 0, + color: index == + repairInfoController + .model.repairProcessList.length - + 1 + ? Colors.white + : Colors.white, + ), + ), + ), + ), + Align( + alignment: AlignmentDirectional(-1, 0), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(0, 0, 0, 10), + child: Text( + // '审核中', + repairInfoController + .model.repairProcessList[index].status ?? + '未知状态', + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + fontSize: AppFontsize.normal_text_size, + letterSpacing: 0, + color: repairInfoController + .model.repairProcessList[index].status == + RepairStatus.pending + ? AppColors().check_Color + : repairInfoController + .model + .repairProcessList[index] + .status == + RepairStatus.approved || + repairInfoController + .model + .repairProcessList[index] + .status == + '维修中' + ? AppColors().repair_Color + : repairInfoController + .model + .repairProcessList[index] + .status == + RepairStatus.completed + ? AppColors().finish_Color + : AppColors().unOp_Color, // 根据状态设置文字颜色 + ), + ), + ), + ), + Align( + alignment: AlignmentDirectional(-1, 0), + child: Text( + // repairProcessModel.content ?? '未备注', + (repairInfoController + .model.repairProcessList[index].desc?.isEmpty ?? + true) + ? '未备注' + : repairInfoController + .model.repairProcessList[index].desc!, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: AppFontsize.small_text_size, + letterSpacing: 0, + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/device_control/room_picker.dart b/lib/pages/device_control/room_picker.dart new file mode 100644 index 0000000..afe3fe2 --- /dev/null +++ b/lib/pages/device_control/room_picker.dart @@ -0,0 +1,185 @@ +import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart'; +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/CustomCard.dart'; + +class RoomPickerPage extends StatefulWidget { + @override + _RoomPickerPageState createState() => _RoomPickerPageState(); +} + +class _RoomPickerPageState extends State { + final List rooms = ['主卧', '次卧', '儿童房', '客厅', '厨房', '书房', '阳台', '洗手间']; + + int selectedIndex = 1; + BoxConstraints? bodysize; + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, // 深蓝背景 + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '房间选择', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + body: SafeArea( + child: Column( + children: [ + // 顶部标题栏 + // const Padding( + // padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 12), + // child: Row( + // children: [ + // Icon(Icons.arrow_back_ios, color: Colors.white), + // Spacer(), + // Text( + // '房间选择', + // style: TextStyle(color: Colors.white, fontSize: 18), + // ), + // Spacer(flex: 2), + // ], + // ), + // ), + const Spacer(), + // 滚轮选择器 + SizedBox( + height: 360.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 滚轮列表 + ListWheelScrollView.useDelegate( + itemExtent: 120.rpx, + perspective: 0.003, + physics: const FixedExtentScrollPhysics(), + onSelectedItemChanged: (index) { + setState(() => selectedIndex = index); + }, + childDelegate: ListWheelChildBuilderDelegate( + builder: (context, index) { + if (index >= rooms.length) return null; + final isSelected = index == selectedIndex; + return Center( + child: Text( + rooms[index], + style: TextStyle( + fontSize: isSelected ? 36.rpx : 30.rpx, + color: isSelected + ? Colors.white + : const Color(0xFF929699), + ), + ), + ); + }, + childCount: rooms.length, + ), + ), + + // 上边线 + Positioned( + top: 120.rpx, + left: 60.rpx, + right: 60.rpx, + child: Container( + height: 1, + color: const Color(0xFF929699), + ), + ), + + // 下边线 + Positioned( + top: 240.rpx, + left: 60.rpx, + right: 60.rpx, + child: Container( + height: 1, + color: const Color(0xFF929699), + ), + ), + ], + ), + ), + const Spacer(), + // 完成按钮 + Padding( + padding: EdgeInsets.only( + left: 30.rpx, + right: 30.rpx, + bottom: 83.rpx, + ), + child: SizedBox( + width: double.infinity, + height: 50, + child: CustomCard( + borderRadius: 10, + gradientDirection: GradientDirection.vertical, + onTap: () { + // Get.toNamed("/applyRepairPage"); + }, + colors: const [ + Color(0xFFFCFCFC), + Color(0xFFF8FAF9), + Color(0XFFECF6F3), + Color(0XFFD9F0E9), + Color(0xFFCEECE3) + ], + child: Container( + width: double.infinity, + height: 90.rpx, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + ), + child: Text("完成", + style: TextStyle( + color: const Color(0xFF003058), + fontSize: 30.rpx, + )), + ), + )), + ), + ], + ), + ), + ))); + }); + } +} diff --git a/lib/pages/device_control/score_page.dart b/lib/pages/device_control/score_page.dart new file mode 100644 index 0000000..2d1d249 --- /dev/null +++ b/lib/pages/device_control/score_page.dart @@ -0,0 +1,468 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/color/appConstants.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/CustomCard.dart'; +import 'package:vbvs_app/controller/mh/score_controller.dart' as mh; + +import '../../common/color/appFontsize.dart'; + +class ScorePage extends GetView { + BoxConstraints? bodysize; + final scaffoldKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + // UserInfoController userInfoController = Get.find(); + // userInfoController.model.user; + controller.model.score = 5; + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + // key: scaffoldKey, + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '评价', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + + body: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 1, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + // TitleComponentWidget( + // titleName: '评价', + // ), + Expanded( + child: Container( + width: bodysize!.maxWidth, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 26.rpx, 30.rpx, 0), + child: Container( + width: bodysize!.maxWidth, + constraints: BoxConstraints( + minWidth: 346, + minHeight: 115, + ), + decoration: BoxDecoration( + color: Color(0xFF003058), + borderRadius: BorderRadius.circular(16), + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 22, 27, 17, 22), + child: Container( + width: bodysize!.maxWidth, + decoration: BoxDecoration( + color: Color(0xFF003058), + borderRadius: BorderRadius.circular(16), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Align( + alignment: + AlignmentDirectional(0, 0), + child: Text( + '我要评价', + style: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: 30.rpx, + letterSpacing: 0, + color: Colors.white), + ), + ), + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + InkWell( + onTap: () { + controller.model.score = 1; + controller.updateAll(); + }, + child: Obx(() { + return Icon( + Icons.star, + color: controller + .model.score! >= + 1 + ? stringToColor( + "#F8AE00") + : stringToColor( + "#D0D0D0"), + size: 40, + ); + }), + ), + InkWell( + onTap: () { + controller.model.score = 2; + controller.updateAll(); + }, + child: Obx(() { + return Icon( + Icons.star, + color: controller + .model.score! >= + 2 + ? stringToColor( + "#F8AE00") + : stringToColor( + "#D0D0D0"), + size: 40, + ); + }), + ), + InkWell( + onTap: () { + controller.model.score = 3; + controller.updateAll(); + }, + child: Obx(() { + return Icon( + Icons.star, + color: controller + .model.score! >= + 3 + ? stringToColor( + "#F8AE00") + : stringToColor( + "#D0D0D0"), + size: 40, + ); + }), + ), + InkWell( + onTap: () { + controller.model.score = 4; + controller.updateAll(); + }, + child: Obx(() { + return Icon( + Icons.star, + color: controller + .model.score! >= + 4 + ? stringToColor( + "#F8AE00") + : stringToColor( + "#D0D0D0"), + size: 40, + ); + }), + ), + InkWell( + onTap: () { + controller.model.score = 5; + controller.updateAll(); + }, + child: Obx(() { + return Icon( + Icons.star, + color: controller + .model.score! >= + 5 + ? stringToColor( + "#F8AE00") + : stringToColor( + "#D0D0D0"), + size: 40, + ); + }), + ), + ].divide(SizedBox(width: 10)), + ), + ].divide(SizedBox(height: 26)), + ), + ), + ), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 30.rpx, 30.rpx, 30.rpx, 0), + child: Container( + width: bodysize!.maxWidth, + constraints: BoxConstraints( + minWidth: 346, + minHeight: 152, + ), + decoration: BoxDecoration( + color: Color(0xFF003058), + borderRadius: BorderRadius.circular(16.rpx), + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 14, 14, 14, 21), + child: Container( + width: bodysize!.maxWidth, + decoration: BoxDecoration( + color: Color(0xFF003058), + borderRadius: + BorderRadius.circular(16.rpx), + ), + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: + AlignmentDirectional(0, 0), + child: Obx(() { + String scoreText; + Color scoreColor; + if (controller.model.score == 1) { + scoreText = '差'; + scoreColor = + stringToColor("#E55E92"); + } else if (controller + .model.score == + 2) { + scoreText = '较差'; + scoreColor = + stringToColor("#E55E92"); + } else if (controller + .model.score == + 3) { + scoreText = '一般'; + scoreColor = + stringToColor("#07C160"); + } else if (controller + .model.score == + 4) { + scoreText = '优秀'; + scoreColor = + stringToColor("#F8AE00"); + } else if (controller + .model.score == + 5) { + scoreText = '完美'; + scoreColor = + stringToColor("#F8AE00"); + } else { + scoreText = + '未评分'; // 如果没有评分显示默认文字 + scoreColor = + Colors.grey; // 默认颜色 + } + return Text( + scoreText, + style: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: 30.rpx, + letterSpacing: 0, + color: scoreColor, + fontWeight: + FontWeight + .bold), + ); + }), + ), + Align( + alignment: + AlignmentDirectional(-1, 0), + child: Padding( + padding: EdgeInsetsDirectional + .fromSTEB(0, 17, 0, 0), + child: Text( + '再多的溢美之词,都比不上您真心的评价。我们愿付出200%的努力,只为您100%的满意~感谢您的支持与厚爱!', + style: FlutterFlowTheme.of( + context) + .bodyMedium + .override( + fontFamily: + 'Readex Pro', + fontSize: 26.rpx, + letterSpacing: 0, + color: + Color(0xFF9AA0B3)), + ), + ), + ), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB( + 15, 0, 15, AppConstants.page_button_bottom_padding), + child: Container( + width: bodysize!.maxWidth, + height: bodysize!.maxHeight * 0.056, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16.rpx), + ), + // child: Container( + // width: bodysize!.maxWidth, + // height: bodysize!.maxHeight * 0.056, + // decoration: BoxDecoration( + // color: FlutterFlowTheme.of(context) + // .secondaryBackground, + // borderRadius: BorderRadius.circular(12), + // ), + // child: FFButtonWidget( + // onPressed: () { + // // RepairListController repairListController = + // // Get.find(); + // // RepairInfoController repairInfoController = + // // Get.find(); + // // repairListController + // // .addScore( + // // repairInfoController + // // .model.applyRepairModel!.id!, + // // controller.model.score!) + // // .then((String msg) { + // // if (msg != null && msg.isNotEmpty) { + // // MyDialogController myDialogController = + // // Get.find(); + // // showToast("评价失败,请稍后再试"); + // // } else { + // // MyDialogController myDialogController = + // // Get.find(); + // // myDialogController + // // .showCustomDialog(context, "评价成功", + // // textColor: stringToColor("#71E2A3")) + // // .then((_) { + // // // 弹窗关闭后执行的代码 + // // // Get.toNamed("/userInfoPage"); + // // repairInfoController.model.applyRepairModel! + // // .score = controller.model.score!; + // // repairInfoController.updateAll(); + // // Get.back(); + // // }).catchError((error) { + // // // 处理弹窗显示错误的逻辑 + // // print("弹窗显示失败: $error"); + // // }); + // // } + // // }); + // }, + // text: '确定', + // options: FFButtonOptions( + // height: 40, + // padding: + // EdgeInsetsDirectional.fromSTEB(24, 0, 24, 0), + // iconPadding: + // EdgeInsetsDirectional.fromSTEB(0, 0, 0, 0), + // color: Color(0xFFD3B684), + // textStyle: FlutterFlowTheme.of(context) + // .titleSmall + // .override( + // fontFamily: 'Readex Pro', + // color: Colors.white, + // fontSize: 13, + // letterSpacing: 0, + // ), + // elevation: 0, + // borderSide: BorderSide( + // color: Colors.transparent, + // width: 1, + // ), + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // ), + + child: CustomCard( + borderRadius: 10, + gradientDirection: GradientDirection.vertical, + onTap: () { + Get.toNamed("/applyRepairPage"); + }, + colors: const [ + Color(0xFFFCFCFC), + Color(0xFFF8FAF9), + Color(0XFFECF6F3), + Color(0XFFD9F0E9), + Color(0xFFCEECE3) + ], + child: Container( + width: double.infinity, + height: 90.rpx, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16.rpx), + ), + child: Text( + "提交", + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: stringToColor("#011D33"), + letterSpacing: 0, + fontSize: 30.rpx, + ), + ), + ), + )), + ), + ], + ), + ), + ), + )); + }); + } +} diff --git a/lib/pages/device_control/searchWidget.dart b/lib/pages/device_control/searchWidget.dart new file mode 100644 index 0000000..1235648 --- /dev/null +++ b/lib/pages/device_control/searchWidget.dart @@ -0,0 +1,268 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutterflow_ui/flutterflow_ui.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; + +import '../../common/color/appFontsize.dart'; +import '../../common/util/MyUtils.dart'; + +class SearchWidget extends GetView { + final String? keyword; + final Color? color; + String? hint; + Function? onChange; + Function? findCallback; + + SearchWidget( + {required this.keyword, + required this.color, + this.hint = "请输入关键字", + this.findCallback, + this.onChange}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsetsDirectional.fromSTEB(25, 0, 25, 0), + child: Container( + width: double.infinity, + decoration: BoxDecoration( + color: themeController.currentColor.sc3, + borderRadius: BorderRadius.circular(20.rpx), + ), + child: Padding( + padding: EdgeInsetsDirectional.fromSTEB(35.rpx, 0, 35.rpx, 0), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: EdgeInsetsDirectional.fromSTEB(0, 0.rpx, 0, 0), + child: Container( + width: 25.rpx, + height: 25.rpx, + // width: double.infinity, + decoration: BoxDecoration(), + child: SvgPicture.asset( + 'assets/img/icon/query.svg', + fit: BoxFit.cover, + color: stringToColor("#333333"), //固定 + ), + ), + ), + Expanded( + child: Container( + width: 100.rpx, + height: 80.rpx, + decoration: BoxDecoration( + color: + FlutterFlowTheme.of(context).secondaryBackground, + ), + child: Align( + alignment: AlignmentDirectional(-1, 0), + child: TextFormField( + autofocus: false, + obscureText: false, + decoration: InputDecoration( + isDense: true, + labelStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + ), + hintText: hint, + hintStyle: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Color(0x00000000), + width: 1.rpx, + ), + borderRadius: BorderRadius.circular(8.rpx), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Color(0x00000000), + width: 1.rpx, + ), + borderRadius: BorderRadius.circular(8.rpx), + ), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).error, + width: 1.rpx, + ), + borderRadius: BorderRadius.circular(8.rpx), + ), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).error, + width: 1.rpx, + ), + borderRadius: BorderRadius.circular(8.rpx), + ), + filled: false, + fillColor: themeController.currentColor.sc22, + ), + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Inter', + fontSize: 26.rpx, + letterSpacing: 0.0, + ), + cursorColor: + FlutterFlowTheme.of(context).primaryText, + // validator: _model + // .textControllerValidator + // .asValidator(context), + ), + ), + ), + ), + ].divide(SizedBox(width: 6.rpx)), + ), + ), + Padding( + padding: EdgeInsetsDirectional.fromSTEB(26.rpx, 0, 0, 0), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + SizedBox( + height: 50.rpx, + child: VerticalDivider( + thickness: 2.rpx, + color: stringToColor("#333333"), //固定 + ), + ), + Text( + '搜索'.tr, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: 'Inter', + fontSize: 30.rpx, + letterSpacing: 0.0, + color: stringToColor("#333333"), //固定 + ), + ), + ].divide(SizedBox(width: 26.rpx)), + ), + ), + ], + ), + ), + ), + // Container( + // width: MediaQuery.sizeOf(context).width, + // height: 44, + // decoration: BoxDecoration( + // // color: Colors.red, + // borderRadius: BorderRadius.circular(50.rpx), + // ), + // child: Container( + // width: MediaQuery.sizeOf(context).width, + // height: 44, + // decoration: BoxDecoration( + // color: valueOrDefault( + // color, + // Color(0xFF821111), + // ), + // borderRadius: BorderRadius.circular(50), + // ), + // child: Stack( + // children: [ + // Align( + // alignment: AlignmentDirectional(0, 0), + // child: Padding( + // padding: EdgeInsetsDirectional.fromSTEB(0, 6, 0, 6), + // child: Container( + // padding: EdgeInsets.only(right: 30.rpx), + // width: double.infinity, + // height: 70.rpx, + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(10.rpx)), + // child: TextField( + // controller: TextEditingController(text: keyword), + // onChanged: (d) { + // onChange?.call(d); + // }, + // style: TextStyle( + // fontSize: 28.rpx, color: stringToColor("#C8CBD2")), + // decoration: InputDecoration( + // contentPadding: + // EdgeInsets.only(top: 0, bottom: 0, right: 20.rpx), + // border: OutlineInputBorder( + // borderSide: BorderSide.none, + // borderRadius: BorderRadius.circular(50.rpx)), + // filled: true, + // hintText: "$hint", + // hintStyle: TextStyle(color: stringToColor("#c8cbd2")), + // fillColor: stringToColor("#FFFFFF"), + // // prefixIcon: Icon( + // // Icons.search, + // // size: 42.rpx, + // // color: stringToColor("#D3B684"), + // // ), + // prefixIcon: Container( + // padding: EdgeInsets.all(15.rpx), // 可根据需求调整内边距 + // child: SvgPicture.asset( + // 'assets/images/search.svg', + // fit: BoxFit.contain, // 确保 SVG 图像不会超出边界 + // color: stringToColor("#D3B684"), + // ), + // ), + // ), + // ), + // ), + // )), + // Align( + // alignment: AlignmentDirectional(0.95, 0), + // child: Padding( + // padding: EdgeInsetsDirectional.fromSTEB(0, 5, 0, 5), + // child: InkWell( + // onTap: () { + // findCallback?.call(); + // }, + // child: Container( + // width: 50, + // // height: 50, + // height: MediaQuery.sizeOf(context).height * 1, + // decoration: BoxDecoration( + // color: Color(0xFFD3B684), + // borderRadius: BorderRadius.circular(50), + // ), + // child: Align( + // alignment: AlignmentDirectional(0, 0), + // child: Text( + // '搜索', + // style: + // FlutterFlowTheme.of(context).bodyMedium.override( + // fontFamily: 'Readex Pro', + // color: Colors.white, + // fontSize: AppFontsize.normal_text_size, + // letterSpacing: 0, + // ), + // ), + // ), + // ), + // ), + // ), + // ), + // ], + // ), + // ), + // ), + ); + } +} diff --git a/lib/pages/device_control/sleep_habit.dart b/lib/pages/device_control/sleep_habit.dart new file mode 100644 index 0000000..87e548a --- /dev/null +++ b/lib/pages/device_control/sleep_habit.dart @@ -0,0 +1,106 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/component/tool/ClickableContainer.dart'; + +class SleepHabitPage extends StatefulWidget { + @override + _SleepHabitPageState createState() => _SleepHabitPageState(); +} + +BoxConstraints? bodysize; + +class _SleepHabitPageState extends State { + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, cc) { + bodysize = cc; + return GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + iconTheme: const IconThemeData(color: Colors.white), + automaticallyImplyLeading: false, + titleSpacing: 0, + title: SizedBox( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '设备报修', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Padding( + padding: EdgeInsets.only( + left: 30.rpx, right: 30.rpx, top: 30.rpx), + child: Column( + children: [ + ClickableContainer( + backgroundColor: Color(0XFF003058), + highlightColor: Color(0XFF055466), + borderRadius: 16.rpx, + padding: EdgeInsets.only(top: 0), + onTap: () {}, + child: Container( + alignment: Alignment.center, + width: bodysize!.maxWidth * 1, + height: bodysize!.maxHeight * 0.056, + child: Text( + '柔性唤醒', + style: TextStyle( + fontSize: 26.rpx, color: Colors.white), + ))), + SizedBox(height: 20.rpx), + ClickableContainer( + backgroundColor: Color(0XFF003058), + highlightColor: Color(0XFF055466), + borderRadius: 16.rpx, + padding: EdgeInsets.only(top: 0), + onTap: () { + Get.toNamed('/syms'); + }, + child: Container( + alignment: Alignment.center, + width: bodysize!.maxWidth * 1, + height: bodysize!.maxHeight * 0.056, + child: Text( + '睡眠隐私', + style: TextStyle( + fontSize: 26.rpx, color: Colors.white), + ))) + ], + ))), + )), + ); + }); + } +} diff --git a/lib/pages/device_control/smys.dart b/lib/pages/device_control/smys.dart new file mode 100644 index 0000000..2d0cc83 --- /dev/null +++ b/lib/pages/device_control/smys.dart @@ -0,0 +1,380 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_switch/flutter_switch.dart'; +import 'package:vbvs_app/common/color/appColors.dart'; +import 'package:vbvs_app/common/util/FitTool.dart'; +import 'package:vbvs_app/common/util/MyUtils.dart'; +import 'package:vbvs_app/pages/common/selectDialog.dart'; + +import '../../controller/mh/sleeping_habit_controller.dart'; + +//睡眠隐私 +class Smys extends GetView { + Smys({super.key}); + + // get glController => Get.find(); + + getLine() { + return Container( + height: 1, + color: stringToColor("#152676"), + ); + } + + // updateParm( + // {int time = 2, bool isShowToast = true, Function? errorccCallback = null}) { + // ApiService.request + // .post( + // "/api/device/info/time/privacy/info?mac=${glController.model.deviceMain["mac"]}&time=${controller.model.smysStartTimeToString}-${controller.model.smysEndTimeToString}&type=${controller.model.smysIsStart ? '1' : '0'}") + // .then((d) { + // if (isShowToast) { + // showToast("操作成功", color: color_success); + // } + // }).catchError((d) { + // if (time > 0) { + // updateParm(time: time - 1, isShowToast: isShowToast, errorccCallback: errorccCallback); + // } else { + // errorccCallback?.call(); + // } + // }); + // } + + @override + Widget build(BuildContext context) { + SleepingHabitController controller = Get.find(); + + return LayoutBuilder( + builder: (context, boxConstraints) => GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/images/new_background.png'), // 本地图片 + fit: BoxFit.fill, // 填满整个 Container + ), + ), + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: AppBar( + backgroundColor: Colors.transparent, + automaticallyImplyLeading: false, + iconTheme: IconThemeData(color: Colors.white), + titleSpacing: 0, + // leading: returnIconButtomAddCallback(() { + // controller.saveDataApi(); + // updateParm(isShowToast: false); + // }), + // leading: returnIconButtomNew, + title: Container( + width: double.infinity, + height: 180.rpx, + child: Stack( + alignment: Alignment.center, + children: [ + // 中间居中的标题 + Text( + '睡眠隐私', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 30.rpx, + ), + ), + // 左侧图标 + Positioned( + left: 20.rpx, + child: returnIconButtomNew, + ), + ], + ), + ), + + actions: [], + centerTitle: false, + ), + body: SafeArea( + top: true, + child: Obx( + () => Container( + padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx), + width: MediaQuery.sizeOf(context).width, + height: MediaQuery.sizeOf(context).height * 1.123, + // decoration: BoxDecoration( + // color: Colors.transparent, + // image: DecorationImage( + // image: AssetImage("assets/images/background.png"), + // fit: BoxFit.cover, + // ), + // ), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + width: double.infinity, + height: MediaQuery.sizeOf(context).height * 0.055, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: const Color(0xFF929699), + width: 0.rpx), + ), + ), + constraints: BoxConstraints( + minHeight: 90.rpx, // 设置最小高度 + ), + child: Padding( + padding: EdgeInsets.fromLTRB( + 39.rpx, 0.rpx, 15.rpx, 0.rpx), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '睡眠隐私功能', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + Container( + + // height: + // MediaQuery.sizeOf(context).height * + // 0.04, + child: FlutterSwitch( + width: 70.rpx, + height: 36.rpx, + toggleSize: 30.rpx, + activeColor: Color(0XFF6BFDAC), + inactiveColor: Color(0XFF003058), + toggleColor: Color(0xFF011D33), + value: controller.model.smysIsStart, + onToggle: (val) { + controller.attr.update((getmodel) { + getmodel.model.smysIsStart = val; + }); + }, + ) + // Switch.adaptive( + // value: controller.model.smysIsStart, + // onChanged: (newValue) async { + // controller.attr.update((getmodel) { + // getmodel.model.smysIsStart = + // newValue; + // }); + // // updateParm(errorccCallback: () { + // // controller.attr.update((getmodel) { + // // getmodel.model.smysIsStart = !newValue; + // // }); + // // }); + // }, + // activeTrackColor: Color(0xFF6BFDAC), + // inactiveTrackColor: Color(0xFF003058), + // inactiveThumbColor: Color(0xFF011D33), + // trackOutlineWidth: MaterialStateProperty + // .resolveWith( + // (Set states) { + // if (states.contains( + // MaterialState.disabled)) { + // return null; + // } + // return null; // Use the default width. + // }), + // ), + + ), + ], + ), + )), + // getLine(), + Container( + width: double.infinity, + height: MediaQuery.sizeOf(context).height * 0.055, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: const Color(0xFF929699), + width: 0.rpx), + ), + ), + constraints: BoxConstraints( + minHeight: 90.rpx, // 设置最小高度 + ), + child: Padding( + padding: EdgeInsets.fromLTRB( + 39.rpx, 0.rpx, 30.rpx, 0.rpx), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '开始时间', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + InkWell( + onTap: () async { + showDayTimeSelectionDialog(context, + dayTimeArr: + controller.model.smysStartTime, + title: "开始时间", checkChange: (d) { + controller.attr.update((getmodel) { + getmodel.model.smysStartTime = [ + int.parse("${d[0]}"), + int.parse("${d[1]}") + ]; + }); + // updateParm(); + }); + }, + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Text( + "${controller.model.smysStartTimeToString}", + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 36.rpx, + letterSpacing: 0, + ), + ), + SizedBox( + width: 16.rpx, + ), + Icon( + Icons.expand_more, + color: Colors.white, + size: 40.rpx, + ), + ], + ), + ), + ], + ), + )), + // getLine(), + Container( + width: double.infinity, + height: MediaQuery.sizeOf(context).height * 0.055, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: const Color(0xFF929699), + width: 0.rpx), + ), + ), + constraints: BoxConstraints( + minHeight: 90.rpx, // 设置最小高度 + ), + child: Padding( + padding: EdgeInsets.fromLTRB( + 39.rpx, 0.rpx, 30.rpx, 0.rpx), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + '结束时间', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 30.rpx, + letterSpacing: 0, + ), + ), + InkWell( + onTap: () async { + showDayTimeSelectionDialog(context, + dayTimeArr: + controller.model.smysEndTime, + title: "结束时间", checkChange: (d) { + controller.attr.update((getmodel) { + getmodel.model.smysEndTime = [ + int.parse("${d[0]}"), + int.parse("${d[1]}") + ]; + }); + // updateParm(); + }); + }, + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Text( + "${controller.model.smysEndTimeToString}", + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Colors.white, + fontSize: 36.rpx, + letterSpacing: 0, + ), + ), + SizedBox( + width: 16.rpx, + ), + Icon( + Icons.expand_more, + color: Colors.white, + size: 40.rpx, + ), + ], + ), + ), + ], + ), + ), + ), + // getLine(), + SizedBox( + height: 30.rpx, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 25.rpx), + child: Container( + width: double.infinity, + decoration: BoxDecoration(), + child: Text( + '*注:开启睡眠隐私功能后,在设置的时间段内,将不会采集您的睡眠数据。', + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: 'Readex Pro', + color: Color(0xFF9EA4B7), + fontSize: 20.rpx, + letterSpacing: 0, + ), + ), + ), + ) + ], + ), + ), + ), + ), + ), + ), + )), + ); + } +} diff --git a/lib/pages/main_bottom/component/MessageWidgetWidget.dart b/lib/pages/main_bottom/component/MessageWidgetWidget.dart index 8725ff0..c54d559 100644 --- a/lib/pages/main_bottom/component/MessageWidgetWidget.dart +++ b/lib/pages/main_bottom/component/MessageWidgetWidget.dart @@ -35,7 +35,7 @@ class _MessageWidgetWidgetState extends State { return Stack( children: [ ClickableContainer( - backgroundColor: themeController.currentColor.sc5, + backgroundColor: Color(0xFF003058), highlightColor: themeController.currentColor.sc3, borderRadius: 20.rpx, padding: @@ -93,7 +93,7 @@ class _MessageWidgetWidgetState extends State { .toList(), ), ), - ].divide(SizedBox(width: 35.rpx)), + ].divide(SizedBox(width: 30.rpx)), ), ], ), diff --git a/lib/pages/main_bottom/component/main_page_b_bottom_change.dart b/lib/pages/main_bottom/component/main_page_b_bottom_change.dart new file mode 100644 index 0000000..9249970 --- /dev/null +++ b/lib/pages/main_bottom/component/main_page_b_bottom_change.dart @@ -0,0 +1,246 @@ +// import 'dart:io'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// import 'package:get/get.dart'; +// import 'package:vbvs_app/component/tool/TopSlideNotification.dart'; +// import 'package:vbvs_app/controller/main_bottom/global_controller.dart'; +// import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart'; +// import 'package:vbvs_app/controller/message/message_controller.dart'; +// import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; +// import 'package:vbvs_app/controller/user_info_controller.dart'; +// import 'package:vbvs_app/enum/LoginStatus.dart'; +// import 'package:vbvs_app/pages/common/bezier_bottom_navigation_bar.dart'; +// import 'package:vbvs_app/pages/main_bottom/e_page.dart'; +// import 'package:vbvs_app/pages/main_bottom/home_page.dart'; +// import 'package:vbvs_app/pages/main_bottom/message_page.dart'; +// import 'package:vbvs_app/pages/main_bottom/mine_page.dart'; + +// class MainPageBBottomChange extends StatefulWidget { +// const MainPageBBottomChange({super.key}); + +// @override +// State createState() => _MainPageBottomChangeState(); +// } + +// class _MainPageBottomChangeState extends State +// with SingleTickerProviderStateMixin { +// final GlobalController globalController = Get.find(); +// final ThemeController themeController = Get.find(); +// final MessageController messageController = Get.find(); +// final MainPageController controller = Get.find(); +// final UserInfoController userInfoController = Get.find(); + +// late AnimationController _animationController; +// late Animation _positionAnimation; + +// final List pages = [ +// const HomePage(), +// const EPage(), +// const MessagePage(), +// const MinePage(), +// ]; + +// final List titles = ['首页', '报告', '控制', '我的']; +// final List icons = [ +// Icons.home, +// Icons.android, +// Icons.message, +// Icons.person, +// ]; + +// int selectedIndex = 0; +// double currentPosition = 0.0; + +// DateTime? _lastBackPressedTime; + +// @override +// void initState() { +// super.initState(); +// selectedIndex = controller.model.currentIndex; +// currentPosition = selectedIndex.toDouble(); + +// _animationController = AnimationController( +// vsync: this, +// duration: const Duration(milliseconds: 300), +// ); + +// _positionAnimation = Tween( +// begin: currentPosition, +// end: currentPosition, +// ).animate(CurvedAnimation( +// parent: _animationController, +// curve: Curves.easeOut, +// )) +// ..addListener(() { +// setState(() {}); +// }); +// } + +// void _onTabTapped(int index) { +// bool isLoggedIn = userInfoController.model.login == LoginStatus.LOGIN.code; + +// if ((index == 1 || index == 2) && !isLoggedIn) { +// TopSlideNotification.show(context, text: "必须登录提示".tr); +// Future.delayed(const Duration(milliseconds: 100), () { +// Get.toNamed("/loginPage"); +// }); +// return; +// } + +// if (selectedIndex != index) { +// final begin = currentPosition; +// final end = index.toDouble(); +// _positionAnimation = Tween(begin: begin, end: end).animate( +// CurvedAnimation(parent: _animationController, curve: Curves.easeOut), +// )..addListener(() { +// setState(() {}); +// }); + +// _animationController.forward(from: 0.0); +// currentPosition = end; +// selectedIndex = index; + +// controller.model.currentIndex = index; +// controller.updateAll(); +// } +// } + +// @override +// void dispose() { +// _animationController.dispose(); +// super.dispose(); +// } + +// Future _handleBackPressed() async { +// final now = DateTime.now(); +// if (_lastBackPressedTime == null || +// now.difference(_lastBackPressedTime!) > const Duration(seconds: 2)) { +// _lastBackPressedTime = now; +// TopSlideNotification.show(context, text: "滑动退出提醒".tr); +// return false; +// } +// return true; +// } + +// @override +// Widget build(BuildContext context) { +// return PopScope( +// canPop: false, +// onPopInvokedWithResult: (disposition, result) async { +// if (Platform.isAndroid) { +// final exit = await _handleBackPressed(); +// if (exit) SystemNavigator.pop(); +// } +// }, +// child: Obx(() { +// final hideBar = globalController.model.hideBottomNavigationBar; +// return Scaffold( +// backgroundColor: Colors.transparent, +// body: pages[controller.model.currentIndex], +// bottomNavigationBar: hideBar +// ? null +// : BezierBottomNavigationBar( +// selectedIndex: selectedIndex, +// animatedPosition: _positionAnimation.value, +// icons: icons, +// titles: titles, +// onTap: _onTabTapped, +// ), +// ); +// }), +// ); +// } +// } +import 'package:flutter/material.dart'; +import 'package:vbvs_app/pages/common/bezier_bottom_navigation_bar.dart'; +import 'package:vbvs_app/pages/device_control/MattressControl.dart'; +import 'package:vbvs_app/pages/device_control/new_Home_page.dart'; +import 'package:vbvs_app/pages/device_control/new_mine_page.dart'; +import 'package:vbvs_app/pages/device_control/score_page.dart'; + +class MainPageBBottomChange extends StatefulWidget { + @override + _HomePageState createState() => _HomePageState(); +} + +class _HomePageState extends State + with SingleTickerProviderStateMixin { + int selectedIndex = 0; + late AnimationController _controller; + late Animation _positionAnimation; + double currentPosition = 0.0; + + final List titles = ['首页', '报告', '控制', '我的']; + final List path = [ + "assets/images/bar_home.svg", + "assets/images/bar_heart.svg", + "assets/images/bar_control.svg", + "assets/images/bar_mine.svg" + ]; + + final List pages = [ + NewHomePage(), + // PeopleInfoPage(), + // Text('报告'), + ScorePage(), + // Smys(), + MattressControlPage(), + NewMinePage() + ]; + @override + void initState() { + super.initState(); + _controller = AnimationController( + vsync: this, duration: const Duration(milliseconds: 300)); + currentPosition = selectedIndex.toDouble(); + _positionAnimation = Tween( + begin: currentPosition, end: currentPosition) + .animate(CurvedAnimation(parent: _controller, curve: Curves.easeOut)) + ..addListener(() { + setState(() {}); // trigger rebuild for CustomPainter + }); + } + + void _onTabTapped(int index) { + setState(() { + final begin = currentPosition; + final end = index.toDouble(); + _positionAnimation = Tween(begin: begin, end: end).animate( + CurvedAnimation(parent: _controller, curve: Curves.easeOut), + )..addListener(() { + setState(() {}); + }); + _controller.forward(from: 0.0); + currentPosition = end; + selectedIndex = index; + }); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + Widget _buildPageContent() { + return Center(child: Text('页面 ${titles[selectedIndex]}')); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color(0xFF011C33), + body: IndexedStack( + index: selectedIndex, + children: pages, + ), + bottomNavigationBar: BezierBottomNavigationBar( + selectedIndex: selectedIndex, + animatedPosition: _positionAnimation.value, + onTap: _onTabTapped, + path: path, + titles: titles, + ), + ); + } +} diff --git a/lib/pages/main_bottom/message_page.dart b/lib/pages/main_bottom/message_page.dart index f894327..160c355 100644 --- a/lib/pages/main_bottom/message_page.dart +++ b/lib/pages/main_bottom/message_page.dart @@ -407,6 +407,7 @@ class _MessagePageState extends State { ], ), ), + SizedBox(height: 17.rpx), ], ), diff --git a/lib/pages/main_bottom/mine_page.dart b/lib/pages/main_bottom/mine_page.dart index 6d6b5f2..90483c7 100644 --- a/lib/pages/main_bottom/mine_page.dart +++ b/lib/pages/main_bottom/mine_page.dart @@ -737,4 +737,5 @@ class _MinePageState extends State { ), ); } + } diff --git a/lib/routers/mh_routers.dart b/lib/routers/mh_routers.dart new file mode 100644 index 0000000..effab34 --- /dev/null +++ b/lib/routers/mh_routers.dart @@ -0,0 +1,110 @@ +import 'package:ef/ef.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:path/path.dart'; +import 'package:vbvs_app/controller/mh/muser_info_controller.dart'; + +import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; + +import 'package:vbvs_app/pages/device_control/HomeDeviceType.dart'; +import 'package:vbvs_app/pages/device_control/LanguagePage.dart'; +import 'package:vbvs_app/pages/device_control/address_list_page.dart'; +import 'package:vbvs_app/pages/device_control/apply_repair_page.dart'; +import 'package:vbvs_app/pages/device_control/book_info_page.dart'; +import 'package:vbvs_app/pages/device_control/book_success_page.dart'; +import 'package:vbvs_app/pages/device_control/device_people_info.dart'; +import 'package:vbvs_app/pages/device_control/edit_bed.dart'; +import 'package:vbvs_app/pages/device_control/edit_userinfo_page.dart'; +import 'package:vbvs_app/pages/device_control/experience_store_page.dart'; +import 'package:vbvs_app/pages/device_control/issue_list_page.dart'; +import 'package:vbvs_app/pages/device_control/my_experience_page.dart'; +import 'package:vbvs_app/pages/device_control/people_info.dart'; +import 'package:vbvs_app/pages/device_control/repair_history_page.dart'; +import 'package:vbvs_app/pages/device_control/repair_list.dart'; +import 'package:vbvs_app/pages/device_control/room_picker.dart'; +import 'package:vbvs_app/pages/device_control/sleep_habit.dart'; +import 'package:vbvs_app/pages/device_control/smys.dart'; + +import '../pages/device_control/bluetooth.dart'; +import '../pages/device_control/edit_address_page.dart'; +import '../pages/device_control/message_page.dart'; +import '../pages/device_control/new_settingPage.dart'; + +ThemeController themeController = Get.find(); + +var mhroutes = { + "/homeDeviceType": (contxt) => HomeDeviceType(), + "/editUserInfoPage": (contxt) => EditUserInfoPage(), + "/peopleInfoPage": (contxt) => PeopleInfoPage(), + "/repairHistoryListPage": (contxt) => RepairHistoryListPage(), + "/deviceRepairPage": (contxt) => DeviceRepairPage(), + "/settingPage": (contxt) => SettingPage(), + "/issueListpage": (contxt) => IssueListPage(), + "/messagePage": (contxt) => MessagePage(), + "/addressListPage": (contxt) => AddressListPage(), + "/editAddressPage": (contxt) => EditAddressPage(), + "/languagePage": (context) => LanguagePage(), + '/bluetoothPage': (context) => BluetoothPage(), + "/devicePeopleInfo": (context) => DevicePeopleInfo(), + "/sleepHabitPage": (context) => SleepHabitPage(), + '/syms': (context) => Smys(), + "/applyRepairPage": (context) => ApplyRepairPage(), + "/roomPickerPage": (context) => RoomPickerPage(), + "/editBedPage": (context) => EditBedPage(), + "/experienceStorePage": (context) => ExperienceStorePage(), + "/bookInfoPage": (context, {arguments}) => BookInfoPage(data: arguments), + "/bookSuccessPage": (contxt, {arguments}) => + BookSuccessPage(data: arguments["data"]), + "/myExperiencePage": (context) => MyExperiencePage(), +}; +var mhonGenerateRoute = (RouteSettings settings) { + final String? name = settings.name; // 获取路由名称,如 /news 或 /search + final Function? pageContentBuilder = mhroutes[name]; // 根据路由名称获取对应的页面构建器 + + if (pageContentBuilder != null) { + MUserInfoController userInfoController = Get.find(); + int loginStatus = userInfoController.model.login!; + + // 检查用户是否已登录,如果未登录且路由不是登录相关页面,跳转到登录页面 + // if (loginStatus != 1) { + // // 如果用户未登录且访问的不是登录页面等,展示提示并重定向 + // if (settings.name != "/loginPage" && + // settings.name != "/otherLoginPage" && + // settings.name != "/mianPageBottomChange") { + // TopSlideNotification.show( + // Get.context!, + // text: "必须登录提示".tr, + // textColor: themeController.currentColor.sc9, + // ); + + // // 创建新的 RouteSettings,并修改 name 为 /loginPage + // final updatedSettings = RouteSettings( + // name: "/loginPage", + // arguments: settings.arguments, + // ); + + // // 创建一个新的路由,跳转到登录页面 + // return CupertinoPageRoute( + // settings: updatedSettings, + // builder: (context) => pageContentBuilder!(context), + // ); + // } + // } + + // 如果有路由参数,传递参数 + if (settings.arguments != null) { + return CupertinoPageRoute( + settings: settings, + builder: (context) => + pageContentBuilder!(context, arguments: settings.arguments), + ); + } else { + // 没有路由参数时,直接构建页面 + return CupertinoPageRoute( + settings: settings, + builder: (context) => pageContentBuilder!(context), + ); + } + } + + return null; // 如果路由名称没有匹配的页面,返回 null +}; diff --git a/lib/routers/routers.dart b/lib/routers/routers.dart index 86a613a..3be65ba 100644 --- a/lib/routers/routers.dart +++ b/lib/routers/routers.dart @@ -21,6 +21,7 @@ import 'package:vbvs_app/pages/device_bind/wifi_page.dart'; import 'package:vbvs_app/pages/device_bind/wifi_page_person.dart'; import 'package:vbvs_app/pages/login/login.dart'; import 'package:vbvs_app/pages/login/other_login.dart'; +import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart'; import 'package:vbvs_app/pages/main_bottom/e_page.dart'; import 'package:vbvs_app/pages/main_bottom/follow_page.dart'; import 'package:vbvs_app/pages/main_bottom/help_page.dart';