rewards_redeem_page.dart 14 KB

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