import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:hgdj/assets_tool/images.dart'; import 'package:hgdj/config/address.dart'; import 'package:hgdj/config/config.dart'; import 'package:hgdj/hj_page/main_page/provider/msg_provider.dart'; import 'package:hgdj/hj_page/pre_sale/pre_sale_provider.dart'; import 'package:hgdj/hj_utils/screen.dart'; import 'package:hgdj/routers/jump_router.dart'; import 'package:hgdj/tools_base/global_store/store.dart'; import 'package:hgdj/tools_base/refresh/pull_refresh.dart'; import 'package:hgdj/tools_base/toast.dart'; import 'package:hgdj/tools_base/widget/net_image_widget.dart'; import 'package:provider/provider.dart'; import '../../hj_utils/widget_util.dart'; import '../../tools_base/banner/ads_grid_view_widget.dart'; import 'home_mine_logic.dart'; import 'widgets/mine_info_widget.dart'; import 'widgets/vip_entry_card.dart'; //我的页面 class HomeMinePage extends StatelessWidget { const HomeMinePage({super.key}); /// 常用功能里唯一需要展示未读红点的入口 static const _messageMenuTitle = '我的消息'; @override Widget build(BuildContext context) { return GetBuilder( init: MineMainLogic(), builder: (logic) { return Consumer(builder: (_, store, ___) { return Scaffold( body: SizedBox.expand( child: pullYsRefresh( onInit: (ctr) => logic.refreshCtr = ctr, enablePullUp: false, onRefresh: (ctr) => logic.onRefresh(), child: SingleChildScrollView( child: Stack( children: [ Positioned( left: 0, right: 0, top: 0, child: _buildBg(), ), SafeArea(child: _buildContent(logic, store)), ], ), ), ), ), ); }); }, ); } //顶部背景:优先后台下发,兜底默认图 Widget _buildBg() { final bg = Config.mineBg; if (bg != null && bg.isNotEmpty) { return NetworkImageLoader(imageUrl: bg, borderRadius: 0); } return Image.asset( 'mine_bg.webp'.mineImgPath, ); } Widget _buildContent(MineMainLogic logic, GlobalStore store) { return Stack( children: [ _buildTop(logic), Column( children: [ 48.sizeBoxH, MineInfoWidget(logic: logic), 21.sizeBoxH, _buildCountView(), //次数 21.sizeBoxH, VipEntryCard(), //会员入口 12.sizeBoxH, MineTaskMenuWidget(), //金币充值等 12.sizeBoxH, MineFunchtionGridView(), //收藏/历史/下载/关注 12.sizeBoxH, _buildShop(logic), //商店入口 AdsGridViewWidget( 8, accordingAdsType: true, padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), ), Container( margin: EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(9), color: Colors.white.withValues(alpha: .05), ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( alignment: Alignment.centerLeft, margin: EdgeInsets.symmetric(horizontal: 16, vertical: 5), child: Text("常用功能", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w500, fontSize: 16, )), ), GridView.builder( physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, shrinkWrap: true, itemCount: logic.menuVerNameArr.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, crossAxisSpacing: 0, mainAxisSpacing: 0, childAspectRatio: 1, ), itemBuilder: (context, index) { String titleDesc = logic.menuVerNameArr[index]; String imagePath = 'mine_menu_${index + 1}.png'.mineImgPath; // 仅「我的消息」带未读红点,按名称判断避免菜单顺序变动后红点错位 final isMessageEntry = titleDesc == _messageMenuTitle; return InkWell( enableFeedback: false, onTap: () => logic.menuVerTapEvent(index), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ !isMessageEntry ? Image.asset(imagePath, width: 28) : Stack( children: [ Image.asset( "mine_notification.png".mineImgPath, width: 28, ), Consumer( builder: (context, model, child) => Positioned( right: 2, top: 2, child: model.buildTipsView(), ), ) ], ), 5.sizeBoxH, Text( titleDesc, style: TextStyle(color: Colors.white, fontSize: 12), ), ], ), ); }, ), // iOS 换图标需弹系统弹窗且要预置图标资源,暂不支持,仅 Android 显示该入口 if (!Platform.isIOS) ...[ Padding( padding: EdgeInsets.only(left: 12, top: 10, right: 12), child: Row( children: [ Text( '设置桌面图标', style: TextStyle( color: Color(0xffEFEFEF), fontSize: 14, fontWeight: FontWeight.w500), ), Spacer(), InkWell( enableFeedback: false, onTap: () => logic.changeIcon(0), child: Text( '恢复默认', style: TextStyle( color: Color(0xff989898), fontSize: 12, fontWeight: FontWeight.w400), ), ), ], ), ), 11.sizeBoxH, SizedBox( height: 76, child: ListView.separated( padding: EdgeInsets.symmetric(horizontal: 16), scrollDirection: Axis.horizontal, separatorBuilder: (_, __) => 7.sizeBoxW, itemCount: logic.iconList.length, itemBuilder: (BuildContext context, int index) { final data = logic.iconList[index]; return InkWell( enableFeedback: false, onTap: () => logic.changeIcon(index), child: Column( children: [ Image.asset(data.image, width: 54), 4.sizeBoxH, Text( data.name, style: TextStyle( color: Colors.white.withValues(alpha: 0.9), fontSize: 12, ), ) ], ), ); }, ), ), 10.sizeBoxH, ], ], ), ), 12.sizeBoxH, Text( '我的邀请码: ${store.meInfo?.promotionCode ?? ''}', style: textStyle(16, Color(0xffBDBDBD), FontWeight.w400), ), 6.sizeBoxH, _buildGroundUrl(), 30.sizeBoxH, ], ), ], ); } //永久官方地址:地址未下发时不渲染,避免点击/复制空串 Widget _buildGroundUrl() { final url = Address.groundUrl; if (url == null || url.isEmpty) return const SizedBox.shrink(); return GestureDetector( onTap: () => launchUrlToWeb(url), onLongPress: () { Clipboard.setData(ClipboardData(text: url)); showToast("复制成功"); }, child: Text( '永久官方地址: $url', style: textStyle(12, Color(0xff525252), FontWeight.w400), ), ); } //消息和设置 Widget _buildTop(MineMainLogic logic) { return Padding( padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( children: [ InkWell( enableFeedback: false, onTap: () => logic.menuTapEvent(3), child: Image.asset("mine_notification.png".mineImgPath, width: 24), ), Spacer(), InkWell( enableFeedback: false, onTap: () => logic.toSetting(), child: Image.asset("setting.png".mineImgPath, width: 24), ), ], ), ); } //次数 Widget _buildCountView() { return Row( children: [ 50.sizeBoxW, Expanded( child: Consumer2( builder: (context, store, provider, child) { int count = (store.wallet?.downloadCount ?? 0) + (provider.remain?.todayDownloadCount ?? 0); return _buildCountItem(count.toString(), '剩余缓存次数'); }, ), ), Container( color: Colors.white.withValues(alpha: .1), width: 0.5, height: 12, ), Expanded( child: Consumer2( builder: (context, store, provider, child) { //预售权益和免费次数的和 final total = (store.wallet?.aiUndressFreeTimes ?? 0) + (provider.remain?.todayAiUndressCount ?? 0); return _buildCountItem(total.toString(), '剩余AI脱衣次数'); }, ), ), 50.sizeBoxW, ], ); } Widget _buildCountItem(String count, String title) { return Column( children: [ Text( count, style: textStyle(16, Colors.white, FontWeight.w500), ), 4.sizeBoxH, Text( title, style: textStyle( 12, Colors.white.withValues(alpha: .7), FontWeight.w400), ), ], ); } Widget _buildShop(MineMainLogic logic) { if (Config.isStoreOpen) { return InkWell( enableFeedback: false, onTap: () => logic.toShop(), child: Padding( padding: const EdgeInsets.only(bottom: 10.0, left: 10, right: 10), child: AspectRatio( aspectRatio: 355 / 82, child: Image.asset('mine_shop_icon.webp'.mineImgPath), ), ), ); } return SizedBox.shrink(); } }