discount_ticket_dialog.dart 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
  4. import 'package:get/get.dart';
  5. import 'package:lottie/lottie.dart';
  6. import '../../../data/consts/constants.dart';
  7. import '../../../data/consts/event_report.dart';
  8. import '../../../handler/event_handler.dart';
  9. import '../../../resource/assets.gen.dart';
  10. import '../../../resource/colors.gen.dart';
  11. import '../../../utils/styles.dart';
  12. import '../suprise/goods_surprise_controller.dart';
  13. // 折扣券一杯奶茶弹窗
  14. class DiscountTicketDialog {
  15. static const String tag = 'DiscountTicketDialog';
  16. static void show({VoidCallback? clickConfirm, VoidCallback? clickCancel}) {
  17. EventHandler.report(EventId.event_02006);
  18. if(SmartDialog.checkExist(tag: tag))return;
  19. SmartDialog.show(
  20. tag: tag,
  21. backType: SmartBackType.block,
  22. clickMaskDismiss: false,
  23. maskColor: ColorName.black70,
  24. animationType: SmartAnimationType.centerScale_otherSlide,
  25. onDismiss: () => Get.delete<GoodsSurpriseController>(),
  26. builder: (_) {
  27. final controller = Get.find<GoodsSurpriseController>();
  28. return Stack(
  29. children: [
  30. Positioned(
  31. top: 0,
  32. left: 0,
  33. right: 0,
  34. bottom: 0,
  35. child: Column(
  36. crossAxisAlignment: CrossAxisAlignment.center,
  37. mainAxisAlignment: MainAxisAlignment.center,
  38. children: [
  39. Stack(
  40. clipBehavior: Clip.none,
  41. children: [
  42. Column(
  43. mainAxisAlignment: MainAxisAlignment.center,
  44. crossAxisAlignment: CrossAxisAlignment.center,
  45. children: [
  46. SizedBox(
  47. width: 360.h,
  48. height: 110.h,
  49. child: IgnorePointer(
  50. child: Lottie.asset(
  51. Assets.anim.animDiscountTicketDialogData,
  52. repeat: false,
  53. fit: BoxFit.contain,
  54. ),
  55. ),
  56. ),
  57. Container(
  58. margin: EdgeInsets.only(left: 31.h, right: 14.h),
  59. width: 317.w,
  60. height: 364.h,
  61. decoration: BoxDecoration(
  62. image: DecorationImage(
  63. image: Assets.images.bgTicketDialog.provider(),
  64. fit: BoxFit.contain,
  65. ),
  66. boxShadow: [
  67. BoxShadow(
  68. color: Colors.black.withAlpha(4), // 阴影颜色
  69. blurRadius: 10, // 模糊程度
  70. spreadRadius: 2, // 扩散程度
  71. offset: Offset(4, 4), // 偏移量 (x, y)
  72. ),
  73. ],
  74. ),
  75. child: Stack(
  76. children: [
  77. Column(
  78. mainAxisAlignment: MainAxisAlignment.start,
  79. crossAxisAlignment: CrossAxisAlignment.center,
  80. children: [
  81. SizedBox(height: 160.h),
  82. Container(
  83. margin: EdgeInsets.only(right: 16.h),
  84. decoration: BoxDecoration(
  85. image: DecorationImage(
  86. image:
  87. Assets.images.bgTicketDialogPrices
  88. .provider(),
  89. fit: BoxFit.cover,
  90. alignment: Alignment.center,
  91. ),
  92. ),
  93. width: 260.w,
  94. height: 100.h,
  95. child: Column(
  96. children: [
  97. Container(
  98. margin: EdgeInsets.only(top: 10.h),
  99. child: Obx(() {
  100. return Text(
  101. controller.secondAmount?.name ??
  102. "",
  103. style: TextStyle(
  104. color: const Color(
  105. 0xFFC39858,
  106. ),
  107. fontSize: 14.sp,
  108. fontWeight: FontWeight.w400,
  109. ),
  110. );
  111. }),
  112. ),
  113. Obx(() {
  114. return Text.rich(
  115. TextSpan(
  116. children: [
  117. TextSpan(
  118. text: '¥',
  119. style: TextStyle(
  120. color: const Color(
  121. 0xFFF55208,
  122. ),
  123. fontSize: 27.sp,
  124. fontWeight:
  125. FontWeight.w700,
  126. height: 0,
  127. ),
  128. ),
  129. TextSpan(
  130. text:
  131. controller
  132. .secondAmount
  133. ?.amountText,
  134. style: TextStyle(
  135. color: const Color(
  136. 0xFFF55208,
  137. ),
  138. height: 0,
  139. fontSize: 36.sp,
  140. fontWeight:
  141. FontWeight.w700,
  142. ),
  143. ),
  144. ],
  145. ),
  146. );
  147. }),
  148. Obx(() {
  149. return Text(
  150. controller
  151. .secondAmount
  152. ?.description ??
  153. "",
  154. style: TextStyle(
  155. color: Colors.black.withAlpha(
  156. 66,
  157. ),
  158. fontSize: 10.sp,
  159. fontWeight: FontWeight.w400,
  160. ),
  161. );
  162. }),
  163. ],
  164. ),
  165. ),
  166. Container(
  167. margin: EdgeInsets.only(right: 25.h),
  168. width: 317.w,
  169. height: 16.h,
  170. decoration: BoxDecoration(
  171. image: DecorationImage(
  172. image:
  173. Assets
  174. .images
  175. .bgTicketDialogPrices2
  176. .provider(),
  177. fit: BoxFit.contain,
  178. ),
  179. ),
  180. ),
  181. SizedBox(height: 9.h),
  182. GestureDetector(
  183. onTap: () {
  184. EventHandler.report(EventId.event_02007);
  185. clickConfirm?.call();
  186. SmartDialog.dismiss(tag: tag);
  187. },
  188. child: Container(
  189. margin: EdgeInsets.only(right: 20.h),
  190. width: 200.w,
  191. height: 54.h,
  192. child: Assets
  193. .images
  194. .iconTicketDialogButton
  195. .image(width: 200.w, height: 54.h),
  196. ),
  197. ),
  198. ],
  199. ),
  200. // 倒计时
  201. Visibility(
  202. visible: isNotHWChannel(),
  203. child: Positioned(
  204. right: 40.w,
  205. child: Container(
  206. height: 24.h,
  207. width: 107.w,
  208. alignment: Alignment.center,
  209. decoration: ShapeDecoration(
  210. gradient: LinearGradient(
  211. begin: Alignment.centerLeft,
  212. end: Alignment.centerRight,
  213. colors: [
  214. const Color(0xFFFF68F4),
  215. const Color(0xFFF96432),
  216. ],
  217. ),
  218. shape: RoundedRectangleBorder(
  219. side: BorderSide(
  220. width: 1,
  221. color: Colors.white,
  222. ),
  223. borderRadius: BorderRadius.only(
  224. topLeft: Radius.circular(15.r),
  225. topRight: Radius.circular(16.r),
  226. bottomRight: Radius.circular(16.r),
  227. ),
  228. ),
  229. ),
  230. margin: EdgeInsets.only(top: 140.h),
  231. child: Obx(() {
  232. int totalMilliseconds =
  233. controller.timeLeft.value;
  234. int minutes =
  235. (totalMilliseconds ~/ 6000);
  236. int seconds =
  237. (totalMilliseconds ~/ 100) % 60;
  238. int milliseconds =
  239. (totalMilliseconds % 100); // 毫秒
  240. return Text(
  241. "${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}:${milliseconds.toString().padLeft(2, '0')} 后过期",
  242. style: TextStyle(
  243. color: Colors.white,
  244. fontSize: 12.sp,
  245. fontWeight: FontWeight.w500,
  246. ),
  247. );
  248. }),
  249. ),
  250. ),
  251. ),
  252. ],
  253. ),
  254. ),
  255. ],
  256. ),
  257. ],
  258. ),
  259. Container(
  260. margin: EdgeInsets.only(top: 24.h),
  261. child: GestureDetector(
  262. onTap: () {
  263. EventHandler.report(EventId.event_02008);
  264. SmartDialog.dismiss(tag: tag);
  265. clickCancel?.call();
  266. },
  267. child: Assets.images.iconCharacterDialogClose.image(
  268. width: 40.r,
  269. height: 40.r,
  270. ),
  271. ),
  272. ),
  273. ],
  274. ),
  275. ),
  276. ],
  277. );
  278. },
  279. );
  280. }
  281. }
  282. class VerticalDots extends StatelessWidget {
  283. final double dotSize;
  284. final double height;
  285. final Color? color;
  286. const VerticalDots({
  287. super.key,
  288. required this.dotSize,
  289. required this.height,
  290. this.color = Colors.white,
  291. });
  292. @override
  293. Widget build(BuildContext context) {
  294. return SizedBox(
  295. width: 2.w,
  296. height: 8.h,
  297. child: Column(
  298. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  299. children: List.generate(2, (index) {
  300. return Container(
  301. width: dotSize,
  302. height: dotSize,
  303. decoration: BoxDecoration(color: color, shape: BoxShape.circle),
  304. );
  305. }),
  306. ),
  307. );
  308. }
  309. }