import 'package:cpt_rewards/modules/rewards_address/rewards_address_page.dart'; import 'package:cpt_rewards/modules/rewards_code/rewards_code_page.dart'; import 'package:cpt_rewards/modules/rewards_detail/rewards_detail_page.dart'; import 'package:cpt_rewards/modules/rewards_list/rewards_list_page.dart'; import 'package:cpt_rewards/modules/rewards_my/rewards_my_page.dart'; import 'package:cpt_rewards/modules/rewards_search/rewards_search_page.dart'; import 'package:cs_resources/generated/assets.dart'; import 'package:domain/entity/rewards_category_entity.dart'; import 'package:domain/entity/rewards_home_entity.dart'; import 'package:flutter/material.dart'; import 'package:auto_route/auto_route.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:plugin_platform/engine/image/image_nine_grid.dart'; import 'package:router/ext/auto_router_extensions.dart'; import 'package:shared/utils/color_utils.dart'; import 'package:shared/utils/log_utils.dart'; import 'package:widgets/ext/ex_widget.dart'; import 'package:widgets/load_state_layout.dart'; import 'package:widgets/my_load_image.dart'; import '../../../router/page/rewards_page_router.dart'; import './rewards_home_vm.dart'; @RoutePage() class RewardsHomePage extends HookConsumerWidget { final int? points; const RewardsHomePage({Key? key, @PathParam('points') required this.points}) : super(key: key); //启动当前页面 static void startInstance({ BuildContext? context, int? points, }) { if (context != null) { context.router.push(RewardsHomePageRoute(points: points)); } else { appRouter.push(RewardsHomePageRoute(points: points)); } } Widget _buildTop(BuildContext context, WidgetRef ref, _vm) { int? point = points ?? 0; // String available = '$point' return Container( decoration: BoxDecoration( border: Border( bottom: BorderSide( color: ColorUtils.string2Color('#4161D0'), // 设置bottom边框的颜色 width: 45.0, // 设置bottom边框的宽度 )), borderRadius: const BorderRadius.only( topLeft: Radius.circular(0.0), topRight: Radius.circular(0.0), bottomLeft: Radius.circular(30.0), bottomRight: Radius.circular(30.0), ), // 圆角 ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const MyAssetImage( Assets.rewardsRewardsBack, width: 44, height: 44, ).onTap(() { // backCallback Navigator.pop(context); }), Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( '$point Available Points', style: const TextStyle( fontSize: 18.0, color: Colors.white, fontWeight: FontWeight.w500), // 设置字体大小 ).paddingOnly(left: 10, top: 20, bottom: 18), ], ), Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Container( decoration: BoxDecoration( border: Border.all(color: Colors.white, width: 1), // 边框 borderRadius: BorderRadius.circular(8), // 圆角 ), child: const Text( 'My Rewards', style: TextStyle( fontSize: 15.0, color: Colors.white, fontWeight: FontWeight.w400), // 设置字体大小 ) .paddingOnly(left: 10, top: 7, bottom: 7, right: 10) .onTap(() { RewardsMyPage.startInstance(); }), ), // Row( // crossAxisAlignment: CrossAxisAlignment.center, // mainAxisAlignment: MainAxisAlignment.center, // children: [ // const MyAssetImage( // Assets.rewardsRewardsY, // width: 26, // height: 26, // ), // Text( // 'Bronze', // style: TextStyle( // fontSize: 17.0, // color: ColorUtils.string2Color('#FFCC00'), // fontWeight: FontWeight.w500), // 设置字体大小 // ).marginOnly( // left: 9, // right: 7, // ), // const MyAssetImage( // Assets.rewardsRewardsRight, // width: 7, // height: 12, // ), // ], // ) ], ).paddingOnly(left: 10) ], ) .paddingOnly(top: 15, left: 5, right: 15, bottom: 0) .border(bottom: 0, color: ColorUtils.string2Color('#4161D0')) .backgroundColor(ColorUtils.string2Color('#4161D0'))); } Widget _buildSearch(BuildContext context, WidgetRef ref, _vm) { // List itemsList = _vm.state.list.toList(); return Container( height: 50, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Search', style: TextStyle( fontSize: 15.0, color: ColorUtils.string2Color('#C7CDE3'), fontWeight: FontWeight.w500), // 设置字体大小 ), const MyAssetImage( Assets.rewardsRewardsIndexSearch, width: 21, height: 21, ), ], ).paddingOnly(left: 15, right: 15), ).onTap(() { RewardsSearchPage.startInstance(); }); } Widget _buildSwiper(BuildContext context, WidgetRef ref, _vm) { // List itemsList = _vm.state.lists.toList(); final state = ref.watch(rewardsHomeVmProvider); List>? itemsList = state.categoryList; return Container( transform: Matrix4.translationValues(0.0, -10.0, 0.0), // color: Colors.white, height: 110, decoration: const BoxDecoration( color: Colors.white, borderRadius: const BorderRadius.only( topLeft: Radius.circular(10.0), topRight: Radius.circular(0.0), bottomLeft: Radius.circular(10.0), bottomRight: Radius.circular(0.0), ), boxShadow: [ BoxShadow(color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6) ], ), child: ClipRect( child: SingleChildScrollView( scrollDirection: Axis.horizontal, physics: const BouncingScrollPhysics(), clipBehavior: Clip.none, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: List.generate(itemsList!.length, (index) { final item = itemsList[index]; return Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ MyLoadImage( item['icon'] ?? '', width: 70, height: 70, ), Text( item['name']!, style: TextStyle( fontSize: 14.0, color: ColorUtils.string2Color('#000001'), fontWeight: FontWeight.w600), // 设置字体大小 ), ], ).marginOnly(right: 5).onTap(() { RewardsListPage.startInstance(); }); }), ).marginOnly(left: 15, right: 15), )), ).paddingOnly(left: 15); } Widget _buildRecommend(BuildContext context, WidgetRef ref, _vm, list) { return list['rewards'].length > 0 ? Container( child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( list?['name'] ?? '', style: TextStyle( fontSize: 17.0, color: ColorUtils.string2Color('#000001'), fontWeight: FontWeight.w500), // 设置字体大小 ), Text( 'See All', style: TextStyle( fontSize: 17.0, color: ColorUtils.string2Color('#4161D0'), fontWeight: FontWeight.w500), // 设置字体大小 ).onTap(() { RewardsListPage.startInstance(); }), ], ).marginOnly(bottom: 15), Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: List.generate(list['rewards'].length, (index) { double hg = 70; return Container( width: MediaQuery.of(context).size.width / 2 - 25, height: 155, decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(6.0)), boxShadow: [ BoxShadow( color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6) ], ), child: _buildItem( context, ref, _vm, hg, list['rewards'][index])); })) ], ), ).paddingOnly(left: 15, right: 15, top: 10) : Container(); } Widget _buildHottest(BuildContext context, WidgetRef ref, _vm) { return Container( child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Hottest', style: TextStyle( fontSize: 17.0, color: ColorUtils.string2Color('#000001'), fontWeight: FontWeight.w500), // 设置字体大小 ), Text( 'See All', style: TextStyle( fontSize: 17.0, color: ColorUtils.string2Color('#4161D0'), fontWeight: FontWeight.w500), // 设置字体大小 ).onTap(() { RewardsListPage.startInstance(); }), ], ).marginOnly(bottom: 15), Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: List.generate(2, (index) { double hg = 70; return Container( width: MediaQuery.of(context).size.width / 2 - 25, height: 185, decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(6.0)), boxShadow: [ BoxShadow( color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6) ], ), child: _buildItem(context, ref, _vm, hg, {})); })) ], ), ).paddingOnly(left: 15, right: 15, top: 10); } Widget _buildItem(BuildContext context, WidgetRef ref, _vm, height, item) { double hg = height; num point = item['point'] ?? 0; num originalPoint = item['original_point'] ?? 0; int id = item['id']; return Column( children: [ MyLoadImage( item?['resources']?[0] ?? '', width: MediaQuery.of(context).size.width, height: hg, ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( maxLines: 2, // 设置最大行数为2 overflow: TextOverflow.ellipsis, // 超出部分用省略号表示 item?['name'] ?? '', style: const TextStyle( fontSize: 15.0, color: Colors.black, fontWeight: FontWeight.w500), ).marginOnly(bottom: 5), Row( children: [ Text( '$point', style: const TextStyle( fontSize: 18.0, color: Colors.black, fontWeight: FontWeight.w500), ), Text( '$originalPoint', style: TextStyle( decoration: TextDecoration.lineThrough, decorationColor: ColorUtils.string2Color('#808DAF'), decorationStyle: TextDecorationStyle.solid, fontSize: 13.0, color: ColorUtils.string2Color('#808DAF'), fontWeight: FontWeight.w400), ).marginOnly(left: 5, right: 5), const Text( 'Points', style: TextStyle( fontSize: 13.0, color: Colors.black, fontWeight: FontWeight.w400), ), ], ) ], ).paddingOnly(top: 12, left: 12, right: 12) ], ).onTap(() { RewardsDetailPage.startInstance(id: id); }); } Widget _buildFood(BuildContext context, WidgetRef ref, _vm, list) { return list['rewards'].length > 0 ? Container( child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( list?['name'] ?? '', style: TextStyle( fontSize: 17.0, color: ColorUtils.string2Color('#000001'), fontWeight: FontWeight.w500), // 设置字体大小 ), Text( 'See All', style: TextStyle( fontSize: 17.0, color: ColorUtils.string2Color('#4161D0'), fontWeight: FontWeight.w500), // 设置字体大小 ).onTap(() { RewardsListPage.startInstance(); }), ], ).marginOnly(bottom: 15), Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: List.generate(list['rewards'].length, (index) { double hg = 70; return Container( width: MediaQuery.of(context).size.width / 2 - 25, height: 185, decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(6.0)), boxShadow: [ BoxShadow( color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6) ], ), child: _buildItem( context, ref, _vm, hg, list['rewards'][index])); })) ], ), ).paddingOnly(left: 15, right: 15, top: 10) : Container(); } Widget _buildBest(BuildContext context, WidgetRef ref, _vm, list) { return list['rewards'].length > 0 ? Container( child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Best Offers in Singapore', style: TextStyle( fontSize: 17.0, color: ColorUtils.string2Color('#000001'), fontWeight: FontWeight.w500), // 设置字体大小 ), Text( 'See All', style: TextStyle( fontSize: 17.0, color: ColorUtils.string2Color('#4161D0'), fontWeight: FontWeight.w500), // 设置字体大小 ), ], ).marginOnly(bottom: 15), Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: List.generate(list['rewards'].length, (index) { double hg = 140; return Container( // width: MediaQuery.of(context).size.width / 2 - 25, height: 220, decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(6.0)), boxShadow: [ BoxShadow( color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6) ], ), child: _buildItem(context, ref, _vm, hg, list['rewards'][index])) .marginOnly(bottom: 13); })) ], ), ).paddingOnly(left: 15, right: 15, top: 10) : Container(); } @override Widget build(BuildContext context, WidgetRef ref) { final _vm = ref.read(rewardsHomeVmProvider.notifier); final state = ref.watch(rewardsHomeVmProvider); useEffect(() { // 组件挂载时执行 - 执行接口请求 Future.microtask(() => _vm.initPageData()); return () { // 组件卸载时执行s Log.d("property_news_page 组件卸载时执行"); }; }, []); return Scaffold( // appBar: AppBar(title: Text("奖励")), body: Column(children: [ Expanded( child: LoadStateLayout( state: state.loadingState, errorMessage: state.errorMessage, errorRetry: () { _vm.retryRequest(); }, successWidget: SingleChildScrollView( scrollDirection: Axis.vertical, physics: const BouncingScrollPhysics(), clipBehavior: Clip.none, child: state.list.length > 0 ? Column( children: [ _buildTop(context, ref, _vm).paddingOnly( top: MediaQuery.of(context).padding.top), Container( transform: Matrix4.translationValues(0.0, -25.0, 0.0), child: _buildSearch(context, ref, _vm), // 使用负数margin ).paddingOnly(left: 15, right: 15), _buildSwiper(context, ref, _vm), _buildRecommend(context, ref, _vm, state.list![0]) .marginOnly(bottom: 15), // _buildHottest(context, ref, _vm).marginOnly(bottom: 15), _buildFood(context, ref, _vm, state.list![2]) .marginOnly(bottom: 15), _buildBest(context, ref, _vm, state.list![1]) .marginOnly(bottom: 15), ], ) : const Column()), )), ]).backgroundColor(ColorUtils.string2Color('#F2F3F6')), ); } }