| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 |
- 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<DiscountController> {
- 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<Color> 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<Path> {
- @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<Path> oldClipper) => false;
- }
|