discount_ticket_dialog.dart 15 KB

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