import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:keyboard/base/base_view.dart'; import 'package:keyboard/module/store/discount/discount_controller.dart'; import 'package:keyboard/resource/string.gen.dart'; import '../../../data/consts/payment_type.dart'; import '../../../resource/assets.gen.dart'; import '../../../utils/styles.dart'; import '../../../widget/vertical_dots.dart'; class DiscountView extends BaseView { const DiscountView({super.key}); @override Color backgroundColor() { return Colors.transparent; } @override Widget buildBody(BuildContext context) { return Container( clipBehavior: Clip.hardEdge, padding: EdgeInsets.only(bottom: 20.h), width: 360.w, decoration: ShapeDecoration( color: Color(0xFFF7FDAD), shape: RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(28.r), topRight: Radius.circular(28.r), ), ), ), child: Column( mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ buildTitleCard(), SizedBox(height: 20.h), buildBottomCard(), Transform.translate( offset: Offset(0, -30.h), child: GestureDetector( onTap: () { controller.clickPayNow(); }, child: Assets.images.gifDiscountUnlockButton.image(width: 244.h), ), ), ], ), ); } //标题和多重权益 Widget buildTitleCard() { return Container( width: 360.w, height: 290.h, decoration: BoxDecoration( image: DecorationImage( image: Assets.images.bgDiscountTitle.provider(), fit: BoxFit.fill, ), ), child: Stack( children: [ Positioned( top: 16.h, left: 16.w, child: GestureDetector( onTap: () => controller.clickBack(), child: Assets.images.iconDiscountClose.image( width: 32.w, height: 32.w, ), ), ), Positioned( left: 0, right: 0, bottom: 0, child: Column( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, children: [ Transform.translate( offset: Offset(0, -3), child: ClipPath( clipper: BottomCurveClipper(), child: Container( width: 328.w, height: 150.h, padding: EdgeInsets.only(left: 15.w, right: 15.w), decoration: ShapeDecoration( gradient: LinearGradient( begin: Alignment(0.50, 0.56), end: Alignment(0.50, 1.00), colors: [Colors.white, const Color(0xFFDFFFD7)], ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(25), ), shadows: [ BoxShadow( color: Color(0xFFC6FF32), blurRadius: 4.r, offset: Offset(0, 0), spreadRadius: 0, ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Row( children: [ Assets.images.iconDiscountBoxTitle.image( width: 73.w, height: 22.h, ), Text( StringName.discountDialogDesc, style: TextStyle( color: const Color(0xFF6EC1A8), fontSize: 10.sp, fontWeight: FontWeight.w400, ), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildBox( colors: [ const Color(0xFFBDE7FF), const Color(0xFFF3FBFF), ], image: Assets.images.iconDiscountChat, text: StringName.discountDialogChat, ), _buildBox( colors: [ const Color(0xFFFFD5DC), const Color(0xFFFFFAFB), ], image: Assets.images.iconDiscountTutorial, text: StringName.discountDialogTutorial, ), _buildBox( colors: [ const Color(0xFFFFECBC), const Color(0xFFFFFDDE), ], image: Assets.images.iconDiscountCharacter, text: StringName.discountDialogCharacter, ), _buildBox( colors: [ const Color(0xFFD2DBFF), const Color(0xFFF1F4FF), ], image: Assets.images.iconDiscountSocial, text: StringName.discountDialogSocial, ), ], ), ], ), ), ), ), ], ), ), ], ), ); } Widget buildBottomCard() { return Container( width: 330.w, decoration: ShapeDecoration( gradient: LinearGradient( begin: Alignment(0.00, 0.50), end: Alignment(1.00, 0.50), colors: [const Color(0xFFB2FB52), const Color(0xFF9CFD27)], ), shape: RoundedRectangleBorder( side: BorderSide(width: 1.w, color: Colors.white), borderRadius: BorderRadius.circular(20.r), ), ), child: Stack( children: [ Positioned( child: IgnorePointer( child: Opacity( opacity: 0.4, child: Assets.images.bgDiscountContent.image(), ), ), ), Positioned( child: Column( children: [ _buildDescTime(), Container( width: 330.w, decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.r), ), ), child: SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox(height: 12.h), buildGoodsItem( tagTop: true, tagTopDesc: "秒杀价", title: "测试", tagRight: true, tagRightDesc: "买断价", selected: false, onTap: () {}, ), SizedBox(height: 12.h), buildGoodsItem( tagTop: true, tagTopDesc: "秒杀价", title: "测试", tagRight: true, tagRightDesc: "买断价", selected: true, onTap: () {}, ), SizedBox(height: 12.h), _buildPayWayCard(), Container( padding: EdgeInsets.symmetric(horizontal: 16.w), alignment: Alignment.centerLeft, child: Text( '*首周18.8元,后续38元/周,可随时取消', style: TextStyle( color: const Color(0x99673300), fontSize: 10.sp, fontWeight: FontWeight.w400, height: 2, ), ), ), SizedBox(height: 54.h), ], ), ), ), ], ), ), ], ), ); } Widget buildGoodsItem({ required bool tagTop, required String? tagTopDesc, required bool tagRight, required String? tagRightDesc, required String title, required bool selected, required VoidCallback onTap, }) { return GestureDetector( onTap: onTap, child: Stack( clipBehavior: Clip.none, children: [ Container( padding: EdgeInsets.symmetric(horizontal: 16.w), height: 72.h, width: 298.w, decoration: ShapeDecoration( color: selected ? Color(0xFFFFF9BB) : Color(0xFFFFFDE2), shape: RoundedRectangleBorder( side: BorderSide( width: 2.w, color: selected ? Color(0xFFFF7F14) : Color(0xFFFFFAC1), ), borderRadius: BorderRadius.circular(16.r), ), ), child: Row( children: [ Text( title, style: TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Color(0xFF663300), ), ), SizedBox(width: 8), if (tagRight == tagRight) // 只有“买断价”才显示这个标签 Container( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Color(0xFFFFD5A0), borderRadius: BorderRadius.circular(6.r), ), child: Text( tagRightDesc ?? '', style: TextStyle(fontSize: 12, color: Color(0xFFBB5A00)), ), ), Spacer(), Container( width: 20.w, height: 20.w, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: selected ? Color(0xFFFF7F14) : Color(0xFFFEE86B), width: 2.w, ), color: selected ? Color(0xFFFF8400) : Colors.white, ), child: selected ? Icon(Icons.check, color: Colors.white, size: 16) : null, ), ], ), ), if (tagTop == true) // 只对“秒杀价”显示上面的标签 Positioned( top: -6.h, child: Container( padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 2.h), decoration: BoxDecoration( image: DecorationImage( image: Assets.images.bgDiscountTagTop.provider(), fit: BoxFit.fill, ), borderRadius: BorderRadius.circular(4.r), ), child: Text( tagTopDesc ?? '', style: TextStyle( fontSize: 12.sp, color: Colors.white, fontWeight: FontWeight.w600, ), ), ), ), ], ), ); } // 倒计时 _buildDescTime() { return Container( padding: EdgeInsets.only( left: 16.w, right: 16.w, top: 12.h, bottom: 12.h, ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Assets.images.iconDiscountSubhead.image(width: 90.w, height: 20.h), Row( children: [ _buildTimeBox("00"), VerticalDots( height: 8.h, dotSize: 2.w, color: const Color(0xFF2F640B), horizontalPadding: 5.w, ), _buildTimeBox("00"), VerticalDots( height: 8.h, dotSize: 2.w, color: const Color(0xFF2F640B), horizontalPadding: 5.w, ), _buildTimeBox("00"), SizedBox(width: 6.w), Text( StringName.discountDialogEndDesc, style: TextStyle( color: const Color(0xFF2F640B), fontSize: 10.sp, fontWeight: FontWeight.w500, ), ), ], ), ], ), ); } Widget _buildTimeBox(String value) { return Container( width: 18.w, height: 15.h, decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.r)), ), child: Center( child: Text( value, style: TextStyle( color: const Color(0xFF2F640B), fontSize: 10.sp, fontWeight: FontWeight.w500, ), ), ), ); } // 功能模块 Widget _buildBox({ required List colors, required AssetGenImage image, required String text, }) { return Container( width: 70.w, height: 76.w, decoration: ShapeDecoration( gradient: LinearGradient( begin: Alignment(0.50, 0.00), end: Alignment(0.50, 1.00), colors: colors, ), shape: RoundedRectangleBorder( side: BorderSide(width: 1, color: Colors.white), borderRadius: BorderRadius.circular(10.r), ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ image.image(width: 28.w, height: 28.w), SizedBox(height: 4.h), Text( text, style: TextStyle( color: const Color(0xFF4A4B28), fontSize: 13.sp, fontWeight: FontWeight.w500, ), ), ], ), ); } Widget _buildPayWayCard() { return GestureDetector( onTap: () => controller.clickPayWaySwitch(), child: Container( height: 36.h, margin: EdgeInsets.symmetric(horizontal: 17.w), 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, ), ], ); }), ], ), ), ); } } // 底部曲线剪裁 class BottomCurveClipper extends CustomClipper { @override Path getClip(Size size) { Path path = Path(); path.lineTo(0, size.height - 20); path.quadraticBezierTo( size.width / 2, size.height, size.width, size.height - 20, ); path.lineTo(size.width, 0); path.close(); return path; } @override bool shouldReclip(CustomClipper oldClipper) => false; }