import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:keyboard/base/base_page.dart'; import 'package:keyboard/module/store/new_discount/new_discount_controller.dart'; import 'package:flutter/material.dart'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:get/get.dart'; import '../../../data/bean/character_info.dart'; import '../../../data/consts/payment_type.dart'; import '../../../data/consts/web_url.dart'; import '../../../resource/assets.gen.dart'; import '../../../resource/colors.gen.dart'; import '../../../resource/string.gen.dart'; import '../../../router/app_pages.dart'; import '../../../utils/styles.dart'; import '../../../widget/auto_scroll_list_view.dart'; import '../../../widget/click_text_span.dart'; class NewDiscountPage extends BasePage { const NewDiscountPage({super.key}); /// 跳转 static void start() { Get.toNamed(RoutePath.newDiscount); } @override bool immersive() { return true; } @override backgroundColor() => Colors.white; @override Widget buildBody(BuildContext context) { return Stack( children: [ Positioned(top: 0.w, child: _buildBanner()), Positioned( top: 408.w, child: Container( decoration: BoxDecoration( color: ColorName.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(24.r), topRight: Radius.circular(24.r), ), ), width: 360.w, height: 392.w, child: SingleChildScrollView( child: Expanded( child: Column( children: [ _buildGoodsCard(), SizedBox(height: 200.w), ], ), ), ), ), ), Positioned(top: 0, left: 0, right: 0, child: _buildTitle()), Positioned(bottom: 0, left: 0, right: 0, child: _buildBuyButtonCard()), ], ); } _buildTitle() { return SafeArea( child: Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(top: 16.h, left: 16.w, right: 16.w), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: controller.clickBack, child: Assets.images.iconStoreBack.image( width: 32.w, height: 32.w, ), ), ], ), ), ); } Widget _buildBanner() { return SizedBox( width: 360.w, child: Stack( children: [ CarouselSlider( carouselController: controller.carouselSliderController, options: CarouselOptions( height: 438.w, viewportFraction: 1, initialPage: 0, enableInfiniteScroll: true, reverse: false, autoPlay: true, autoPlayInterval: const Duration(seconds: 3), autoPlayAnimationDuration: const Duration(milliseconds: 500), autoPlayCurve: Curves.fastOutSlowIn, scrollDirection: Axis.horizontal, onPageChanged: (index, reason) { controller.onBannerChanged(index, reason); }, ), items: controller.bannerList.map((item) { return item.image(width: 360.w, fit: BoxFit.contain); }).toList(), ), Positioned( bottom: 149.16.w, left: 31.w, child: Assets.images.iconNewDiscountCharacterTitle.image( width: 296.w, height: 39.w, ), ), Positioned( bottom: 211.13.w, left: 42.w, right: 0, child: _buildIndicator(), ), Positioned( bottom: 0, left: 0, right: 0, child: _buildAutoCharacterList(), ), ], ), ); } /// 指示器 _buildIndicator() { return Row( children: controller.bannerList.asMap().entries.map((entry) { return Obx(() { final isSelectedBanner = controller.currentBannerIndex == entry.key; return Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ GestureDetector( onTap: () => controller.carouselSliderController.animateToPage( entry.key, ), child: AnimatedContainer( duration: const Duration(milliseconds: 300), margin: EdgeInsets.only(right: 5.w), height: 5.w, width: isSelectedBanner ? 10.w : 5.w, decoration: BoxDecoration( color: isSelectedBanner ? const Color(0xff483459) : const Color(0xffAFB4BF), borderRadius: BorderRadius.circular(5.r), ), ), ), ], ); }); }).toList(), ); } Widget _buildAutoCharacterList() { return Obx(() { if (controller.charactersList.isEmpty) { return Container(); } return SizedBox( height: 130.w, child: AutoScrollListView( itemCount: (controller.charactersList.length / 2).ceil(), scrollDirection: Axis.horizontal, itemBuilder: (context, columnIndex) { int rowCount = 2; int startIndex = columnIndex * rowCount; final List columnItems = controller.charactersList .skip(startIndex) .take(rowCount) .toList(); return Column( children: columnItems.map((item) { final emoji = item.emoji ?? ""; final name = item.name ?? ""; return Padding( padding: EdgeInsets.symmetric( vertical: 4.w, horizontal: 4.w, ), child: Container( padding: EdgeInsets.symmetric( horizontal: 12.w, vertical: 6.w, ), decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( side: BorderSide( width: 1.w, color: const Color(0xFFF4F1FF), ), borderRadius: BorderRadius.circular(31.r), ), ), child: Text( "$emoji$name", style: TextStyle( color: Colors.black.withAlpha(204), fontSize: 13.sp, fontWeight: FontWeight.w400, ), ), ), ); }).toList(), ); }, ), ); }); } Widget _buildBuyButtonCard() { return Container( width: 360.w, padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 11.h), decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(24.r), topRight: Radius.circular(24.r), ), ), shadows: [ BoxShadow( color: Color(0x99FFE498), blurRadius: 20, offset: Offset(0, 0), spreadRadius: 0, ), ], ), child: Column( children: [ GestureDetector( onTap: controller.clickPayNow, child: Container( width: 328.w, height: 54.h, decoration: ShapeDecoration( gradient: LinearGradient( begin: Alignment(0.60, -0.39), end: Alignment(0.60, 0.95), colors: [ const Color(0xFFF95FAC), const Color(0xFFFD5E4D), const Color(0xFFFD5E4D), const Color(0xFFFB8A3C), ], ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30.55.r), ), ), child: Center( child: Text( StringName.storePayNow, style: Styles.getTextStyleWhiteW500(17.sp), ), ), ), ), SizedBox(height: 11.h), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Obx(() { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { controller.isAgree.value = !controller.isAgree.value; }, child: controller.isAgree.value ? Assets.images.iconStoreAgreePrivacy.image( width: 16.w, height: 16.w, ) : SizedBox( child: Container( padding: EdgeInsets.all(1.w), width: 16.w, height: 16.w, child: Container( decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: Colors.black.withAlpha(153), width: 1.w, ), ), ), ), ), ); }), Text.rich( TextSpan( children: [ TextSpan( text: StringName.textSpanIHaveReadAndAgree, style: TextStyle( color: Colors.black.withAlpha(153), fontSize: 10.sp, fontWeight: FontWeight.w400, ), ), ClickTextSpan( text: StringName.textSpanPrivacyPolicy, url: WebUrl.privacyPolicy, ), TextSpan( text: StringName.textSpanAnd, style: TextStyle( color: Colors.black.withAlpha(153), fontSize: 10.sp, fontWeight: FontWeight.w400, ), ), ClickTextSpan( text: StringName.textSpanServiceTerms, url: WebUrl.serviceAgreement, ), ], ), ), ], ), ], ), ); } Widget _buildGoodsCard() { return Container( margin: EdgeInsets.symmetric(horizontal: 16.w), padding: EdgeInsets.only( top: 16.w, left: 16.w, right: 16.w, bottom: 24.w, ), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(16.r), topRight: Radius.circular(16.r), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ SizedBox(height: 16.h), Obx(() { return Column( children: controller.filteredGoodsList.map((item) { return Obx(() { return GestureDetector( onTap: () => controller.onGoodsItemClick(item), child: _buildGoodsItem( item, controller.selectedGoodsInfoItem?.id == item.id, ), ); }); }).toList(), ); }), _buildPayWayCard(), ], ), ); } Widget _buildPayWayCard() { return GestureDetector( onTap: () => controller.clickPayWaySwitch(), child: Container( height: 36.h, padding: EdgeInsets.symmetric(horizontal: 10.w), decoration: ShapeDecoration( shape: RoundedRectangleBorder( side: BorderSide(width: 1, color: const Color(0xFFECEBE0)), borderRadius: BorderRadius.circular(10.r), ), ), child: Row( children: [ Text( StringName.storePayWay, style: Styles.getTextStyleBlack204W400(14.sp), ), const Spacer(), Obx(() { if (controller.selectedPayWay == null) { return SizedBox.shrink(); } return Row( children: [ Image.asset( getPaymentIconPath( payMethod: controller.selectedPayWay!.payMethod, payPlatform: controller.selectedPayWay!.payPlatform, ), width: 20.w, height: 20.w, ), SizedBox(width: 4.w), Text( controller.selectedPayWay?.title ?? '', style: Styles.getTextStyleBlack204W400(14.sp), ), SizedBox(width: 6.w), Assets.images.iconStoreSwitchPay.image( width: 20.w, height: 20.w, fit: BoxFit.fill, ), ], ); }), ], ), ), ); } Widget _buildGoodsItem(item, bool isSelected) { return Container( margin: EdgeInsets.only(bottom: 8.h), decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( side: BorderSide( width: 2.w, color: Colors.black.withAlpha( 26), ), borderRadius: BorderRadius.circular(16), ), ), child: Row( children: [ Text( '¥${item.amountText}', textAlign: TextAlign.center, style: isSelected ? Styles.getTextStyleFF7F14W500(12.sp) : Styles.getTextStyleWhiteW500(12.sp), ) // Container( // width: 212.w, // height: 70.h, // decoration: ShapeDecoration( // gradient: // isSelected // ? LinearGradient( // begin: Alignment(-0.06, 0.50), // end: Alignment(1.14, 0.50), // colors: [ // const Color(0xFFFFF895), // const Color(0xFFFFE941), // ], // ) // : null, // color: isSelected ? null : const Color(0xFFFFFDEE), // shape: RoundedRectangleBorder( // side: BorderSide(width: 1, color: const Color(0xFFFEE86B)), // borderRadius: BorderRadius.circular(isSelected ? 8 : 10.r), // ), // ), // child: Stack( // children: [ // if (isSelected) // IgnorePointer( // child: Assets.images.bgStoreSelectedItem.image( // width: 212.w, // height: 70.h, // fit: BoxFit.fill, // ), // ), // Padding( // padding: EdgeInsets.only(left: 16.w), // child: Column( // crossAxisAlignment: CrossAxisAlignment.start, // mainAxisAlignment: MainAxisAlignment.center, // children: [ // Row( // children: [ // RichText( // text: TextSpan( // children: [ // TextSpan( // text: '¥', // style: Styles.getTextStyleFF663300W700(14.sp), // ), // TextSpan( // text: item.priceDescNumber, // style: Styles.getTextStyleFF663300W700(18.sp), // ), // TextSpan( // text: item.priceDescUnit, // style: Styles.getTextStyleFF663300W400(13.sp), // ), // ], // ), // ), // if (item.mostDesc?.isNotEmpty == true) // Container( // padding: EdgeInsets.only( // left: 16.w, // top: 2.h, // bottom: 2.h, // ), // decoration: BoxDecoration( // image: DecorationImage( // image: Assets.images.iconStoreMost.provider(), // fit: BoxFit.cover, // alignment: Alignment.bottomLeft, // ), // ), // child: Text( // item.mostDesc!, // style: TextStyle( // color: Colors.white, // fontSize: 12.sp, // fontWeight: FontWeight.w500, // letterSpacing: -0.60, // ), // ), // ), // ], // ), // Text( // item.description!, // style: Styles.getTextStyle99673300W400(12.sp), // ), // ], // ), // ), // ], // ), // ), // // 右侧 // Expanded( // child: Column( // mainAxisAlignment: MainAxisAlignment.center, // crossAxisAlignment: CrossAxisAlignment.center, // children: [ // Text( // item.name, // style: // isSelected // ? Styles.getTextStyleFFECBBW500(15.sp) // : Styles.getTextStyleFF663300W500(15.sp), // ), // Container( // padding: EdgeInsets.symmetric(horizontal: 8.w), // decoration: ShapeDecoration( // color: isSelected ? const Color(0xFFFFECBB) : null, // gradient: // isSelected // ? null // : LinearGradient( // begin: Alignment(0.77, -0.00), // end: Alignment(0.77, 1.00), // colors: [ // const Color(0xFFFF9416), // const Color(0xFFFF7813), // ], // ), // shape: RoundedRectangleBorder( // borderRadius: BorderRadius.circular( // isSelected ? 17.r : 10.r, // ), // ), // ), // child: Text( // '¥${item.amountText}', // textAlign: TextAlign.center, // style: // isSelected // ? Styles.getTextStyleFF7F14W500(12.sp) // : Styles.getTextStyleWhiteW500(12.sp), // ), // ), // ], // ), // ), ], ), ); } }