From 5064de739935904e9fd3a31bbebe94833c333303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E5=AE=87=E5=AE=81?= Date: Thu, 8 Oct 2026 20:10:40 +0700 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=9F=8B=E7=82=B9=EF=BC=8Cim?= =?UTF-8?q?=E5=92=8C=E5=AE=A2=E6=9C=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/images/common/ic_launcher.webp | Bin 0 -> 29686 bytes assets/images/home/home_0_0.png | Bin 0 -> 5200 bytes assets/images/home/home_0_1.png | Bin 0 -> 1427 bytes assets/images/home/home_1_0.png | Bin 0 -> 4188 bytes assets/images/home/home_1_1.png | Bin 0 -> 1265 bytes assets/images/home/home_2_0.png | Bin 0 -> 2652 bytes assets/images/home/home_2_1.png | Bin 0 -> 945 bytes assets/images/home/home_3_0.png | Bin 0 -> 4376 bytes assets/images/home/home_3_1.png | Bin 0 -> 1262 bytes assets/images/home/home_4_0.png | Bin 0 -> 4435 bytes assets/images/home/home_4_1.png | Bin 0 -> 1431 bytes assets/images/home/home_5_0.png | Bin 0 -> 5224 bytes assets/images/home/home_5_1.png | Bin 0 -> 1868 bytes assets/images/home/publish.png | Bin 0 -> 1342 bytes assets/images/mine/mine_agent_enter.webp | Bin 0 -> 4030 bytes assets/images/mine/mine_ai_enter.webp | Bin 0 -> 12496 bytes assets/images/mine/mine_gold_enter.webp | Bin 0 -> 7452 bytes assets/images/mine/mine_vip_enter.webp | Bin 0 -> 13724 bytes lib/alert/splash/app_center_dialog.dart | 3 - lib/alert/splash/notice_image_dialog.dart | 3 - lib/alert/video/buy_vip_alert.dart | 63 ---------- lib/alert/video/share_media_dialog.dart | 6 +- lib/assets_tool/images.dart | 2 - lib/hj_model/splash/ads_model.dart | 8 -- lib/hj_model/user/user_info_model.dart | 17 --- lib/hj_page/ai/ai_home_page.dart | 12 +- lib/hj_page/ai/ai_mod_detail_page.dart | 3 +- .../ai/ai_sub_type/ai_strip_sub_page.dart | 2 +- lib/hj_page/ai/widgets/ai_girl_sheet.dart | 26 ---- lib/hj_page/ai/widgets/ai_image_record.dart | 7 -- lib/hj_page/cartoon/audio_player_content.dart | 8 +- lib/hj_page/cartoon/cartoon_read_logic.dart | 46 ++----- .../cartoon/cartoon_sub_detail_page.dart | 2 +- .../cartoon/cartoon_sub_grid_logic.dart | 10 -- .../cartoon/cartoon_sub_grid_page.dart | 5 - .../cartoon/text_novel_read_logic.dart | 48 ------- .../cartoon/widget/acg_source_manager.dart | 50 +------- .../comment/widget/comment_rich_text.dart | 2 +- .../community/community_tab_page.dart | 5 - .../community_main_logic.dart | 3 - .../community_main_page.dart | 11 -- .../community/group_chat/group_chat_page.dart | 4 - .../post_detail_page/post_detail_page.dart | 2 - .../widget/community_sort_header.dart | 13 -- lib/hj_page/drama/drama_list_logic.dart | 1 - lib/hj_page/drama/drama_list_page.dart | 6 - lib/hj_page/drama/drama_tag_detail_logic.dart | 1 - lib/hj_page/drama/drama_tag_detail_page.dart | 6 - .../find/pic_collect/pics_detail_logic.dart | 1 - .../find/rank_module/rank_type_tab_view.dart | 1 - .../activity_float/home_float_banner.dart | 2 +- .../swiper_floating_widget.dart | 1 - .../home/home_cell_style/quick_entry_row.dart | 2 +- .../home_cell_style/tiktok_simple_cell.dart | 4 +- .../home/home_cell_style/video_hor_cell.dart | 4 +- .../home_cell_style/video_simple_cell.dart | 25 +--- lib/hj_page/home/home_main_page.dart | 46 ++----- .../home_sub_module/home_tab_drama_logic.dart | 4 - .../home_tab_section_page.dart | 9 -- .../home_sub_module/home_tab_sort_page.dart | 22 +--- .../home_sub_module/widget/sort_header.dart | 11 +- .../home/search_page/search_main_page.dart | 2 - .../search_acg_result_page.dart | 20 +-- .../search_video_result_page.dart | 119 +++--------------- .../widget/common_search_widget.dart | 2 - lib/hj_page/home/widget/home_txt_marquee.dart | 10 +- .../home/widget/publist_entry_alert.dart | 3 +- lib/hj_page/live/live_detail_page.dart | 2 - lib/hj_page/live/live_main_page.dart | 2 +- lib/hj_page/live/live_sub_page.dart | 5 +- lib/hj_page/main_page/main_logic.dart | 38 ++---- lib/hj_page/main_page/main_tabbar.dart | 42 +------ lib/hj_page/mine/home_mine_logic.dart | 7 +- lib/hj_page/mine/home_mine_page.dart | 61 ++------- .../mine/identity/mine_identity_page.dart | 2 +- .../mine_withdrawal_record_logic.dart | 2 - .../mine/make_money/withdrawal_page.dart | 14 --- .../mine/message/message_center_logic.dart | 4 +- .../mine/message/message_center_page.dart | 23 +--- .../mine_following/mine_follow_sub_logic.dart | 2 - .../widget/gesture_password_widget.dart | 3 - .../mine/mine_profit/bank_card_home_page.dart | 2 +- .../mine_setting/mine_find_account_page.dart | 5 - .../mine/mine_setting/mine_setting_page.dart | 1 - .../mine_setting_profile_logic.dart | 2 - .../mine/mine_share/mine_share_page.dart | 2 +- .../mine/mine_vip/mine_charge_coin_page.dart | 31 +---- .../mine/mine_vip/mine_charge_vip_page.dart | 68 +--------- .../mine/mine_vip/online_pay_page.dart | 17 --- .../mine/mine_vip/pay_success_alert.dart | 21 +--- .../widgets/coin_pay_bottom_sheet.dart | 34 +---- .../mine/more_question/mine_qa_page.dart | 4 +- .../mine/welfare/lou_feng_ad_page.dart | 6 +- .../mine/welfare/more_free_video_logic.dart | 4 +- .../mine/welfare/welfare_home_page.dart | 1 - .../welfare/widget/recommend_app_page.dart | 15 +-- .../mine/welfare/widget/task_widgets.dart | 4 +- .../mine/widgets/integral_exchange_page.dart | 86 +------------ .../mine/widgets/mine_info_widget.dart | 9 +- .../mine/widgets/mine_share_qr_view.dart | 2 +- .../short_video/view/feed_ad_view.dart | 6 +- .../short_video/view/float_ad_view.dart | 6 +- .../short_video/view/media_action_menu.dart | 3 - .../view/video_player_base_logic.dart | 10 +- lib/hj_page/splash/splash_ad_view.dart | 11 +- lib/hj_page/splash/splash_logic.dart | 55 +------- .../user_center_page/user_center_logic.dart | 16 --- .../widget/user_center_header.dart | 19 +-- .../cartoon/video_detail_cartoon_view.dart | 7 +- lib/hj_page/video/video_logic.dart | 18 +-- lib/hj_page/video/view/video_ad_widget.dart | 2 - lib/hj_page/video/view/video_detail_view.dart | 6 +- lib/hj_page/video/view/video_menu_view.dart | 7 -- lib/hj_utils/api_service/common_service.dart | 9 +- lib/hj_utils/api_service/drama_service.dart | 2 +- lib/hj_utils/api_service/mine_service.dart | 6 - lib/hj_utils/dns_solve/_response.dart | 2 +- lib/hj_utils/local_server.dart | 40 +++--- lib/hj_utils/local_server_guard.dart | 16 ++- lib/main.dart | 25 +--- lib/routers/jump_router.dart | 34 +---- lib/tools_base/banner/ads_banner.dart | 12 -- lib/tools_base/banner/ads_grid_view.dart | 13 +- lib/tools_base/banner/ads_item.dart | 65 +++------- .../src/item_positions_listener.dart | 4 +- .../src/positioned_list.dart | 5 +- .../src/scrollable_positioned_list.dart | 9 +- .../scroll_positioned_list/src/viewport.dart | 3 - .../scroll_positioned_list/src/wrapping.dart | 11 +- lib/track_event_manager/device_service.dart | 3 +- m3u8_downloader-master/example/lib/main.dart | 2 - m3u8_downloader-master/pubspec.yaml | 1 - pubspec.yaml | 13 -- 133 files changed, 220 insertions(+), 1405 deletions(-) create mode 100644 assets/images/common/ic_launcher.webp create mode 100644 assets/images/home/home_0_0.png create mode 100644 assets/images/home/home_0_1.png create mode 100644 assets/images/home/home_1_0.png create mode 100644 assets/images/home/home_1_1.png create mode 100644 assets/images/home/home_2_0.png create mode 100644 assets/images/home/home_2_1.png create mode 100644 assets/images/home/home_3_0.png create mode 100644 assets/images/home/home_3_1.png create mode 100644 assets/images/home/home_4_0.png create mode 100644 assets/images/home/home_4_1.png create mode 100644 assets/images/home/home_5_0.png create mode 100644 assets/images/home/home_5_1.png create mode 100644 assets/images/home/publish.png create mode 100644 assets/images/mine/mine_agent_enter.webp create mode 100644 assets/images/mine/mine_ai_enter.webp create mode 100644 assets/images/mine/mine_gold_enter.webp create mode 100644 assets/images/mine/mine_vip_enter.webp diff --git a/assets/images/common/ic_launcher.webp b/assets/images/common/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..7e39d852e41fc7a80c4097aa6357ae5de8a34184 GIT binary patch literal 29686 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 literal 0 HcmV?d00001 diff --git a/assets/images/home/home_1_0.png b/assets/images/home/home_1_0.png new file mode 100644 index 0000000000000000000000000000000000000000..ed90360ce9857c124727bffd9f75c397cdeffd82 GIT binary patch literal 4188 zcmV-i5ToyjP)#Mr6?hCAzGzE@0clrb$g|O#7oYq#6zNkyhzL5qwp7 zv%v1&bIwe^$ILnB-rbdZFT3Yf)T%oY0z*^v{5JtN3z&-f>z(DWXr(qIdLJ4&1 z?JK|HQuio|#vIxv?vb`0wprX~4nn-FUqSk6`eUe^;u5%b^ zxqQpUp66i#p)LZ=U(&rD@tFfv3YO6Ws8*mJ?5I8@Ng8+KyyDFWGe%zmQ9-ry*RD0X z4HZ<^Kwr-@FhQW}>^BWpP7rDTC@ygq3GO06v|`jdiR15LKj3fa1BtaR=5KJZvzEu_ z{b){`y(32?&bLcj{w{O63>TS`aKLX34|Xo?{xVDu)Wt!acdq&ZZf_ZO?y%M(Cus6f z&c&v4t2!1fPv-B`%23{qM5w5Av2FnW|6|RZ4~$wT>+TJ~=!PRor#B5e{_qEIl5kQ= zdfwu$enj$WdJnYVy^qm1BTj%#Ksw{_5iUxijQKE!xA8d{7HO!tU&sK%j#H+vU&@NE}K!CDI4=v z)i@<{(OAgW%;uIh{=V3>xBUc85a0IW zwryT|2)vTc7E~e>-c9CjkoR(1^qozQuKBPQ59HJ*aI&ka%syLBTi_lo%W|J=d*oBz zJg{-yKcPv8#%s8BY1i_2*!@TuCF|01BlvFkHFszi zUa3^Z^d)i0UR+^A?tN?Y6D&{3E&=1`8_DlbxftS#%dxlvnuKvh%sTiXTMuMc+z_#L zg8l}ww<6I=f$Bjllp}Fs>mvQ3_^^eMck0LO3Q`*DTsEHGRlX6 zx74X5Z}a^un`xZJGg3JHRlCc$WP<(vEZe(~|A;jv)B z%Cl@_ug8V1!_Uhz(^a#RDvtvjJ4(lI+^}K8QD_jNdOI4WzmX#MgvGUDUxT{vG((G9j|Ab@~-RSpad=@Ma>3?%(Kh6L_$U6 z7JB2(&Ig+UZ1h>BDG@x+_m10~{PQv!MHL4PK&n$DJBKd5hWUsBT*bJs*DvcKhn@#b zKwTV!gt%Ifk|uO)fpfS{%Ak~kLMAS8Y*C1ltbF@=?uR9kn3b)fl1{lE87m@hjFb74 zIHO_B3>PKef>>-Q5>LgHRU-;Rf2gdCrt_D63-lECnH@cx|Fz5J7Y?-3!Pyuh<#p z-7Ra^9$UEVXJ^Jkl?U;}r(uxk#gq&}cc{9@SbN!D$@@{C;NkVd)D4VHd zE=ePzrv%oQtSU*_jW8GOf{7*&ESoeP*4^6YVMPCC z%a)!h9@)J9fxQ@czm3yg;@I08ZDcTQdnHbHnzHHjsnyrdThg^xEB6)>YUv$pRofm02wYsKV?sc2BBUnRzl}BX6M!Bhm1aka&me;vbH{IU=~wyD*+p~_O07K z-o$wNsU`71D3!{iILNZ{RcW4|wx?mI>(E!cj#tte@v>gQan3Pw8yFu^e3FcGZsG~_ z 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 b-X{M5TCi%2{E#<-00000NkvXXu0mjfh?zMd literal 0 HcmV?d00001 diff --git a/assets/images/home/home_2_0.png b/assets/images/home/home_2_0.png new file mode 100644 index 0000000000000000000000000000000000000000..f33266ce64e93bb1f3dd66ca6e4be489dec693fe GIT binary patch literal 2652 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 KMNUMnLSTXg-Q@x8NbgeOa+tpsz&PVkl$k?Qu zE{-E4^vYC?pcp-WQ9?-AJ5-`>1ck0u`iy&2q?$m(@9eHM=Eg?i9V$_!i?MXA=eUIZ zriM4F6G3J+xpua}?_GZRf8cDMX=-^R@d)z%Wv($H8oJSa^HFC-wfFskAfgcz8%Y_O zr@T#rIjrz;qAP}M7hB;2sMCpKC=D0)Mq&c_=o#>lczJ#l*mu}>ts#V51f_YNDS=wh z-zDaaLM@j|qR>HrV8U6?gqgHC;UQL{Bk%ovjVihRX zY_{OQ;3d*=b)%Fz(=2QPc|T&Zhun7JT;9lL6E>$e;)|eF(PWgv^ctiF5D^6cTo^H!7OV$I0j)aO99sknazk%TYfn zt{as_P>$!J!S&2yZ7SCj7I zr#p6#A=w*|BdB200pa1t%gKJ^;aG`1CdnJoBghm@M$bQbVy#_p{k=&k(UJs;K4OdO zVMFysvo1fGNdozurD4y`HHfs2+h%&o#bl%C z_wQH-3e?*`DZp-OFVZ=(O0IE<*Ckcyp_q#vZlZbt{~V(zilQirq9}@@D8>8({6N_j TgEcmo00000NkvXXu0mjfvjeAx literal 0 HcmV?d00001 diff --git a/assets/images/home/home_3_0.png b/assets/images/home/home_3_0.png new file mode 100644 index 0000000000000000000000000000000000000000..30c39a4a71f6f8b68704331a9ce1991c28bdd0b4 GIT binary patch literal 4376 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 Y1B`Ql62Yshy#N3J07*qoM6N<$f<~}SXaE2J literal 0 HcmV?d00001 diff --git a/assets/images/home/home_4_0.png b/assets/images/home/home_4_0.png new file mode 100644 index 0000000000000000000000000000000000000000..3b77a729ea360a28bc8fdd3d06dcf546315f5cef GIT binary patch literal 4435 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 lQzbr literal 0 HcmV?d00001 diff --git a/assets/images/home/home_5_0.png b/assets/images/home/home_5_0.png new file mode 100644 index 0000000000000000000000000000000000000000..b9f013b9a2d694e38cddd64569dc40da9102fd71 GIT binary patch literal 5224 zcmV-u6qoCXP)UbncsKreed-`vue44Ac=~m1!YmL?(0Wu%e&nVW@^GmJ?=gCp8K71zVq$hX@K)^9?rvA1cU-XWp&+O z6SfBd&09((o@!e9^gcKTP*GF+C>XU6z&y8l`QoRbz)%nZJ@m&5MyJ!}LqLUKjG;%L z5aJ&;FJJsToF%B5H*aXzuId4?lG`-siI(MyFN6Yvf&xG~(BlbJNW=+<<{>>ANfUmy zqGrLa8MA69K!JfbB<%1v5OHR>@j?U~R8=)^C=?h9LLe35<+O)1QKJDg{Xiy7+d2|G zTw7UFxAcLB7L0}h0EzPWOd8*yp+-?Nh{hw1)oITg0tJSG5J)2oMkInD2J#bPahnNc zLXx`sJ%nEnp&oz%Kvm8B>p+=b7&MpJu^==;B+v#-pio~91qL4q00wX*{TD_J0&VC& zR!2yCVB{fOM(rOFk?t`jTx-xDg+`C2SA(g`cEsvXUZi`OvP z%9;hYYGYOtLCUB}T!XCZdMQzVBor75LLg$pkR~4zO~CMs(dufxHM|zOGp;W^znh45 zH?lMWfa_#?8MxGS`#NF0kJUZtv6D-?sXXy7z#ol z)-P=0WjR)|$R!eSqK!q-M$(HFjmdsxMEvNzQt}yhr-lAr}tIN~y+$~Zze z-UZczy--jX5i?i{!YIb>Iu2}>|IO@J&1S=W+nAw~_$g*nt@&Cdosk|!&( zX!~ZFQk#N{SV7D@O}7MCd5WGuXWq#-kt>^hq<7*(I!DqvceV|^?&a!!7=0gF+#<@k z?`2H1I08`WyOrPn^UI)s;K2Z)qWbY`XyV^vYwi@Mc3i^DpfRg5gtgq&sU3cAADV1G z)AN1yKKl%N@S!}jqGnYa<4X_??-)P%=E3i8UiU5(00tb3RnD$^g6Jagkh4c7vRT6U z&W1U8a>mWcn%FF3PPcJ6CeKk1bKdpzlYtD%m{x~HuUy}Q=;^BFr40vQ05Bj9s;sV^ zL6e!w6IHTO+F`3mS;Gpqpj9WvsZnj!4Bs2kRO|vNr`oBlBW_aGI2k1jVhuiG4|k#U zo()+qR$gvAF$sc)`jyd}>DN!b6}D|&w+Z?Q{U*??S&v^zEBlcU!HJD5h$h^lt?lBB z^L#B4qkCoVt(eGy9cytv9pMv#38C#X1WOQ0{778UjblX|-8lAJm~`Fbn}I}bGxP)c zO`!5gQ(I|brDChH3yI88v}kMi(Q+1ZiExBt7)u<3St5b^<=(5DdlLzuf!uF)(;U_j zwKkEZTuazC5&P|?cf+a6Am=$voG^unv_3YG`lW*&tf~7$t@U5^D2beFk8fZS}RnNBdHP0C|PjahflSE%4ZUU;gEscw| zKn&=YAEdRJMcy67Us@<()d%J%TgNY~gOv>fvSAWBWlFMWqA<<%b?>ckMBlP@VM-&u zXV6;}XMrt^^}n1^GjEGRzlrdak(AD&$FT?$n}aH6FSv*NwI|W~v^|z3FOYZ%jLA|9 za#;_0g`T#D*-DCFRrAs%??FGIqUNz_MCnImd=DOtgDW-%(GZnZNowmc1G*R?TBM81 zMMbEbHbw^BJ&#(slBaUz>oX73Gfm4EZG{0smtXouQKpSt5miR+>{sYf-UN!}Nza&5 zJAr6%p-qB`$IDa-t%WfzIpz{r#wN~CuITzfwjWp}tt}2Q|Ma7H&S>(CaZ6dEb9Nz! z!|>XV7q-*oL;8iJ^~c8fHXa9QxKk+%#jpw!*oRRhs>M=EPs>lj7AkAtoL7g|Z?XdC z{1OPq0oSEfQBlk8N^EL$0Cq2SWb#r6bO4V#(BhOeZH&$mM#>clOm5C zB$IV=Tr*iR!l#aElpB5}YDUTkcz`&pdN@+J^^-WZA_Ld&2z z21-E>p>p%3+Pcjc^#|(~^K)er`b6yzJj7p;&UqEiG8k0FD3uRri}PLH1k#|m@({We z=eR5qVWIW;&~XrpyH!h)GZQ~j_)fY+4Cg8DQ1i0-RS**@>gr1UHZxjlA75Vn%m;aW zWOOl$7a5Xvhyi(7EYKS1{(iTL+}?5&Z(`;=Q~=coxkyZ2QeUT0=ei|7ELS>5N8NM$YKTj z1IQK$UG`8268S};=r74Kq7aWP*K04m^!y=+0W)Vlc_GDMPtt8FBD&UiSH;8gt~t}U z#KOa59tn&^p!{`^QNziJ3vH+XQV6-vgK@7;7gD79&M2b9Jxz{eoY~+XT zJzqut(!EmbcW~ZV#EQy7_DcKsI>Z1=oc8-^mxhUW+9G8@>WxHLJo+mutLNX_*Y_EJ z&`VcNC2w*2H11P6zBZ8k-6t{lpaqtF@hvXpa=wlCylQwYBWzS08zK z<)XFu4qG|9_Np#uzmG)wax1cAk8BD+ct{eI!c*#xDrVOXGoin}W!1C0b8%$4{1Ws6 z5y{5Jg&hzB@)t3{cEjAkA%%7&C}*LB&526dXluzhCrEZJ>nmcEjb`@%`}B91Q!<&8 zBQTj59_Y*{!hR*;xXNX3LyIc1l#($KL#dQ?8|cwZ=!G{`&VIZDb?}cbuUztPj8`S} zaN@a;#@-JxA%6lXI834uKvbxcnw`p4LAk7;T=dCn5j&19NauBES3~p@dwS!ZUR^tt z2z+CQX}ena%!L6&XCGWiTN16-fw1_vZJe*kk#RPqAe0JIbk9+{5QvB~j5b$OGB}q0 ziA5k%&xg^Pb&($~hmr}gN(>>|LMMHyCwFGEVm2FsxVQO*9~{ZWJ7dmccVigdBRJi` zglrnp7+Xkk-n+ziQN~-TV{~~VOs9`}sl;`}us2edVv%nGPeXPiE+`BB<48LF&WL0( zmUzV?5N*SL@H`#OofafXL3tGg>EI-)ce+%<5Q+Lf%|$tV_JS$IZQo|`rMF$u9pI=P z54&h`vLLct#pK0bN&^j#Vma-Ztt~Gue#fEuuwwRtYiSlq>U^+!ka^*?hK9~)oTDez zlu#9wAMQ3-QC&+L=&=fYd-c-#9Z)C&b)SR-#Y6203lS@1@nQ~AE&#Q0M{YjQRh|tP z+mm*AZ!XUCAiaYYGQam&bLajk`z+8AhQmq26onX+sL*@gc)@+j8D0u{uBFT0^L@pv z$0ySU3{kc+dr@&aJXJAg{!dpgYuIELsdoVS2c%LEnqtzG#lBXZkO#y{xmL_sP(!;p z7G>qEhBaVL{XNPfsMGF=kSvPy(DRdxFTMEmNBsN&B7zsD?;wAQhyX)fSjU7pMjUyJ z*z;0aNKu3j93IQI_S}P)@cto#-cA*yYiOKd{GOs};ymwzwCDZnD=$8MtZL!HB0PBN z+9J>U_(f_%Oo){aBI4|z`HhyHuxCzej@`M93@F;#x{F#8v$Uz6ecMfok8r83@CxJM z^`uab6U*-)e4qIv%OtJ}54T@}8MvLWjU^5`7V6A;axRA`4{wRw2Sqr;K!3-F@OB!% zh(so&_neFRuXMr^M+VwQoa*bbK=ST9^ro`d~+Kiy@E5b%7!sw9>r&t^osu67$jcDy>Q5zQ9JC! z+c>o0=efjTX!`M@yb@=z&j&R%J$IZIvOz@^3c1?UhswFf?0KF@EId*J>aWCw1 zYMvNEGx{2T=X=Swp`XyN15|u8mz42AUI71)-ALq#(n452q38o`q|K!tWp$7-U;QFn zz6bAQLh~PBTi<1`e+ZB=y4M5>Ahaq|C8W^jjMnpE(iX?bMlD zv;@cMXj9`e+o7M(?-OQW$&lAc2_KUx0Z*K5oZ@>eIU%a{1d=SHHu?C(U7ESdpEI~tVL`a|T1cHnG8tw2IdrA%YIX#nc6xY7Z`$tk^nsSNr;Or;9 zMqDp+;Am6JZzo zS1qfSZ0if>J&!z+x}eh=OC-5~{GSWtA#Y^}ZNAcnew)nfdgJ-$yT5Qg)wTCgoOYoJ z!#3y&UTeclh!vJAGNASi^ofL-J`(9_@mn5~?t&-{hg$EbQ z!4-F)Q#=#Cw;`KmPuqB0UeK3b{nc;(X6MegViofGf*CcBO(dOD&SFXYyQ#Hl@lGfJ z42VG6Hg4>kIOW!plmWegR(>TZm;_2qS|!|x4wvg!_9U6H_cn^fqGYPOWZQe|KY;;4 z^f`fsN;zl}Je%Qyo_{77? zZ=9OkzG*|hPonZ)0g;)zhOH>YXCJmKU$PDg2m@Bq5lnmd;X%c^4{^quHZ7SNI%+bB^H&6|4nJyL`CQ()?tEdu92CLMjT_TfU2)e(D%G7L z3pSJ;MJhHL);VNVYh!@)EE| zfPd4vvSB@(1t=JS7+B$M-?D!Hgef;2rCARr&EtnQb4q&I9S8DJbP#1Hg*5EjP#&6{ zfD5mmI2E>S*>J{UV)>+R+(G7XD1S$qZFkGcCH+1JeI_WFh3w^X0jANewD#*CC#a{u-%YX=lYC!^L zIVVsAT(@dj*|4|csNP6Pqy1=e%3LPtDjMdkqp;)@iBidont7LS|1g22VL*{hGIhjD zniK3Bz&U{bH3CKO+G`D+KUv=JfyxY8!`viUfZvsP%2#_SX&+EJ3p!E#sJ~Z7yNnVA&fxi5Pi_(f9MKwt{_SUf-105fuRZ_R}iWK z(G{4kz)}T*DhN}7E)|$=An@+pf;fU-Sl|w%X82|>AV3^&_prOS9|z!!GtPJms9x}Q zRpOPlFV!;)Mgl$eFM8&8em)W)Lj*WNGQ0+-EGm4?t}#O*&@(6W%m?~e$f;$P;~gU7 z0&#HJI%dKioJ2iu{5Kf#LjFNR4rAg-i;P$VnVsipATia>5uV{0+n;%|1Rd&F!Gof~ z6&Qd6)2AvAt+${FyG1e?L7T)YM zKMpc{j2-3-CMbocJOC5tZ$*sDhD*=|KH{`s$c30nm}4*yg9zeCnmTib(}WA4he}iL zXnsosf4ayp&8~2d9_UX{>BuoSJ{E4P@B`lCX0R>#fUti(N$N$A3py#T!g0WH+7s;` z;bXPst_!7~tYXHWz;zwlbwxjdjw3xK4e(w&z#w8YZR^2DwZQ9Qjs$Noh3+OE`wC4@F``Ps4p}UWRMD8a?+BM z;aB-(p@4>^U{?x+?u994x;kgIgaR4~ik}p# zbY87%;>$m;u0G~-KMx(7*8R6o;CM-UZ+EP!i4PmNa5xF>bJx*3HnO)+;8;f5YVD3J zR(Rg}=K=4&RkKf~V)0Pv(hk8&4zuHu{6J#N1ivj5&=6!12P{4Ft{02VVaX}>U+B`T zUv{Y5N`m&KN47x|YN&3!6MLjbRKd9If@aOi4K_!2aQ>%oRjpWu;LpbtZ`42(e#cSjuD7DRKIEWvl_#2(hxU#Oz%xMfYHW9$S9U5J?DJYHf)>LGql?nq%Hd_k#--Pz2xl;y2swmmcV98YpC z3rnB7tcq1n+;r1<@6>CnF2#-=`~cb=UAh^{uVb7-7bwq(j9ckzQ~jkGEHuiJ0JMi3 z$3CIP6#b>htQ~okZ4bV5({bkN{xj&v@#TK9Tf z^Q^tC`82>UT21d_X9~G*ue!YJBYJ|=gN@^*uGRL>1!yoVDHbd}?Q}*r)Z|z+{bP~~ z{!i>&FZ7S*y;o|X!(>}9$yr4gH~ENNM^1&WQbV(=Q{FEsyUO%|;NoE3aeAgmEY>LKMhdt>`Qcwc&j%p%ue76#S25@trOtY&u zok&{q;v?IfHj>oEcm|R50vll4xgnQs4lMkZQgcnteM)i|NhB!5Drod-XF4_7AxW*p z>w{vfu1H>4WoOWpnSJ$v2W<~F@{+V^$HFj$W3UmBT!PwANtE}t7pr#Rrw>(-luwA! zYx63JT3^k-vO8!T(&RYW@|PA-p}M#@4N}<%zO}D&Pi4ElmJ-KXA0!Z>3Rn5`r1-j3 zoyTc>DkJ;)no)2vUp+gb>dFHdW3ewKc4sXuM!?AsRKxi-6<%EC(M!=}M;*&z1e_c} zjC%E%l!$oa6v{%*S-H&OjHXV{@fU4V`K>J$oN>k(r-`5aaFhs}FNWU$0000P)uqQW5)};# zB@OTb++Kk20uUN1B$k$DjYLnVC>c5sw?IJ$=A7|3>p1q>o{Te2JfGxv*Sp#z-=4Yn zjD6z4BJnOZXcy8Jz{6R&Pc~%sDHGbnbRXjr?IYU8-j+OO1rJMPD$K_w2^e5rk}d)) zGsY|4FH`7J1d_Orp6M2nXxl*hj94a#+(FBMBXvctbHs< z{DzvVhj&;VdCY)cvurU7q8)*%ue+!Ey4A(Qkov|u&_qk1YO*is%X3%{#uNybb((Zz zflA&kx;s$l!UN1!Q;CfPuCct7#u94_?18+LMiOfY?2){b+7jzcW0Cfq)LA5 zOQk@X=RLyujJ8cUC#Pu@?AwIZso7KXndFRRSoY&mfvVr*GmNez1Z*)OiRa7u!}2EV z$)?+PdCbOst*}s_I!7G9BEy|yICJxq+#WtZ0n3DC=goypIF9fU7DwHO&yVBD>!UNr zZV$fE_7xTpswvMb7tBQ#c5$3B{=Gl zi9#t*b&T6^)Fn&@lQaTDIGT`N)1w5s=Bq=<4=w_AQ9ER?Cy2uE0S!aC$kCLZ9VNfDxk~tY#l#;T^;Y0s$<-#xAz4{pj z5iBrCASw+Sv+XRN#$^-_dorA2i89BsZx9FaY;2ymrA& zxr>7c|AYB88f4@oe3Ne9nn)C~;9(jzDg#m=P#D#tuXw z=kDf@{e^X6Jj>s3Qw_)&y~2cC-ayu zdy?V`@66*$KkcDa`l;~+ENXhQh4orb9_z?sw5|Z+Cz2!7I!tl+J!r~f7Or5aYRjx* zg^!6U2Rg(8EG&>w{US@WTIr(!d|~r-6D2^62uyKBXbnLk@6%tthVF<=6U9T*RnA)x z$jD|5S;5?9M7Aa_r8R+BR6T})ipsW0*0_^IK!lcAiolf2r#G<7O_=;J0`)-zSjP_| zC_@S5EKjKJ*$aT_{mc1jk;v>>*n9Q$QibLD4-BA;-28}_6aWAK07*qoM6N<$g1`)E A*Z=?k literal 0 HcmV?d00001 diff --git a/assets/images/mine/mine_agent_enter.webp b/assets/images/mine/mine_agent_enter.webp new file mode 100644 index 0000000000000000000000000000000000000000..064df1d197f56ae487e17cba0bbd1858b6528090 GIT binary patch literal 4030 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 literal 0 HcmV?d00001 diff --git a/assets/images/mine/mine_ai_enter.webp b/assets/images/mine/mine_ai_enter.webp new file mode 100644 index 0000000000000000000000000000000000000000..0916c7fe1482efd3bf1e6732292158d53f888f23 GIT binary patch literal 12496 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 aOO$=&q?Go!U7%lNdWwzRrf&L%zyJU{>mNV> literal 0 HcmV?d00001 diff --git a/assets/images/mine/mine_gold_enter.webp b/assets/images/mine/mine_gold_enter.webp new file mode 100644 index 0000000000000000000000000000000000000000..84f3681cec171707088c711c08076c0749786456 GIT binary patch literal 7452 zcmV+%9pmCsNk&E#9RL7VMM6+kP&il$0000G000160RXcA06|PpNPQ3h00A5WY1_2^ zZEyP}M8pJu8L%JXgCiXWfaErkCS=O66iIYI1J_&xBQxWiG9*9(M(|uBBe!ODmzayj zazP&?9aW|KhkeUFTa9WVMIWZBsp%A1DOy=Z9Wl$9Op2o^+q^0RuY$$#hj!coF0?;~5K{@B5q=)(K~XaRD3gea5cGduF|OtQqcioFC4% z*gofsb1v`&(Wd|zZ7NP!t)Q@-c3E;ti6|2(|;+q7TQn`FZq+^O)AbxYWlSw6pv z96LT28eolZDQy>9M7BRR< zggKJkN>E*^xk@FwcpH1Kn&I)4n#)uQT3KrJztGzeI8RKvDzI`{+r{8Q5!U$3yr)!# z;6^bzG+&-!IRa;j1wJ<`q8wZ*=47-QUhnpnbK|MfXNaR)gEg8ZB++cv1olLrNS^h zVV|r^a6fZoYcdCvRT>E*2UIBjga~5^BFoOZ1!m8yhFXlL9;yu84Pbq!pjrns5%KF$ zrBULf5DV1+Ls!WSpa9O|~{xoYbg1}Nk&4p#*T456@ zt(VLjeu5}As{m7A3^?*&vvgfGQf^jKwJXJl01Y)n`YPk90zZQxm{FYKXZ8e3%rLD{toS!%EXAr^2sEhs*h0>4s0`?|ZVj=(Bo6tRYb8Yk@K zbXkPMZwJAsA<$?Y7}@@KNbDXyuyWYT5gSl}EhHP19Gq_qc}LYb(apCvYJQKU0I+^v&F*k=SnQb&7qg&2sI9Sy z5f{F-&!uHsz*2`(0F-c*Ek|t#MV zW?LXZ;3tT570Qfmqww)NFFJ_SENOrVK_!pGDFxKQk#FYJ;fM`pi4fA?7I@q6_s;_` z`bNlIDXQiLGL#PPI)h(#4Pl{xZ;JdluB?51I%2!ID# zk|~0M^xNEq^zH=axrB!eRCrdo~|xjmME5^JmpV9JCB6xdv0 zDDzi8@if6Q!U3-yMVN{1e#`1hnmR-*K2w6BE%s6hsTdiEB#0<&ju5>thsO@MxP14M z&p%te@xsOPV^K#el}3Wdl6*j66{7-?1QDeN37+97=-ztC3m?w{4ri7gH54uNioFIP zx5EM+!Ql<~5P}EO12K-*)KU&XGAN-&JLP(qPG%(-P>wmc&jXVUD$vwFGCD>qLrjgR zhXN@AV++7Tj%8b_jtKGCE<~};iqbkK#<;*nQ2*cCO`V6NQ#IKWpIJ!}n)_oc(ugHs zCx{*z!Q>sn16JE8_*XSIB0Q>4<1F_*(bNq*DN}$2J-LO$I`*|WiqrI-Q9dPw8Z&up zu(*E3HVm+#P78oipTVO-v2E|4q-ede=N22TndvfhideoB<^kmZy~2p% zxNAID`2M9+hb{{X9zrhmHHlFs3l$Z5^a(~q3`3?m;(NSJRjTpw1*36g5exZuZL+1?(fnlbycq{#k&7@)r_TtW0NX9ul5v; zl(}0|(h-ZsW(_@BERdAikT`zDER9&N?9(atk&!JCcGXN+neZ5tN%g7v6LVnf0RO6o zpMP_fMz8x9%H8V_VpmNwkx0a2ihdto|MYu4nWGJ=i(Xk*CSs9xSIw>sFI_%EHPhSp zaI?(#2_m6t+uZOu)ld(2qhA%|_E^q}(+t?Tvv8=cWBHEY6$Wp2|Z+EJUShnz?G~9;f{Zo{F zo^aZU^ZZ)P`_K2In3I$VB2)A9JIFes;tPAp)m)sL>bJC}wuOO>Sfor4naeb0?twMX zpC{a6dM;3c=uUn4Vj^uINfDUVC5Yp4ZTaZPJ_AeM4w%|Z9tSn_Wb*cHk_MV`C1!%i zSp7>qFQ-r9AHPr;u|yckWBw<4cJ55FD2-UM8sxDs(38(LH}TBbn~YS40?EFuC$nb_ zC7LLWSbW@p_W(~r$bPlA+qMI9f^4|90=L@j+IwVXG#rxCD zbHS%-%G`MP%7NO5r4U5I$`V#vzo%*PnfZha;UboXzgdGE*^Ax`;Wcku)7}SbH1pJj zidYnX$(0zbf@iJQc|lJ;UXS_I5hh}J#@|&_2wfQ>&`x@e`fy#+6e4tq*|VfnDa4~2 z@oLK!Pc$^-tyMyL)I}^!Cd8bx3_)nE=QN};k9iebS;R8LREC@BG(qWl4Qq*ff}~sW zchwYuMQ~i8UozN^;1Ulh;%?SZ%g~lZ;!bPF4GY+>nkb7{z9H0qw+k|g>3}q2Z zAj8n|hy;6n8C?Z&qd}V~+L-<5k%_%lA&`0vLs`VKg}bu-SyYXTM|1lgTRf$B)Lt7e zBCt}OxO*KDd*30Dq8UGPWDET-L24+D{5;{1+Z#L}u z)e%?*S}_HJBV_E%<;n-{!F|6I%>+I66B!Y*>Y;bMt#m}Ai1OZxMtvEul`^o10B(woFkbgE5RlQxcD%yAVf=k~4tWQ0(XIIFT9*b;mmB^}Lqqh~^ z=-db&{Ol*X#F=@>NnRc6;9uB{WhlLhdS@y5ENpNPzD8sT;%@c3h42794S^Wzt_Ibx zc6m;om6t6-x2MivTu%M|s~YG;QwYIS)U0}w^lxS^Tb*DzY6|&Q%b&59X*ZUl^sAX+ z&8KCD|FtH;vcYTUGwvrX0nPy=J-L2GYVecuS0iXH!5_u`3be|)yCCTs*y9olTegja z+coMGuRk8>9a1sY0w{vaJK#0swm*5vDnx=^WUg%f-_|?SVw}zrRa)hQmsSdyu1#zv zw;h}(a|CN#{Ee^0$!VfaYaIXZhttqS$@^7*<9S4i1#(YkulT7{Pn~ayi;#uRN&kBC zjrZSw`{nANk8u{s?_pIbKCz|n#kjW~A*wZhl{MB_ZQ(p64p)Chis`%*g9Ils7$*8^ z4av*#6Xh5zg;+Oe=}R{KkQ|;Q-fzd766n)*XeeR+ElLJ{B|=GN^&A>Zn1C*twuyaGwRB3JoNi2MxH{~y{LJ!unv4!I7`%x)b@>Iwae?+J-|SGR zsKO%c`7xzv>6XjUfdS?|-DN-QP^+k-`t8GBUksm$l7!6nOh#SrKMxD8&-#>D*U@>)e)YTZr;f`fEW+Cu$ybn z$6H|CFt&1z$R_^>yd%yW*M;2Wa)O-YShH*{aQWbzp|Z-F&F!?uo_q1yn;pOR-i(Pb z#X4Y3F|Igcd+!FV0e*$TaY`K%?@6X%9=#QNY&c|Ks$1H5I=`4%%7YWr*G_=?H+->FyG#CLcJsM0qYC-9E9WkzFVEM z@>!ho9j>Hdu4xm5Ar9rwy?xg$SF1{d>2hMie)Y%!rTsSA_3(nvQg+1$hjwkYRK>!s z;SC_WgfxQxd;bF_Mt+%d1w<{SBA(7Ga0Md_6sFB(+7Z<^Xen1)i8rZ{r+Uvx!W8Hx zm6)@lTTi}QKJD?w%$`Qwo}D*nDI5)|;WSA66pXNbMGE*-6Y(QX7ErZmB55N5QaB$6 z6XQ9%4cDQ4Z9it-6>lLKi_oV~PX3!%UBHMs!V}=0)ba`IG#uM5c(+dNv4$~WOGcJ6 zsCg}&>2-y+;+2f5YiS~8uI7i4=rx(1=I(_WCHJRI+BjkFBk<8y?D>mijTq8eA;<)c zK6uX=%Adfqnaz^lwUormZFsEM-Yrdo!6MzanK%X_*oR|1I&Pygefs~}4vzE90&l67 zfjPj4eAK9CmjqrWLhX%nxVl?yu$ z4eAPt%S=p6OiWAB$FAiyhupgxNf-gO&JVVa$JL;LsWLEC3h@z}Kmh*pSH=0ItPO9+ zByHGgrCj{!stf#F6)rA}NH#3fq@Hr`uir!ckulr#PlFqn#Xc(?>y)9}DFKih%;7^5ePdwR~1Y*3aZ5#d$UAvtzyDw@I%zA3IECx3KQzqBXvR&`d@ zD&o(jkm$4%z^k*OBXKha#;*fd*Z=?nc#_^RtN?;C6EaCigyLyv-QvRo?KSUAD22>C zO4QR$uhe07i4M7f(MJK*FOUJ*?_&Jcw~_>(xsNuw zz4;L_)$nla181$~Qve)t*e^Ir={k0JC}KHQ8tHEc5|k2 zG9F6nn5q^`>@hW+B^9FBNWMx@ol3@E#q`n-wC+d%WziJY;VB4F^hb-fB)gV_ABdkvIlq?B9$x)*|+h8FBQnb z+N;u`+a%C(EvA0A z|J@LlumGfb|DjSNY;<*6s0lEMlcOu*Xbzl**!0q_-{9-#T1607>=*2J<8UVlu3usUNSI|A3~P<}5XpsrltJR!tT-u{};6Xbl? zf_cZ>n!XQR3GNv3;48vo=4!#de=cY?vFa?|6LytBDN}w7#=&1r9Zw+7w3s4|2>X=- z*O$DgEbG)H&Ps&7-@SO)dRd;x4JL156q|~%uNxtec!U?RoF2UnEE;``jkYLZt#A=Mb(B1;8-h{vH zLOUV`jL0R;|14qQx6;r=9{AVauIhtIZrz$?PHIppD+PA~UcLVP&(VD*+(gfm#9Yir zUQ!%tQU@91kPY_PH4rltECKRHtn#4cmbD1(_Z!Qzk$?-;5EmOl-sy$RGxcNa4Gbe& zUGO4&xt=GI^FVERY0kSa9~6MY=lEyX2UMMHyXv?wz^zMrX^%UG2!lNC+G!8bWNV>U z`t=k~GWxpUhPFNc*bSr~*B!q9@kb~7wzo3dQA|00@@jR^%@SHQHZ*5PRW@f0++$D`ah;6srZ&3IN>!Kj(K2xtcL?1&$xj z%`ot)MyD~(^psIDDl_(=4MVJd9AWo0@UTnfKAD^d2LlY1Q1x_hO$!Dupv^2#2ftSD zA3A3Nh>SD~su`Jg8xAX6d55t67~r@YE%Jd+m0QgnjiA+=Xr!>ZF@B5eu{51khH z5@ROB>^)0}{uY57I^pE839EA)TaWJ>rvQH+PXN40w2(H8+eRz_+1*M|{Y_kNh2A@y zO;8nvTjH9!=x9R9<^t+)2O9c|+mvg7$^k7wF|9{M%7iu{AcI6`pC|=Vu7+a=>%ZIv z{C)PE4a^h-mIGkmsA_m=cN+Lbu|SIFDRO$|G)QrT(Itu7m4{ycr9UWm*-*X}1~;&n z|0wad|;XLp6<30H83#RzW2Q`ptLMezsaw6X9v&<7J1a7oN z%KRqMXaDW9T>B3@6-qG3O&H@V7GmSxacgDbzK55g42o8Aw4aHcr*|@~AqHw|x%G5X zP|;d)m@`3x9?$uFz~z?EdN7xX;$7j+cqo*};v2&pzBY~ehFSM(sBg{mGK(Q@WE?5e zL51LpvUENp?_DzzEQ#_uPqcWbifKZGa<-Y4m#5}5vdJA^_FezNkOzAR5U{LQ5Ln-mr@&_f6=PLIdji-KT@o?Eve+B;rn8)LDWT|^CuG)W3S^D%yH%aai{ zH1@AEr)k>yj9bAMPEM|rJeQhHyTZ408wYJJI3zhhr zKg{J?m*$?o?z&?qJk5Xz@RM)~3Hg`QC_u-W?SIi_O|fJI#s}SLzj$z5Qv4yJaIVFR zjtNnzhjgXB2_((z7i&+w)=Vw0-q1P}WZ7sG8my}88aI!Ej3bA)QQ#J-Xq90+i}?i` z%m<=v`c3m!rR9)Zf2vt6$^f4f-wsQc*T*8E^-Uk+d<1U-X40Z-RY& zxg+JQEOa05a?$9zHZ?j#jpv@AYCe{)hR$6MWO=qAGq4h<)vGyynEzf`F3E*}@+euM zSe*TM?4j;QRE_g&Ydztnif#(^DM(746y|Oslw3VbSYzdr^o+Pi0$b{ts-Q83mjt{o za)SI4ixUFtZQDkI z)bu;w{tI7jhlu`9K>n$s1MS{VlBlR_MIf>0GX}>%+BR?J-}QD45itSBRIGsTN}^Ij zm90*-ZF`b8LUix+N3lT@A~Z79$f-%vq$ePzJ(3NQd(XDDy)j|}7`ScQi0ZuY5o_4C z9g`#7&s)_@(j9d&NXFKBwARepwr$(CZQHgt9D63?sCy>u>caQE&vDdyKhO8oSIHjx zGa?|`wiP6Lf&n5P-UZTX<^ya|+rPGv^OFp6NZ$CYy(E=}$5}?DOmT`snPpC<6l80Pajnd$hjotir=RqJJropID0#m%2VO3U@M%x<&|V8W9gF8R7=h|XJ-%9IeVx^S0#e3 zLd5^`jQ)})a92kJ14)va3}6PQrg#DF}z+?tgS=e@bz-6mjjBP9tbwDOF`x~k%N;NjcCb*{a0*NZZ2XxX`zepyUi5)({ zXy-*DM2rEU%#G!aU)~8Y3aolJi4vNCQr8$y00Y$n1;S_9IdIE$FAeChv ze!Elpv-Pzsm|>N6^N&+5c31^>{kmWcXtn9YFn;`htDWi_nf-N;|5L3!yz1&d>Hn)c z1+ZlcfXb4l!JrW_myCMajwIhTRX{6>B^K_Ojj%6%lDa6>juPAy=ny?<=5@U`7D0HP zZ0+tUOCBsRg{Vx3+xTWQ#Tm(LH|`&3dNft(md((r!rUxJj0e6Q6_%@x`|~V{P?YXY z0Iehx4sr#Vs6+(h%4SAT!_YFeZiOlYDpFM?_BOptUMCjBE~N5C6n%Qq!qzPch^j)X ziQiuIg&qlmfO0f?pzHSM_4Y0}+Cg-ZEY$`gagxWp=1q8@wQZ2})lRO%hTWdRT@ zl511+kb|ad+ajV+#R_7G=1}8e)-}ePS|X zgI1WQ4-rX%iXcB9F_^7oz}D>olNQ*cHu;##b^1TvVxwk^kYeSJ>?!vC&9)vneK`QS zb!*h_Cgya3sy82Yew4bbec%Z}$;ajj)U+z@p$FYwK(iS+eL%_z9;qKlKfCKD_sX3iq zfeLd0v3rkP*!gzNZU!_zy8C+9qzAUve7>Kw<@kDT-wHE3RL#i(JB1#7Nw+otw}0$` zT5n&~a^7mSg%)yzTD?{ewQ4$%&t&_>t42oKU>^rXR5_{UI#SiRwkIJ%oXhSn?yovE z2~sI|HXZkeBZ@;}bOa)l&b7-vNZp8b@qt*kO$kZnY@hbu%;jYuc2iz^z#ee?z=zI7 zjMuR!-O15M&_5Wec8d%9!I35q(e|XDq^Qc(sE}ArJktxxuT%qjJ8G3=U_}r$-j`GX z&JtW2@{r85`u|tjb)c(hZyp4hL3nxk&Tj(KVqv?mKvVuOxceoG+9D{)q!wci_>c$( zRGlmkEn)k1p|_i^v5qQKi&Xy3ncJm$vY(3!Yd1?2ruujxsKyc|te3uHN~hlObq8^j zF)9y0_m}L@sBN$;Yovnbb#R`0?zI(=0G;mi>BwJoGEo>LB8v}zUuHRLFO=s)d(-ch0n9d&>zJ&idG@0r{lv(jM;x>)+r9bL{(qifG=cV1 zpFX`PtV_FYJk(?E5=tvo=-LJd2uSHoF0B6Om08wy|_dcT9q0FPalO;)Q2CSRM zbwVg9?h)hhun6PpHynQ0x-}z+yHY7UB7zWL2Fi51sXs8%{~@oSvT6+ji!+63*`dI z{GzI3!=Q1$TNaxT9PjGMN+4Z?K4 zdRt_Gg$9pt^0rp_#KK&B)aXd+8iKi zUUi-cg+L0;@=iOJ|4}M)U#CO}!yt%(GHZ}Is-DCLv?*xb^4NMg)Z6(8ZmqPFJDpZm z1}FziRP3k43ZbATNjVl!p=J%Thx%@EUsR{Re3>lz{ry#WPX=h-S`vP359Iu?(8Be> zCqXHKQmMU2$NonYVSA2$RhoeKo}bv49?<$!u{#!4g`FFO0I?{nu&Qvi2t-&2J)lEO zL$Yn7L>kUN=gQv0&@k_eVzBpi+T$FT8v+Pb;r8A0qsjptG!@6tC#6#HlIJeg5g(uxu zK~M(xAEi>Fnu#GsNN05dV^DjXkch&jaX=YMxI+sE`F!M1SZ@N)JMZf;>-pvD=94v9WX4$CB=JR&@vbJ9 zD@%bBKC?V$6Vh!Lh%!e<%3nvekB^5W(5(VoD)q{3Nv}q&>@J8V|r+_CiB6>8nHCq+IMVc zmVd!2HF{#Xq|g}Dkdjy$7>6*T(A1;I;zD2nxB}MChSCQpE*Jxu5%5q}b1^`J;;ukv zrkN~d*I`%TtBAr#MGOKd`aO!Wz@mIAI1iSXg>s{q9@?6c`eO;wb zePSt23RE}}ub7;g`5;Qi7(xS`*M;#9Z3r(qlDEjM@<$*0_@_SS)$je%FSqZG>gaX5 zl@R`O#ep*4b+B~wxNWqdKrvwmh(+&*?R(P&c+4aM%B6Z}<#H6p^JX$#TVVKvER|hn zS`EkBvvRZNvI{r;_2*xG|0^GVk2^i(^OrS~0Ab*W!!SJJJP}UpD30k|hOo^E2qsY| z?{SI_g-BWo#MYC;$M|#3kTs>37vYlT3Kp-B3mj%#&p(}x~*-&dZm z66)cU!4+0AtQ#scrBLuQDJBWT5I7tLOsNo3YE@KIz^SJx*tvk!JRODUDz%>3 zGQOgOKqykP%KFMN&opZ3*mIQViQ>lZkmxG7@sd01897!q8o7;A?%mY#auxjgV6;Uo zILSLiJ8<{e`uim3+UYVszxY5Ji8y>0 z3liZ!1k*Bx@lXzG28mXda1~WupO_17v#`_(WY6~vNY3xH#GUrXP6p!g6HG*HXyTdz zV<4d%?;MD1jSvc+{2OB4hU8B6KaSbNfmCqii`v`zx( z%@VBP-bn=|Hb2It0OY3EmXhcFmo=WT*KHXy1k#6jt^XD0VJx3uLe!SD=w$8TzVnql zT)3sk4*KT(l8TYu&dk=C*jd6vOiT8!0+cS0aE`vuea|s69(`^C@XG)FZ-#_9eXDhv zcFPmm7!B=q_q1DQ3s1+H32-r8kec6h* zj#QXhMT)8&XHmFvv-j@>HwUl!$O?*4p?WRY^7W-^+VAeoE1hq4SN!y6KS^>u^3ZF4 zulBtXmOu~)`^c?Khrqr+n2w@gXMAX1N@Xn793QmQ+-j93wVo78x8wXd40XBr`HX8P zfA=LLtfC5_e>B!Qbb4PIOJo4oOUFzWjL_YWZ%8hakd7r3zKEzo&_pC}E&n9YJx~Uq zLBgw=uVk~K_7pF;r4xIK;GwG%Sa{wy3De#tLS0!I?-I>$;p zv4E#Z5V}Bck1B~r7#q;qAxTHlI&h1kU6f&ITan*tyEFHbBEp{B36St|lh(q$e)g&XA=9oY;`bw4YjkW!8B67UvtVZL zCsTT&+_C}O4yfKuFzeMgT2}1ce-a>~Bn5ef+Mca^bSxkGH}R1z7Gs>SYCf7z0hkM; zeAdBQRZ+XC5~EJbtKR;FlLg+ZVAHP++u{VuoT(|0et{HpSA0-H$2MTYqq^qg=DrwN ze;L-g16 zWOB~;-nG)vMRW4?8_gqDdkOr+QnDb`^KY+H%FLymKTTRjiS#3>+uj2|*AyZ!E_)Ht zBFJK}qL=`uXEzpX)P3A0RFZ!bYEk!zU;>_aSm+b&+~A-BAn0SC{^lA0IDbako`0OW zea;u&b+UW!o_9^Mx7j~@TTpB$*(z%Zi2E&_Foh-po*aCEaN<4nZ*z$ULBo1XV(uXE zZ~=z_&WRJO=`5@AX{Jd`2K#5B?!+*dfFl8!EVV$(q{Ky9z5C82VXbqrW`DU4;q3Rn z@~B#XV=;=N{iQ#FZ9cg%kO9GZLg_w>kx3)uaj)o%PlJN@x=w59Z7LcKh>4@)o4*VZ(2=|KfR(5F8C1>HB1 zN7(6>G*H*fvs@L6uliX8*-`_*#*$AgW)B!0Er*)5N#*q0YU}1}ceKVH zJkk8yWpr*jBpZh(X9E{OT=$~B_a%U=j*zLo-a9$gBHogHLceX^o+i`d&FXRDpJRgl zqDMbYIwP0W~*O5JQM0cHAb&Rm0hp>uW>+&o|Y!c9pQF0z#JnPVJNtXYyWZ7 zp+^Hd4jr2P<)nhrqL5Q?6V&PycgJxo@xU!2Mpjwr4b1rq1)7u9uD)yO<9*3|lg-3% z9C0i>b`w3yp1+^h-uFMrXyy6dX&sPmO7l#O&UuvcUVgqoYtJQ|@$qYVfEV5yC4fnmO&0EA}7D^Q<0jY19Mg z{w!v(#ym0p=<_YG!p%1E16dG_jFZF=h>GVqXE?SecTTMx!s>(aDd)qIr?fsfOEz@I z)fZj-w}1ZiKijW7`ny{~* z!06iZ6-08(egF7dVB_O%`Yy7oZkW2YnE}T?ZuQ~k9QKRN3Msa&>(patzO`0Eq0qUh;kD=g)PmIhvm2U>Mg!3dKMEpSzO`2XEwoAjF#hNL zsSU8{@4xtc(}VlM4S#oSWEo0XXMT7Y*2;a{q-MA{F5f3g%9ihICSpirh`KGDIu2+95_7 zIuOLVKWqbIrD8UphHZWIS5EZ0Is2i%_-MmlJh^`*QSBU52=ZGq(WHlVx2% z=`1zC|IXQZO|iH@La0hW>MN$RJ|z_zd6}P!Yy?raXEkX-gLCQP@6U)>P^#uxdZ;R@5FO*3cij-YyFn$j z)KrD-wlAR)lW0+U3hAfShf!=x3+nxo$vlb27>gnEEHN?Xu1?X zJ3;EHXa9IpUY7fX^>iWdA`vO3;|BAZrDwKx504n(6#?g9sxCzhtL^-_*CqC?y< z8w6^kQtq=Q15_-w=Mm)#h$)9?e?AtMj9>`Sa0=i!rypvCubtUgsMs$~$|Qg9Z+c>1{iP$y&Jzt%mNfTVCOW&I zwHyAht;lUljZ#Zr4s*xitnKzPFpEByI})m}l&qYYM@DIauu>C(1JT=my9L&sD~!PF zo*UwyU$i3h1b^`NRumXNYxP2!YjUOvM7wck^FRN+J_6$SP;|ak_P@a*3J_bMOkqUe%$uo=YSNnS-N{* zAbN$>58yr#3CRJ%5UY_Dj`+;1pmK#0nX=x_1&F1uOA1>nwY}(7$f2PwOH(^`HNI?g8UHkWf;8^jSt2*5xo*Ygo&=f|5$_35^M4;Z2i_%`KqeThD zO2&JFD$v5x2zWTUCvz;$c1p8tUY`sp6mFfx#ZI2(h(LW}424`OAq4-J@*7; zjNZRaE0Z#DY&UyzoY@gC+^`a2)m08a2%>O~fcs{&vlk!$G9=L)dL_qo6Nt}B8Fx?Fs2su$;%WaJQMm0I{71Eqbt)$8vqvWS+c z(IkX(QzBeXA!hOb$~r-fK%z=!edPL!on&Dwsg0PEO zjH%~C2aTYZD`^FV5nEeJ4Vf7A;eI~LU_fiBXP;>~#2w4t!R4eLtcvie3Dr~Sn!@Ce z7z*kN7>i_P_0)n=PpA)@XTlelkG;Ts^`1Q95o)1ux-B+ZSme&ai9ek04%hxvzqhFkm$#@$@99< zQ^ba!t)?zgD9kpRojljH+(4GE9|X!2D19we8$GGcNwR?oS%Lmq{o|Ovig{5|$M@3AkjIXa- zEuCZ8Qm3OU#_FZI6F>XcTqTxCRsY1Yc>P+4sFl$DajL1O&g6wTl(e!+t3yN-3SojM z;O;~bn8wam{6%^1YwU5KJKXeHitd(Uy30;4h>2?TM9tvw{l-F5Mn{JS%63LS@r{mR zsa2Vyj5Zm`mdIv#WFJe3OW%)?xb<7Su z?eQCg3ugsi*@ZfSACp>*MCyiq-9cn* z9k2q_Qp~$sWP#Ms&=ju)Nso86LykJ-sCBD{M+R!boo>x7F16cBbB*b}yQU`7?5m&f z=rh)pGo9bF8V+)Jl=loK=59o2}0_T*IST0`OMt!jbH zc(7Tb^KAf42UOs9(IS+9sYz{kXmDt#UJto;I;~E-JJGZNeB{LY+<&~l+81AR^>w@F z6o`r-OxTPS+S!hSWARsOC!jD&ikKkcs7MP5xsgdMjIz+oV~ND$pcK2$^{#7Ay-;>j zRW%)_P|R13eDwDBJo8|Jp1tDA>#w|qyQdN2VK1RNJ9+Fy^cM&Zx@8JtR49@T5(z*} zy|j;X9z&>#{qS84ivy}I9!yKshE)T-2USGZBov3z;K!dho=;u8OC5X_s&A~7SNJDy z?J>M)4;s1L^AqXgx1cyXVpj1h&(nbRMZyFbxcZQ;$e|90LoS3ecLx2xI4PK~3Y1yh4T)J`)o>({3)dbtW_4f^QKi{s6~0s-?CnUou2h)+ z7vuvn-|3A8U>&4fPk2Xli*@u>q6*5B$dlhhO-%mSsIu{}I>1l#WK{=^FeRmIF{{k# zusXP7v)zGnf`E0PmXzyxvqDrI9EI6CdXtC+Q0_RW`ekUm3WI8aNv)C2nbv!zjSiskWnbPj*ArPw&ZDL<)OvEx!d;O%-$YE z1XCKU>bFp@*9U^6P}(H5r!mrp_cAav94a~1&hos{-kbU4(lH3nZTZ{O;U}#%SA%_; z0|{o7@g$4V-7DP7khvIYa~_4=_h+lsLfS;ksnp9DyX8ny7QWRD5B5-?G3#XXO=qsb;jG3O)_hfh|N7hbUpXMZ=LiK85Py1N-H`3-%R zbvk)O^(C8(>L55Mh(ZiB-g(>$6b^);kOXGf43t9(sKZzYXJ9>;Ffdq?L=j__WrXR13DmL* z0Chc(JY!jfO?TZ@xF+%EA0MiNG;Zo|Z+rXKe{=QdDBlgL)xeaik^@o!(w0<*=b(7v_^OBlB1$>qXMr*e7zsXJA-yOGVsJoeF|G>`10#po&11O3M&W7VG^99yu*+#J&)A275(H6Der$PZoNp&4T-np;(x+Cvdlqfny?bWPtb@LuYW8ef?4&EG95&cY7)zr8 zE{p`aE}Fa()wN)w%sM)i4OH&jHU{TCn)TQnR;V5}Vq`=JKh}X`ENH+<6%tHOF0*Xg z%`a_BwSU?G-#aoLKag1y>sS*5V$5ei@Vc@J89f`I7kOb4B(exc+x+f38r!|6qOxKk z{n;4jNQ?hV!iZ;9{I!1Yq)nr(9+V9Nq4Yr#p`zWG`33xVerW^ws|k~}Bt0~U%2^sU zgJ0+r;B#E`#*JfT49(mGEc(rM)RTsquSQ*1TZECQJ$0Ylp3tfoMj2-|k9R`+P2o{8 zOc9D(jUn>OLquz(ops2PuVR?3hMs!-T-4QKY0$IbpEV!26QeIab8!oyLQVTTA8{qt zUW%TdwrJ$Y@qUd{ek^pvM}F~5De=19A14u#H2Z>Kuf2M7w9W%<{QxNRT->{7*v8o5 zm~I5p@vhg((qQHOX4`=_ILZR3C3Tot9ky*M?u-tl}lLt)=mkm3fIqj*rm4oiUA)D4<8FAQRI(ONQtkU~CmKqbl*w^X*w z+oJy#U~J4rTcU1I%vuk98ZlS(`23lpO~EE>{IiE@?5MT&6*|_2bGWy#G-jwTH(py& zUUAd5VLh=Vryc8f$HKm?RoJydp%=Xf156AI3=8XiSnr>d?Y}tik(yrrFaZAJO1{vh zeHW3(9Hh*!Gn0q+eKAK?l}yTH<|Cz}81R!gB-gzu{5@-xUnWdmkh(0Y8hBvb4Hon+ z7KS!ABvKbg!S1_9)PvynU8C-cD}F@pJ?IhmKFjG8-UQUjk_)e7i6#1HNT2q)mnW1l zI_)?HZTHH^mhFe<73P}C^823MFEcxAEjUfg8KT$#0001e_CF9{FMYc{UBwDhvfd2| zLiQ)&<#NNQ{T9wD89ylJQj@eC#@?P3>?EHyy{QNd&sCZ%L^#+Ztl9KkZ1w-F(<0GJnfQnhAX)pWgF9MOYA5%$ ztE0B8bGSM+%vEb)(tP}AbZ-0EZ@>pFYPPtF+&&Pto@+nZId%C^H@qaUq{G;%GYEAc zN}VI;H#BB#+PDC$q48VTpc>x+N<>p2;RvjeEpKpDNtj%)OIvRlzAThaGcYzXcE04y z-U_i$CHwz@OF(6VT!6x(AJFYp^;_Oofc;U^K9E`FTIe$N9r^b_x^Of{UeLd%fFm7KH*rO6bv*>Gyiu zh*CHi$jHVRBki}RuMt1Wqn`%n$6HUPU4Oqq(VU~3O}^&{$dy~uc(xB^;;vRUC366# zu+o*}Tbh!+Tfa08>RKf(Dex9b5N41r=<$!Ly+tIyY}zxrWQC!}`t-n1FQ%|P_LCRF!jthkMOyQliZ_bNqqPT5#d~+G$ z0roYG{u8CuqunWh9!%kG@wW#Uh{JYJJocgcgIfvSRxWbNL$<*gDa&0(nn^+9)@o1_ zYH~P?0f#M!orT*#2gLYM^gb)?4svf$Y?=kmH#g9@YX)K<=6SC&>j#L@^UhROAW~RX zr{g)Z5bvtl!g%F>oRi1_tzO%-m1g&X+$?Bw)O^ ztMJ+0nBKCkCEMG}_-&2EQ6PTAS!FUt{Sm(a^Q_UH$tBf|gZ9mJDJod(2Z6#(Bxy!d zqw^`;`Lky17G(c0^Ba!R-0hqZ(spA-C+y-8IihIyqKBYg*n1Vq9kGou9GN% z#pd!b40akFKnOT!ozW+Q!JYrytbDKZY>;odmrkUKSnuaU^|tPgyy9Wv8D=&Q z-Uql+W70q1vdMUv)YOc;FAhL(uEm_ejq>M@B&?5VJ_G*`t^fp`81*OOBiRG?HM4mf z!A1JFgX)L0CMrW&OYLTc;CxZ77h0?FOq3GdSvr*Wv%R&DxAJfH&-Ue3 zsWkVd$k5gowUbJyXs0S;7x{?lqQO z1X3JG;i6o(G73|gRb?=Bl9+}t>U|Ru5a0-CA+~hpARJDzB^Vu>O|KvFggN9j8%e0M zVrgI2)Pv{OF@p7)fwvxN?avQUj5FMfVq!*`&sV%bp@A6Hr2UQ2aap2{8{5yF=p|SJ zQ5K(Bl0hpN{?nFCS*1MIouiwrhMHb0)&L0e{b#u$)jWAw>f&)3sxz?V|ImXW!=EoJ zDt7rXZTQx={^qa7y%;?=hMVX@!}&t`Jp6-dTzRIf+O^Szj5RWe4Buk-c2b1gE*jmG zT#o4H1_knZ6@hyl34jMni$VLt?HYAj4BKo{WkQ2f0Y1w3*86`Cm~IB-zK~>B zoq>aLk;?l{ehugk2TB&pzgQSn$+(}L7x|Ritux1RDhZxSn~jQtZk#lERaTA?uuyYp z=tFazIRWV$e);ceO8h%kiZRK0!8KY`P-m`|J{Z|K)4bcel{25=tch?@LV{{;f62RO znuK?-iv{*CmOij%a9l;$uHPPzLn5n7PZ+Iywp$%%?O?Uo(6Y7mkr$E5ii}w|l#A`B zk8yCOW2FTHjG^5Gn{2FUw*7clC@bcasV8CBX+)S9EGOY(wNZfWthu52*}M9V-Ue2A z0kd$VAQwi?(s`BLN5aJYl_DulW}JLSmQhTAkxL~E%l? appList; @@ -60,7 +59,6 @@ class _AppCenterDialogState extends State { width: 329, height: 88, autoPlayMs: 5000, - exposureModel: AdExposureModel(pageType: TrackEventPageType.home, adType: AdType.moreIcon), ), ), //Flexible 兜住矮屏:内容再多也不会顶破屏幕 @@ -81,7 +79,6 @@ class _AppCenterDialogState extends State { itemBuilder: (context, index) { return AdsItem( adInfo: _appList[index], - exposureModel: AdExposureModel(pageType: TrackEventPageType.home, adType: AdType.moreIcon), ); }, ), diff --git a/lib/alert/splash/notice_image_dialog.dart b/lib/alert/splash/notice_image_dialog.dart index 36e04a6..aacf813 100644 --- a/lib/alert/splash/notice_image_dialog.dart +++ b/lib/alert/splash/notice_image_dialog.dart @@ -8,7 +8,6 @@ import 'package:jydj/hj_model/splash/ads_model.dart'; import 'package:jydj/hj_utils/screen.dart'; import '../../tools_base/banner/ads_item.dart'; -import '../../track_event_manager/track_manager.dart'; /// 系统公告--图片公告 class NoticeImageDialog extends StatelessWidget { @@ -30,7 +29,6 @@ class NoticeImageDialog extends StatelessWidget { adInfo: model!, showType: AdShowType.img, aspectRatio: 6 / 8, - exposureModel: AdExposureModel(pageType: TrackEventPageType.home, adType: AdType.dialog), ), 20.sizeBoxH, InkWell(enableFeedback: false, @@ -71,7 +69,6 @@ class SystemImagesDialog extends StatelessWidget { adInfo: ads![index], showType: AdShowType.img, aspectRatio: 6 / 8, - exposureModel: AdExposureModel(pageType: TrackEventPageType.home, adType: AdType.dialog), ), ); }, diff --git a/lib/alert/video/buy_vip_alert.dart b/lib/alert/video/buy_vip_alert.dart index 82cbce1..a5947f8 100644 --- a/lib/alert/video/buy_vip_alert.dart +++ b/lib/alert/video/buy_vip_alert.dart @@ -3,8 +3,6 @@ import 'dart:math' as math; import 'package:carousel_slider/carousel_slider.dart'; -import 'package:easy_rich_text/easy_rich_text.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/hj_utils/screen.dart'; @@ -12,7 +10,6 @@ import 'package:jydj/tools_base/unique_tag_mixin.dart'; import 'package:jydj/tools_base/widget/sheet_handle_bar.dart'; import 'package:provider/provider.dart'; -import '../../assets_tool/images.dart'; import '../../hj_model/splash/domain_source_model.dart'; import '../../hj_page/main_page/provider/msg_provider.dart'; import '../../hj_page/mine/mine_vip/mine_charge_vip_logic.dart'; @@ -22,7 +19,6 @@ import '../../hj_page/mine/mine_vip/vip_pay_button.dart'; import '../../hj_page/mine/mine_vip/vip_product_manager.dart'; import '../../hj_page/mine/mine_vip/vip_support_model.dart'; import '../../hj_page/mine/mine_vip/vip_ui_kit.dart'; -import '../../routers/jump_router.dart'; import '../../tools_base/loading/loading_center_widget.dart'; import 'buy_vip_alert_logic.dart'; @@ -207,18 +203,6 @@ class _BuyVipAlertState extends State with UniqueTagMixin { mainAxisSize: MainAxisSize.min, children: [ _selectionBuilder((l) => VipPayButton(l, classic: classic)), - 12.sizeBoxH, - EasyRichText( - '支付问题反馈,点击联系 在线客服', - patternList: [ - EasyRichTextPattern( - targetString: '在线客服', - style: const TextStyle(color: Color(0xFFFFD460), fontSize: 12), - recognizer: TapGestureRecognizer()..onTap = () => pushToCustomService(), - ) - ], - defaultStyle: const TextStyle(color: Color(0xffDCDCDC), fontSize: 12), - ), ], ), ) @@ -323,53 +307,6 @@ class _BuyVipAlertState extends State with UniqueTagMixin { }); } - // 核心权益:横向滚动卡片 —— B 改版 - Widget _buildCorePrivileges(List list) { - if (list.isEmpty) return const SizedBox.shrink(); - return Column( - children: [ - const VipCoreSectionTitleImage(), - 16.sizeBoxH, - SizedBox( - height: 92, - child: ListView.separated( - clipBehavior: Clip.none, - scrollDirection: Axis.horizontal, - padding: const EdgeInsets.fromLTRB(16, 2, 16, 26), - itemCount: list.length, - separatorBuilder: (_, __) => 8.sizeBoxW, - itemBuilder: (_, i) => VipCorePrivilegeCard(list[i]), - ), - ), - 16.sizeBoxH, - ], - ); - } - - // 核心权益:一行金边方卡横向滑动 —— A / DISABLED - Widget _buildClassicCorePrivileges(List list) { - if (list.isEmpty) return const SizedBox.shrink(); - return Column( - children: [ - const VipSectionTitle('我的核心权益', classic: true), - 16.sizeBoxH, - SizedBox( - //设计稿一行放得下 4 张多一点,第 5 张露半张提示可以划 - height: 72, - child: ListView.separated( - clipBehavior: Clip.none, // 金边有外发光,裁了会缺一圈 - scrollDirection: Axis.horizontal, - padding: const EdgeInsets.symmetric(horizontal: 16), - itemCount: list.length, - separatorBuilder: (_, __) => 8.sizeBoxW, - itemBuilder: (_, i) => SizedBox(width: 72, child: VipCorePrivilegeCard(list[i], classic: true)), - ), - ), - 16.sizeBoxH, - ], - ); - } - // 更多权益:深色圆角 + 四列网格 —— B 改版 Widget _buildMorePrivileges(List list) { if (list.isEmpty) return const SizedBox.shrink(); diff --git a/lib/alert/video/share_media_dialog.dart b/lib/alert/video/share_media_dialog.dart index 5c080ea..fdfeab9 100644 --- a/lib/alert/video/share_media_dialog.dart +++ b/lib/alert/video/share_media_dialog.dart @@ -3,9 +3,9 @@ import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:jydj/assets_tool/app_colors.dart'; +import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/config/config.dart'; import 'package:jydj/hj_model/user/user_info_model.dart'; -import 'package:jydj/hj_utils/holiday_theme.dart'; import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/toast.dart'; import 'package:jydj/tools_base/widget/common_dialog.dart'; @@ -72,7 +72,7 @@ class _ShareMediaDialogState extends State { //app 图标 + 名称 + 标语 Row( children: [ - Image.asset(HolidayTheme.theme.appIcon, width: 48.w, height: 48.w), + Image.asset('ic_launcher.webp'.commonImgPath, width: 48.w, height: 48.w), 10.w.sizeBoxW, Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -124,7 +124,7 @@ class _ShareMediaDialogState extends State { ), 20.sizeBoxH, Text( - '每邀请 1人 送 1天 会员 ${Address.groundUrl ?? ""}', + '每邀请 1人 送 1天 会员 ${Address.groundUrl}', maxLines: 2, style: TextStyle(fontSize: 12, color: Colors.white.withValues(alpha: .55)), ), diff --git a/lib/assets_tool/images.dart b/lib/assets_tool/images.dart index d44d7f0..ebcab7d 100644 --- a/lib/assets_tool/images.dart +++ b/lib/assets_tool/images.dart @@ -22,6 +22,4 @@ extension ImageLoad on String { String get launchPath => 'assets/images/launch/$this'; //app icon String get appImgPath => 'assets/images/app_icon/$this'; - //节日皮肤 - String get holidayPath => 'assets/images/holiday/$this'; } diff --git a/lib/hj_model/splash/ads_model.dart b/lib/hj_model/splash/ads_model.dart index bea50f4..093d9d6 100644 --- a/lib/hj_model/splash/ads_model.dart +++ b/lib/hj_model/splash/ads_model.dart @@ -1,5 +1,4 @@ import '../../tools_base/banner/ads_grid_view.dart'; -import '../../track_event_manager/track_manager.dart'; /// 广告信息 class AdsInfoModel { @@ -59,13 +58,6 @@ class AdsInfoModel { _ => AdStyle.twoAutoScroll, }; - /// 广告样式对应的埋点类型 - AdType get adType => switch (coverImgSize) { - 'vertical-cube' => AdType.verticalIcon, - 'banner-720300' => AdType.bigBanner, - _ => AdType.smallIcon, - }; - //同时兼容 Adv(image/name/url) 与 ShuApp(icon/name/url) 字段 AdsInfoModel.fromJson(dynamic json) { json ??= {}; diff --git a/lib/hj_model/user/user_info_model.dart b/lib/hj_model/user/user_info_model.dart index c47b713..3b5f107 100644 --- a/lib/hj_model/user/user_info_model.dart +++ b/lib/hj_model/user/user_info_model.dart @@ -1,5 +1,4 @@ import 'package:jydj/assets_tool/images.dart'; -import 'package:jydj/im_manager/im_manager.dart'; /// 用户信息 class UserInfoModel { @@ -52,11 +51,6 @@ class UserInfoModel { // —— 状态 / 权限 —— int? adverAbTestShowType; // 广告AB -1-首次进app免广告 0-全部展示 其他N-注册后N分钟内免广告(分层后固定不变) - // —— IM 私信 —— - String? imToken; // IM SDK 登录令牌 - int? imUserId; // IM 用户 id - int? sendMsgPrice; // 私信消费金币 - // ============ 计算属性 ============ /// 观影券总数量 @@ -127,17 +121,6 @@ class UserInfoModel { level = map['level']; adverAbTestShowType = map['adverAbTestShowType']; - - imToken = map['imToken']; - imUserId = map['imUserId']; - sendMsgPrice = map['sendMsgPrice']; - // IM SDK 连接配置随登录返回,写入 ImManager 供初始化使用 - if (map['socketURL']?.toString().isNotEmpty == true) { - ImManager().socketURL = map['socketURL']; - } - if (map['dynamicConfigDomain']?.toString().isNotEmpty == true) { - ImManager().dynamicConfigDomain = map['dynamicConfigDomain']; - } } } diff --git a/lib/hj_page/ai/ai_home_page.dart b/lib/hj_page/ai/ai_home_page.dart index ab896e1..fae6aa3 100644 --- a/lib/hj_page/ai/ai_home_page.dart +++ b/lib/hj_page/ai/ai_home_page.dart @@ -5,7 +5,6 @@ import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/loading/loading_center_widget.dart'; import 'package:jydj/tools_base/widget/keep_alive_widget.dart'; -import '../../hj_utils/holiday_theme.dart'; import '../../hj_utils/widget_util.dart'; import 'ai_home_logic.dart'; import 'ai_record/ai_main_record_page.dart'; @@ -21,20 +20,11 @@ class AiHomePage extends StatelessWidget { builder: (logic) { return Stack( children: [ - if (holidayTheme.openHoliday) ...[ - Container(color: AppColors.primaryColor), - Positioned( - top: 0, - left: 0, - right: 0, - child: Image.asset(HolidayTheme.theme.mainBg, fit: BoxFit.fitWidth), - ), - ], Scaffold( backgroundColor: Colors.transparent, appBar: AppBar( title: Text('AI科技'), - backgroundColor: holidayTheme.openHoliday ? Colors.transparent : AppColors.primaryColor, + backgroundColor: AppColors.primaryColor, actions: [ Center( child: InkWell( diff --git a/lib/hj_page/ai/ai_mod_detail_page.dart b/lib/hj_page/ai/ai_mod_detail_page.dart index ba38778..0e1ffac 100644 --- a/lib/hj_page/ai/ai_mod_detail_page.dart +++ b/lib/hj_page/ai/ai_mod_detail_page.dart @@ -124,8 +124,7 @@ class AIModDetailPage extends StatelessWidget { '''1. 选择一张人脸清晰,不得有任何遮挡的照片上传(注意:只含一个人物和脸部,图片不能过暗) 2. 选择一个心仪的视频或图片模板,点击生成,生成时间需要3-5分钟,耐心等待。(图片模板可自行上传) 3. 在右上角记录查看生成进度,生成成功后可以点击进行下载,也可以在线观看。 -4. 按照上方操作,有问题随时联系在线客服进行处理。 -5. 不支持多人图片,禁止未成年人图片''', +4. 不支持多人图片,禁止未成年人图片''', style: TextStyle( color: Color(0xff656565), fontSize: 12, diff --git a/lib/hj_page/ai/ai_sub_type/ai_strip_sub_page.dart b/lib/hj_page/ai/ai_sub_type/ai_strip_sub_page.dart index f87833f..c0cca02 100644 --- a/lib/hj_page/ai/ai_sub_type/ai_strip_sub_page.dart +++ b/lib/hj_page/ai/ai_sub_type/ai_strip_sub_page.dart @@ -167,7 +167,7 @@ class AIStripSubPage extends StatelessWidget { indicatorStyle: IndicatorStyle.dot, onTap: (index) { final ad = (logic.modList!.aiUndressMod ?? [])[index]; - pushToPageByLink(ad.href, id: ad.id); + pushToPageByLink(ad.href); }, ), ); diff --git a/lib/hj_page/ai/widgets/ai_girl_sheet.dart b/lib/hj_page/ai/widgets/ai_girl_sheet.dart index ebd7316..d8ff7a3 100644 --- a/lib/hj_page/ai/widgets/ai_girl_sheet.dart +++ b/lib/hj_page/ai/widgets/ai_girl_sheet.dart @@ -1,8 +1,5 @@ -import 'package:easy_rich_text/easy_rich_text.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:jydj/assets_tool/app_colors.dart'; import 'package:jydj/hj_utils/api_service/ai_service.dart'; import 'package:jydj/routers/jump_router.dart'; import 'package:jydj/tools_base/debug_log.dart'; @@ -26,20 +23,11 @@ class AIGirlSheet extends StatefulWidget { class _AIGirlSheetState extends State { int selectIndex = 0; - //TapGestureRecognizer 必须自己释放,建一次复用,别在 build 里 new - final _serviceTap = TapGestureRecognizer()..onTap = pushToCustomService; - List get _items => widget.list ?? []; //列表可能为空,取不到就没得选 AIGirlFriendCurrency? get _selected => selectIndex < _items.length ? _items[selectIndex] : null; - @override - void dispose() { - _serviceTap.dispose(); - super.dispose(); - } - @override Widget build(BuildContext context) { return Material( @@ -107,20 +95,6 @@ class _AIGirlSheetState extends State { ), ), ), - const SizedBox(height: 18), - EasyRichText( - '支付中如有问题 请联系在线客服', - textAlign: TextAlign.center, - defaultStyle: textStyle(12, Colors.white.withValues(alpha: .6), FontWeight.w400), - patternList: [ - EasyRichTextPattern( - targetString: '在线客服', - matchOption: 'first', - style: const TextStyle(color: AppColors.primaryHighColor), - recognizer: _serviceTap, - ), - ], - ), const SizedBox(height: 30), ], ), diff --git a/lib/hj_page/ai/widgets/ai_image_record.dart b/lib/hj_page/ai/widgets/ai_image_record.dart index a70eefa..7748c48 100644 --- a/lib/hj_page/ai/widgets/ai_image_record.dart +++ b/lib/hj_page/ai/widgets/ai_image_record.dart @@ -7,7 +7,6 @@ import 'package:jydj/tools_base/toast.dart'; import 'package:jydj/tools_base/video_download/video_cache_store.dart'; import 'package:jydj/tools_base/video_download/video_download_manager.dart'; import 'package:jydj/tools_base/widget/image_browser_page.dart'; -import 'package:permission_handler/permission_handler.dart'; import '../../video/simple_video_player_page.dart'; import '../ai_sub_type/ai_function_logic.dart'; @@ -145,12 +144,6 @@ class AIImageRecord extends StatelessWidget { await VideoCacheStore.instance.saveVideoInfo(MediaStyle.Video, viewModel); } - Future _checkPermission() async { - var status = await Permission.storage.status; - if (!status.isGranted) status = await Permission.storage.request(); - return status.isGranted; - } - //视频换脸的结果位单独接播放器,链接由 VideoModel 拼(和 AiRecordModel.realVideoUrl 的 query 不一样) void _playResultVideo() { final videoModel = VideoModel()..sourceURL = model.url; diff --git a/lib/hj_page/cartoon/audio_player_content.dart b/lib/hj_page/cartoon/audio_player_content.dart index 4150825..830172f 100644 --- a/lib/hj_page/cartoon/audio_player_content.dart +++ b/lib/hj_page/cartoon/audio_player_content.dart @@ -67,7 +67,7 @@ class _AudioPlayerContentState extends State { 18.sizeBoxH, _progressRow(audioValue, progress, max), 14.sizeBoxH, - _controlRow(audioValue, progress), + _controlRow(audioValue), 18.sizeBoxH, ], ); @@ -142,7 +142,7 @@ class _AudioPlayerContentState extends State { } // 控制行:循环模式、上一集/播放暂停/下一集、播放列表 - Widget _controlRow(AudioPlayerValue audioValue, double progress) { + Widget _controlRow(AudioPlayerValue audioValue) { final isLoop = playMod == AudioPlayMod.loop; final isPlaying = audioValue.isPlaying ?? false; return Row( @@ -179,7 +179,7 @@ class _AudioPlayerContentState extends State { children: [ InkWell( enableFeedback: false, - onTap: () => manager.playForward(progress), + onTap: () => manager.playForward(), child: Image.asset('forward.png'.acgImgPath, width: 24), ), 40.sizeBoxW, @@ -199,7 +199,7 @@ class _AudioPlayerContentState extends State { 40.sizeBoxW, InkWell( enableFeedback: false, - onTap: () => manager.playNext(progress), + onTap: () => manager.playNext(), child: Image.asset('next.png'.acgImgPath, width: 24), ), ], diff --git a/lib/hj_page/cartoon/cartoon_read_logic.dart b/lib/hj_page/cartoon/cartoon_read_logic.dart index c4c2a5c..8336563 100644 --- a/lib/hj_page/cartoon/cartoon_read_logic.dart +++ b/lib/hj_page/cartoon/cartoon_read_logic.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:analytics_sdk/enum/read_behavior_enum.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/hj_model/media_content.dart'; @@ -8,7 +7,6 @@ import 'package:jydj/tools_base/toast.dart'; import 'package:jydj/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart'; import 'package:jydj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; -import '../../track_event_manager/track_manager.dart'; import 'widget/acg_source_manager.dart'; class CartoonReadLogic extends GetxController { @@ -21,7 +19,6 @@ class CartoonReadLogic extends GetxController { bool showProgress = false; // 展示进度 bool sortType = true; // 排序类型 true-正序 false-倒序 bool autoPlay = false; // 是否自动播放 - bool playFinish = false; // 是否触底播放完成 double readScale = 0; // 播放比例 double bottomHeight = 155; int animationTime = 250; // 显示时间(ms) @@ -74,7 +71,7 @@ class CartoonReadLogic extends GetxController { showToast('这是最后一${manager.mediaInfo?.unit}了喔~'); return; } - _openEpisode(index, behavior: next ? ReadBehaviorEnum.PAGE_NEXT : ReadBehaviorEnum.PAGE_PREV); + _openEpisode(index); } // 目录点击切章 @@ -105,7 +102,7 @@ class CartoonReadLogic extends GetxController { // 松手:jumpTo 的位置回调下一帧才到,延后一帧再放开 void onSeekEnd(double value) { WidgetsBinding.instance.addPostFrameCallback((_) { - // 拖动期间位置回调被屏蔽,松手补一次触底结算,别把「读完」埋点漏了; + // 拖动期间位置回调被屏蔽,松手补一次触底结算(停自动播放); // 放在解锁之前,免得这一步引起的滚动又被 onScrollAction 收了菜单 _checkReachBottom(); _isSeeking = false; @@ -155,9 +152,9 @@ class CartoonReadLogic extends GetxController { } // ========== 私有方法 ========== - /// 切章统一入口:权限/缓存都在 manager 里,这里只管埋点顺序和刷新 - /// [behavior] 非空则先补一条翻页行为(用旧章数据),[isFirstLoad] 失败时才进错误页 - Future _openEpisode(int index, {ReadBehaviorEnum? behavior, bool isFirstLoad = false}) async { + /// 切章统一入口:权限/缓存都在 manager 里,这里只管状态重置和刷新 + /// [isFirstLoad] 失败时才进错误页 + Future _openEpisode(int index, {bool isFirstLoad = false}) async { // 首次进入页面已有全屏 loading,不再叠遮罩 final model = await manager.getComicsMediaContent(index: index, showLoading: !isFirstLoad); if (model == null) { @@ -165,29 +162,10 @@ class CartoonReadLogic extends GetxController { update(); return; } - // 上下翻页,先上传切换行为(旧章的进度和集号),再上传展示行为 - if (behavior != null) { - TrackVideoManager.comicEvent( - behavior, - model: manager.mediaInfo, - readProgress: (readScale * 100).floor(), - pageNo: currentEpisode + 1, - mediaContent: detailInfo, - ); - } currentEpisode = index; detailInfo = model; readIndex = 0; readScale = 0; - playFinish = false; // 重置播放完成状态 - // 漫画展示 - TrackVideoManager.comicEvent( - ReadBehaviorEnum.VIEW, - model: manager.mediaInfo, - readProgress: 0, - pageNo: currentEpisode + 1, - mediaContent: model, - ); update(); // 首次加载时列表还没 build,controller 未 attach,跳转会空断言崩 if (itemScrollCtr.isAttached) itemScrollCtr.jumpTo(index: 0); @@ -205,24 +183,14 @@ class CartoonReadLogic extends GetxController { update(['slider']); } - // 触底:停自动播放(顺带弹回菜单)+ 上报读完 + // 触底:停自动播放(顺带弹回菜单) void _checkReachBottom() { final positions = itemListener.itemPositions.value; if (positions.isEmpty) return; final count = detailInfo?.urlSet?.length ?? 0; - // 首图还在视野内就不算触底(整章不足一屏时不上报读完) + // 首图还在视野内就不算触底(整章不足一屏时不处理) if (positions.first.index == 0 || positions.last.index != count - 1) return; onChangeAutoPlay(false); - // 播放完毕只记录一次 - if (playFinish) return; - playFinish = true; - TrackVideoManager.comicEvent( - ReadBehaviorEnum.COMPLETE, - model: manager.mediaInfo, - readProgress: 100, - pageNo: manager.index + 1, - mediaContent: detailInfo, - ); } void _startTimer() { diff --git a/lib/hj_page/cartoon/cartoon_sub_detail_page.dart b/lib/hj_page/cartoon/cartoon_sub_detail_page.dart index 36548fa..2cc6b5e 100644 --- a/lib/hj_page/cartoon/cartoon_sub_detail_page.dart +++ b/lib/hj_page/cartoon/cartoon_sub_detail_page.dart @@ -21,6 +21,6 @@ class CartoonSubDetailPage extends StatelessWidget { @override Widget build(BuildContext context) { - return CartoonSubGridPage(tagData: tagData, type: type, scrollCtr: scroll, tabIndex: index).keepAlive; + return CartoonSubGridPage(tagData: tagData, type: type, scrollCtr: scroll).keepAlive; } } diff --git a/lib/hj_page/cartoon/cartoon_sub_grid_logic.dart b/lib/hj_page/cartoon/cartoon_sub_grid_logic.dart index 6f7836f..649719e 100644 --- a/lib/hj_page/cartoon/cartoon_sub_grid_logic.dart +++ b/lib/hj_page/cartoon/cartoon_sub_grid_logic.dart @@ -5,8 +5,6 @@ import 'package:jydj/hj_utils/api_service/vid_service.dart'; import 'package:jydj/hj_utils/const.dart'; import 'package:jydj/tools_base/base_list_controller.dart'; -import '../../track_event_manager/track_manager.dart'; - class CartoonSubGridLogic extends ListBaseLogic { final MediaStyle type; //-1:动漫和漫画 0:图集 1:黄游 2:小说 final ModuleData? tagData; //模块model @@ -30,14 +28,6 @@ class CartoonSubGridLogic extends ListBaseLogic { return 1; } - TrackEventPageType get pageType { - if (type == MediaStyle.Cartoon) return TrackEventPageType.home; - if (type == MediaStyle.Pic) return TrackEventPageType.commImg; - if (type == MediaStyle.Game) return TrackEventPageType.commNovel; - if (type == MediaStyle.Novel) return TrackEventPageType.commNovel; - return TrackEventPageType.home; - } - String get newsType { if (tagData?.moduleName == '热门推荐' && tagData?.type == -100) return 'PIC'; if (tagData?.moduleName == '热门推荐' && tagData?.type == -101) return 'SEED_LINK'; diff --git a/lib/hj_page/cartoon/cartoon_sub_grid_page.dart b/lib/hj_page/cartoon/cartoon_sub_grid_page.dart index 3a7eeb0..b48273c 100644 --- a/lib/hj_page/cartoon/cartoon_sub_grid_page.dart +++ b/lib/hj_page/cartoon/cartoon_sub_grid_page.dart @@ -7,7 +7,6 @@ import 'package:jydj/hj_utils/sliver_delegate.dart'; import 'package:jydj/tools_base/banner/ads_grid_view.dart'; import 'package:jydj/tools_base/loading/loading_center_widget.dart'; import 'package:jydj/tools_base/refresh/pull_refresh.dart'; -import 'package:jydj/track_event_manager/track_manager.dart'; import '../home/home_cell_style/quick_entry_row.dart'; import '../home/home_cell_style/video_simple_cell.dart'; @@ -21,14 +20,12 @@ class CartoonSubGridPage extends StatelessWidget { final ModuleData? tagData; //模块model final MediaStyle type; //-1:动漫和漫画 0:图集 1:黄游 2:小说 final ScrollController? scrollCtr; - final int tabIndex; //所属 tab 下标,只用于广告曝光埋点 const CartoonSubGridPage({ super.key, this.tagData, this.type = MediaStyle.Pic, this.scrollCtr, - this.tabIndex = 0, }); // 多 type/模块 tab 经 keepAlive 并存,按 id+type 隔离各自的 logic @@ -58,7 +55,6 @@ class CartoonSubGridPage extends StatelessWidget { type == MediaStyle.Cartoon ? 4 : 7, //广告位标识 padding: const EdgeInsets.fromLTRB(16, 0, 16, 12), autoStyle: true, - exposureModel: AdExposureModel(pageType: logic.pageType, tabIndex: tabIndex), ), ), // 这两块只有动漫/漫画有 @@ -139,7 +135,6 @@ class CartoonSubGridPage extends StatelessWidget { videoModel: list[index], isFromHY: true, textLines: 1, - exposureModel: AdExposureModel(pageType: TrackEventPageType.acgHome), ), _ => const SizedBox.shrink(), }, diff --git a/lib/hj_page/cartoon/text_novel_read_logic.dart b/lib/hj_page/cartoon/text_novel_read_logic.dart index 838d5a7..2aa591d 100644 --- a/lib/hj_page/cartoon/text_novel_read_logic.dart +++ b/lib/hj_page/cartoon/text_novel_read_logic.dart @@ -1,4 +1,3 @@ -import 'package:analytics_sdk/enum/read_behavior_enum.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/hj_model/media_content.dart'; @@ -8,7 +7,6 @@ import 'package:jydj/tools_base/toast.dart'; import '../../hj_model/acg/comic_chapters_model.dart'; import '../../hj_model/cartoon_media_info.dart'; import '../../tools_base/loading/loading_helper.dart'; -import '../../track_event_manager/track_manager.dart'; import 'widget/acg_source_manager.dart'; // 文字小说阅读 logic @@ -23,10 +21,7 @@ class TextNovelReadLogic extends GetxController { bool showMenu = true; bool isDark = true; bool isAscend = true; // 排序类型 true-正序 false-倒序 - bool playFinish = false; // 是否触底播放完成 - bool isSwitching = false; // 是否正在切换集,避免竞态 int durationTime = 250; - int progress = 0; // 0 ~ 100 final ScrollController scrollCtr = ScrollController(); @@ -37,7 +32,6 @@ class TextNovelReadLogic extends GetxController { super.onInit(); mediaInfo = manager.mediaInfo; currentEpisode = manager.index; - scrollCtr.addListener(_onScroll); } @override @@ -49,7 +43,6 @@ class TextNovelReadLogic extends GetxController { @override void onClose() { - scrollCtr.removeListener(_onScroll); scrollCtr.dispose(); super.onClose(); } @@ -68,9 +61,7 @@ class TextNovelReadLogic extends GetxController { // true 下一集 / false 上一集 void loadOtherEpisode(bool next, {bool showLoading = false}) async { - isSwitching = true; final index = next ? currentEpisode + 1 : currentEpisode - 1; - final pageNo = next ? index : currentEpisode + 1; if (index < 0) { showToast('这是第一${mediaInfo?.unit}了喔~'); return; @@ -81,14 +72,6 @@ class TextNovelReadLogic extends GetxController { } final model = await manager.getComicsMediaContent(index: index); if (model == null) return; - TrackVideoManager.novelEvent( - next ? ReadBehaviorEnum.PAGE_NEXT : ReadBehaviorEnum.PAGE_PREV, - model: manager.mediaInfo, - readProgress: progress, - pageNo: pageNo, - chapterId: detailInfo?.id, - chapterName: detailInfo?.name, - ); currentEpisode = index; _setData(model); update(); @@ -138,19 +121,8 @@ class TextNovelReadLogic extends GetxController { void _setData(MediaContent? model) { if (model != null) { detailInfo = model; - playFinish = false; - progress = 0; manager.changeEpisodesIndex((model.episodeNumber ?? 1) - 1); update(); - // 小说展示 - TrackVideoManager.novelEvent( - ReadBehaviorEnum.VIEW, - model: manager.mediaInfo, - readProgress: progress, - pageNo: manager.index + 1, - chapterId: model.id, - chapterName: model.name, - ); } else { detailInfo = MediaContent(); } @@ -160,26 +132,6 @@ class TextNovelReadLogic extends GetxController { void _toTop() { Future.delayed(const Duration(milliseconds: 100)).then((_) { scrollCtr.jumpTo(0); - isSwitching = false; }); } - - void _onScroll() { - if (!scrollCtr.hasClients) return; - final position = scrollCtr.position; - final max = position.maxScrollExtent; - final current = position.pixels; - progress = max > 0 ? ((current / max).clamp(0.0, 1.0) * 100).round() : 0; - if (current >= max - 20 && !playFinish && !isSwitching) { - playFinish = true; - TrackVideoManager.novelEvent( - ReadBehaviorEnum.COMPLETE, - model: manager.mediaInfo, - readProgress: progress, - pageNo: manager.index + 1, - chapterId: detailInfo?.id, - chapterName: detailInfo?.name, - ); - } - } } diff --git a/lib/hj_page/cartoon/widget/acg_source_manager.dart b/lib/hj_page/cartoon/widget/acg_source_manager.dart index 997e383..54e5200 100644 --- a/lib/hj_page/cartoon/widget/acg_source_manager.dart +++ b/lib/hj_page/cartoon/widget/acg_source_manager.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:analytics_sdk/enum/read_behavior_enum.dart'; import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; @@ -17,7 +16,6 @@ import '../../../alert/video/vip_acg_dialog.dart'; import '../../../hj_model/acg/comic_chapters_model.dart'; import '../../../hj_utils/api_service/acg_service.dart'; import '../../../tools_base/global_store/store.dart'; -import '../../../track_event_manager/track_manager.dart'; /// 小说/漫画/有声资源管理器 class ACGSourceManager extends ChangeNotifier { @@ -245,14 +243,6 @@ class AudioPlayerManager { double playSpeed = 1; - ComicChapterInfo? _currentEpisode() { - final manager = sourceManger; - if (manager == null || manager.index < 0 || manager.index >= manager.allEpisodes.length) { - return null; - } - return manager.allEpisodes[manager.index]; - } - void initPlayer() { if (_audioPlayer != null) return; // 防重入:已初始化则跳过,避免 5 个 stream 监听重复注册、旧 sub 泄漏 _audioPlayer = AudioPlayer(); @@ -290,15 +280,7 @@ class AudioPlayerManager { _audioCompleSub = _audioPlayer?.onPlayerComplete.listen((event) { if (playMod == AudioPlayMod.loopList && (value.isPlaying ?? false)) { audioValue.value = AudioPlayerValue.copyWith(value..isPlaying = false); - TrackVideoManager.novelEvent( - ReadBehaviorEnum.COMPLETE, - model: sourceManger?.mediaInfo, - readProgress: 100, - pageNo: (sourceManger?.index ?? 0) + 1, - chapterId: _currentEpisode()?.id, - chapterName: _currentEpisode()?.name, - ); - playNext(0); + playNext(); } else { audioValue.value = AudioPlayerValue.copyWith(value ..isCompleted = true @@ -340,30 +322,12 @@ class AudioPlayerManager { ..duration = null); showToast('音频加载失败'); }); - if (sourceManger?.mediaInfo != null) { - TrackVideoManager.novelEvent( - ReadBehaviorEnum.VIEW, - model: sourceManger?.mediaInfo, - readProgress: 0, - pageNo: (sourceManger?.index ?? 0) + 1, - chapterId: _currentEpisode()?.id, - chapterName: _currentEpisode()?.name, - ); - } } /// 上一集 - Future playForward(double progress) async { + Future playForward() async { final epm = await sourceManger?.backToForward(); if (epm != null) { - TrackVideoManager.novelEvent( - ReadBehaviorEnum.PAGE_PREV, - model: sourceManger?.mediaInfo, - readProgress: (progress * 100).round(), - pageNo: (sourceManger?.index ?? 0) + 2, - chapterId: epm.id, - chapterName: epm.name, - ); play(epm.getRealAudioUrl); } else { pause(); @@ -371,17 +335,9 @@ class AudioPlayerManager { } /// 下一集 - Future playNext(double progress) async { + Future playNext() async { final epm = await sourceManger?.jumpToNext(); if (epm != null) { - TrackVideoManager.novelEvent( - ReadBehaviorEnum.PAGE_NEXT, - model: sourceManger?.mediaInfo, - readProgress: (progress * 100).round(), - pageNo: sourceManger?.index ?? 0, - chapterId: epm.id, - chapterName: epm.name, - ); play(epm.getRealAudioUrl); } else { pause(); diff --git a/lib/hj_page/comment/widget/comment_rich_text.dart b/lib/hj_page/comment/widget/comment_rich_text.dart index bcdefa8..f1d1086 100644 --- a/lib/hj_page/comment/widget/comment_rich_text.dart +++ b/lib/hj_page/comment/widget/comment_rich_text.dart @@ -26,7 +26,7 @@ class CommentRichText extends StatelessWidget { if (i != parts.length - 1) WidgetSpan( child: GestureDetector( - onTap: () => pushToPageByLink(model?.linkStr, id: model?.id), + onTap: () => pushToPageByLink(model?.linkStr), child: Text( keyword, style: const TextStyle(color: Color(0xffF68804), fontSize: 14, height: 1.2), diff --git a/lib/hj_page/community/community/community_tab_page.dart b/lib/hj_page/community/community/community_tab_page.dart index 594981a..c0f5f2a 100644 --- a/lib/hj_page/community/community/community_tab_page.dart +++ b/lib/hj_page/community/community/community_tab_page.dart @@ -11,7 +11,6 @@ import '../../../hj_model/home/plate_model.dart'; import '../../../hj_model/video_model.dart'; import '../../../hj_utils/sliver_delegate.dart'; import '../../../tools_base/widget/net_image_widget.dart'; -import '../../../track_event_manager/track_manager.dart'; import '../widget/community_middle_header.dart'; import '../widget/community_post_widget.dart'; import 'community_tab_logic.dart'; @@ -48,10 +47,6 @@ class CommunityTabPage extends StatelessWidget { 7, autoStyle: true, padding: EdgeInsets.fromLTRB(16.w, 0, 16.w, 10.h), - exposureModel: AdExposureModel( - pageType: TrackEventPageType.commPost, - tabIndex: index, - ), ), ), SliverToBoxAdapter( diff --git a/lib/hj_page/community/community_main_page_page/community_main_logic.dart b/lib/hj_page/community/community_main_page_page/community_main_logic.dart index 35d28ce..a776983 100644 --- a/lib/hj_page/community/community_main_page_page/community_main_logic.dart +++ b/lib/hj_page/community/community_main_page_page/community_main_logic.dart @@ -16,19 +16,16 @@ class CommunityMainLogic extends GetxController with GetTickerProviderStateMixin title: '社区', imageNor: 'community_main_sel.png'.communityPath, imageSel: 'community_main_sel.png'.communityPath, - trackKey: 'Community', ), MainTabModel( title: '色图', imageNor: 'community_pic_sel.png'.communityPath, imageSel: 'community_pic_sel.png'.communityPath, - trackKey: 'Pic', ), MainTabModel( title: '小说', imageNor: 'community_noval_sel.png'.communityPath, imageSel: 'community_noval_sel.png'.communityPath, - trackKey: 'Novel', ), ]; diff --git a/lib/hj_page/community/community_main_page_page/community_main_page.dart b/lib/hj_page/community/community_main_page_page/community_main_page.dart index 853078f..eb0b709 100644 --- a/lib/hj_page/community/community_main_page_page/community_main_page.dart +++ b/lib/hj_page/community/community_main_page_page/community_main_page.dart @@ -2,11 +2,9 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/hj_utils/const.dart'; -import 'package:jydj/hj_utils/holiday_theme.dart'; import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/widget/keep_alive_widget.dart'; -import '../../../assets_tool/app_colors.dart'; import '../../../config/config.dart'; import '../../cartoon/cartoon_sub_module_page.dart'; import '../../home/search_page/search_main_page.dart'; @@ -48,15 +46,6 @@ class CommunityMainPageState extends State with SingleTickerP return Stack( fit: StackFit.expand, children: [ - if (holidayTheme.openHoliday) ...[ - Container(color: AppColors.primaryColor), - Positioned( - top: 0, - left: 0, - right: 0, - child: Image.asset(HolidayTheme.theme.findBg, fit: BoxFit.fitWidth), - ), - ], Scaffold( backgroundColor: Colors.transparent, body: GetBuilder( diff --git a/lib/hj_page/community/group_chat/group_chat_page.dart b/lib/hj_page/community/group_chat/group_chat_page.dart index b22969a..4d1b65c 100644 --- a/lib/hj_page/community/group_chat/group_chat_page.dart +++ b/lib/hj_page/community/group_chat/group_chat_page.dart @@ -6,7 +6,6 @@ import 'package:jydj/tools_base/banner/ads_grid_view.dart'; import 'package:jydj/tools_base/loading/loading_center_widget.dart'; import 'package:jydj/tools_base/refresh/pull_refresh.dart'; -import '../../../track_event_manager/track_manager.dart'; import 'group_chat_logic.dart'; import 'widget/chat_group_cell.dart'; @@ -31,9 +30,6 @@ class GroupChatPage extends StatelessWidget { 6, autoStyle: true, padding: EdgeInsets.fromLTRB(16, 12, 16, 18), - exposureModel: AdExposureModel( - pageType: TrackEventPageType.commGroup, - ), ), ), if (logic.groupList == null) diff --git a/lib/hj_page/community/post_detail_page/post_detail_page.dart b/lib/hj_page/community/post_detail_page/post_detail_page.dart index 8517ee0..18d8423 100644 --- a/lib/hj_page/community/post_detail_page/post_detail_page.dart +++ b/lib/hj_page/community/post_detail_page/post_detail_page.dart @@ -10,7 +10,6 @@ import 'package:jydj/tools_base/loading/loading_center_widget.dart'; import 'package:jydj/tools_base/refresh/pull_refresh.dart'; import 'package:jydj/tools_base/unique_tag_mixin.dart'; -import '../../../track_event_manager/track_manager.dart'; import '../../comment/widget/comment_foot_view.dart'; import '../../home/widget/quick_search_view.dart'; import '../widget/post_user_info_view.dart'; @@ -89,7 +88,6 @@ class _PostDetailPageState extends State with UniqueTagMixin { child: AdsGridView( 7, autoStyle: true, - exposureModel: AdExposureModel(pageType: TrackEventPageType.postDetail), ), ), //评论数 + 快捷搜索词 diff --git a/lib/hj_page/community/widget/community_sort_header.dart b/lib/hj_page/community/widget/community_sort_header.dart index 15a31ef..22f773d 100644 --- a/lib/hj_page/community/widget/community_sort_header.dart +++ b/lib/hj_page/community/widget/community_sort_header.dart @@ -1,17 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:jydj/assets_tool/app_colors.dart'; -import 'package:jydj/hj_utils/holiday_theme.dart'; class CommunitySortHeader extends StatefulWidget { final Function(int sort) sortOnTap; final TabController? controller; - final bool isInTop; //吸顶时才在节日主题下叠渐变底 const CommunitySortHeader({ super.key, required this.sortOnTap, this.controller, - this.isInTop = false, }); @override @@ -44,16 +41,6 @@ class _CommunitySortHeaderState extends State with SingleTi return Container( decoration: BoxDecoration( color: AppColors.primaryColor, - gradient: (widget.isInTop && holidayTheme.openHoliday) - ? LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Color(0xff3e161c), - Color(0xff26161c), - ], - ) - : null, ), child: TabBar( isScrollable: true, diff --git a/lib/hj_page/drama/drama_list_logic.dart b/lib/hj_page/drama/drama_list_logic.dart index 92425d6..6562a51 100644 --- a/lib/hj_page/drama/drama_list_logic.dart +++ b/lib/hj_page/drama/drama_list_logic.dart @@ -1,5 +1,4 @@ import 'package:jydj/hj_model/drama/drama_models.dart'; -import 'package:jydj/hj_model/video_model.dart'; import 'package:jydj/hj_utils/api_service/drama_service.dart'; import 'package:jydj/tools_base/base_list_controller.dart'; diff --git a/lib/hj_page/drama/drama_list_page.dart b/lib/hj_page/drama/drama_list_page.dart index 7a94819..ec2adcd 100644 --- a/lib/hj_page/drama/drama_list_page.dart +++ b/lib/hj_page/drama/drama_list_page.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/assets_tool/images.dart'; -import 'package:jydj/hj_model/video_model.dart'; -import 'package:jydj/hj_page/drama/drama_detail_page.dart'; import 'package:jydj/hj_page/drama/drama_list_logic.dart'; import 'package:jydj/tools_base/loading/loading_center_widget.dart'; import 'package:jydj/tools_base/refresh/pull_refresh.dart'; @@ -143,10 +141,6 @@ class _DramaListPageState extends State with UniqueTagMixin { ); } - void _openDrama(VideoModel model) { - Get.to(() => DramaDetailPage(drama: model.dramaInfo)); - } - Widget _buildBody(DramaListLogic logic) { if (logic.isLoading) return const LoadingCenterWidget(); if (logic.isEmptyData) return CErrorWidget(retryOnTap: () => logic.loadData()); diff --git a/lib/hj_page/drama/drama_tag_detail_logic.dart b/lib/hj_page/drama/drama_tag_detail_logic.dart index 6ba4677..11d376c 100644 --- a/lib/hj_page/drama/drama_tag_detail_logic.dart +++ b/lib/hj_page/drama/drama_tag_detail_logic.dart @@ -1,4 +1,3 @@ -import 'package:jydj/hj_model/video_model.dart'; import 'package:jydj/hj_utils/api_service/drama_service.dart'; import 'package:jydj/hj_utils/const.dart'; import 'package:jydj/tools_base/base_list_controller.dart'; diff --git a/lib/hj_page/drama/drama_tag_detail_page.dart b/lib/hj_page/drama/drama_tag_detail_page.dart index 48ece13..28233f9 100644 --- a/lib/hj_page/drama/drama_tag_detail_page.dart +++ b/lib/hj_page/drama/drama_tag_detail_page.dart @@ -1,9 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/hj_model/video_model.dart'; -import 'package:jydj/hj_page/drama/drama_detail_page.dart'; import 'package:jydj/hj_page/drama/drama_tag_detail_logic.dart'; -import 'package:jydj/hj_page/home/home_cell_style/video_simple_cell.dart'; import 'package:jydj/tools_base/loading/loading_center_widget.dart'; import 'package:jydj/tools_base/refresh/pull_refresh.dart'; import 'package:jydj/tools_base/unique_tag_mixin.dart'; @@ -83,10 +81,6 @@ class _DramaTagDetailPageState extends State with UniqueTagM ); } - void _openDrama(VideoModel model) { - Get.to(() => DramaDetailPage(drama: model.dramaInfo)); - } - Widget _buildBody(DramaTagDetailLogic logic) { if (logic.isLoading) return const LoadingCenterWidget(); if (logic.isEmptyData) return CErrorWidget(retryOnTap: () => logic.loadData()); diff --git a/lib/hj_page/find/pic_collect/pics_detail_logic.dart b/lib/hj_page/find/pic_collect/pics_detail_logic.dart index d9fa471..e94f4be 100644 --- a/lib/hj_page/find/pic_collect/pics_detail_logic.dart +++ b/lib/hj_page/find/pic_collect/pics_detail_logic.dart @@ -10,7 +10,6 @@ import 'package:jydj/tools_base/widget/scroll_positioned_list/src/item_positions import 'package:jydj/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart'; import '../../../alert/video/video_buy_bottom_sheet.dart'; -import '../../../alert/video/vip_acg_dialog.dart'; import '../../mine/mine_vip/mine_charge_vip_page.dart'; class PicsDetailLogic extends GetxController { diff --git a/lib/hj_page/find/rank_module/rank_type_tab_view.dart b/lib/hj_page/find/rank_module/rank_type_tab_view.dart index 5c6c81e..99e9702 100644 --- a/lib/hj_page/find/rank_module/rank_type_tab_view.dart +++ b/lib/hj_page/find/rank_module/rank_type_tab_view.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:jydj/hj_page/find/rank_module/rank_sort_tab_bar.dart'; import 'package:jydj/hj_utils/const.dart'; -import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/widget/keep_alive_widget.dart'; import 'rank_sub_page.dart'; diff --git a/lib/hj_page/home/activity_float/home_float_banner.dart b/lib/hj_page/home/activity_float/home_float_banner.dart index a82a321..ee6a722 100644 --- a/lib/hj_page/home/activity_float/home_float_banner.dart +++ b/lib/hj_page/home/activity_float/home_float_banner.dart @@ -183,7 +183,7 @@ class _HomeFloatBannerState extends State { return InkWell( enableFeedback: false, // 内链可配到会员/金币页,来源统一记首页浮窗 - onTap: () => pushToPageByLink(_banner.url, id: _banner.id, sourcePage: PaySourcePage.homeFloatWindow), + onTap: () => pushToPageByLink(_banner.url, sourcePage: PaySourcePage.homeFloatWindow), child: SizedBox( width: widget.width, height: widget.height, diff --git a/lib/hj_page/home/activity_float/swiper_floating_widget.dart b/lib/hj_page/home/activity_float/swiper_floating_widget.dart index c2ccb58..9a515a1 100644 --- a/lib/hj_page/home/activity_float/swiper_floating_widget.dart +++ b/lib/hj_page/home/activity_float/swiper_floating_widget.dart @@ -134,7 +134,6 @@ class _SwiperFloatingWidgetState extends State { // 内链可配到会员/金币页,来源统一记首页浮窗 pushToPageByLink( ad.url, - id: ad.id ?? (ad.position ?? 0).toString(), sourcePage: PaySourcePage.homeFloatWindow, ); } diff --git a/lib/hj_page/home/home_cell_style/quick_entry_row.dart b/lib/hj_page/home/home_cell_style/quick_entry_row.dart index 3cac8a7..e59574f 100644 --- a/lib/hj_page/home/home_cell_style/quick_entry_row.dart +++ b/lib/hj_page/home/home_cell_style/quick_entry_row.dart @@ -45,7 +45,7 @@ class QuickEntryRow extends StatelessWidget { margin: const EdgeInsets.only(right: 16), child: InkWell( enableFeedback: false, - onTap: () => pushToPageByLink(model.linkUrl, id: model.id), + onTap: () => pushToPageByLink(model.linkUrl), child: Column( children: [ Expanded( diff --git a/lib/hj_page/home/home_cell_style/tiktok_simple_cell.dart b/lib/hj_page/home/home_cell_style/tiktok_simple_cell.dart index 1285539..d4c3e73 100644 --- a/lib/hj_page/home/home_cell_style/tiktok_simple_cell.dart +++ b/lib/hj_page/home/home_cell_style/tiktok_simple_cell.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:jydj/assets_tool/images.dart'; +import 'package:jydj/hj_utils/api_service/common_service.dart'; import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/routers/jump_router.dart'; @@ -50,7 +51,8 @@ class TiktokSimpleCell extends StatelessWidget { void _onTap() { if (videoModel?.isRandomAd() == true) { - pushToPageByLink(videoModel?.randomAdsInfo?.href, id: videoModel?.randomAdsInfo?.id); + pushToPageByLink(videoModel?.randomAdsInfo?.href); + CommonService.adsClick(videoModel?.randomAdsInfo?.id); return; } pushToVideoPage(videoModel: videoModel); diff --git a/lib/hj_page/home/home_cell_style/video_hor_cell.dart b/lib/hj_page/home/home_cell_style/video_hor_cell.dart index 748443b..c6aec9a 100644 --- a/lib/hj_page/home/home_cell_style/video_hor_cell.dart +++ b/lib/hj_page/home/home_cell_style/video_hor_cell.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:jydj/hj_utils/api_service/common_service.dart'; import 'package:jydj/hj_utils/screen.dart'; import '../../../hj_model/video_model.dart'; @@ -76,7 +77,8 @@ class VideoHorCell extends StatelessWidget { void _onTap() { if (videoModel?.isRandomAd() == true) { - pushToPageByLink(videoModel?.randomAdsInfo?.href, id: videoModel?.randomAdsInfo?.id); + pushToPageByLink(videoModel?.randomAdsInfo?.href); + CommonService.adsClick(videoModel?.randomAdsInfo?.id); return; } pushToVideoPage(videoModel: videoModel); diff --git a/lib/hj_page/home/home_cell_style/video_simple_cell.dart b/lib/hj_page/home/home_cell_style/video_simple_cell.dart index 4965be1..937c46c 100644 --- a/lib/hj_page/home/home_cell_style/video_simple_cell.dart +++ b/lib/hj_page/home/home_cell_style/video_simple_cell.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/config/config.dart'; import 'package:jydj/extension/extensions.dart'; +import 'package:jydj/hj_utils/api_service/common_service.dart'; import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/routers/jump_router.dart'; import 'package:jydj/tools_base/banner/ads_item.dart'; @@ -14,7 +15,6 @@ import '../../../hj_utils/free_play_manager.dart'; import '../../../tools_base/banner/ads_banner.dart'; import '../../../tools_base/widget/net_image_widget.dart'; import 'level_mark_chip.dart'; -import '../../../track_event_manager/track_manager.dart'; /// 竖版视频 item:封面(角标/售卖标/暗网遮罩) + 标题 +(可选)标签/评论数。 /// 命中广告数据时整体换成 [VideoSimpleAdsCell] @@ -26,7 +26,6 @@ class VideoSimpleCell extends StatelessWidget { final bool isFromHY; // 黄油风格 final bool isShowBottom; // true 显示底部标签和评论数 final bool isFromSearch; - final AdExposureModel? exposureModel; final double titleFontSize; // 标题字号,小卡场景传小值 final double coverFontSize; // 封面底部播放量/时长字号,小卡场景传小值避免溢出 final String? coverRightText; // 封面右下角文案,默认时长;短剧传「共N集」 @@ -42,7 +41,6 @@ class VideoSimpleCell extends StatelessWidget { this.isFromHY = false, this.isShowBottom = false, this.isFromSearch = false, - this.exposureModel, this.titleFontSize = 12, this.coverFontSize = 10, this.coverRightText, @@ -65,7 +63,6 @@ class VideoSimpleCell extends StatelessWidget { ? VideoSimpleAdsCell( videoModel: videoModel, textLines: textLines, - exposureModel: exposureModel, isShowBottom: isShowBottom, ) : _buildContent(), @@ -74,7 +71,8 @@ class VideoSimpleCell extends StatelessWidget { void _onTap() { if (videoModel?.isRandomAd() == true) { - pushToPageByLink(videoModel?.randomAdsInfo?.href, id: videoModel?.randomAdsInfo?.id); + pushToPageByLink(videoModel?.randomAdsInfo?.href); + CommonService.adsClick(videoModel?.randomAdsInfo?.id); return; } if (_needVipUnlock) { @@ -279,14 +277,12 @@ class VideoSimpleCell extends StatelessWidget { class VideoSimpleAdsCell extends StatefulWidget { final VideoModel? videoModel; final int textLines; - final AdExposureModel? exposureModel; final bool isShowBottom; const VideoSimpleAdsCell({ super.key, this.videoModel, this.textLines = 2, - this.exposureModel, this.isShowBottom = false, }); @@ -303,18 +299,11 @@ class _VideoSimpleAdsCellState extends State { AdsInfoModel? get adsModel => videoModel?.randomAdsInfo; - // 广告点击:跳落地页并带曝光埋点参数 + // 广告点击:跳落地页并上报点击 void _onAdTap() { final ad = adsInfoArr![adIndex]; - pushToPageByLink( - ad.href, - id: ad.id, - arguments: { - 'pageType': widget.exposureModel?.pageType, - 'adInfo': ad, - 'payload': {'ad_type': widget.exposureModel?.adType?.value ?? ''}, - }, - ); + pushToPageByLink(ad.href); + CommonService.adsClick(ad.id); } @override @@ -345,7 +334,6 @@ class _VideoSimpleAdsCellState extends State { child: AdsBanner( adsInfoArr, autoPlayMs: 3000, - exposureModel: widget.exposureModel, borderRadius: 4, onIndexChanged: (index) { adIndex = index; @@ -414,7 +402,6 @@ class _VideoSimpleAdsCellState extends State { children: [ AdsItem( adInfo: adModel!, - exposureModel: widget.exposureModel, borderRadius: 4, showType: AdShowType.img, ), diff --git a/lib/hj_page/home/home_main_page.dart b/lib/hj_page/home/home_main_page.dart index d119a23..ac521bd 100644 --- a/lib/hj_page/home/home_main_page.dart +++ b/lib/hj_page/home/home_main_page.dart @@ -1,11 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; -import 'package:jydj/assets_tool/app_colors.dart'; import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/hj_page/home/provider/home_update_marker_provider.dart'; import 'package:jydj/hj_utils/const.dart'; -import 'package:jydj/hj_utils/holiday_theme.dart'; import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/indicator/custom_tab_indicator.dart'; import 'package:jydj/tools_base/loading/loading_center_widget.dart'; @@ -33,47 +31,30 @@ class HomeMainPage extends StatelessWidget { init: HomeMainLogic(), tag: "HomeMainLogic", builder: (logic) { - final isHoliday = holidayTheme.openHoliday; - return Stack( - fit: StackFit.expand, - children: [ - //节日皮肤:铺底色 + 顶部通栏背景图 - if (isHoliday) ...[ - Container(color: AppColors.primaryColor), - Positioned( - top: 0, - left: 0, - right: 0, - child: Image.asset(HolidayTheme.theme.mainBg, fit: BoxFit.fitWidth), - ), + return Scaffold( + key: logic.scaffoldKey, + endDrawer: HSHomeDrawer(homeLogic: logic), + //浮窗放 body 里,endDrawer 才能盖住,避免挡住抽屉里的模块点击 + body: Stack( + fit: StackFit.expand, + children: [ + _body(logic), + const Positioned(right: 12, bottom: 40, child: HomeFloatWidget()), ], - Scaffold( - key: logic.scaffoldKey, - backgroundColor: isHoliday ? Colors.transparent : null, - endDrawer: HSHomeDrawer(homeLogic: logic), - //浮窗放 body 里,endDrawer 才能盖住,避免挡住抽屉里的模块点击 - body: Stack( - fit: StackFit.expand, - children: [ - _body(logic, isHoliday), - const Positioned(right: 12, bottom: 40, child: HomeFloatWidget()), - ], - ), - ), - ], + ), ); }, ), ); } - Widget _body(HomeMainLogic logic, bool isHoliday) { + Widget _body(HomeMainLogic logic) { if (logic.isLoading) return const LoadingCenterWidget(); return Column( children: [ //顶部搜索栏(状态栏 + 导航栏高度) Container( - color: isHoliday ? Colors.transparent : Colors.black, + color: Colors.black, padding: EdgeInsets.only(top: screen.paddingTop), height: kToolbarHeight + screen.paddingTop, child: CommonSearchBarView(logic: logic), @@ -147,12 +128,11 @@ class _HomeTabViewState extends State with SingleTickerProviderStat @override Widget build(BuildContext context) { - final isHoliday = holidayTheme.openHoliday; return Column( children: [ Container( height: 48.h, - color: isHoliday ? Colors.transparent : Colors.black, + color: Colors.black, child: _tabBar(), ), Expanded( diff --git a/lib/hj_page/home/home_sub_module/home_tab_drama_logic.dart b/lib/hj_page/home/home_sub_module/home_tab_drama_logic.dart index 68e41c2..ee102eb 100644 --- a/lib/hj_page/home/home_sub_module/home_tab_drama_logic.dart +++ b/lib/hj_page/home/home_sub_module/home_tab_drama_logic.dart @@ -1,12 +1,8 @@ -import 'package:flutter/widgets.dart'; -import 'package:get/get.dart'; import 'package:jydj/hj_model/drama_media_info.dart'; import 'package:jydj/hj_utils/api_service/acg_service.dart'; import 'package:jydj/tools_base/debug_log.dart'; -import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../hj_model/home/module_detail_model.dart'; -import '../../../hj_model/home/plate_model.dart'; import '../../../hj_utils/api_service/vid_service.dart'; import 'home_tab_base_logic.dart'; diff --git a/lib/hj_page/home/home_sub_module/home_tab_section_page.dart b/lib/hj_page/home/home_sub_module/home_tab_section_page.dart index 6e97c2d..ca09983 100644 --- a/lib/hj_page/home/home_sub_module/home_tab_section_page.dart +++ b/lib/hj_page/home/home_sub_module/home_tab_section_page.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/tools_base/loading/loading_center_widget.dart'; -import 'package:jydj/track_event_manager/track_manager.dart'; import '../../../hj_model/home/plate_model.dart'; import '../../../hj_model/home/module_detail_model.dart'; @@ -51,10 +50,6 @@ class _HomeTabSectionPageState extends State with UniqueTagM 4, autoStyle: true, padding: EdgeInsets.fromLTRB(12, 0, 12, 12), - exposureModel: AdExposureModel( - pageType: widget.isDarkStyle ? TrackEventPageType.darkweb : TrackEventPageType.home, - tabIndex: widget.tabIndex, - ), ), ), SliverToBoxAdapter(child: QuickEntryRow(widget.tabModel)), @@ -95,10 +90,6 @@ class _HomeTabSectionPageState extends State with UniqueTagM -1, ads: section.adsInfoArr ?? [], padding: EdgeInsets.fromLTRB(12, 0, 12, 16), - exposureModel: AdExposureModel( - pageType: widget.isDarkStyle ? TrackEventPageType.darkweb : TrackEventPageType.home, - tabIndex: widget.tabIndex * 100 + index, - ), ); } else if (logic.lastIsGuessLike && index == logic.allSection.length - 1) { return SizedBox(); // 最后一个猜你喜欢列表单独处理 diff --git a/lib/hj_page/home/home_sub_module/home_tab_sort_page.dart b/lib/hj_page/home/home_sub_module/home_tab_sort_page.dart index 7dc26f3..3a51d09 100644 --- a/lib/hj_page/home/home_sub_module/home_tab_sort_page.dart +++ b/lib/hj_page/home/home_sub_module/home_tab_sort_page.dart @@ -12,7 +12,6 @@ import '../../../hj_model/video_model.dart'; import '../../../hj_utils/sliver_delegate.dart'; import '../../../tools_base/banner/ads_grid_view.dart'; import '../../../tools_base/refresh/pull_refresh.dart'; -import '../../../track_event_manager/track_manager.dart'; import '../../cartoon/acg_widget_item.dart'; import '../home_cell_style/quick_entry_row.dart'; import '../home_cell_style/video_simple_cell.dart'; @@ -61,10 +60,6 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { 4, autoStyle: true, padding: EdgeInsets.fromLTRB(12, 0, 12, 12), - exposureModel: AdExposureModel( - pageType: widget.isDarkStyle ? TrackEventPageType.darkweb : TrackEventPageType.home, - tabIndex: widget.tabIndex, - ), ), ), SliverToBoxAdapter(child: QuickEntryRow(widget.tabModel)), @@ -96,9 +91,11 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { }, child: Obx( () { + //非暗网风格也要读一次:Obx 读不到可观察变量会抛 improper use of a GetX + final isInTop = logic.isSortMenuInTop.value; Color? bgColor; if (widget.isDarkStyle) { - if (logic.isSortMenuInTop.value) { + if (isInTop) { bgColor = Colors.transparent; } else { bgColor = Colors.black; @@ -108,7 +105,6 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { isLatest: logic.isNewestStyle, labelPadding: const EdgeInsets.symmetric(horizontal: 10), tabs: logic.isNewestStyle ? logic.lastestSortTitles : logic.sortTitles, - isPinned: !logic.isSortMenuInTop.value, bgColor: bgColor, onSort: logic.sortMenuEvent, rightWidget: logic.isNewestStyle ? null : _buildSortStyleMenu(logic), @@ -222,10 +218,6 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { child: VideoSimpleCell( videoModel: videoModel, textLines: logic.isGridStyle.value ? 2 : 1, - exposureModel: AdExposureModel( - pageType: widget.isDarkStyle ? TrackEventPageType.darkweb : TrackEventPageType.home, - tabIndex: widget.tabIndex * 100 + index, - ), ), ); }, @@ -260,10 +252,6 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { VideoModel videoModel = subList[index]; return VideoSimpleCell( videoModel: videoModel, - exposureModel: AdExposureModel( - pageType: widget.isDarkStyle ? TrackEventPageType.darkweb : TrackEventPageType.home, - tabIndex: widget.tabIndex * 100 + i * gapValue + index, - ), ); }, childCount: subList.length, @@ -300,10 +288,6 @@ class _HomeTabSortPageState extends State with UniqueTagMixin { VideoModel videoModel = subList[index]; return VideoSimpleCell( videoModel: videoModel, - exposureModel: AdExposureModel( - pageType: widget.isDarkStyle ? TrackEventPageType.darkweb : TrackEventPageType.home, - tabIndex: widget.tabIndex * 100 + allIndex * gapValue + index, - ), ); }, childCount: subList.length, diff --git a/lib/hj_page/home/home_sub_module/widget/sort_header.dart b/lib/hj_page/home/home_sub_module/widget/sort_header.dart index 159556c..dbe9321 100644 --- a/lib/hj_page/home/home_sub_module/widget/sort_header.dart +++ b/lib/hj_page/home/home_sub_module/widget/sort_header.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:jydj/assets_tool/app_colors.dart'; import 'package:jydj/hj_page/home/provider/home_update_marker_provider.dart'; -import 'package:jydj/hj_utils/holiday_theme.dart'; import 'package:provider/provider.dart'; /// 首页模块的排序切换栏(热门推荐 / 最新上架 / ...) @@ -10,7 +9,6 @@ class HomeSortHeader extends StatefulWidget { final ValueChanged onSort; final List? tabs; final EdgeInsets? labelPadding; - final bool isPinned; //已吸顶:节日主题下只有吸顶才铺底色,未吸顶保持透明露出节日背景图 final Widget? rightWidget; final Color? bgColor; final bool isLatest; @@ -20,7 +18,6 @@ class HomeSortHeader extends StatefulWidget { required this.onSort, this.tabs, this.labelPadding, - this.isPinned = false, this.rightWidget, this.bgColor, this.isLatest = false, @@ -45,12 +42,9 @@ class _HomeSortHeaderState extends State with SingleTickerProvid if (widget.isLatest) { return _buildNewsetsStyle(); }else { - final showBg = !holidayTheme.openHoliday || widget.isPinned; return Container( height: 38, - color: showBg ? (widget.bgColor ?? Theme - .of(context) - .scaffoldBackgroundColor) : Colors.transparent, + color: widget.bgColor ?? Theme.of(context).scaffoldBackgroundColor, child: widget.rightWidget == null ? _tabBar() : Row(children: [Expanded(child: _tabBar()), widget.rightWidget!]), @@ -79,10 +73,9 @@ class _HomeSortHeaderState extends State with SingleTickerProvid /// 「最新」页专用:字号更小、选中态红色胶囊、首个 tab 带更新红点 Widget _buildNewsetsStyle() { - final showBg = !holidayTheme.openHoliday || widget.isPinned; return Container( height: 38, - color: showBg ? (widget.bgColor ?? Theme.of(context).scaffoldBackgroundColor) : Colors.transparent, + color: widget.bgColor ?? Theme.of(context).scaffoldBackgroundColor, child: TabBar( controller: tabCtr, isScrollable: true, diff --git a/lib/hj_page/home/search_page/search_main_page.dart b/lib/hj_page/home/search_page/search_main_page.dart index 03c6a69..24945c0 100644 --- a/lib/hj_page/home/search_page/search_main_page.dart +++ b/lib/hj_page/home/search_page/search_main_page.dart @@ -4,7 +4,6 @@ import 'package:get/get.dart'; import 'package:jydj/hj_utils/const.dart'; import 'package:jydj/tools_base/banner/ads_grid_view.dart'; -import '../../../track_event_manager/track_manager.dart'; import '../../find/rank_module/rank_main_page.dart'; import '../../find/rank_module/rank_sub_page.dart'; import 'search_main_logic.dart'; @@ -58,7 +57,6 @@ class SearchMainPage extends StatelessWidget { 32, autoStyle: true, padding: EdgeInsets.symmetric(vertical: 12.h, horizontal: 12.w), - exposureModel: AdExposureModel(pageType: TrackEventPageType.search), ), ), //搜索历史:随增删局部刷新,不带动整页(id 要和 logic 里 update 的一致) diff --git a/lib/hj_page/home/search_page/search_result_page/search_acg_result_page.dart b/lib/hj_page/home/search_page/search_result_page/search_acg_result_page.dart index a332ae5..c878ee9 100644 --- a/lib/hj_page/home/search_page/search_result_page/search_acg_result_page.dart +++ b/lib/hj_page/home/search_page/search_result_page/search_acg_result_page.dart @@ -9,8 +9,6 @@ import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../../hj_model/acg/cartoon_more_list.dart'; import '../../../../hj_model/cartoon_media_info.dart'; import '../../../../tools_base/refresh/pull_refresh.dart'; -import '../../../../tools_base/widget/multitap_recognizer.dart'; -import '../../../../track_event_manager/track_manager.dart'; import '../../../cartoon/acg_widget_item.dart'; class SearchACGResultPage extends StatefulWidget { @@ -51,12 +49,6 @@ class _SearchACGResultPageState extends State { } videoList?.addAll(retResp?.list ?? []); retResp?.hasNext == false ? refreshController?.loadNoData() : refreshController?.loadComplete(); - searchClickManager.searchKeyword( - keyword: widget.keywords, - count: retResp?.list?.length ?? 0, - searchId: '', - traceId: '', - ); } catch (e) { refreshController?.loadComplete(); debugLog(e); @@ -93,17 +85,7 @@ class _SearchACGResultPageState extends State { ), itemCount: videoList?.length ?? 0, itemBuilder: (context, index) { - return MultiTap( - onTap: () { - searchClickManager.searchClicks( - keyword: widget.keywords, - clickType: TrackEventSearchType.acg, - id: videoList![index].id, - index: index, - traceId: '', - ); - }, - child: AcgItemWidget(info: videoList![index])); + return AcgItemWidget(info: videoList![index]); }, ), ); diff --git a/lib/hj_page/home/search_page/search_result_page/search_video_result_page.dart b/lib/hj_page/home/search_page/search_result_page/search_video_result_page.dart index b21b879..23d7fc6 100644 --- a/lib/hj_page/home/search_page/search_result_page/search_video_result_page.dart +++ b/lib/hj_page/home/search_page/search_result_page/search_video_result_page.dart @@ -2,9 +2,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:jydj/hj_model/drama_media_info.dart'; import 'package:jydj/hj_model/video_model.dart'; -import 'package:jydj/hj_page/drama/drama_detail_page.dart'; import 'package:jydj/hj_page/drama/drama_tag_detail_page.dart'; import 'package:jydj/hj_utils/api_service/drama_service.dart'; import 'package:jydj/hj_utils/api_service/search_service.dart'; @@ -16,8 +14,6 @@ import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../../hj_model/home/video_list_model.dart'; import '../../../../tools_base/refresh/pull_refresh.dart'; -import '../../../../tools_base/widget/multitap_recognizer.dart'; -import '../../../../track_event_manager/track_manager.dart'; import '../../../cartoon/photo_gallery_item.dart'; import '../../../community/widget/community_post_widget.dart'; import '../../home_cell_style/drama_cover_card.dart'; @@ -83,12 +79,6 @@ class _SearchVideoResultPageState extends State { videoList ??= []; videoList?.addAll(retResp?.list.map((e) => e.toVideoModel(null)) ?? []); retResp?.hasNext != true ? refreshController?.loadNoData() : refreshController?.loadComplete(); - searchClickManager.searchKeyword( - keyword: widget.keywords, - count: retResp?.list.length ?? 0, - searchId: '', - traceId: '', - ); } else { VideoListResp? retResp = await SearchService.searchMedia(widget.keywords, pageNumber: page, pageSize: size, realm: widget.type.searchRealm, sortType: sortValue); @@ -103,12 +93,6 @@ class _SearchVideoResultPageState extends State { tagID = retResp?.tagID; } retResp?.hasNext == false ? refreshController?.loadNoData() : refreshController?.loadComplete(); - searchClickManager.searchKeyword( - keyword: widget.keywords, - count: retResp?.videos?.length ?? 0, - searchId: '', - traceId: '', - ); } } catch (e) { refreshController?.loadComplete(); @@ -186,18 +170,6 @@ class _SearchVideoResultPageState extends State { } } - /// 进短剧二级页;搜索列表不一定带 dramaInfo,最少用 id/标题/封面兜底 - void _openDrama(VideoModel model) { - final drama = model.dramaInfo ?? - (DramaMediaInfo() - ..id = model.id - ..title = model.title - ..verticalCover = model.cover - ..horizontalCover = model.cover - ..totalEpisode = model.totalEpisode); - Get.to(() => DramaDetailPage(drama: drama)); - } - Widget _buildTypeList() { if (widget.type == MediaStyle.Drama) { return GridView.builder( @@ -211,18 +183,7 @@ class _SearchVideoResultPageState extends State { itemCount: videoList?.length ?? 0, itemBuilder: (context, index) { final model = videoList![index]; - return MultiTap( - onTap: () { - searchClickManager.searchClicks( - keyword: widget.keywords, - clickType: TrackEventSearchType.video, - id: '${model.id}', - index: index, - traceId: '', - ); - }, - child: DramaCoverCard(mediaInfo: model.dramaInfo!), - ); + return DramaCoverCard(mediaInfo: model.dramaInfo!); }, ); } @@ -238,22 +199,12 @@ class _SearchVideoResultPageState extends State { ), itemCount: videoList?.length ?? 0, itemBuilder: (context, index) { - return MultiTap( - onTap: () { - searchClickManager.searchClicks( - keyword: widget.keywords, - clickType: TrackEventSearchType.video, - id: "${videoList![index].id}", - index: index, - traceId: '', - ); - }, - child: VideoSimpleCell( - videoModel: videoList![index], - textLines: isShort ? 1 : 2, - isFromSearch: true, - isShort: isShort, - )); + return VideoSimpleCell( + videoModel: videoList![index], + textLines: isShort ? 1 : 2, + isFromSearch: true, + isShort: isShort, + ); }, ); } else if (widget.type == MediaStyle.Pic) { @@ -267,17 +218,7 @@ class _SearchVideoResultPageState extends State { ), itemCount: videoList?.length ?? 0, itemBuilder: (context, index) { - return MultiTap( - onTap: () { - searchClickManager.searchClicks( - keyword: widget.keywords, - clickType: TrackEventSearchType.image, - id: "${videoList![index].id}", - index: index, - traceId: '', - ); - }, - child: PhotoGalleryItem(videoModel: videoList![index], textline: 1)); + return PhotoGalleryItem(videoModel: videoList![index], textline: 1); }, ); } else { @@ -285,20 +226,10 @@ class _SearchVideoResultPageState extends State { padding: EdgeInsets.zero, itemCount: videoList?.length ?? 0, itemBuilder: (context, index) { - return MultiTap( - onTap: () { - searchClickManager.searchClicks( - keyword: widget.keywords, - clickType: TrackEventSearchType.post, - id: "${videoList![index].id}", - index: index, - traceId: '', - ); - }, - child: CommunityPostWidget( - videoModel: videoList![index], - videoModels: videoList, - )); + return CommunityPostWidget( + videoModel: videoList![index], + videoModels: videoList, + ); }, ); } @@ -330,10 +261,7 @@ class _SearchVideoResultPageState extends State { ), itemBuilder: (context, index) { final videoModel = tagVidList![index]; - return MultiTap( - onTap: (){}, - child: DramaCoverCard(mediaInfo: videoModel.dramaInfo!), - ); + return DramaCoverCard(mediaInfo: videoModel.dramaInfo!); }, ), if (tagID?.isNotEmpty == true) ...[ @@ -391,22 +319,11 @@ class _SearchVideoResultPageState extends State { ), itemBuilder: (context, index) { VideoModel videoModel = tagVidList![index]; - return MultiTap( - onTap: () { - searchClickManager.searchClicks( - keyword: widget.keywords, - clickType: TrackEventSearchType.video, - id: "${videoModel.id}", - index: index, - traceId: '', - ); - }, - child: VideoSimpleCell( - videoModel: videoModel, - textLines: isShort ? 1 : 2, - isFromSearch: true, - isShort: isShort, - ), + return VideoSimpleCell( + videoModel: videoModel, + textLines: isShort ? 1 : 2, + isFromSearch: true, + isShort: isShort, ); }, ), diff --git a/lib/hj_page/home/search_page/widget/common_search_widget.dart b/lib/hj_page/home/search_page/widget/common_search_widget.dart index 67ba6c2..28d32b5 100644 --- a/lib/hj_page/home/search_page/widget/common_search_widget.dart +++ b/lib/hj_page/home/search_page/widget/common_search_widget.dart @@ -4,7 +4,6 @@ import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/config/config.dart'; import 'package:jydj/hj_utils/screen.dart'; -import '../../../../hj_utils/holiday_theme.dart'; import '../../../../tools_base/widget/marquee_widget.dart'; import '../../../../tools_base/widget/net_image_widget.dart'; import '../../../mine/welfare/sign_daily_page.dart'; @@ -113,7 +112,6 @@ class _CommonSearchBarViewState extends State { /// 签到入口 Widget _buildSignIcon() { - final useHolidayIcon = holidayTheme.openHoliday && HolidayTheme.theme.signIcon.isNotEmpty; return InkWell( enableFeedback: false, onTap: () => Get.to(SignDailyPage()), diff --git a/lib/hj_page/home/widget/home_txt_marquee.dart b/lib/hj_page/home/widget/home_txt_marquee.dart index 955e496..24e4203 100644 --- a/lib/hj_page/home/widget/home_txt_marquee.dart +++ b/lib/hj_page/home/widget/home_txt_marquee.dart @@ -11,7 +11,6 @@ import 'package:jydj/hj_model/splash/domain_source_model.dart'; import 'package:jydj/hj_utils/screen.dart'; import '../../../hj_utils/api_service/vid_service.dart'; -import '../../../hj_utils/holiday_theme.dart'; import '../../../routers/jump_router.dart'; class HomeTxtMarQuee extends StatefulWidget { @@ -108,12 +107,7 @@ class HomeTxtMarQueeState extends State with SingleTickerProvide ), child: Row( children: [ - Image.asset( - (holidayTheme.openHoliday && HolidayTheme.theme.broadcastIcon.isNotEmpty) - ? HolidayTheme.theme.broadcastIcon - : "icon_broadcast.png".commonImgPath, - width: widget.iconSize ?? 20, - ), + Image.asset("icon_broadcast.png".commonImgPath, width: widget.iconSize ?? 20), 6.sizeBoxW, Expanded( child: InfiniteMarquee( @@ -124,7 +118,7 @@ class HomeTxtMarQueeState extends State with SingleTickerProvide return InkWell( enableFeedback: false, onTap: () { - pushToPageByLink(model.url, id: model.id); + pushToPageByLink(model.url); }, child: Text( model.content ?? '', diff --git a/lib/hj_page/home/widget/publist_entry_alert.dart b/lib/hj_page/home/widget/publist_entry_alert.dart index 94be2c3..2ac8262 100644 --- a/lib/hj_page/home/widget/publist_entry_alert.dart +++ b/lib/hj_page/home/widget/publist_entry_alert.dart @@ -3,7 +3,6 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:jydj/assets_tool/app_colors.dart'; import 'package:jydj/assets_tool/images.dart'; -import 'package:jydj/hj_utils/holiday_theme.dart'; import 'package:jydj/hj_utils/screen.dart'; // sizeBoxH/sizeBoxW 扩展 import 'package:jydj/tools_base/widget/sheet_handle_bar.dart'; @@ -17,7 +16,7 @@ enum PublishEntry { const PublishEntry(this.width, this.height); - String realPath() => HolidayTheme.theme.addPublish; + String realPath() => 'publish.png'.homePath; } class PublishButton extends StatelessWidget { diff --git a/lib/hj_page/live/live_detail_page.dart b/lib/hj_page/live/live_detail_page.dart index 6e41751..c2cfb1d 100644 --- a/lib/hj_page/live/live_detail_page.dart +++ b/lib/hj_page/live/live_detail_page.dart @@ -11,7 +11,6 @@ import 'package:jydj/tools_base/refresh/pull_refresh.dart'; import 'package:jydj/tools_base/widget/net_image_widget.dart'; import 'package:video_player/video_player.dart'; -import '../../track_event_manager/track_manager.dart'; import '../video/video_full_page.dart'; import 'live_detail_logic.dart'; @@ -295,7 +294,6 @@ class _LiveDetailPageState extends State { 36, autoStyle: true, padding: const EdgeInsets.fromLTRB(16, 18, 0, 0), - exposureModel: AdExposureModel(pageType: TrackEventPageType.liveDetail), ); } diff --git a/lib/hj_page/live/live_main_page.dart b/lib/hj_page/live/live_main_page.dart index 0b976d0..8e831da 100644 --- a/lib/hj_page/live/live_main_page.dart +++ b/lib/hj_page/live/live_main_page.dart @@ -29,7 +29,7 @@ class LiveMainPage extends StatelessWidget { controller: logic.tabController, children: List.generate( logic.liveTabs.length, - (index) => LiveSubPage(tagData: logic.liveTabs[index], index: index).keepAlive, + (index) => LiveSubPage(tagData: logic.liveTabs[index]).keepAlive, ), ), ), diff --git a/lib/hj_page/live/live_sub_page.dart b/lib/hj_page/live/live_sub_page.dart index f26acc9..7eed800 100644 --- a/lib/hj_page/live/live_sub_page.dart +++ b/lib/hj_page/live/live_sub_page.dart @@ -8,16 +8,14 @@ import 'package:jydj/tools_base/loading/loading_center_widget.dart'; import 'package:jydj/tools_base/refresh/pull_refresh.dart'; import 'package:jydj/tools_base/widget/card_swiper/src/swiper.dart'; -import '../../track_event_manager/track_manager.dart'; import 'live_model.dart'; import 'live_sub_logic.dart'; //直播子列表页面 class LiveSubPage extends StatefulWidget { final LiveModule? tagData; - final int index; - const LiveSubPage({super.key, this.tagData, this.index = 0}); + const LiveSubPage({super.key, this.tagData}); @override State createState() => _LiveSubPageState(); @@ -66,7 +64,6 @@ class _LiveSubPageState extends State { 35, autoStyle: true, padding: const EdgeInsets.fromLTRB(16, 15, 16, 15), - exposureModel: AdExposureModel(pageType: TrackEventPageType.live, tabIndex: widget.index), ), ); } diff --git a/lib/hj_page/main_page/main_logic.dart b/lib/hj_page/main_page/main_logic.dart index 31e986d..6ddc532 100644 --- a/lib/hj_page/main_page/main_logic.dart +++ b/lib/hj_page/main_page/main_logic.dart @@ -1,16 +1,14 @@ import 'dart:async'; -import 'package:analytics_sdk/analytics_sdk.dart'; import 'package:get/get.dart'; +import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/config/config.dart'; import 'package:jydj/hj_model/home/plate_model.dart'; import 'package:jydj/hj_page/pre_sale/pre_sale_provider.dart'; import 'package:jydj/hj_utils/const.dart'; import 'package:jydj/hj_utils/free_play_manager.dart'; -import 'package:jydj/im_manager/im_manager.dart'; import 'package:jydj/tools_base/global_store/store.dart'; -import '../../hj_utils/holiday_theme.dart'; import '../../tools_base/event_bus/event_bus_util.dart'; import '../../tools_base/event_bus/events.dart'; import '../../tools_base/toast.dart'; @@ -46,13 +44,11 @@ class MainTabModel { final String title; //title final String imageNor; //nor图片 final String imageSel; //选中图片 - final String trackKey; //导航埋点key MainTabModel({ required this.title, required this.imageNor, required this.imageSel, - required this.trackKey, }); } @@ -60,40 +56,34 @@ class MainPageLogic extends GetxController { final tabs = [ MainTabModel( title: '首页', - imageNor: HolidayTheme.theme.homeNor, - imageSel: HolidayTheme.theme.homeSel, - trackKey: 'Home', + imageNor: 'home_0_0.png'.homePath, + imageSel: 'home_0_1.png'.homePath, ), MainTabModel( title: '短剧', - imageNor: HolidayTheme.theme.shortNor, - imageSel: HolidayTheme.theme.shortSel, - trackKey: 'ShortVideo', + imageNor: 'home_1_0.png'.homePath, + imageSel: 'home_1_1.png'.homePath, ), if (Config.darkWebEnable) MainTabModel( title: Config.darkWebIconName?.isNotEmpty == true ? Config.darkWebIconName! : '暗网', - imageNor: HolidayTheme.theme.darkNor, - imageSel: HolidayTheme.theme.darkSel, - trackKey: 'DarkWeb', + imageNor: 'home_2_0.png'.homePath, + imageSel: 'home_2_1.png'.homePath, ), MainTabModel( title: 'AI', - imageNor: HolidayTheme.theme.aiNor, - imageSel: HolidayTheme.theme.aiSel, - trackKey: 'AI', + imageNor: 'home_3_0.png'.homePath, + imageSel: 'home_3_1.png'.homePath, ), MainTabModel( title: '社区', - imageNor: HolidayTheme.theme.communityNor, - imageSel: HolidayTheme.theme.communitySel, - trackKey: 'Community', + imageNor: 'home_4_0.png'.homePath, + imageSel: 'home_4_1.png'.homePath, ), MainTabModel( title: '我的', - imageNor: HolidayTheme.theme.mineNor, - imageSel: HolidayTheme.theme.mineSel, - trackKey: 'Mine', + imageNor: 'home_5_0.png'.homePath, + imageSel: 'home_5_1.png'.homePath, ), ]; @@ -152,7 +142,6 @@ class MainPageLogic extends GetxController { _backToRoot(); jumpToPage(0); globalStore.refreshWallet(); - unawaited(ImManager().reloginOnAccountSwitch()); //切换账号:登出旧 IM 并用新账号重连,避免私信列表残留旧数据 MineMsgProvider().loadData(); //内含 refreshPayPopup:重拉支付分层配置,即时刷新浮窗/我的横幅/播放器横幅 unawaited(FreePlayManager().refresh()); //切号:免费观看次数是账户维度的,不重拉会一直用着上个账号的次数 HomeUpdateMarkerProvider().loadData(); @@ -275,7 +264,6 @@ class MainPageLogic extends GetxController { void onClose() { _yinseSub.cancel(); _loginSub.cancel(); - unawaited(AnalyticsSdk.instance.dispose()); super.onClose(); } } diff --git a/lib/hj_page/main_page/main_tabbar.dart b/lib/hj_page/main_page/main_tabbar.dart index f78c488..f9b5c76 100644 --- a/lib/hj_page/main_page/main_tabbar.dart +++ b/lib/hj_page/main_page/main_tabbar.dart @@ -1,12 +1,9 @@ -import 'package:analytics_sdk/analytics_sdk.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/hj_page/main_page/provider/bottom_bar_provider.dart'; import 'package:jydj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:jydj/hj_utils/holiday_theme.dart'; import 'package:jydj/hj_utils/screen.dart'; -import 'package:jydj/im_manager/im_notification.dart'; import 'package:jydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; @@ -42,11 +39,6 @@ class MainPageTabbar extends StatelessWidget { if (index == logic.tabs.length - 1 && Get.isRegistered()) { Get.find().onRefresh(); } - // 用户点击底部 Tab 时调用,应早于页面切换完成 - AnalyticsSdk.instance.trackNavigation( - pageKey: logic.tabs[index].trackKey, // 'Home' - pageName: logic.tabs[index].title, // '主页' - ); } @override @@ -96,7 +88,7 @@ class MainPageTabbar extends StatelessWidget { }); } - /// 普通 tab;最后一个(我的)带私信未读小红点 + /// 普通 tab Widget _normalItem(int index, int cur) { final isSelected = index == cur; final imagePath = _iconPath(index, isSelected); @@ -104,32 +96,10 @@ class MainPageTabbar extends StatelessWidget { child: InkWell( enableFeedback: false, onTap: () => _selectIndex(index), - child: Stack( - children: [ - _tabContent( - isSelected: isSelected, - text: logic.tabs[index].title, - icon: Image.asset(imagePath, key: ValueKey(imagePath), width: 24), - ), - if (index == logic.tabs.length - 1) - Consumer( - builder: (_, imPro, __) { - if (!imPro.hasUnreadCount) return const SizedBox.shrink(); - return Positioned( - right: 22, - top: 24, - child: Container( - width: 8, - height: 8, - decoration: BoxDecoration( - color: Color(0xfff74f49), - borderRadius: BorderRadius.all(Radius.circular(6)), - ), - ), - ); - }, - ), - ], + child: _tabContent( + isSelected: isSelected, + text: logic.tabs[index].title, + icon: Image.asset(imagePath, key: ValueKey(imagePath), width: 24), ), ), ); @@ -153,7 +123,7 @@ class MainPageTabbar extends StatelessWidget { AnimatedDefaultTextStyle( duration: const Duration(milliseconds: 200), style: TextStyle( - color: isSelected ? HolidayTheme.theme.tabSelColor : HolidayTheme.theme.tabNorColor, + color: isSelected ? const Color(0xffFFC000) : const Color(0x59FFFFFF), fontSize: 10, ), child: Text(text), diff --git a/lib/hj_page/mine/home_mine_logic.dart b/lib/hj_page/mine/home_mine_logic.dart index dab08bf..8a35489 100644 --- a/lib/hj_page/mine/home_mine_logic.dart +++ b/lib/hj_page/mine/home_mine_logic.dart @@ -5,7 +5,6 @@ import 'package:get/get.dart'; import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/hj_page/pre_sale/pre_sale_provider.dart'; import 'package:jydj/hj_utils/api_service/vid_service.dart'; -import 'package:jydj/hj_utils/holiday_theme.dart'; import 'package:jydj/hj_utils/light_model.dart'; import 'package:jydj/hj_utils/store_keys.dart'; import 'package:jydj/tools_base/global_store/store.dart'; @@ -17,7 +16,6 @@ import 'package:jydj/tools_base/widget/common_alert.dart'; import '../../config/config.dart'; import '../../hj_model/user/user_info_model.dart'; -import '../../routers/jump_router.dart'; import '../main_page/provider/msg_provider.dart'; import '../web_page/h5_page.dart'; import 'collec_history_buy/col_his_buy_page.dart'; @@ -61,11 +59,10 @@ class MineMainLogic extends GetxController with GetTickerProviderStateMixin { ("账号凭证", 'mine_menu_9.png'.mineImgPath, () => Get.dialog(MineAccountIdentityPage())), ("锁屏密码", 'mine_menu_10.png'.mineImgPath, _toggleLockPassword), ("我的消息", 'mine_menu_11.png'.mineImgPath, () => menuTapEvent(3)), - ("在线客服", 'mine_menu_12.png'.mineImgPath, pushToCustomService), ]; List iconList = [ - IconBean(HolidayTheme.theme.appIcon, Config.appName), + IconBean('ic_launcher.webp'.commonImgPath, Config.appName), IconBean('icon_1.webp'.appImgPath, "爱音乐"), IconBean('icon_2.webp'.appImgPath, "爱阅读"), IconBean('icon_3.webp'.appImgPath, "支付宝"), @@ -187,6 +184,6 @@ class MineMainLogic extends GetxController with GetTickerProviderStateMixin { changeIcon(int index) async { if (!await CommonAlert.show(content: '您确定要更换图标吗?')) return; const platform = MethodChannel(DeviceInfoService.requestChannel); - platform.invokeMethod('changeIcon', {"iconIndex": index == 0 ? holidayTheme.iconIndex : index}); + platform.invokeMethod('changeIcon', {"iconIndex": index}); } } diff --git a/lib/hj_page/mine/home_mine_page.dart b/lib/hj_page/mine/home_mine_page.dart index 22328af..3e37609 100644 --- a/lib/hj_page/mine/home_mine_page.dart +++ b/lib/hj_page/mine/home_mine_page.dart @@ -8,7 +8,6 @@ import 'package:jydj/config/address.dart'; import 'package:jydj/config/config.dart'; import 'package:jydj/hj_page/main_page/provider/msg_provider.dart'; import 'package:jydj/hj_page/pre_sale/pre_sale_provider.dart'; -import 'package:jydj/im_manager/im_notification.dart'; import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/routers/jump_router.dart'; import 'package:jydj/tools_base/global_store/store.dart'; @@ -17,10 +16,8 @@ import 'package:jydj/tools_base/toast.dart'; import 'package:jydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; -import '../../hj_utils/holiday_theme.dart'; import '../../hj_utils/widget_util.dart'; import '../../tools_base/banner/ads_grid_view.dart'; -import '../../track_event_manager/track_manager.dart'; import 'home_mine_logic.dart'; import 'widgets/mine_info_widget.dart'; import 'widgets/vip_entry_card.dart'; @@ -65,14 +62,14 @@ class HomeMinePage extends StatelessWidget { ); } - //顶部背景:优先后台下发,兜底节日/默认图 + //顶部背景:优先后台下发,兜底默认图 Widget _buildBg() { final bg = Config.mineBg; if (bg != null && bg.isNotEmpty) { return NetworkImageLoader(imageUrl: bg, borderRadius: 0); } return Image.asset( - holidayTheme.openHoliday ? HolidayTheme.theme.mineBg : 'mine_bg.webp'.mineImgPath, + 'mine_bg.webp'.mineImgPath, ); } @@ -98,7 +95,6 @@ class HomeMinePage extends StatelessWidget { 8, autoStyle: true, padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), - exposureModel: AdExposureModel(pageType: TrackEventPageType.mine), ), Container( margin: EdgeInsets.symmetric(horizontal: 16), @@ -148,22 +144,12 @@ class HomeMinePage extends StatelessWidget { "mine_notification.png".mineImgPath, width: 28, ), - Consumer( - builder: (ctx, imPro, child) { - if (!imPro.hasUnreadCount) return const SizedBox.shrink(); - return Positioned( - right: 2, - top: 2, - child: Container( - width: 8, - height: 8, - decoration: BoxDecoration( - color: Color(0xfff74f49), - borderRadius: BorderRadius.all(Radius.circular(6)), - ), - ), - ); - }, + Consumer( + builder: (context, model, child) => Positioned( + right: 2, + top: 2, + child: model.buildTipsView(), + ), ), ], ), @@ -249,7 +235,7 @@ class HomeMinePage extends StatelessWidget { //永久官方地址:地址未下发时不渲染,避免点击/复制空串 Widget _buildGroundUrl() { final url = Address.groundUrl; - if (url == null || url.isEmpty) return const SizedBox.shrink(); + if (url.isEmpty) return const SizedBox.shrink(); return GestureDetector( onTap: () => launchUrlToWeb(url), onLongPress: () { @@ -269,31 +255,10 @@ class HomeMinePage extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( children: [ - Stack( - children: [ - InkWell( - enableFeedback: false, - onTap: () => logic.menuTapEvent(3), - child: Image.asset("mine_notification.png".mineImgPath, width: 24), - ), - Consumer( - builder: (ctx, imPro, child) { - if (!imPro.hasUnreadCount) return const SizedBox.shrink(); - return Positioned( - right: 2, - top: 2, - child: Container( - width: 8, - height: 8, - decoration: BoxDecoration( - color: Color(0xfff74f49), - borderRadius: BorderRadius.all(Radius.circular(6)), - ), - ), - ); - }, - ), - ], + InkWell( + enableFeedback: false, + onTap: () => logic.menuTapEvent(3), + child: Image.asset("mine_notification.png".mineImgPath, width: 24), ), Spacer(), InkWell( diff --git a/lib/hj_page/mine/identity/mine_identity_page.dart b/lib/hj_page/mine/identity/mine_identity_page.dart index 2f4d094..f4aadc8 100644 --- a/lib/hj_page/mine/identity/mine_identity_page.dart +++ b/lib/hj_page/mine/identity/mine_identity_page.dart @@ -145,7 +145,7 @@ class MineAccountIdentityPage extends StatelessWidget { height: 30, padding: EdgeInsets.symmetric(horizontal: 18, vertical: 3), child: Text( - '${Config.appName} 官网地址 ${Address.groundUrl ?? ""}', + '${Config.appName} 官网地址 ${Address.groundUrl}', style: TextStyle( color: Colors.white.withValues(alpha: .55), fontSize: 12, diff --git a/lib/hj_page/mine/make_money/mine_withdrawal_record_logic.dart b/lib/hj_page/mine/make_money/mine_withdrawal_record_logic.dart index d6e1739..5e3f4d3 100644 --- a/lib/hj_page/mine/make_money/mine_withdrawal_record_logic.dart +++ b/lib/hj_page/mine/make_money/mine_withdrawal_record_logic.dart @@ -143,7 +143,5 @@ MineWithdrawalRecordLogic instanceController(RecordType type) { return RechargeRecordController(); case RecordType.income: return IncomeRecordController(); - default: - throw '$type 没有找到'; } } diff --git a/lib/hj_page/mine/make_money/withdrawal_page.dart b/lib/hj_page/mine/make_money/withdrawal_page.dart index a5b8eed..fc99d22 100644 --- a/lib/hj_page/mine/make_money/withdrawal_page.dart +++ b/lib/hj_page/mine/make_money/withdrawal_page.dart @@ -1,5 +1,4 @@ import 'package:easy_rich_text/easy_rich_text.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -13,7 +12,6 @@ import 'package:provider/provider.dart'; import '../../../assets_tool/app_colors.dart'; import '../../../hj_utils/widget_util.dart'; -import '../../../routers/jump_router.dart'; import 'in_come_entity.dart'; import 'mine_withdrawal_record_page.dart'; import 'withdrawal_logic.dart'; @@ -359,18 +357,6 @@ class WithdrawalPage extends StatelessWidget { ), )), ), - 10.sizeBoxH, - EasyRichText( - '提现中如有问题,请联系 在线客服', - defaultStyle: textStyle(12, Colors.white.withValues(alpha: .8), FontWeight.w400), - patternList: [ - EasyRichTextPattern( - targetString: '在线客服', - style: TextStyle(color: Color(0xffFFD460)), - recognizer: TapGestureRecognizer()..onTap = pushToCustomService, - ), - ], - ), 34.sizeBoxH, ], ) diff --git a/lib/hj_page/mine/message/message_center_logic.dart b/lib/hj_page/mine/message/message_center_logic.dart index 6602e92..5b711a5 100644 --- a/lib/hj_page/mine/message/message_center_logic.dart +++ b/lib/hj_page/mine/message/message_center_logic.dart @@ -2,13 +2,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../../hj_utils/api_service/mine_service.dart'; +import 'message_center_sub_page.dart'; class MessageCenterLogic extends GetxController with GetTickerProviderStateMixin { MessageCenterLogic get to => Get.find(); late TabController tabController = TabController(length: titleArr.length, vsync: this); - List titleArr = ['私信', '评论', '公告']; + List titleArr = ['评论', '公告']; + List typeArr = [MessageType.comment, MessageType.thumb]; //与 titleArr 一一对应 void getUnReadNum() async { await MineService.getUnreadNum(); diff --git a/lib/hj_page/mine/message/message_center_page.dart b/lib/hj_page/mine/message/message_center_page.dart index d40041e..7663c68 100644 --- a/lib/hj_page/mine/message/message_center_page.dart +++ b/lib/hj_page/mine/message/message_center_page.dart @@ -1,8 +1,5 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:jydj/im_manager/chat_detail_page/Im_ad_view.dart'; -import 'package:jydj/im_manager/chat_detail_page/chat_session_list_view.dart'; -import 'package:jydj/im_manager/im_ad/im_ad_manager.dart'; import 'package:jydj/tools_base/widget/keep_alive_widget.dart'; import 'message_center_logic.dart'; @@ -54,25 +51,7 @@ class MessageCenterPage extends StatelessWidget { controller: logic.tabController, children: logic.titleArr .asMap() - .map((key, value) { - final type = MessageType.values[key]; - // 私信 Tab 走 IM 会话列表 + 顶部 banner 广告,其余走原有 HTTP 消息 - if (type == MessageType.session) { - return MapEntry( - key, - CustomScrollView(slivers: [ - SliverToBoxAdapter( - child: ImAdView( - padding: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - position: ImAdManager.kPosListBanner, - ), - ), - const ChatSessionListView(), - ]).keepAlive, - ); - } - return MapEntry(key, MessageCenterSubPage(type).keepAlive); - }) + .map((key, value) => MapEntry(key, MessageCenterSubPage(logic.typeArr[key]).keepAlive)) .values .toList()), ), diff --git a/lib/hj_page/mine/mine_following/mine_follow_sub_logic.dart b/lib/hj_page/mine/mine_following/mine_follow_sub_logic.dart index 334e48d..0b7e7b4 100644 --- a/lib/hj_page/mine/mine_following/mine_follow_sub_logic.dart +++ b/lib/hj_page/mine/mine_following/mine_follow_sub_logic.dart @@ -157,7 +157,5 @@ MineFollowSubLogic instanceController(FollowType type, {int? uid}) { return TopicController(uid); case FollowType.actress: return ActressController(uid); - default: - throw 'type 没有定义'; } } diff --git a/lib/hj_page/mine/mine_gesture_pwd/widget/gesture_password_widget.dart b/lib/hj_page/mine/mine_gesture_pwd/widget/gesture_password_widget.dart index b8a8c69..3c9e0b9 100644 --- a/lib/hj_page/mine/mine_gesture_pwd/widget/gesture_password_widget.dart +++ b/lib/hj_page/mine/mine_gesture_pwd/widget/gesture_password_widget.dart @@ -280,9 +280,6 @@ class _GesturePasswordWidgetState extends State { @override Widget build(BuildContext context) { - //预览小点的边长:每行 singleLineCount 个 10px 的点 + 之间 8px 间距。必须按 singleLineCount 算, - //写死值(原来是 56)比内容宽时 Wrap 默认贴左上,整块预览会偏左偏上,且换行数只对 3x3 成立 - final previewSize = 10.0 * widget.singleLineCount + 8 * (widget.singleLineCount - 1); return Column( children: [ /*SizedBox( diff --git a/lib/hj_page/mine/mine_profit/bank_card_home_page.dart b/lib/hj_page/mine/mine_profit/bank_card_home_page.dart index 8e3ed6d..74e239b 100644 --- a/lib/hj_page/mine/mine_profit/bank_card_home_page.dart +++ b/lib/hj_page/mine/mine_profit/bank_card_home_page.dart @@ -141,7 +141,7 @@ class _BankCardHomePageState extends State { child: ListView.builder( padding: EdgeInsets.only(top: 10, bottom: 80), shrinkWrap: true, - itemCount: aliList.length ?? 0, + itemCount: aliList.length, itemBuilder: (BuildContext context, int index) { return _buildCardView(index, aliList[index]); }, diff --git a/lib/hj_page/mine/mine_setting/mine_find_account_page.dart b/lib/hj_page/mine/mine_setting/mine_find_account_page.dart index ad3b7bc..7f80392 100644 --- a/lib/hj_page/mine/mine_setting/mine_find_account_page.dart +++ b/lib/hj_page/mine/mine_setting/mine_find_account_page.dart @@ -3,7 +3,6 @@ import 'package:get/get.dart'; import 'package:jydj/hj_utils/screen.dart'; import '../../../hj_utils/permission_util.dart'; -import '../../../routers/jump_router.dart'; import 'bing_phone_page.dart'; import 'mine_scan_login_page.dart'; @@ -21,10 +20,6 @@ class MineFindAccountPage extends StatelessWidget { } } }, - { - 'title': '联系客服', - 'ontap': () => pushToCustomService(), - } ]; MineFindAccountPage({super.key}); diff --git a/lib/hj_page/mine/mine_setting/mine_setting_page.dart b/lib/hj_page/mine/mine_setting/mine_setting_page.dart index 718000a..58bbe77 100644 --- a/lib/hj_page/mine/mine_setting/mine_setting_page.dart +++ b/lib/hj_page/mine/mine_setting/mine_setting_page.dart @@ -3,7 +3,6 @@ import 'package:jydj/assets_tool/app_colors.dart'; import 'package:jydj/routers/jump_router.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; -import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/config/config.dart'; import 'package:jydj/tools_base/toast.dart'; import 'package:jydj/hj_utils/screen.dart'; diff --git a/lib/hj_page/mine/mine_setting/mine_setting_profile_logic.dart b/lib/hj_page/mine/mine_setting/mine_setting_profile_logic.dart index 804ef91..8a80d21 100644 --- a/lib/hj_page/mine/mine_setting/mine_setting_profile_logic.dart +++ b/lib/hj_page/mine/mine_setting/mine_setting_profile_logic.dart @@ -82,7 +82,5 @@ MineSettingProfilePage instanceSettingProfileController(SettingProfileType type) return SettingNickNameController(); case SettingProfileType.slogan: return SettingSloganController(); - default: - throw ''; } } diff --git a/lib/hj_page/mine/mine_share/mine_share_page.dart b/lib/hj_page/mine/mine_share/mine_share_page.dart index 98eaf98..61a10e0 100644 --- a/lib/hj_page/mine/mine_share/mine_share_page.dart +++ b/lib/hj_page/mine/mine_share/mine_share_page.dart @@ -144,7 +144,7 @@ class MineSharePage extends StatelessWidget { height: 30, padding: EdgeInsets.symmetric(horizontal: 18, vertical: 3), child: Text( - '${Config.appName} 官网地址 ${Address.groundUrl ?? ""}', + '${Config.appName} 官网地址 ${Address.groundUrl}', style: TextStyle( color: Colors.white.withValues(alpha: .55), fontSize: 12, diff --git a/lib/hj_page/mine/mine_vip/mine_charge_coin_page.dart b/lib/hj_page/mine/mine_vip/mine_charge_coin_page.dart index baad76d..cece768 100644 --- a/lib/hj_page/mine/mine_vip/mine_charge_coin_page.dart +++ b/lib/hj_page/mine/mine_vip/mine_charge_coin_page.dart @@ -1,5 +1,3 @@ -import 'package:easy_rich_text/easy_rich_text.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; @@ -11,7 +9,6 @@ import 'package:jydj/tools_base/loading/loading_center_widget.dart'; import 'package:provider/provider.dart'; import '../../../hj_utils/widget_util.dart'; -import '../../../routers/jump_router.dart'; import '../make_money/mine_withdrawal_record_page.dart'; import 'charge_user_header.dart'; import 'mine_charge_coin_logic.dart'; @@ -98,16 +95,9 @@ class MineChargeCoinPage extends StatelessWidget { ), SliverToBoxAdapter(child: 18.sizeBoxH), SliverToBoxAdapter( - child: EasyRichText( - '*如提示【交易失败】【账户风险】等,可重新发起订单,或在15分钟后重试支付。如支付未到账,请反馈客服订单号', - defaultStyle: TextStyle(color: Color(0xff666666), fontSize: 12), - patternList: [ - EasyRichTextPattern( - targetString: '反馈客服订单号', - style: TextStyle(color: Color(0xffFFD460), fontWeight: FontWeight.w500), - recognizer: TapGestureRecognizer()..onTap = () => pushToCustomService(), - ) - ], + child: Text( + '*如提示【交易失败】【账户风险】等,可重新发起订单,或在15分钟后重试支付。', + style: TextStyle(color: Color(0xff666666), fontSize: 12), ).paddingSymmetric(horizontal: 16), ), ], @@ -122,7 +112,7 @@ class MineChargeCoinPage extends StatelessWidget { ); } - // 底部支付按钮 + 客服入口 + // 底部支付按钮 Widget _buildBottomBar(MineChargeCoinLogic controller) { return Column( mainAxisSize: MainAxisSize.min, @@ -140,19 +130,6 @@ class MineChargeCoinPage extends StatelessWidget { ), ), ), - 12.sizeBoxH, - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text('权益长期有效 I 支持帐号找回 I ', style: textStyle(12, Color(0xffBFBFC1), FontWeight.w400)), - GestureDetector( - onTap: () { - pushToCustomService(); - }, - child: Text('在线客服', style: textStyle(12, Color(0xffFFD460), FontWeight.w400)), - ) - ], - ), // 垫上虚拟导航栏高度,避免底部内容被遮挡(edge-to-edge) (16 + screen.paddingBottom).sizeBoxH, ], diff --git a/lib/hj_page/mine/mine_vip/mine_charge_vip_page.dart b/lib/hj_page/mine/mine_vip/mine_charge_vip_page.dart index 4944009..220d484 100644 --- a/lib/hj_page/mine/mine_vip/mine_charge_vip_page.dart +++ b/lib/hj_page/mine/mine_vip/mine_charge_vip_page.dart @@ -1,8 +1,6 @@ import 'dart:math' as math; import 'package:carousel_slider/carousel_slider.dart'; -import 'package:easy_rich_text/easy_rich_text.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/assets_tool/images.dart'; @@ -12,7 +10,6 @@ import 'package:jydj/tools_base/unique_tag_mixin.dart'; import 'package:jydj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; -import '../../../routers/jump_router.dart'; import '../../pre_sale/pre_sale_entry.dart'; import '../make_money/mine_withdrawal_record_page.dart'; import 'charge_user_header.dart'; @@ -189,57 +186,6 @@ class _MineChargeVipPageState extends State with UniqueTagMix ); } - //核心权益:横向滚动卡片(左图标 + 右文案)—— B 改版 - Widget _buildCorePrivileges(List list) { - if (list.isEmpty) return const SizedBox.shrink(); - return Column( - children: [ - const VipCoreSectionTitleImage(), - 16.sizeBoxH, - SizedBox( - height: 92, - child: ListView.separated( - clipBehavior: Clip.none, - scrollDirection: Axis.horizontal, - padding: const EdgeInsets.fromLTRB(16, 2, 16, 26), - itemCount: list.length, - separatorBuilder: (_, __) => 8.sizeBoxW, - itemBuilder: (_, index) => VipCorePrivilegeCard(list[index]), - ), - ), - 16.sizeBoxH, - ], - ); - } - - //核心权益:4 列金边方卡 —— A / DISABLED 旧版 - Widget _buildClassicCorePrivileges(List list) { - if (list.isEmpty) return const SizedBox.shrink(); - return Column( - children: [ - const VipSectionTitle("我的核心权益", classic: true), - 16.sizeBoxH, - GridView.builder( - padding: const EdgeInsets.symmetric(horizontal: 14), - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 4, - crossAxisSpacing: 8, - mainAxisSpacing: 8, - childAspectRatio: 1, - ), - itemCount: list.length, - itemBuilder: (_, index) => FittedBox( - fit: BoxFit.contain, - child: SizedBox(width: 72, height: 72, child: VipCorePrivilegeCard(list[index], classic: true)), - ), - ), - 16.sizeBoxH, - ], - ); - } - //更多权益:深色圆角容器 + 四列网格 + 展开/收起 —— B 改版 Widget _buildMorePrivileges(List list) { if (list.isEmpty) return const SizedBox.shrink(); @@ -274,7 +220,7 @@ class _MineChargeVipPageState extends State with UniqueTagMix ); } - //底部支付区域:只有按钮跟选中卡走,渐变底和客服文案是静态的 + //底部支付区域:只有按钮跟选中卡走,渐变底是静态的 Widget _buildPay({required bool classic}) { return Container( padding: EdgeInsets.symmetric(horizontal: 16), @@ -294,18 +240,6 @@ class _MineChargeVipPageState extends State with UniqueTagMix id: MineChargeVipLogic.kSelection, builder: (logic) => VipPayButton(logic, classic: classic), ), - 12.sizeBoxH, - EasyRichText( - '权益长期有效 I 支持帐号找回 I 在线客服', - patternList: [ - EasyRichTextPattern( - targetString: '在线客服', - style: TextStyle(color: Color(0xFFFFC000), fontSize: 12), - recognizer: TapGestureRecognizer()..onTap = () => pushToCustomService(), - ) - ], - defaultStyle: TextStyle(color: Color(0xffBFBFC1), fontSize: 12), - ), // 垫上虚拟导航栏高度,避免底部内容被遮挡(edge-to-edge) (12 + screen.paddingBottom).sizeBoxH, ], diff --git a/lib/hj_page/mine/mine_vip/online_pay_page.dart b/lib/hj_page/mine/mine_vip/online_pay_page.dart index 6aacab7..001b481 100644 --- a/lib/hj_page/mine/mine_vip/online_pay_page.dart +++ b/lib/hj_page/mine/mine_vip/online_pay_page.dart @@ -1,7 +1,5 @@ import 'dart:convert'; -import 'package:easy_rich_text/easy_rich_text.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; @@ -154,21 +152,6 @@ class _OnlinePayPageState extends State { ), ), ), - 18.sizeBoxH, - //客服入口 - Center( - child: EasyRichText( - '支付问题反馈,点击联系 在线客服', - defaultStyle: textStyle(12, Colors.white.withValues(alpha: .6), FontWeight.w500), - patternList: [ - EasyRichTextPattern( - targetString: '在线客服', - style: textStyle(12, Color(0xffFFD460), FontWeight.w500), - recognizer: TapGestureRecognizer()..onTap = () => pushToCustomService(), - ), - ], - ), - ), ]); } diff --git a/lib/hj_page/mine/mine_vip/pay_success_alert.dart b/lib/hj_page/mine/mine_vip/pay_success_alert.dart index 065a4a3..7a76a1f 100644 --- a/lib/hj_page/mine/mine_vip/pay_success_alert.dart +++ b/lib/hj_page/mine/mine_vip/pay_success_alert.dart @@ -4,7 +4,6 @@ import 'package:jydj/assets_tool/app_colors.dart'; import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/widget/common_dialog.dart'; -import '../../../routers/jump_router.dart'; import '../../../tools_base/global_store/store.dart'; class PaySuccessAlert extends StatelessWidget { @@ -34,7 +33,7 @@ class PaySuccessAlert extends StatelessWidget { 0.5.line, 12.sizeBoxH, Text( - '''1.订单支付后,一般会在1-10分钟内到账,如超时未到账,请联系在线客服为您处理。 + '''1.订单支付后,一般会在1-10分钟内到账。 2.受特殊行业限制,如支付失败可尝试重新发起订单,系统将会随机切换备用的支付通道。 3.本APP有稳定的广告收益,产品稳定安全,请放心充值使用,如遇报毒提示忽略即可。''', style: TextStyle( @@ -43,24 +42,6 @@ class PaySuccessAlert extends StatelessWidget { height: 1.8, ), ), - 12.sizeBoxH, - InkWell(enableFeedback: false, - onTap: () => pushToCustomService(), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - '支付遇到问题', - style: TextStyle(color: Color(0xff999999), fontSize: 14), - ), - 2.sizeBoxW, - Icon( - Icons.arrow_forward_ios_outlined, - size: 14, - color: Colors.white, - ) - ], - )), 24.sizeBoxH, InkWell(enableFeedback: false, onTap: () { diff --git a/lib/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart b/lib/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart index 446c5f0..4e80499 100644 --- a/lib/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart +++ b/lib/hj_page/mine/mine_vip/widgets/coin_pay_bottom_sheet.dart @@ -3,8 +3,6 @@ import 'package:get/get.dart'; import 'package:jydj/assets_tool/app_colors.dart'; import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/hj_utils/screen.dart'; -import 'package:jydj/hj_utils/widget_util.dart'; -import 'package:jydj/routers/jump_router.dart'; import 'package:jydj/tools_base/global_store/store.dart'; import 'package:jydj/tools_base/loading/loading_center_widget.dart'; import 'package:provider/provider.dart'; @@ -148,25 +146,6 @@ class CoinPayBottomSheet extends StatelessWidget { ); }, ), - 16.sizeBoxH, - Text.rich( - TextSpan( - style: const TextStyle(fontSize: 12, height: 18 / 12, color: Color(0xff656565)), - children: [ - const TextSpan(text: '*如提示【交易失败】【账户风险】等,可重新发起订单,或在15分钟后重试支付。如支付未到账,请'), - WidgetSpan( - alignment: PlaceholderAlignment.middle, - child: GestureDetector( - onTap: pushToCustomService, - child: const Text( - '反馈客服订单号', - style: TextStyle(fontSize: 12, height: 18 / 12, color: Color(0xffFFD460)), - ), - ), - ), - ], - ), - ), 18.sizeBoxH, ], ), @@ -234,7 +213,7 @@ class CoinPayBottomSheet extends StatelessWidget { ); } - /// 立即支付 + 在线客服 + /// 立即支付 Widget _buildBottomBar(MineChargeCoinLogic logic) { return Column( mainAxisSize: MainAxisSize.min, @@ -259,17 +238,6 @@ class CoinPayBottomSheet extends StatelessWidget { ), ), ), - 12.sizeBoxH, - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text('支付问题反馈,点击联系 ', style: textStyle(12, const Color(0xffBFBFC1), FontWeight.w400)), - GestureDetector( - onTap: pushToCustomService, - child: Text('在线客服', style: textStyle(12, const Color(0xffFFD460), FontWeight.w400)), - ), - ], - ), 16.sizeBoxH, ], ); diff --git a/lib/hj_page/mine/more_question/mine_qa_page.dart b/lib/hj_page/mine/more_question/mine_qa_page.dart index 298d564..68fb003 100644 --- a/lib/hj_page/mine/more_question/mine_qa_page.dart +++ b/lib/hj_page/mine/more_question/mine_qa_page.dart @@ -26,13 +26,13 @@ class _MineQAPageState extends State { { "question": "怎么找回账号?", "answer": - "本平台登录会自动创建账号,需保存账号凭证或绑定手机号码,才能记录之前的账号信息。受行业限制,APP无法正常使用时需升级,未绑定手机号码会导致账号信息丢失。请及时绑定手机号码或保存账号凭证,以免VIP信息丢失,造成巨大财产损失!账号丢失的用户可在 『我的』页面-账号找回,原账号的VIP信息会转移至新账号上。『账号凭证』『手机绑定』都没有的情况下,如账号VIP信息丢失,可以提供VIP支付充值凭证截图联系在线客服为您查询核实恢复VIP。", + "本平台登录会自动创建账号,需保存账号凭证或绑定手机号码,才能记录之前的账号信息。受行业限制,APP无法正常使用时需升级,未绑定手机号码会导致账号信息丢失。请及时绑定手机号码或保存账号凭证,以免VIP信息丢失,造成巨大财产损失!账号丢失的用户可在 『我的』页面-账号找回,原账号的VIP信息会转移至新账号上。", 'isOpen': false }, { "question": "怎么支付不成功?", "answer": - "1.因超时支付无法到账,请重新发起。\n2.每天发起支付不能超过5次,连续发起且未支付,账号可能被加入黑名单。\n3.支付通道在夜间比较忙碌,尝试多次发起,后台会为您自动切换不同支付通道。\n4.若充值成功,用户权益通常会在数分钟内到账,请刷新APP或重启。\n6.若支付成功并重启APP后依然没有到账,请联系在线客服并提供付款成功凭证截图。", + "1.因超时支付无法到账,请重新发起。\n2.每天发起支付不能超过5次,连续发起且未支付,账号可能被加入黑名单。\n3.支付通道在夜间比较忙碌,尝试多次发起,后台会为您自动切换不同支付通道。\n4.若充值成功,用户权益通常会在数分钟内到账,请刷新APP或重启。", 'isOpen': false }, {"question": "收到手机报毒提醒?", "answer": "本平台有主要收益为广告赞助,且保证APP安全无毒,因平台主要展示内容为色情属于特殊行业,某些杀毒软件会误报毒提醒,如遇此类提醒请忽略继续使用。", 'isOpen': false}, diff --git a/lib/hj_page/mine/welfare/lou_feng_ad_page.dart b/lib/hj_page/mine/welfare/lou_feng_ad_page.dart index 2b2a64e..c084049 100644 --- a/lib/hj_page/mine/welfare/lou_feng_ad_page.dart +++ b/lib/hj_page/mine/welfare/lou_feng_ad_page.dart @@ -4,7 +4,6 @@ import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/loading/loading_center_widget.dart'; import 'package:jydj/tools_base/unique_tag_mixin.dart'; import 'package:jydj/tools_base/widget/keep_alive_widget.dart'; -import 'package:jydj/track_event_manager/track_manager.dart'; import 'lou_feng_ad_logic.dart'; import 'widget/recommend_app_page.dart'; @@ -92,8 +91,5 @@ class _LouFengAdPageState extends State with UniqueTagMixin { ); } - Widget _adView(LouFengAdLogic logic, int index) => RecommendAppPage( - logic.configs[index], - exposureModel: AdExposureModel(tabIndex: index, pageType: TrackEventPageType.appList), - ); + Widget _adView(LouFengAdLogic logic, int index) => RecommendAppPage(logic.configs[index]); } diff --git a/lib/hj_page/mine/welfare/more_free_video_logic.dart b/lib/hj_page/mine/welfare/more_free_video_logic.dart index 0d709ab..31c0b7a 100644 --- a/lib/hj_page/mine/welfare/more_free_video_logic.dart +++ b/lib/hj_page/mine/welfare/more_free_video_logic.dart @@ -34,8 +34,8 @@ class MoreFreeVideoLogic extends GetxController with GetTickerProviderStateMixin dataSource.clear(); refreshController?.refreshCompleted(); } - res?.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); - dataSource.addAll(res?.list ?? []); + res.hasNext ?? false ? refreshController?.loadComplete() : refreshController?.loadNoData(); + dataSource.addAll(res.list ?? []); page += 1; update(); } diff --git a/lib/hj_page/mine/welfare/welfare_home_page.dart b/lib/hj_page/mine/welfare/welfare_home_page.dart index b87347f..a42de28 100644 --- a/lib/hj_page/mine/welfare/welfare_home_page.dart +++ b/lib/hj_page/mine/welfare/welfare_home_page.dart @@ -4,7 +4,6 @@ import 'package:jydj/tools_base/widget/keep_alive_widget.dart'; import '../../../tools_base/indicator/custom_tab_indicator.dart'; import 'lou_feng_ad_page.dart'; -import 'mine_income_page.dart'; class WelfareHomePage extends StatefulWidget { diff --git a/lib/hj_page/mine/welfare/widget/recommend_app_page.dart b/lib/hj_page/mine/welfare/widget/recommend_app_page.dart index 0ceec3d..cec423e 100644 --- a/lib/hj_page/mine/welfare/widget/recommend_app_page.dart +++ b/lib/hj_page/mine/welfare/widget/recommend_app_page.dart @@ -3,15 +3,13 @@ import 'package:jydj/hj_model/mine/happy/happy_model.dart'; import 'package:jydj/hj_model/splash/ads_model.dart'; import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/banner/ads_banner.dart'; -import 'package:jydj/track_event_manager/track_manager.dart'; import '../../../../tools_base/banner/ads_item.dart'; class RecommendAppPage extends StatelessWidget { final AdTabConfig model; - final AdExposureModel? exposureModel; - const RecommendAppPage(this.model, {super.key, this.exposureModel}); + const RecommendAppPage(this.model, {super.key}); @override Widget build(BuildContext context) { return CustomScrollView( @@ -24,10 +22,7 @@ class RecommendAppPage extends StatelessWidget { borderRadius: BorderRadius.circular(8), child: AspectRatio( aspectRatio: 343 / 143, - child: AdsBanner( - model.bannerAds ?? [], - exposureModel: exposureModel?..adType = AdType.bigBanner, - ), + child: AdsBanner(model.bannerAds ?? []), ), ), ), @@ -113,8 +108,6 @@ class RecommendAppPage extends StatelessWidget { _buildVItem(AdsInfoModel item, int index) { return AdsItem( adInfo: item, - exposureModel: exposureModel?..adType = AdType.smallIcon, - clickType: 0, ); } @@ -126,8 +119,6 @@ class RecommendAppPage extends StatelessWidget { AdsItem( adInfo: item, showType: AdShowType.hor, - exposureModel: exposureModel?..adType = AdType.smallIcon, - clickType: 0, ), 12.sizeBoxH, ], @@ -138,8 +129,6 @@ class RecommendAppPage extends StatelessWidget { return AdsItem( adInfo: item, showType: AdShowType.vImgText, - exposureModel: exposureModel?..adType = AdType.smallBanner, - clickType: 0, ); } } diff --git a/lib/hj_page/mine/welfare/widget/task_widgets.dart b/lib/hj_page/mine/welfare/widget/task_widgets.dart index 96de876..255506f 100644 --- a/lib/hj_page/mine/welfare/widget/task_widgets.dart +++ b/lib/hj_page/mine/welfare/widget/task_widgets.dart @@ -614,7 +614,7 @@ class _TaskItemState extends State { /// 任务按钮点击:红包雨 → 跳转 link;未完成 → 去完成;待领取 → 领奖 void _onBtnTap(DailyTask task, String btnText) { if (btnText == '领红包' || btnText == '待开启') { - pushToPageByLink(task.link, id: task.id); + pushToPageByLink(task.link); return; } switch (task.status) { @@ -623,7 +623,7 @@ class _TaskItemState extends State { Get.to(MineChargeCoinPage()); return; } - pushToPageByLink(task.link, id: task.id); + pushToPageByLink(task.link); _doTask(task); break; case 1: diff --git a/lib/hj_page/mine/widgets/integral_exchange_page.dart b/lib/hj_page/mine/widgets/integral_exchange_page.dart index 181b277..5d1a786 100644 --- a/lib/hj_page/mine/widgets/integral_exchange_page.dart +++ b/lib/hj_page/mine/widgets/integral_exchange_page.dart @@ -8,9 +8,7 @@ import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/global_store/store.dart'; import 'package:jydj/tools_base/loading/loading_center_widget.dart'; -import '../../../routers/jump_router.dart'; import '../../../tools_base/loading/loading_helper.dart'; -import '../../../tools_base/widget/common_dialog.dart'; import '../../../tools_base/widget/net_image_widget.dart'; import 'integral_exchange_logic.dart'; @@ -105,90 +103,8 @@ class IntegralExchangePage extends StatelessWidget { final res = await MineService.integralExchange(model.id ?? ''); LoadingHelper.dismissLoading(); if (res) { - if (model.type == 5) { - Get.dialog(InputAddressAlert(model: model)); - } else { - showToast('兑换成功~'); - } + showToast('兑换成功~'); globalStore.refreshWallet(); } } } - -class InputAddressAlert extends StatefulWidget { - // final Function()? confirmCallback; - final IntegralExchangeModel model; - const InputAddressAlert({super.key, required this.model}); - - @override - State createState() => _InputAddressAlertState(); -} - -class _InputAddressAlertState extends State { - final nameCtr = TextEditingController(); - final addressCtr = TextEditingController(); - final phoneCtr = TextEditingController(); - - @override - Widget build(BuildContext context) { - return CommonDialog( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - '温馨提示', - style: TextStyle(color: Color(0xffffffff), fontSize: 18.sp, fontWeight: FontWeight.w800), - ), - 20.h.sizeBoxH, - Divider( - height: 1, - color: Colors.white.withValues(alpha: .1), - ), - 20.h.sizeBoxH, - Container( - width: double.infinity, - height: 45.h, - alignment: Alignment.center, - padding: EdgeInsets.symmetric(horizontal: 13.w), - child: Text( - "兑换成功!", - style: TextStyle(color: Color(0x8CFFFFFF), fontSize: 18), - textAlign: TextAlign.center, - ), - ), - 5.h.sizeBoxH, - Container( - width: double.infinity, - height: 45.h, - alignment: Alignment.center, - padding: EdgeInsets.symmetric(horizontal: 13.w), - child: Text( - "请联系客服填写收货地址", - style: TextStyle(color: Color(0x8CFFFFFF), fontSize: 18), - textAlign: TextAlign.center, - ), - ), - 20.h.sizeBoxH, - Padding( - padding: EdgeInsets.symmetric(horizontal: 15.w), - child: GestureDetector( - onTap: () async { - pushToCustomService(); - }, - child: Container( - decoration: BoxDecoration(color: Color(0xffFFC000), borderRadius: BorderRadius.circular(6)), - height: 48, - alignment: Alignment.center, - child: Text( - '联系客服', - style: TextStyle(color: Colors.white, fontSize: 18.sp, fontWeight: FontWeight.w500), - ), - ), - ), - ) - ], - ), - ); - } -} diff --git a/lib/hj_page/mine/widgets/mine_info_widget.dart b/lib/hj_page/mine/widgets/mine_info_widget.dart index fd1af4f..c5e75b9 100644 --- a/lib/hj_page/mine/widgets/mine_info_widget.dart +++ b/lib/hj_page/mine/widgets/mine_info_widget.dart @@ -3,7 +3,6 @@ import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/hj_model/video_model.dart'; -import 'package:jydj/hj_utils/holiday_theme.dart'; import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/global_store/store.dart'; import 'package:jydj/tools_base/toast.dart'; @@ -13,9 +12,7 @@ import '../../home/widget/user_avatar.dart'; import '../../home/widget/user_name_view.dart'; import '../collec_history_buy/col_his_buy_page.dart'; import '../home_mine_logic.dart'; -import '../mine_following/mine_following_view.dart'; import '../mine_setting/mine_setting_page.dart'; -import '../mine_video_cache/video_cache_page.dart'; import '../mine_vip/mine_charge_coin_page.dart'; import '../mine_vip/mine_charge_vip_page.dart'; import '../welfare/sign_daily_page.dart'; @@ -157,7 +154,7 @@ class MineTaskMenuWidget extends StatelessWidget { InkWell( enableFeedback: false, onTap: () => Get.to(() => MineChargeVipPage(), preventDuplicates: false), - child: _buildItem("", HolidayTheme.theme.vipEnter, 0), + child: _buildItem("", 'mine_vip_enter.webp'.mineImgPath, 0), ), InkWell( enableFeedback: false, @@ -167,14 +164,14 @@ class MineTaskMenuWidget extends StatelessWidget { }, child: _buildItem( "余额:${(globalStore.wallet?.amount ?? 0) + (globalStore.wallet?.income ?? 0)}", - HolidayTheme.theme.coin, + 'mine_gold_enter.webp'.mineImgPath, 15, ), ), InkWell( enableFeedback: false, onTap: _openAiGirlFriendDetail, - child: _buildItem("", HolidayTheme.theme.aiEnter, 0), + child: _buildItem("", 'mine_ai_enter.webp'.mineImgPath, 0), ), ]; return Stack( diff --git a/lib/hj_page/mine/widgets/mine_share_qr_view.dart b/lib/hj_page/mine/widgets/mine_share_qr_view.dart index 6c58482..c613087 100644 --- a/lib/hj_page/mine/widgets/mine_share_qr_view.dart +++ b/lib/hj_page/mine/widgets/mine_share_qr_view.dart @@ -145,7 +145,7 @@ class _MineShareQRViewState extends State { borderRadius: BorderRadius.circular(30), ), child: Text( - '${Config.appName} 官网地址 ${Address.groundUrl ?? ""}', + '${Config.appName} 官网地址 ${Address.groundUrl}', style: TextStyle( color: Colors.white.withValues(alpha: .55), fontSize: 12, diff --git a/lib/hj_page/short_video/view/feed_ad_view.dart b/lib/hj_page/short_video/view/feed_ad_view.dart index ece31c3..7e7415f 100644 --- a/lib/hj_page/short_video/view/feed_ad_view.dart +++ b/lib/hj_page/short_video/view/feed_ad_view.dart @@ -1,5 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:jydj/hj_model/video_model.dart'; +import 'package:jydj/hj_utils/api_service/common_service.dart'; import 'package:jydj/routers/jump_router.dart'; import '../../../hj_model/splash/ads_model.dart'; @@ -14,7 +15,10 @@ class FeedAdView extends StatelessWidget { Widget build(BuildContext context) { final AdsInfoModel? adv = mediaInfo?.randomAdsInfo; return GestureDetector( - onTap: () => pushToPageByLink(adv?.href, id: adv?.id), + onTap: () { + pushToPageByLink(adv?.href); + CommonService.adsClick(adv?.id); + }, // 强制全屏铺满(与视频页一致),避免 iOS 上未撑满导致显示不全 child: SizedBox.expand( child: NetworkImageLoader( diff --git a/lib/hj_page/short_video/view/float_ad_view.dart b/lib/hj_page/short_video/view/float_ad_view.dart index 1f62c60..afbb0d4 100644 --- a/lib/hj_page/short_video/view/float_ad_view.dart +++ b/lib/hj_page/short_video/view/float_ad_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/hj_model/splash/ads_model.dart'; +import 'package:jydj/hj_utils/api_service/common_service.dart'; import 'package:jydj/routers/jump_router.dart'; import 'package:jydj/tools_base/ad_manager.dart'; import 'package:jydj/tools_base/widget/net_image_widget.dart'; @@ -34,7 +35,10 @@ class _FloatAdViewState extends State { clipBehavior: Clip.none, children: [ GestureDetector( - onTap: () => pushToPageByLink(ad.href, id: ad.id), + onTap: () { + pushToPageByLink(ad.href); + CommonService.adsClick(ad.id); + }, child: NetworkImageLoader( imageUrl: cover, width: 70, diff --git a/lib/hj_page/short_video/view/media_action_menu.dart b/lib/hj_page/short_video/view/media_action_menu.dart index d2e8bd8..c672a19 100644 --- a/lib/hj_page/short_video/view/media_action_menu.dart +++ b/lib/hj_page/short_video/view/media_action_menu.dart @@ -1,4 +1,3 @@ -import 'package:analytics_sdk/enum/video_event_enum.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/assets_tool/images.dart'; @@ -21,7 +20,6 @@ import '../../../hj_utils/api_service/mine_service.dart'; import '../../../tools_base/debug_log.dart'; import '../../../tools_base/global_store/store.dart'; import '../../../tools_base/widget/net_image_widget.dart'; -import '../../../track_event_manager/track_manager.dart'; import '../../comment/comment_alert.dart'; import '../../home/widget/collect_status_wrapper.dart'; import '../../user_center_page/user_center_page.dart'; @@ -301,7 +299,6 @@ class _MediaActionMenuState extends State with TickerProviderSt void _onShareEvent() async { final isPlaying = widget.playerCtr?.value.isPlaying ?? false; widget.playerCtr?.pause(); - TrackVideoManager.send(VideoEventEnum.VIDEO_SHARE, _video, widget.playerCtr); await Get.dialog(ShareMediaDialog(videoModel: _video)); //短剧分享要回服务端累计互动数(推荐分要吃),eventId 幂等:同一次分享重试沿用同一个 if (_isDrama) { diff --git a/lib/hj_page/short_video/view/video_player_base_logic.dart b/lib/hj_page/short_video/view/video_player_base_logic.dart index d950e2c..8a89b86 100644 --- a/lib/hj_page/short_video/view/video_player_base_logic.dart +++ b/lib/hj_page/short_video/view/video_player_base_logic.dart @@ -1,4 +1,3 @@ -import 'package:analytics_sdk/enum/video_event_enum.dart'; import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; import 'package:jydj/hj_model/video_model.dart'; @@ -10,7 +9,6 @@ import 'package:video_player/video_player.dart'; import 'package:visibility_detector/visibility_detector.dart'; import '../../../tools_base/debug_log.dart'; -import '../../../track_event_manager/track_manager.dart'; /// 竖屏播放器的**播放器管线**:建控制器、H.265 降级、可见性驱动播停、倍速、完播检测。 /// 只放与业务无关的机制——试看拦截、付费墙、续播这些各自在子类里做。 @@ -157,7 +155,6 @@ abstract class VideoPlayerBaseLogic extends GetxController { notify(); await playerCtr?.initialize(); if (isRetry) confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 - TrackVideoManager.send(VideoEventEnum.VIDEO_VIEW, video, playerCtr); preVideoCtr?.removeListener(_onProgress); preVideoCtr?.dispose(); // 切线路/刷新:释放旧控制器,避免解码器泄漏累积导致后续视频全部加载失败 // initialize 期间可能已被销毁(快速连滑),playerCtr 已在 onClose() 里释放, @@ -235,20 +232,18 @@ abstract class VideoPlayerBaseLogic extends GetxController { //duration 为 0 的异常流 isCompleted 也是 true,必须由外层这个条件挡住,别刚起播就当播完 if (duration.inMilliseconds > 0 && (ctr.value.isCompleted || position.inMilliseconds >= duration.inMilliseconds - 300)) { - //上报和回调都只发一次:条件成立后每个 tick 都会再进来 + //回调只发一次:条件成立后每个 tick 都会再进来 if (!_completedSent) { _completedSent = true; - TrackVideoManager.send(VideoEventEnum.VIDEO_COMPLETE, video, ctr); onFinished(); } } onTick(position.inSeconds); } - /// 点屏播放/暂停,顺带上报。返回操作前是否在播(子类要据此落进度) + /// 点屏播放/暂停。返回操作前是否在播(子类要据此落进度) bool togglePlay() { final isPlaying = playerCtr?.value.isPlaying == true; - TrackVideoManager.send(isPlaying ? VideoEventEnum.VIDEO_PAUSE : VideoEventEnum.VIDEO_PLAY, video, playerCtr); isPlaying ? playerCtr?.pause() : playerCtr?.play(); return isPlaying; } @@ -256,7 +251,6 @@ abstract class VideoPlayerBaseLogic extends GetxController { /// 长按 2 倍速 void speedUp() { showToast("长按不动,2X倍速播放"); - TrackVideoManager.send(VideoEventEnum.VIDEO_FORWARD, video, playerCtr); playerCtr?.setPlaybackSpeed(2.0); } diff --git a/lib/hj_page/splash/splash_ad_view.dart b/lib/hj_page/splash/splash_ad_view.dart index 0a6813d..0a7b004 100644 --- a/lib/hj_page/splash/splash_ad_view.dart +++ b/lib/hj_page/splash/splash_ad_view.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:jydj/assets_tool/app_colors.dart'; import 'package:jydj/assets_tool/images.dart'; +import 'package:jydj/hj_utils/api_service/common_service.dart'; import 'package:jydj/hj_utils/screen.dart'; import '../../hj_model/splash/ads_model.dart'; @@ -11,7 +12,6 @@ import '../../routers/jump_router.dart'; import '../../tools_base/banner/ads_banner.dart'; import '../../tools_base/banner/ads_item.dart'; import '../../tools_base/widget/net_image_widget.dart'; -import '../../track_event_manager/track_manager.dart'; /// 启动页广告:3 秒倒计时后右上角按钮变为"关闭",点击触发 callback 跳首页 class SplashAdView extends StatefulWidget { @@ -73,7 +73,10 @@ class _SplashAdViewState extends State { if (dataLen == 1) { final ad = widget.adData!.first; return GestureDetector( - onTap: () => pushToPageByLink(ad.href ?? "", id: ad.id), + onTap: () { + pushToPageByLink(ad.href ?? ""); + CommonService.adsClick(ad.id); + }, child: Container( alignment: Alignment.center, child: NetworkImageLoader( @@ -221,10 +224,6 @@ class _SplashBannerWidgetState extends State { return AdsItem( adInfo: ad, showType: AdShowType.splash, - exposureModel: AdExposureModel( - pageType: TrackEventPageType.start, - adType: AdType.splash, - ), ); }, ), diff --git a/lib/hj_page/splash/splash_logic.dart b/lib/hj_page/splash/splash_logic.dart index dea1607..d92a400 100644 --- a/lib/hj_page/splash/splash_logic.dart +++ b/lib/hj_page/splash/splash_logic.dart @@ -1,8 +1,5 @@ import 'dart:convert'; -import 'package:analytics_sdk/analytics_sdk.dart'; -import 'package:analytics_sdk/entity/app_install_event.dart'; -import 'package:analytics_sdk/enum/user_type_enum.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; @@ -19,12 +16,10 @@ import 'package:jydj/hj_page/pre_sale/limit_time_provider.dart'; import 'package:jydj/hj_page/pre_sale/pre_sale_provider.dart'; import 'package:jydj/hj_utils/api_service/common_service.dart'; import 'package:jydj/hj_utils/detect_line_manager.dart'; -import 'package:jydj/hj_utils/holiday_theme.dart'; import 'package:jydj/hj_utils/local_server.dart'; import 'package:jydj/hj_utils/local_server_guard.dart'; import 'package:jydj/hj_utils/text_util.dart'; import 'package:jydj/hj_utils/version_util.dart'; -import 'package:jydj/im_manager/im_manager.dart'; import 'package:jydj/tools_base/debug_log.dart'; import 'package:jydj/tools_base/ad_manager.dart'; import 'package:jydj/tools_base/global_store/store.dart'; @@ -36,7 +31,6 @@ import 'package:jydj/tools_base/widget/common_alert.dart'; import '../../alert/splash/line_error_dialog.dart'; import '../../alert/splash/update_dialog.dart'; import '../../hj_utils/free_play_manager.dart'; -import '../../hj_utils/install_util.dart'; import '../../tools_base/loading/loading_alert_widget.dart'; import '../../track_event_manager/device_service.dart'; import '../live/live_main_page.dart'; @@ -51,7 +45,6 @@ class SplashLogic extends GetxController { // ===== 启动数据 ===== bool isDataReady = false; //模块列表已落地 - bool _isTracked = false; //登录埋点去重 bool _isExiting = false; //强更被拒、已请求退出 app:后续流程一律不再放行首页 @override @@ -76,19 +69,13 @@ class SplashLogic extends GetxController { //1. 初始化网络层 _initNet(line); //2.先登录,后升级,不然渠道一升级就没有量了,先登录才能获取配置信息 - final userInfo = await _devLogin(); - ImManager().initImSDK(); // 登录后初始化 IM SDK,需先拿到动态配置(随登录返回写入 ImManager) + await _devLogin(); // 模块列表只依赖登录拿到的 token,请求先发出去跟下面的配置/更新检查并行跑, // 但结果留到更新检查之后才放行(见末尾)——强更期间不能让首页变成可跳 // ignore():先占个监听位,免得错误在 await 到之前被当成未捕获异常上报;真正的错误照旧在 await 处抛 final tagTask = CommonService.getTagMarks()..ignore(); //2. 获取远程配置 final versions = await _fetchConfig(); - ImManager().connectServer(); //登录并拿到配置后连接 IM 服务器 - //3.获取到配置信息拿到baseurl才进行埋点 - if (userInfo != null) { - _trackEvents(userInfo); - } PreSaleProvider().refreshConfig(); MineMsgProvider().startPayTimer(); //冷启动 /ping/domain 下发支付分层配置后启动倒计时 FreePlayManager().refresh(); //免费次数进首页才用得到,不 await、不挡启动 @@ -107,34 +94,6 @@ class SplashLogic extends GetxController { update(); } - //埋点事件 - Future _trackEvents(UserInfoModel userInfo) async { - //安装 - final traceId = await DeviceInfoService.fetchTraceId(); - final isFirst = await InstallUtil.isFirstInstall(); - if (isFirst) { - debugLog('splash', '第一次安装,执行首次安装初始化'); - // 执行首次安装的初始化操作 - await InstallUtil.markAsInstalled(); - //新增SDK埋点 - AnalyticsSdk.instance.track(AppInstallEvent( - traceId: traceId, - )); - } else { - debugLog('splash', '已安装过,跳过首次安装初始化'); - } - // 登录埋点 - if (!_isTracked) { - _isTracked = true; - - //新增SDK埋点 - AnalyticsSdk.setUserIdAndType( - userId: "${userInfo.uid}", - userTypeEnum: userInfo.isVip == true ? UserTypeEnum.vip : UserTypeEnum.normal, - ); - } - } - ///一直检查网络直到成功 Future _detectLine() async { LoadingAlertWidget.show(title: "选线中..."); @@ -172,20 +131,11 @@ class SplashLogic extends GetxController { ..dc = channel ..tid = traceId; paste = json.encode(cutInfo.toJson()); - AnalyticsSdk.setChannel(channel); } else { //1.获取粘贴板(走缓存,避免 iOS 多次弹系统读取提示) final clipText = await DeviceInfoService.getClipboardTextCached(); if (TextUtil.isNotEmpty(clipText)) { paste = clipText!; - try { - final map = jsonDecode(paste) as Map; - final dc = map['dc'] as String?; - //更新渠道信息 - if (dc != null) AnalyticsSdk.setChannel(dc); - } catch (_) { - //粘贴板内容非合法 JSON,忽略 - } } } final deviceId = DeviceInfoService.deviceId; @@ -238,15 +188,12 @@ class SplashLogic extends GetxController { //限时活动相关 limitTimeProvider.bannerJump = info.bannerJump; Config.proxyBanner = info.proxyBannerJump; - holidayTheme.setThemeValue(info.festivalUi ?? ''); - // holidayTheme.setThemeValue('春节'); Config.hotWords = info.hotSearchTerms ?? []; Config.searchHints = info.searchHintWord ?? []; Config.darkWebVipId = info.darkWebVipId; Config.darkWebVipName = info.darkWebVipName; Config.shortDramaCardId = info.shortDramaCardId; - await AnalyticsSdk.instance.refreshDomainConfig(encryptedConfig: info.reportSdkConfig); } catch (e) { debugLog('getRemoteConfig', e.toString()); final retry = await CommonAlert.show( diff --git a/lib/hj_page/user_center_page/user_center_logic.dart b/lib/hj_page/user_center_page/user_center_logic.dart index a7d4daa..50be4da 100644 --- a/lib/hj_page/user_center_page/user_center_logic.dart +++ b/lib/hj_page/user_center_page/user_center_logic.dart @@ -3,11 +3,8 @@ import 'package:get/get.dart'; import 'package:jydj/hj_model/user/user_info_model.dart'; import 'package:jydj/hj_utils/api_service/mine_service.dart'; import 'package:jydj/hj_utils/const.dart'; -import 'package:jydj/im_manager/im_manager.dart'; -import 'package:jydj/im_manager/model/im_message_resp.dart'; import 'package:jydj/tools_base/debug_log.dart'; import 'package:jydj/tools_base/global_store/store.dart'; -import 'package:jydj/tools_base/toast.dart'; class UserCenterController extends GetxController with GetTickerProviderStateMixin { // ===== 数据 ===== @@ -76,19 +73,6 @@ class UserCenterController extends GetxController with GetTickerProviderStateMix update(); } - void gotoPrivateChat() { - if (globalStore.isMe(model?.uid)) { - showToast("不能给自己私信哦~"); - return; - } - // 私信走 IM(替换原 HTTP MineChatPage) - jumpToChatDetail(IMSessionModel( - peerId: model?.uid ?? 0, - nickName: model?.name ?? '', - avatar: model?.portrait, - )); - } - /// 关注/取关成功后更新本地状态;[isFollow] 为操作后的最新状态(与 [FollowButton] 回调一致) void onUserFollowSuccess(bool isFollow) { if (model == null) return; diff --git a/lib/hj_page/user_center_page/widget/user_center_header.dart b/lib/hj_page/user_center_page/widget/user_center_header.dart index 31d81f0..e9ceea0 100644 --- a/lib/hj_page/user_center_page/widget/user_center_header.dart +++ b/lib/hj_page/user_center_page/widget/user_center_header.dart @@ -1,10 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:jydj/assets_tool/app_colors.dart'; import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/extension/extensions.dart'; import 'package:jydj/hj_page/user_center_page/user_center_logic.dart'; import 'package:jydj/hj_utils/screen.dart'; -import 'package:jydj/hj_utils/widget_util.dart'; import 'package:jydj/tools_base/global_store/store.dart'; import 'package:jydj/tools_base/widget/follow_button.dart'; @@ -102,24 +100,9 @@ class UserCenterHeader extends StatelessWidget { ); } - //私信 + 关注,仅他人主页展示 + //关注,仅他人主页展示 List _actionButtons() { return [ - InkWell( - enableFeedback: false, - onTap: logic.gotoPrivateChat, - child: Container( - width: 32, - height: 24, - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(3), - color: const Color(0x1AF68804), - ), - child: Text('私信', style: textStyle(10, AppColors.actionRed, FontWeight.w400)), - ), - ), - 12.sizeBoxW, FollowButton( mediaId: (logic.model?.uid ?? 0).toString(), followType: FollowEnum.user, diff --git a/lib/hj_page/video/cartoon/video_detail_cartoon_view.dart b/lib/hj_page/video/cartoon/video_detail_cartoon_view.dart index ce0c44a..a10d11e 100644 --- a/lib/hj_page/video/cartoon/video_detail_cartoon_view.dart +++ b/lib/hj_page/video/cartoon/video_detail_cartoon_view.dart @@ -1,4 +1,3 @@ -import 'package:analytics_sdk/enum/video_event_enum.dart'; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -17,7 +16,6 @@ import 'package:video_player/video_player.dart'; import '../../../hj_model/acg/comic_chapters_model.dart'; import '../../../hj_model/cartoon_media_info.dart'; -import '../../../track_event_manager/track_manager.dart'; import '../../../alert/video/share_media_dialog.dart'; import '../../cartoon/cartoon_recommend_page.dart'; import 'cartoon_episode_menu_alert.dart'; @@ -103,8 +101,6 @@ class _VideoDetailCartoonViewState extends State child: AdsGridView( 6, padding: EdgeInsets.only(left: 12, bottom: 18), - exposureModel: - AdExposureModel(pageType: TrackEventPageType.videoPlay), ), ), SliverToBoxAdapter(child: _buildTitleMenu()), @@ -143,9 +139,8 @@ class _VideoDetailCartoonViewState extends State ); } - /// 分享:带播放器上报埋点(进度/时长),再弹分享面板 + /// 分享:弹分享面板 void _onShare() { - TrackVideoManager.send(VideoEventEnum.VIDEO_SHARE, videoModel, widget.playCtr); Get.dialog(ShareMediaDialog(videoModel: videoModel)); } diff --git a/lib/hj_page/video/video_logic.dart b/lib/hj_page/video/video_logic.dart index 0b89411..e1eab3c 100644 --- a/lib/hj_page/video/video_logic.dart +++ b/lib/hj_page/video/video_logic.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:analytics_sdk/enum/video_event_enum.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; @@ -38,7 +37,6 @@ import '../../tools_base/debug_log.dart'; import '../../tools_base/event_bus/event_bus_util.dart'; import '../../tools_base/event_bus/events.dart'; import '../../tools_base/global_store/store.dart'; -import '../../track_event_manager/track_manager.dart'; import '../main_page/provider/msg_provider.dart'; import '../pre_sale/pre_sale_provider.dart'; @@ -342,7 +340,6 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { /// 注:贴片广告期间不直接 play,由广告结束回调触发本方法(见 video_page.dart 的 onFinish) void play() { if (isDispose || isShowAd) return; // 有贴片广告时不自动播,等广告结束回调 - TrackVideoManager.send(VideoEventEnum.VIDEO_PLAY, videoModel, playerCtr, isPreVideo: _isPreview()); playerCtr?.play(); _startPayGuideTimer(); // 需付费的起播满3秒 → 前置购买引导(场景1);不满足条件的它自己会挡 } @@ -399,7 +396,6 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { try { await playerCtr?.initialize(); if (isRetry) confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地 - TrackVideoManager.send(VideoEventEnum.VIDEO_VIEW, videoModel, playerCtr, isPreVideo: _isPreview()); update(); } catch (e) { debugLog("视频初始化失败:$e play url = $videoUrl"); @@ -469,9 +465,6 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { return; } int duration = playerCtr?.value.duration.inSeconds ?? 0; - if (duration > 0 && playerCtr!.value.position.inSeconds >= duration - 1) { - _trackComplete(); - } if (_hasFreeWatchRight) return; // 免费次数/免费区/动漫已购/免费章节/VIP金币限免,整片随便看 if (!_isPreview()) { //每帧都走这里,videoStatus 是重算 getter,只读一次 @@ -572,15 +565,9 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { return videoModel?.previewURL?.isNotEmpty == true && videoStatus.isNeedPay; } - /// 上报当前视频播放结束(切视频/切集/退页统一入口) - void _trackComplete() { - TrackVideoManager.send(VideoEventEnum.VIDEO_COMPLETE, videoModel, playerCtr, isPreVideo: _isPreview()); - } - /// 推荐区切内容(释放控制器 + 重拉详情起播,不开新页)。 /// **必须按被点内容的 videoType 定接口**,用页面入参会串接口 → 「视频资源加载失败」 Future switchVideo(VideoModel model) async { - _trackComplete(); videoModel = model; isShowBuy.value = false; isCartoon = model.videoType == 1; @@ -601,7 +588,6 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { /// 切视频或切 CDN 路线:[model] 非空=切新视频,为空=同视频换 URL;控制器为空走首次进入路径 Future startPlay({VideoModel? model, bool resetPos = false}) async { if (model != null) { - _trackComplete(); videoModel = model; } if (playerCtr == null) { @@ -619,7 +605,6 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { return; } try { - _trackComplete(); currentEpisode = episode; isShowBuy.value = false; releasePlayer(rebuild: false); @@ -653,13 +638,12 @@ class VideoLogic extends GetxController with GetSingleTickerProviderStateMixin { playerCtr = null; } - /// 页面销毁清理:上报 VIDEO_COMPLETE → 取消事件订阅 → 非预览视频上报观看记录 → 释放播放器 + /// 页面销毁清理:取消事件订阅 → 非预览视频上报观看记录 → 释放播放器 @override void onClose() { isDispose = true; // 第一时间置位,让所有异步回调(initialize/postFrame/Future.delayed)能尽早 return TimedPopupManager().cancel(TimedPopupType.freeWatchPay); TimedPopupManager().cancel(TimedPopupType.videoPayAhead); - _trackComplete(); playerCtr?.pause(); playerCtr?.removeListener(_onProgress); diff --git a/lib/hj_page/video/view/video_ad_widget.dart b/lib/hj_page/video/view/video_ad_widget.dart index 4fbdb00..972e91d 100644 --- a/lib/hj_page/video/view/video_ad_widget.dart +++ b/lib/hj_page/video/view/video_ad_widget.dart @@ -7,7 +7,6 @@ import 'package:jydj/assets_tool/images.dart'; import '../../../hj_model/splash/ads_model.dart'; import '../../../tools_base/banner/ads_banner.dart'; import '../../../tools_base/global_store/store.dart'; -import '../../../track_event_manager/track_manager.dart'; /// 播放前贴片广告(Banner + 倒计时关闭)。 /// 倒计时完或 VIP 关闭走 [onFinish],未到时间的非 VIP 走 [onToVip] 引导开通 @@ -91,7 +90,6 @@ class _VideoAdWidgetState extends State { height: 88, autoPlayMs: 2000, indicatorAlign: IndicatorAlign.bottomCenter, - exposureModel: AdExposureModel(pageType: TrackEventPageType.videoPlay, adType: AdType.smallBanner), ), _closeBtn(), if (widget.showBackArrow) _backBtn(), diff --git a/lib/hj_page/video/view/video_detail_view.dart b/lib/hj_page/video/view/video_detail_view.dart index 02c623b..3c91d19 100644 --- a/lib/hj_page/video/view/video_detail_view.dart +++ b/lib/hj_page/video/view/video_detail_view.dart @@ -1,4 +1,3 @@ -import 'package:analytics_sdk/enum/video_event_enum.dart'; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -17,7 +16,6 @@ import 'package:video_player/video_player.dart'; import '../../../alert/video/share_media_dialog.dart'; import '../../../routers/jump_router.dart'; -import '../../../track_event_manager/track_manager.dart'; import '../../cartoon/cartoon_recommend_page.dart'; /// 视频播放页数据详情 @@ -83,7 +81,6 @@ class _VideoDetailViewState extends State with SingleTickerProv 6, padding: EdgeInsets.only(left: 12, bottom: 18), autoStyle: true, - exposureModel: AdExposureModel(pageType: TrackEventPageType.videoPlay), ), ), SliverToBoxAdapter(child: _buildTitleMenu()), @@ -209,9 +206,8 @@ class _VideoDetailViewState extends State with SingleTickerProv ); } - /// 分享:带播放器上报埋点(进度/时长),再弹分享面板 + /// 分享:弹分享面板 void _onShare() { - TrackVideoManager.send(VideoEventEnum.VIDEO_SHARE, videoModel, widget.playCtr); Get.dialog(ShareMediaDialog(videoModel: videoModel)); } diff --git a/lib/hj_page/video/view/video_menu_view.dart b/lib/hj_page/video/view/video_menu_view.dart index d5a54ea..f0a1dc3 100644 --- a/lib/hj_page/video/view/video_menu_view.dart +++ b/lib/hj_page/video/view/video_menu_view.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:ui' show ImageFilter; -import 'package:analytics_sdk/enum/video_event_enum.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; @@ -16,7 +15,6 @@ import '../../../hj_utils/buy_util.dart'; import '../../../hj_utils/date_time_util.dart'; import '../../../hj_utils/free_play_manager.dart'; import '../../../tools_base/global_store/store.dart'; -import '../../../track_event_manager/track_manager.dart'; import '../../pre_sale/pre_sale_provider.dart'; import '../../short_video/view/video_progress_widget.dart'; import 'long_video_status.dart'; @@ -196,8 +194,6 @@ class _VideoMenuViewState extends State { void _setPlay(bool play) { _playing.value = play; - TrackVideoManager.send(play ? VideoEventEnum.VIDEO_PLAY : VideoEventEnum.VIDEO_PAUSE, widget.videoModel, playCtr, - isPreVideo: isPreview); play ? playCtr.play() : playCtr.pause(); } @@ -219,8 +215,6 @@ class _VideoMenuViewState extends State { const step = Duration(seconds: 10); final pos = playCtr.value.position; playCtr.seekTo(_snapSeek(forward ? pos + step : pos - step)); - TrackVideoManager.send(forward ? VideoEventEnum.VIDEO_FORWARD : VideoEventEnum.VIDEO_REWIND, widget.videoModel, playCtr, - isPreVideo: isPreview); } void _onPlayerTick() { @@ -282,7 +276,6 @@ class _VideoMenuViewState extends State { }, onLongPressStart: (_) { showToast("长按不动,2X倍速播放", gravity: ToastGravity.top); - TrackVideoManager.send(VideoEventEnum.VIDEO_FORWARD, widget.videoModel, playCtr, isPreVideo: isPreview); _isLongPress = true; _showSpeed = false; _showSeekText = false; diff --git a/lib/hj_utils/api_service/common_service.dart b/lib/hj_utils/api_service/common_service.dart index 3bf4e69..3366a60 100644 --- a/lib/hj_utils/api_service/common_service.dart +++ b/lib/hj_utils/api_service/common_service.dart @@ -204,11 +204,12 @@ class CommonService { return result.isSuccess ? result.data : null; } - //广告点击统计 广告类型 0:应用 1:广告 - static Future adsClick(int? type) async { + /// 广告点击日志:[id] 广告 id(后端必填,空就不报);type 固定传 0(普通广告) + static Future adsClick(String? id) async { + if (id == null || id.isEmpty) return false; final result = await httpManager.fetchResponseByPOST( - '/ads/click/stat', - param: {'type': type}, + '/ads/click', + param: {'id': id, 'type': 0}, ); return result.isSuccess; } diff --git a/lib/hj_utils/api_service/drama_service.dart b/lib/hj_utils/api_service/drama_service.dart index 28245c2..d4b6499 100644 --- a/lib/hj_utils/api_service/drama_service.dart +++ b/lib/hj_utils/api_service/drama_service.dart @@ -8,7 +8,7 @@ import 'package:jydj/tools_base/net/http_manager.dart'; /// 短剧接口。金币解锁已并入 PayManager/BuyService,这里只剩读操作 + 两个计数型写操作: /// 信息流翻页去重、分享互动计数,都必须带 `X-Request-ID`——同一次业务的重试要复用同一个 id, -/// 换新 id 就会重复计数。播放埋点走现有 analytics SDK(TrackVideoManager),不另建短剧专用上报 +/// 换新 id 就会重复计数。 class DramaService { static Options _idempotent(String requestId) => Options(headers: {'X-Request-ID': requestId}); diff --git a/lib/hj_utils/api_service/mine_service.dart b/lib/hj_utils/api_service/mine_service.dart index 133890f..a49e55c 100644 --- a/lib/hj_utils/api_service/mine_service.dart +++ b/lib/hj_utils/api_service/mine_service.dart @@ -177,12 +177,6 @@ class MineService { return result.isSuccess ? result.data : null; } - /// 获取客服对接地址 - static Future fetchCustomService() async { - final result = await httpManager.fetchResponseByGET('/customer/url', param: {}); - return result.isSuccess ? result.data : null; - } - /// 积分兑换商品 static Future integralExchange(String id, {String? name, String? tel, String? address}) async { final param = {"id": id, "name": name, "tel": tel, "address": address}; diff --git a/lib/hj_utils/dns_solve/_response.dart b/lib/hj_utils/dns_solve/_response.dart index c0f6446..a6f89f7 100644 --- a/lib/hj_utils/dns_solve/_response.dart +++ b/lib/hj_utils/dns_solve/_response.dart @@ -74,7 +74,7 @@ class ResolveResponse { final data = json['Question']; if (data == null) return null; if (data is List) { - return (data as List) + return data .map( (question) => _Question.fromJson(question as Map), ) diff --git a/lib/hj_utils/local_server.dart b/lib/hj_utils/local_server.dart index 1beccd5..25e989b 100644 --- a/lib/hj_utils/local_server.dart +++ b/lib/hj_utils/local_server.dart @@ -342,8 +342,8 @@ class CacheServer { // 是否是预缓存的请求 bool isPreCache = false; Map queryParameters = {}; - queryParameters.addAll(localReq.uri.queryParameters ?? {}); - if (queryParameters.containsKey("isPreCache") ?? false) { + queryParameters.addAll(localReq.uri.queryParameters); + if (queryParameters.containsKey("isPreCache")) { queryParameters.remove("isPreCache"); isPreCache = true; } @@ -432,7 +432,7 @@ class CacheServer { if (rangeStart <= 0) { resp.data?.headers.forEach((key, values) { if (HttpHeaders.contentLengthHeader == key) { - var ct = int.parse(values[0] ?? "0"); + var ct = int.parse(values[0]); localReq.response.headers.add(key, ct > 0 ? (ct - 6) : ct); csPrint("resp header ct:$key ${ct > 0 ? (ct - 6) : ct}"); } else { @@ -515,12 +515,6 @@ class CacheServer { /// 处理M3u8 _handleM3u8(Uri remoteUri, HttpRequest localReq, Stream s, BaseCacheManager cacheManager) async { final sc = s.listen((f) { - if (null == f) { - //l.e(local_server_tag, "handleM3u8()...$remoteUri 来了个null���鬼东西"); - _requestErr(localReq); - return; - } - if (f is FileInfo) { var len = localReq.response.headers.value(HttpHeaders.contentLengthHeader); if (null != len) { @@ -540,7 +534,7 @@ class CacheServer { ); // csPrint("before source:$source"); if (TextUtil.isNotEmpty(tsLine) && tsLine.startsWith("http")) { - var domin = Uri.parse(tsLine ?? "").origin; + var domin = Uri.parse(tsLine).origin; if (TextUtil.isNotEmpty(domin)) { csPrint("need replace m3u8 inner host:$domin"); source = source.replaceAll(domin, ""); @@ -581,17 +575,15 @@ class CacheServer { /// 请求错误 _requestErr(HttpRequest req, {StreamSubscription? sc}) async { - if (null != req) { - // if (null == req.response.statusCode) { - try { - req.response.statusCode = HttpStatus.badRequest; - } catch (e) { - //l.e(local_server_tag, "_requestErr()..." + req.response.toString()); - } - // } - await req.response.close(); - sc?.cancel(); + // if (null == req.response.statusCode) { + try { + req.response.statusCode = HttpStatus.badRequest; + } catch (e) { + //l.e(local_server_tag, "_requestErr()..." + req.response.toString()); } + // } + await req.response.close(); + sc?.cancel(); } BaseCacheManager _getCacheManager(String url) { @@ -641,7 +633,6 @@ class CacheServer { // l.i(local_server_tag, "getCacheFile()...闲时缓存策略预测需要缓��的url:$remoteUrl"); var cacheManager = _getCacheManager(remotePath); var fileInfo = cacheManager.getFileFromMemory(getCacheKey(remotePath)); - fileInfo ??= (await cacheManager.getFileFromCache(getCacheKey(remotePath))) as Future; return fileInfo; } @@ -662,8 +653,7 @@ class CacheServer { // return "https://fs.lhexm.com/sp/8a/67/lf/mg/605635d590d11f0679a058dbc013bd53.mp4"; // remotePath = "sp/r1/8p/mt/if/970dd3185c924ff29c273917615c844a.m3u8"; if (TextUtil.isEmpty(remotePath)) return null; - var remoteUri = Uri.parse(remotePath); //修正后的绝对��径 - if (null == remoteUri) return null; + var remoteUri = Uri.parse(remotePath); final dot = remoteUri.path.lastIndexOf("."); if (dot <= 0 || dot >= remoteUri.path.length - 1) return null; final fileExtension = remoteUri.path.substring(dot); @@ -715,8 +705,7 @@ class CacheServer { // 兼容相对路径 sp/vid/xxxx.m3u8 remotePath = reqFilter.pathPrefix + "/" + remotePath; } - var uri = Uri.parse(remotePath); //修正后的绝对路径 - if (null == uri) return null; + var uri = Uri.parse(remotePath); //这里替换远程 final remoteUri = uri.replace(scheme: reqFilter.schema, host: reqFilter.host, port: reqFilter.port); return remoteUri.toString(); @@ -725,6 +714,5 @@ class CacheServer { /// url/绝对路径和相对路径 String getCacheKey(String url) { - assert(null != url); return FileUtil.getName(url); } diff --git a/lib/hj_utils/local_server_guard.dart b/lib/hj_utils/local_server_guard.dart index 8320c04..0c725d7 100644 --- a/lib/hj_utils/local_server_guard.dart +++ b/lib/hj_utils/local_server_guard.dart @@ -12,7 +12,7 @@ class LocalServerGuard { bool _running = false; bool _checking = false; - LocalServerGuard(this.cacheServer) : assert(cacheServer != null); + LocalServerGuard(this.cacheServer); /// 运行localserver守护 Future run() async { @@ -28,14 +28,12 @@ class LocalServerGuard { _checking = true; // csPrint("local_server_gard is called"); Uri uri = cacheServer.localServerUri; - if (uri != null) { - uri = uri.replace(path: LOCAL_SERVER_PING_PATH); - var options = Options(responseType: ResponseType.bytes); - // l.i(local_server_tag, "begin ping local server"); - final response = await _dio.getBytes(uri.toString(), options: options); - // l.i(local_server_tag, "end ping local server"); - if ((response.data?.statusCode ?? 0) > 0) return; - } + uri = uri.replace(path: LOCAL_SERVER_PING_PATH); + var options = Options(responseType: ResponseType.bytes); + // l.i(local_server_tag, "begin ping local server"); + final response = await _dio.getBytes(uri.toString(), options: options); + // l.i(local_server_tag, "end ping local server"); + if ((response.data?.statusCode ?? 0) > 0) return; await cacheServer.start(); } catch (e) { } finally { diff --git a/lib/main.dart b/lib/main.dart index ff7868d..efe7025 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,5 @@ import 'dart:async'; -import 'package:analytics_sdk/analytics_sdk.dart'; -import 'package:analytics_sdk/widget/global_click_wrapper.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -13,8 +11,6 @@ import 'package:jydj/hj_page/pre_sale/pre_sale_provider.dart'; import 'package:jydj/hj_page/splash/splash_page.dart'; import 'package:jydj/hj_utils/codec_support.dart'; import 'package:jydj/hj_utils/video_view_type.dart'; -import 'package:jydj/im_manager/im_ad/im_ad_provider.dart'; -import 'package:jydj/im_manager/im_notification.dart'; import 'package:jydj/routers/router_map.dart'; import 'package:visibility_detector/visibility_detector.dart'; import 'package:jydj/tools_base/debug_log.dart'; @@ -23,7 +19,6 @@ import 'package:jydj/tools_base/headphone_monitor.dart'; import 'package:jydj/tools_base/net/http_manager.dart'; import 'package:jydj/tools_base/video_download/video_download_manager.dart'; import 'package:jydj/track_event_manager/device_service.dart'; -import 'package:jydj/track_event_manager/track_manager.dart'; import 'package:jydj/track_event_manager/track_session.dart'; // 只引 OKToast 挂载所需符号:oktoast 也导出同名 showToast,全量 import 会与自家 toast.dart 冲突 import 'package:oktoast/oktoast.dart' show OKToast, ToastPosition; @@ -35,7 +30,6 @@ import 'package:ume_kit_ui/ume_kit_ui.dart'; import 'alert/vip_guide/guide_countdown_dialog.dart'; import 'assets_tool/app_colors.dart'; -import 'config/config.dart'; import 'hj_page/home/provider/home_update_marker_provider.dart'; import 'hj_page/main_page/provider/msg_provider.dart'; import 'hj_page/mine/mine_vip/vip_product_manager.dart'; @@ -47,7 +41,7 @@ void main() async { runZonedGuarded(() async { WidgetsFlutterBinding.ensureInitialized(); // 可见性回调默认攒 500ms 才发,短视频切 tab 会拖半秒才静音;压到 100ms(听不出延迟)。 - // 不设 0:那样滚动中每帧都回调,广告曝光(AdsItem)会跟着每帧注册一次 postFrame + // 不设 0:那样滚动中每帧都回调 VisibilityDetectorController.instance.updateInterval = const Duration(milliseconds: 100); VideoDownloadManager.instance.init(); await lightKV.init(); //初始化本地存储(lightKV/MMKV),其余初始化都依赖它,必须最先 @@ -56,22 +50,13 @@ void main() async { await Future.wait([ globalStore.init(), //获取密码 DeviceInfoService.init(), //获取设备信息 - ImAdProvider().loadLocalAdIds(), //加载本地已点击 IM 广告记录 initVideoViewType(), //视频渲染方式:读本机持久化标记,决定 textureView/platformView CodecSupport.init(), //H.265 硬解能力:查芯片能力 + 读本机禁用标记,决定选 265 还是回落 264 ]); - await TrackSessionManager().onAppColdStart(); //初始化埋点sid(依赖 DeviceInfoService) + await TrackSessionManager().onAppColdStart(); //初始化请求头 sid(依赖 DeviceInfoService) WidgetsBinding.instance.addObserver(_TrackLifecycleObserver()); PromoCountdown.reset(); //优惠倒计时(场景3/4):app 启动时设定一次起点,全局仅此一次,进程存活期间自然倒数、不重置 HeadphoneMonitor.instance.start(); //耳机/蓝牙断开、来电等自动暂停视频,防止音频外放泄露隐私 - //埋点SDK接入 - addMappings(); //添加页面映射 - await AnalyticsSdk.instance.init( - appId: Config.appId, - encryptedConfig: null, // 服务端下发 - deviceId: DeviceInfoService.deviceId, // Android IMEI/OAID、iOS IDFV 等 - appVersion: Config.innerVersion, - ); if (kReleaseMode) { runApp(const MyApp()); } else { @@ -127,8 +112,6 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider.value(value: MineMsgProvider()), //消息中心红点,新人倒计时 ChangeNotifierProvider.value(value: HomeUpdateMarkerProvider()), //首页最新/今日最新红点 ChangeNotifierProvider.value(value: vipProductManager), //会员卡列表统一数据源 - ChangeNotifierProvider.value(value: ImAdProvider()), //IM 广告 - ChangeNotifierProvider.value(value: ImMsgProvider()), //IM 私信未读红点 ChangeNotifierProvider.value(value: LimitTimeProvider()), //限时活动 ], child: GetMaterialApp( @@ -137,7 +120,7 @@ class MyApp extends StatelessWidget { // 只能写在这,写 main() 里会被 GetMaterialApp.build 覆盖回 full。 // 前提是所有 logic 都走 GetBuilder(init:)——手写 Get.put 的没人回收,要自己 Get.delete smartManagement: SmartManagement.onlyBuilder, - navigatorObservers: [routeObserver, AnalyticsSdk.instance.pageObserver], + navigatorObservers: [routeObserver], debugShowCheckedModeBanner: true, initialRoute: SplashPage.routeName, getPages: AppRoutes.routePages, @@ -185,7 +168,7 @@ class MyApp extends StatelessWidget { radius: 8, textStyle: const TextStyle(color: Colors.white, fontSize: 14), textPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - child: GlobalClickWrapper(child: child!), + child: child!, ), ), ); diff --git a/lib/routers/jump_router.dart b/lib/routers/jump_router.dart index bf477ba..a23ef07 100644 --- a/lib/routers/jump_router.dart +++ b/lib/routers/jump_router.dart @@ -11,10 +11,8 @@ import 'package:jydj/tools_base/loading/loading_helper.dart'; import 'package:jydj/tools_base/toast.dart'; import 'package:url_launcher/url_launcher.dart'; -import '../config/address.dart'; import '../config/config.dart'; import '../hj_model/cartoon_media_info.dart'; -import '../hj_model/splash/ads_model.dart'; import '../hj_page/cartoon/cartoon_detail_page.dart'; import '../hj_page/cartoon/novel_detail_page.dart'; import '../hj_page/community/post_detail_page/post_detail_page.dart'; @@ -29,11 +27,8 @@ import '../hj_page/mine/mine_vip/pay_order_source.dart'; import '../hj_page/mine/welfare/welfare_home_page.dart'; import '../hj_page/short_video/short_video_page.dart'; import '../hj_page/web_page/h5_page.dart'; -import '../hj_utils/api_service/mine_service.dart'; import '../hj_utils/api_service/vid_service.dart'; import '../tools_base/event_bus/event_bus_util.dart'; -import '../tools_base/loading/loading_alert_widget.dart'; -import '../track_event_manager/track_manager.dart'; /// 跳转视频/动漫/短视频详情页 /// - [isCartoon] 优先级最高 → 长视频页(标记动漫) @@ -65,7 +60,6 @@ Future? pushToVideoPage({ } // // 3. 短视频:playTime < 300 且非 0(此分支 videoModel 必非 null,playTime 取自它) - final playTime = videoModel?.playTime ?? 1000; if (isShort) { final list = videoArr?.isNotEmpty == true ? videoArr! : [videoModel!]; final idx = list.indexWhere((e) => e.id == videoModel?.id); @@ -106,7 +100,7 @@ void pushToCartoonPage(CartoonMediaInfo? info) { /// 解析 deeplink/h5 链接并执行跳转 /// [sourcePage] 链接落到会员/金币页时的下单来源(如首页浮窗),不传走 pushToWalletPage 的默认 -Future? pushToPageByLink(String? url, {String? id, Map? arguments, PaySourcePage? sourcePage}) async { +Future? pushToPageByLink(String? url, {Map? arguments, PaySourcePage? sourcePage}) async { if (url?.isNotEmpty != true) return null; Uri? uri; @@ -120,18 +114,6 @@ Future? pushToPageByLink(String? url, {String? id, Map? argumen arguments ??= {}; arguments.addAll(uri.queryParameters); - // 广告点击埋点(新版本:不上报服务器,仅上报埋点) - if (id?.isNotEmpty == true) { - try { - final TrackEventPageType? pageType = arguments['pageType']; - final AdsInfoModel? adInfo = arguments['adInfo']; - final Map? payload = arguments['payload']; - adClickManager.adClicks(adInfo: adInfo, payload: payload ?? {}, page: pageType); - } catch (e) { - debugLog("pushToPageByLink", e.toString()); - } - } - final host = uri.host.toLowerCase().removeAllWhitespace; if (uri.scheme == "yinseinner") { @@ -204,9 +186,6 @@ Future? _handleYinseInnerLink(String host, Map arguments, [PayS debugLog(e); return null; } - case "kefu": // 在线客服 - pushToCustomService(); - return null; case "userhomepage": // 跳转博主 final uid = arguments["uid"] ?? 0; if (uid == 0) return null; @@ -276,14 +255,3 @@ Future pushToWalletPage({int? tabPosition, String? vipId, PaySourcePage? sourceP preventDuplicates: false, ); } - -/// 跳转客服系统 -void pushToCustomService() async { - LoadingAlertWidget.show(); - final url = await MineService.fetchCustomService(); - LoadingAlertWidget.cancel(); - if (url?.isNotEmpty == true) { - // final h5Url = '${Address.baseHost}/api$url'; - Get.to(H5Page(url: url, title: '在线客服'), opaque: false); - } -} diff --git a/lib/tools_base/banner/ads_banner.dart b/lib/tools_base/banner/ads_banner.dart index e264889..9126e25 100644 --- a/lib/tools_base/banner/ads_banner.dart +++ b/lib/tools_base/banner/ads_banner.dart @@ -5,7 +5,6 @@ import 'package:jydj/tools_base/widget/image_browser_page.dart'; import 'package:jydj/tools_base/widget/net_image_widget.dart'; import '../../hj_model/splash/ads_model.dart'; -import '../../track_event_manager/track_manager.dart'; import 'ads_item.dart'; /// 广告轮播的指示器位置 @@ -31,8 +30,6 @@ class AdsBanner extends StatefulWidget { final Color? color; //未选中色,不传按位置/样式取默认 final Color? selectColor; //选中色,不传按位置/样式取默认 - final AdExposureModel? exposureModel; //曝光埋点模型 - const AdsBanner( this.models, { super.key, @@ -46,7 +43,6 @@ class AdsBanner extends StatefulWidget { this.indicatorStyle = IndicatorStyle.bar, this.color, this.selectColor, - this.exposureModel, }); @override @@ -59,13 +55,6 @@ class _AdsBannerState extends State { int get _count => widget.models?.length ?? 0; - @override - void initState() { - super.initState(); - //adType 兜底设一次(不放 itemBuilder 里,避免每次构建都 mutate) - widget.exposureModel?.adType ??= AdType.bigBanner; - } - @override void dispose() { _index.dispose(); @@ -134,7 +123,6 @@ class _AdsBannerState extends State { adInfo: widget.models![index], showType: AdShowType.img, borderRadius: widget.borderRadius, - exposureModel: widget.exposureModel, ), onTap: widget.onTap, onIndexChanged: (index) { diff --git a/lib/tools_base/banner/ads_grid_view.dart b/lib/tools_base/banner/ads_grid_view.dart index 9841d45..a3f84de 100644 --- a/lib/tools_base/banner/ads_grid_view.dart +++ b/lib/tools_base/banner/ads_grid_view.dart @@ -6,7 +6,6 @@ import 'package:jydj/hj_utils/screen.dart'; import 'package:jydj/tools_base/ad_manager.dart'; import '../../hj_model/splash/ads_model.dart'; -import '../../track_event_manager/track_manager.dart'; import 'ads_banner.dart'; import 'ads_item.dart'; @@ -24,7 +23,6 @@ class AdsGridView extends StatelessWidget { final List? ads; //外部直接传入的广告,优先于 position final bool autoStyle; //true:按第一个广告的 coverImgSize 选样式;false:固定两排九宫格 final EdgeInsetsGeometry? padding; - final AdExposureModel? exposureModel; //曝光埋点模型 const AdsGridView( this.position, { @@ -32,7 +30,6 @@ class AdsGridView extends StatelessWidget { this.ads, this.autoStyle = false, this.padding, - this.exposureModel, }); @override @@ -50,14 +47,9 @@ class AdsGridView extends StatelessWidget { }; } - //统一构造广告项;每个 item 用独立的曝光模型副本,避免共享同一实例导致曝光 adType 被覆盖串号 + //统一构造广告项 Widget _item(AdsInfoModel model, {double? aspectRatio}) { - final em = exposureModel; - return AdsItem( - adInfo: model, - aspectRatio: aspectRatio, - exposureModel: em == null ? null : AdExposureModel(pageType: em.pageType, adType: model.adType, tabIndex: em.tabIndex), - ); + return AdsItem(adInfo: model, aspectRatio: aspectRatio); } //两排共 10 个 @@ -89,7 +81,6 @@ class AdsGridView extends StatelessWidget { child: AdsBanner( list.length > 20 ? list.take(20).toList() : list, autoPlayMs: 2000, - exposureModel: exposureModel, ), ), ), diff --git a/lib/tools_base/banner/ads_item.dart b/lib/tools_base/banner/ads_item.dart index 4e34a87..22bf9f6 100644 --- a/lib/tools_base/banner/ads_item.dart +++ b/lib/tools_base/banner/ads_item.dart @@ -3,11 +3,9 @@ import 'package:get/get.dart'; import 'package:jydj/assets_tool/images.dart'; import 'package:jydj/hj_utils/api_service/common_service.dart'; import 'package:jydj/hj_utils/screen.dart'; -import 'package:visibility_detector/visibility_detector.dart'; import '../../hj_model/splash/ads_model.dart'; import '../../routers/jump_router.dart'; -import '../../track_event_manager/track_manager.dart'; import '../widget/net_image_widget.dart'; enum AdShowType { @@ -17,14 +15,12 @@ enum AdShowType { splash, //启动全屏图 } -/// 广告项:按 [AdShowType] 出不同样式(不传是上图下标题的九宫格项);进入可视区上报曝光,点击按链接跳转并上报 +/// 广告项:按 [AdShowType] 出不同样式(不传是上图下标题的九宫格项);点击按链接跳转并上报 class AdsItem extends StatefulWidget { final AdsInfoModel adInfo; final AdShowType? showType; final double? aspectRatio; final double borderRadius; //纯图样式的圆角 - final int clickType; //点击上报类型 0:应用 1:广告 - final AdExposureModel? exposureModel; final Widget? child; //自定义子视图(IM 广告用) final VoidCallback? onTap; //点击附加回调(IM 广告已读上报用) @@ -34,8 +30,6 @@ class AdsItem extends StatefulWidget { this.showType, this.aspectRatio, this.borderRadius = 12, - this.clickType = 1, - this.exposureModel, this.child, this.onTap, }); @@ -44,57 +38,28 @@ class AdsItem extends StatefulWidget { State createState() => _AdsItemState(); } -class _AdsItemState extends State with AdExposureMixin { +class _AdsItemState extends State { AdsInfoModel get adInfo => widget.adInfo; - AdExposureModel? get exposureModel => widget.exposureModel; - - //⚠️ 曝光去重 key 必须稳定 - Key get _visibilityKey => ValueKey( - 'ad_${adInfo.id ?? adInfo.href ?? ''}_${exposureModel?.pageType?.name ?? ''}_${exposureModel?.tabIndex}', - ); - @override Widget build(BuildContext context) { - return VisibilityDetector( - key: _visibilityKey, - onVisibilityChanged: (info) { - if (info.visibleFraction > 0.1) _expose(); - }, - child: InkWell( - enableFeedback: false, - onTap: _onTap, - child: widget.child ?? - switch (widget.showType) { - AdShowType.img => _image(), - AdShowType.hor => _hor(), - AdShowType.vImgText => _imageText(), - AdShowType.splash => _splash(), - null => _normal(), - }, - ), + return InkWell( + enableFeedback: false, + onTap: _onTap, + child: widget.child ?? + switch (widget.showType) { + AdShowType.img => _image(), + AdShowType.hor => _hor(), + AdShowType.vImgText => _imageText(), + AdShowType.splash => _splash(), + null => _normal(), + }, ); } - //进入可视区上报曝光 - void _expose() { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (!mounted || exposureModel?.pageType == null) return; - adExposure(adInfo: adInfo, exposureModel: exposureModel); - }); - } - void _onTap() { - pushToPageByLink( - adInfo.href, - id: adInfo.id, - arguments: { - 'pageType': exposureModel?.pageType ?? TrackEventPageType.acgHome, - 'adInfo': adInfo, - 'payload': {'ad_type': exposureModel?.adType?.value ?? ''}, - }, - ); - CommonService.adsClick(widget.clickType); + pushToPageByLink(adInfo.href); + CommonService.adsClick(adInfo.id); widget.onTap?.call(); } diff --git a/lib/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart b/lib/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart index dfb3e7d..1face09 100644 --- a/lib/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart +++ b/lib/tools_base/widget/scroll_positioned_list/src/item_positions_listener.dart @@ -42,9 +42,9 @@ class ItemPosition { final double itemTrailingEdge; @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { if (other.runtimeType != runtimeType) return false; - final ItemPosition otherPosition = other; + final otherPosition = other as ItemPosition; return otherPosition.index == index && otherPosition.itemLeadingEdge == itemLeadingEdge && otherPosition.itemTrailingEdge == itemTrailingEdge; diff --git a/lib/tools_base/widget/scroll_positioned_list/src/positioned_list.dart b/lib/tools_base/widget/scroll_positioned_list/src/positioned_list.dart index 5c6929e..d214f2d 100644 --- a/lib/tools_base/widget/scroll_positioned_list/src/positioned_list.dart +++ b/lib/tools_base/widget/scroll_positioned_list/src/positioned_list.dart @@ -44,9 +44,7 @@ class PositionedList extends StatefulWidget { this.addSemanticIndexes = true, this.addRepaintBoundaries = true, this.addAutomaticKeepAlives = true, - }) : assert(itemCount != null), - assert(itemBuilder != null), - assert((positionedIndex == 0) || (positionedIndex < itemCount)), + }) : assert((positionedIndex == 0) || (positionedIndex < itemCount)), super(key: key); /// Number of items the [itemBuilder] can produce. @@ -89,7 +87,6 @@ class PositionedList extends StatefulWidget { /// See [ScrollView.reverse]. final bool reverse; - /// {@template flutter.widgets.scroll_view.shrinkWrap} /// Whether the extent of the scroll view in the [scrollDirection] should be /// determined by the contents being viewed. /// diff --git a/lib/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart b/lib/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart index 268369d..ae7e13e 100644 --- a/lib/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart +++ b/lib/tools_base/widget/scroll_positioned_list/src/scrollable_positioned_list.dart @@ -60,9 +60,7 @@ class ScrollablePositionedList extends StatefulWidget { this.addRepaintBoundaries = true, this.minCacheExtent, this.scrollAction, - }) : assert(itemCount != null), - assert(itemBuilder != null), - itemPositionsNotifier = itemPositionsListener as ItemPositionsNotifier?, + }) : itemPositionsNotifier = itemPositionsListener as ItemPositionsNotifier?, scrollOffsetNotifier = scrollOffsetListener as ScrollOffsetNotifier?, separatorBuilder = null, super(key: key); @@ -91,9 +89,7 @@ class ScrollablePositionedList extends StatefulWidget { this.addRepaintBoundaries = true, this.minCacheExtent, this.scrollAction, - }) : assert(itemCount != null), - assert(itemBuilder != null), - assert(separatorBuilder != null), + }) : assert(separatorBuilder != null), itemPositionsNotifier = itemPositionsListener as ItemPositionsNotifier?, scrollOffsetNotifier = scrollOffsetListener as ScrollOffsetNotifier?, super(key: key); @@ -141,7 +137,6 @@ class ScrollablePositionedList extends StatefulWidget { /// See [ScrollView.reverse]. final bool reverse; - /// {@template flutter.widgets.scroll_view.shrinkWrap} /// Whether the extent of the scroll view in the [scrollDirection] should be /// determined by the contents being viewed. /// diff --git a/lib/tools_base/widget/scroll_positioned_list/src/viewport.dart b/lib/tools_base/widget/scroll_positioned_list/src/viewport.dart index 1de5ff0..e0c65aa 100644 --- a/lib/tools_base/widget/scroll_positioned_list/src/viewport.dart +++ b/lib/tools_base/widget/scroll_positioned_list/src/viewport.dart @@ -100,7 +100,6 @@ class UnboundedRenderViewport extends RenderViewport { @override set anchor(double value) { - assert(value != null); if (value == _anchor) return; _anchor = value; markNeedsLayout(); @@ -124,7 +123,6 @@ class UnboundedRenderViewport extends RenderViewport { @override Rect describeSemanticsClip(RenderSliver? child) { - assert(axis != null); if (_calculatedCacheExtent == null) { return semanticBounds; @@ -178,7 +176,6 @@ class UnboundedRenderViewport extends RenderViewport { double correction; var count = 0; do { - assert(offset.pixels != null); correction = _attemptLayout(mainAxisExtent, crossAxisExtent, offset.pixels + centerOffsetAdjustment); if (correction != 0.0) { diff --git a/lib/tools_base/widget/scroll_positioned_list/src/wrapping.dart b/lib/tools_base/widget/scroll_positioned_list/src/wrapping.dart index 47a4b7e..c6df795 100644 --- a/lib/tools_base/widget/scroll_positioned_list/src/wrapping.dart +++ b/lib/tools_base/widget/scroll_positioned_list/src/wrapping.dart @@ -419,14 +419,10 @@ abstract class CustomViewport extends MultiChildRenderObjectWidget { this.cacheExtentStyle = CacheExtentStyle.pixel, this.clipBehavior = Clip.hardEdge, List slivers = const [], - }) : assert(offset != null), - assert(slivers != null), - assert(center == null || + }) : assert(center == null || slivers.where((Widget child) => child.key == center).length == 1), - assert(cacheExtentStyle != null), assert(cacheExtentStyle != CacheExtentStyle.viewport || cacheExtent != null), - assert(clipBehavior != null), super(key: key, children: slivers); /// The direction in which the [offset]'s [ViewportOffset.pixels] increases. @@ -497,7 +493,6 @@ abstract class CustomViewport extends MultiChildRenderObjectWidget { /// otherwise, the default cross axis direction is downwards. static AxisDirection getDefaultCrossAxisDirection( BuildContext context, AxisDirection axisDirection) { - assert(axisDirection != null); switch (axisDirection) { case AxisDirection.up: assert(debugCheckHasDirectionality( @@ -662,11 +657,9 @@ abstract class CustomRenderViewport double? cacheExtent, CacheExtentStyle cacheExtentStyle = CacheExtentStyle.pixel, Clip clipBehavior = Clip.hardEdge, - }) : assert(anchor != null), - assert(anchor >= 0.0 && anchor <= 1.0), + }) : assert(anchor >= 0.0 && anchor <= 1.0), assert(cacheExtentStyle != CacheExtentStyle.viewport || cacheExtent != null), - assert(clipBehavior != null), _center = center, super( axisDirection: axisDirection, diff --git a/lib/track_event_manager/device_service.dart b/lib/track_event_manager/device_service.dart index 2405840..7d7d73b 100644 --- a/lib/track_event_manager/device_service.dart +++ b/lib/track_event_manager/device_service.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'dart:io'; -import 'package:analytics_sdk/analytics_sdk.dart'; import 'package:crypto/crypto.dart'; import 'package:device_identity/device_identity.dart'; import 'package:device_info_plus/device_info_plus.dart'; @@ -131,7 +130,7 @@ class DeviceInfoService { 'DeviceBrand': DeviceInfoService.brand, 'SystemName': DeviceInfoService.deviceOS, 'SystemVersion': DeviceInfoService.systemVersion, - 'device_model': AnalyticsSdk.getDeviceCommonFields()['device_model'], + 'device_model': DeviceInfoService.model, }; params.removeWhere((key, value) => value == null || value.isEmpty); final ua = Uri.encodeComponent(params.entries.map((e) => "${e.key}=${e.value}").join(";")); diff --git a/m3u8_downloader-master/example/lib/main.dart b/m3u8_downloader-master/example/lib/main.dart index e3b271e..fff695c 100644 --- a/m3u8_downloader-master/example/lib/main.dart +++ b/m3u8_downloader-master/example/lib/main.dart @@ -5,7 +5,6 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:m3u8_downloader/m3u8_downloader.dart'; -import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'video_player_page.dart'; @@ -80,7 +79,6 @@ class _MyAppState extends State { } Future _findSavePath() async { - var directory = await getExternalStorageDirectory(); //getApplicationSupportDirectory(); String saveDir = "/sdcard/vPlayDownload"; //directory!.path + '/vPlayDownload'; Directory root = Directory(saveDir); if (!root.existsSync()) { diff --git a/m3u8_downloader-master/pubspec.yaml b/m3u8_downloader-master/pubspec.yaml index cca2962..666ef6b 100644 --- a/m3u8_downloader-master/pubspec.yaml +++ b/m3u8_downloader-master/pubspec.yaml @@ -1,7 +1,6 @@ name: m3u8_downloader description: m3u8 downloader version: 1.3.0 -author: Vincent homepage: environment: diff --git a/pubspec.yaml b/pubspec.yaml index e968cef..5cf291f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -70,8 +70,6 @@ dependencies: waterfall_flow: ^3.1.1 m3u8_downloader: path: m3u8_downloader-master - analytics_sdk: - path: analytics_sdk # 或 git/pub 地址 audioplayers: ^5.2.1 audio_session: ^0.1.25 # 监听音频路由变化(耳机/蓝牙断开、来电中断) @@ -92,11 +90,6 @@ dependencies: path: any fixnum: any - # IM 私信 SDK(自研 WebSocket + 本地 SQLite),私有源 - flutter_mm_core: - hosted: https://pub.imopsus.co/ - version: ^2.2.0 - # 区别于dependencies标签,dependencies是生产环境依赖库版本,dev_dependencies是开发环境依赖库版本,该环境仅在开发调试时使用。标签规则同dependencies。 dev_dependencies: flutter_test: @@ -121,9 +114,6 @@ flutter: - assets/images/ai/ - assets/images/live_images/ - assets/images/acg/ - - assets/images/holiday/ - - assets/images/holiday/1/ - - assets/images/holiday/5/ dependency_overrides: flutter_plugin_android_lifecycle: ^2.0.34 @@ -131,7 +121,4 @@ dependency_overrides: # 锁定与 Dart 3.10 兼容的版本,避免 ^ 解析到 3.12 语言版本的包导致无法编译 video_player_android: 2.9.5 url_launcher_android: 6.3.30 - # flutter_mm_core 传递依赖锁版本,避免 sqlite3/protobuf 冲突 - sqlite3: 1.8.0 - protobuf: ^3.1.0 package_info_plus: ^9.0.1 #包信息