rewards_redeem_page.dart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. import 'package:cs_resources/theme/app_colors_theme.dart';
  2. import 'package:domain/entity/rewards_active_detail_entity.dart';
  3. import 'package:domain/entity/rewards_my_detail_entity.dart';
  4. import 'package:flutter/cupertino.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:auto_route/auto_route.dart';
  7. import 'package:flutter_hooks/flutter_hooks.dart';
  8. import 'package:hooks_riverpod/hooks_riverpod.dart';
  9. import 'package:router/ext/auto_router_extensions.dart';
  10. import 'package:shared/utils/log_utils.dart';
  11. import 'package:shared/utils/color_utils.dart';
  12. import 'package:widgets/ext/ex_widget.dart';
  13. import 'package:widgets/load_state_layout.dart';
  14. import 'package:widgets/my_appbar.dart';
  15. import 'package:widgets/my_load_image.dart';
  16. import 'package:widgets/my_text_view.dart';
  17. import 'package:widgets/shatter/picker_container.dart';
  18. import 'package:widgets/widget_export.dart';
  19. import 'package:cs_resources/generated/assets.dart';
  20. import '../../../router/page/rewards_page_router.dart';
  21. import './rewards_redeem_vm.dart';
  22. @RoutePage()
  23. class RewardsRedeemPage extends HookConsumerWidget {
  24. final int? id;
  25. const RewardsRedeemPage({Key? key, @PathParam('id') required this.id})
  26. : super(key: key);
  27. //启动当前页面
  28. static void startInstance({
  29. BuildContext? context,
  30. int? id,
  31. }) {
  32. if (context != null) {
  33. context.router.push(RewardsRedeemPageRoute(id: id));
  34. } else {
  35. appRouter.push(RewardsRedeemPageRoute(id: id));
  36. }
  37. }
  38. // listitem
  39. Widget _buildSaleItem(BuildContext context, WidgetRef ref, _vm, detailInfo) {
  40. String title = detailInfo!.reward.title ?? "";
  41. List? resources = detailInfo!.reward.resources ?? [];
  42. int point = detailInfo!.reward.point ?? 0;
  43. int originalPoint = detailInfo!.reward.originalPoint ?? 0;
  44. return Column(
  45. children: [
  46. Container(
  47. decoration: const BoxDecoration(
  48. color: Colors.white,
  49. borderRadius: BorderRadius.all(Radius.circular(6.0)),
  50. boxShadow: [
  51. BoxShadow(
  52. color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
  53. ],
  54. ),
  55. width: MediaQuery.of(context).size.width - 30,
  56. // height: 420,
  57. // margin: const EdgeInsets.only(left: 15, right: 15, top: 12.5),
  58. child: Column(
  59. crossAxisAlignment: CrossAxisAlignment.start,
  60. mainAxisAlignment: MainAxisAlignment.start,
  61. children: [
  62. resources!.length > 0
  63. ? MyLoadImage(
  64. resources[0] ?? '',
  65. width: MediaQuery.of(context).size.width,
  66. height: 150,
  67. )
  68. : Container(),
  69. Column(
  70. crossAxisAlignment: CrossAxisAlignment.start,
  71. mainAxisAlignment: MainAxisAlignment.start,
  72. children: [
  73. Text(
  74. maxLines: 1, // 设置最大行数为2
  75. overflow: TextOverflow.ellipsis, // 超出部分用省略号表示
  76. title,
  77. style: const TextStyle(
  78. fontSize: 17.0,
  79. color: Colors.black,
  80. fontWeight: FontWeight.w500),
  81. ).marginOnly(bottom: 5),
  82. Row(
  83. children: [
  84. Text(
  85. '$point',
  86. style: const TextStyle(
  87. fontSize: 19.0,
  88. color: Colors.black,
  89. fontWeight: FontWeight.w500),
  90. ),
  91. Text(
  92. '$originalPoint',
  93. style: TextStyle(
  94. decoration: TextDecoration.lineThrough,
  95. decorationColor:
  96. ColorUtils.string2Color('#808DAF'),
  97. decorationStyle: TextDecorationStyle.solid,
  98. fontSize: 12.0,
  99. color: ColorUtils.string2Color('#808DAF'),
  100. fontWeight: FontWeight.w400),
  101. ).marginOnly(left: 5, right: 5),
  102. const Text(
  103. 'Points',
  104. style: TextStyle(
  105. fontSize: 13.0,
  106. color: Colors.black,
  107. fontWeight: FontWeight.w400),
  108. ),
  109. ],
  110. ),
  111. ],
  112. ).paddingOnly(left: 15, right: 15, top: 10, bottom: 20),
  113. ],
  114. )),
  115. ],
  116. ).marginOnly(left: 15, bottom: 15, right: 15);
  117. }
  118. Widget _buildPackage(BuildContext context, WidgetRef ref, _vm, detailInfo) {
  119. String createdAt = detailInfo.createdAt ?? "";
  120. return Column(
  121. children: [
  122. Container(
  123. decoration: const BoxDecoration(
  124. color: Colors.white,
  125. borderRadius: BorderRadius.all(Radius.circular(6.0)),
  126. boxShadow: [
  127. BoxShadow(
  128. color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
  129. ],
  130. ),
  131. width: MediaQuery.of(context).size.width - 30,
  132. child: Column(
  133. crossAxisAlignment: CrossAxisAlignment.start,
  134. children: [
  135. Row(
  136. mainAxisSize: MainAxisSize.min,
  137. mainAxisAlignment: MainAxisAlignment.start,
  138. crossAxisAlignment: CrossAxisAlignment.center,
  139. children: [
  140. const MyAssetImage(
  141. Assets.rewardsRewardsIconDatd,
  142. width: 25,
  143. height: 25,
  144. ).marginOnly(right: 10),
  145. Text(
  146. 'Redeem Date',
  147. style: TextStyle(
  148. fontSize: 15.0,
  149. color: ColorUtils.string2Color('#000000'),
  150. fontWeight: FontWeight.w500),
  151. )
  152. ],
  153. ).marginOnly(bottom: 10),
  154. Column(
  155. crossAxisAlignment: CrossAxisAlignment.start,
  156. children: [
  157. Text(
  158. createdAt,
  159. style: TextStyle(
  160. fontSize: 15.0,
  161. color: ColorUtils.string2Color('#54638C'),
  162. fontWeight: FontWeight.w400),
  163. ),
  164. ],
  165. ),
  166. ],
  167. ).paddingOnly(left: 15, right: 15, top: 12, bottom: 20),
  168. ),
  169. ],
  170. ).marginOnly(left: 15, bottom: 15, right: 15);
  171. }
  172. Widget _buildFrom(BuildContext context, WidgetRef ref, _vm, detailInfo) {
  173. String redeemedStart = detailInfo!.reward.redeemedStart ?? "";
  174. String redeemedEnd = detailInfo.reward.redeemedEnd ?? "";
  175. String redeemedDate = '$redeemedStart until $redeemedEnd';
  176. return Column(
  177. children: [
  178. Container(
  179. decoration: const BoxDecoration(
  180. color: Colors.white,
  181. borderRadius: BorderRadius.all(Radius.circular(6.0)),
  182. boxShadow: [
  183. BoxShadow(
  184. color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
  185. ],
  186. ),
  187. width: MediaQuery.of(context).size.width - 30,
  188. child: Column(
  189. crossAxisAlignment: CrossAxisAlignment.start,
  190. children: [
  191. Row(
  192. mainAxisSize: MainAxisSize.min,
  193. mainAxisAlignment: MainAxisAlignment.start,
  194. crossAxisAlignment: CrossAxisAlignment.center,
  195. children: [
  196. const MyAssetImage(
  197. Assets.rewardsRewardsIconDate,
  198. width: 25,
  199. height: 25,
  200. ).marginOnly(right: 10),
  201. Text(
  202. 'Redeem From',
  203. style: TextStyle(
  204. fontSize: 15.0,
  205. color: ColorUtils.string2Color('#000000'),
  206. fontWeight: FontWeight.w500),
  207. )
  208. ],
  209. ).marginOnly(bottom: 10),
  210. Column(
  211. crossAxisAlignment: CrossAxisAlignment.start,
  212. children: [
  213. Text(
  214. redeemedDate,
  215. style: TextStyle(
  216. fontSize: 15.0,
  217. color: ColorUtils.string2Color('#54638C'),
  218. fontWeight: FontWeight.w400),
  219. ),
  220. ],
  221. ),
  222. ],
  223. ).paddingOnly(left: 15, right: 15, top: 12, bottom: 20),
  224. ),
  225. ],
  226. ).marginOnly(left: 15, bottom: 15, right: 15);
  227. }
  228. Widget _buildRedeemed(BuildContext context, WidgetRef ref, _vm) {
  229. return Column(
  230. children: [
  231. Container(
  232. decoration: const BoxDecoration(
  233. color: Colors.white,
  234. borderRadius: BorderRadius.all(Radius.circular(6.0)),
  235. boxShadow: [
  236. BoxShadow(
  237. color: Color.fromRGBO(184, 191, 217, 0.3), blurRadius: 6)
  238. ],
  239. ),
  240. width: MediaQuery.of(context).size.width - 30,
  241. child: Column(
  242. crossAxisAlignment: CrossAxisAlignment.start,
  243. children: [
  244. Row(
  245. mainAxisSize: MainAxisSize.max,
  246. mainAxisAlignment: MainAxisAlignment.start,
  247. crossAxisAlignment: CrossAxisAlignment.center,
  248. children: [
  249. const MyAssetImage(
  250. Assets.rewardsRewardsSuccess,
  251. width: 17,
  252. height: 17,
  253. ).marginOnly(right: 12),
  254. Expanded(
  255. child: Text(
  256. 'You’ve redeemed the following promotion.',
  257. style: TextStyle(
  258. fontSize: 15.0,
  259. color: ColorUtils.string2Color('#4161D0'),
  260. fontWeight: FontWeight.w500),
  261. ),
  262. )
  263. ],
  264. )
  265. ],
  266. ).paddingOnly(left: 15, right: 75, top: 22, bottom: 20),
  267. ),
  268. ],
  269. ).marginOnly(left: 15, bottom: 15, right: 15);
  270. }
  271. Widget _buildTop(BuildContext context, WidgetRef ref, _vm) {
  272. return Container(
  273. width: MediaQuery.of(context).size.width,
  274. color: ColorUtils.string2Color('#FFFFFF'),
  275. padding: const EdgeInsets.only(top: 15, bottom: 30),
  276. child: Column(
  277. mainAxisAlignment: MainAxisAlignment.center,
  278. crossAxisAlignment: CrossAxisAlignment.center,
  279. children: [
  280. const MyAssetImage(
  281. Assets.rewardsRewardsSuccess,
  282. width: 54,
  283. height: 54,
  284. ),
  285. Text(
  286. 'Congratulations!',
  287. style: TextStyle(
  288. fontSize: 18.0,
  289. color: ColorUtils.string2Color('#4161D0'),
  290. fontWeight: FontWeight.w500),
  291. ).marginOnly(top: 12, bottom: 15),
  292. ],
  293. ));
  294. }
  295. @override
  296. Widget build(BuildContext context, WidgetRef ref) {
  297. final _vm = ref.read(rewardsRedeemVmProvider.notifier);
  298. final state = ref.watch(rewardsRedeemVmProvider);
  299. RewardsMyDetailEntity? detailInfo = state.detail;
  300. useEffect(() {
  301. // 组件挂载时执行 - 执行接口请求
  302. Future.microtask(() => _vm.initPageData(id: id));
  303. return () {
  304. // 组件卸载时执行
  305. Log.d("property_news_page 组件卸载时执行");
  306. };
  307. }, []);
  308. return Scaffold(
  309. appBar: MyAppBar.appBar(
  310. context,
  311. "Payment Successful",
  312. backgroundColor: context.appColors.whiteBG,
  313. ),
  314. body: detailInfo?.createdAt != ''
  315. ? LoadStateLayout(
  316. state: state.loadingState,
  317. errorMessage: state.errorMessage,
  318. errorRetry: () {
  319. _vm.retryRequest(id: id);
  320. },
  321. successWidget: Column(
  322. children: [
  323. Expanded(
  324. child: SingleChildScrollView(
  325. scrollDirection: Axis.vertical,
  326. physics: const BouncingScrollPhysics(),
  327. clipBehavior: Clip.none,
  328. child: Column(
  329. children: [
  330. _buildTop(context, ref, _vm),
  331. Container(
  332. color: ColorUtils.string2Color('#F2F3F6'),
  333. padding: const EdgeInsets.only(top: 15),
  334. child: Column(
  335. children: [
  336. _buildPackage(
  337. context, ref, _vm, detailInfo),
  338. _buildRedeemed(context, ref, _vm),
  339. _buildSaleItem(
  340. context, ref, _vm, detailInfo),
  341. _buildFrom(context, ref, _vm, detailInfo),
  342. ],
  343. )),
  344. ],
  345. ))),
  346. ],
  347. ))
  348. : const SizedBox.shrink(),
  349. );
  350. }
  351. }