facility_detail_page.dart 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. import 'package:cs_resources/generated/assets.dart';
  2. import 'package:cs_resources/generated/l10n.dart';
  3. import 'package:cs_resources/theme/app_colors_theme.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:auto_route/auto_route.dart';
  6. import 'package:flutter_hooks/flutter_hooks.dart';
  7. import 'package:hooks_riverpod/hooks_riverpod.dart';
  8. import 'package:router/ext/auto_router_extensions.dart';
  9. import 'package:widgets/ext/ex_widget.dart';
  10. import 'package:widgets/my_appbar.dart';
  11. import 'package:widgets/my_load_image.dart';
  12. import 'package:widgets/my_text_view.dart';
  13. import '../../router/page/facility_page_router.dart';
  14. import 'facility_detail_view_model.dart';
  15. @RoutePage()
  16. class FacilityDetailPage extends HookConsumerWidget {
  17. final String? bookingId;
  18. const FacilityDetailPage({Key? key, required this.bookingId}) : super(key: key);
  19. //启动当前页面
  20. static void startInstance({BuildContext? context, required String? bookingId}) {
  21. if (context != null) {
  22. context.router.push(FacilityDetailPageRoute(bookingId: bookingId));
  23. } else {
  24. appRouter.push(FacilityDetailPageRoute(bookingId: bookingId));
  25. }
  26. }
  27. //启动当前页面并回退至设施首页
  28. static void startWithPop2Main({required String? bookingId}) {
  29. appRouter.pushAndPopUntil(
  30. FacilityDetailPageRoute(bookingId: bookingId),
  31. predicate: (route) {
  32. return route.settings.name == 'FacilityPageRoute';
  33. },
  34. );
  35. }
  36. @override
  37. Widget build(BuildContext context, WidgetRef ref) {
  38. final viewModel = ref.watch(facilityDetailViewModelProvider.notifier);
  39. final state = ref.watch(facilityDetailViewModelProvider);
  40. useEffect(() {
  41. // 组件挂载时执行 - 执行接口请求
  42. Future.microtask(() => viewModel.fetchFacilityDetail(bookingId));
  43. return () {
  44. // 组件卸载时执行
  45. };
  46. }, []);
  47. return Scaffold(
  48. appBar: MyAppBar.appBar(context, state.detail?.facility?.type?.name ?? "", backgroundColor: context.appColors.backgroundWhite),
  49. backgroundColor: context.appColors.backgroundDark,
  50. body: SingleChildScrollView(
  51. scrollDirection: Axis.vertical,
  52. physics: const BouncingScrollPhysics(),
  53. child: Column(
  54. mainAxisSize: MainAxisSize.max,
  55. crossAxisAlignment: CrossAxisAlignment.center,
  56. children: [
  57. //顶部的信息展示
  58. _buildHeaderWidget(context, ref),
  59. //预定
  60. _buildDetailItem(
  61. context,
  62. ref,
  63. S.current.book,
  64. Assets.facilityConfirmDateIcon,
  65. 28.5,
  66. 29,
  67. state.detail?.booking?.date ?? "",
  68. null,
  69. "${state.detail?.booking?.start ?? ""}-${state.detail?.booking?.end ?? ""}",
  70. null,
  71. ),
  72. //设施
  73. _buildDetailItem(
  74. context,
  75. ref,
  76. S.current.facility,
  77. Assets.facilityConfirmFacilityIcon,
  78. 25.0,
  79. 30.5,
  80. state.detail?.facility?.type?.name ?? "",
  81. null,
  82. state.detail?.facility?.name ?? "",
  83. null,
  84. ),
  85. //付款
  86. _buildDetailItem(
  87. context,
  88. ref,
  89. S.current.payment,
  90. Assets.facilityConfirmPaymentIcon,
  91. 27.0,
  92. 22.0,
  93. S.current.booking_fee,
  94. state.detail?.timePeriod?.price ?? "",
  95. S.current.total,
  96. "\$${state.detail?.timePeriod?.price ?? ""}",
  97. ),
  98. // 押金
  99. _buildDetailItem(
  100. context,
  101. ref,
  102. S.current.deposit,
  103. Assets.facilityConfirmDepositIcon,
  104. 28.0,
  105. 26.5,
  106. S.current.on_hold,
  107. "\$${state.detail?.timePeriod?.deposit ?? ""}",
  108. null,
  109. null,
  110. ),
  111. ],
  112. ),
  113. ),
  114. );
  115. }
  116. Widget _buildHeaderWidget(BuildContext context, WidgetRef ref) {
  117. final state = ref.watch(facilityDetailViewModelProvider);
  118. return Container(
  119. width: double.infinity,
  120. color: context.appColors.whiteBG,
  121. margin: const EdgeInsets.only(bottom: 7.5),
  122. child: Column(
  123. children: [
  124. //成功图片
  125. const MyAssetImage(
  126. Assets.facilityPaymentSuccessIcon,
  127. width: 54,
  128. height: 54,
  129. ).marginOnly(top: 11, bottom: 13),
  130. //支付成功
  131. MyTextView(
  132. S.current.booking_successful,
  133. fontSize: 18,
  134. marginBottom: 3,
  135. isFontMedium: true,
  136. textColor: context.appColors.textPrimary,
  137. ),
  138. MyTextView(
  139. S.current.have_fun,
  140. fontSize: 18,
  141. marginBottom: 19,
  142. isFontMedium: true,
  143. textColor: context.appColors.textPrimary,
  144. ),
  145. //支付金额
  146. MyTextView(
  147. S.current.fee_paid,
  148. fontSize: 15,
  149. isFontRegular: true,
  150. textColor: context.appColors.textBlack,
  151. ),
  152. MyTextView(
  153. "\$${state.detail?.timePeriod?.price ?? ""}",
  154. fontSize: 15,
  155. isFontRegular: true,
  156. textColor: context.appColors.textPrimary,
  157. ),
  158. //付款类型与时间
  159. Row(
  160. mainAxisSize: MainAxisSize.min,
  161. children: [
  162. MyTextView(
  163. "Master card ending",
  164. fontSize: 15,
  165. isFontRegular: true,
  166. textColor: context.appColors.textBlack,
  167. ),
  168. MyTextView(
  169. "9423",
  170. fontSize: 15,
  171. isFontMedium: true,
  172. textColor: context.appColors.textBlack,
  173. ),
  174. ],
  175. ).marginOnly(top: 12),
  176. Row(
  177. mainAxisSize: MainAxisSize.min,
  178. children: [
  179. MyTextView(
  180. S.current.paid_on,
  181. fontSize: 15,
  182. isFontRegular: true,
  183. textColor: context.appColors.textBlack,
  184. ),
  185. MyTextView(
  186. " ${state.detail?.booking?.date ?? ""}",
  187. fontSize: 15,
  188. isFontMedium: true,
  189. textColor: context.appColors.textBlack,
  190. ),
  191. ],
  192. ).marginOnly(top: 5),
  193. //退还押金的布局展示
  194. Visibility(
  195. visible: state.detail?.booking?.depositRefund != "0.00",
  196. child: Column(
  197. children: [
  198. Divider(height: 0.5, color: context.appColors.dividerDefault).marginOnly(top: 14, bottom: 14),
  199. //退还的押金
  200. MyTextView(
  201. S.current.deposit_released_caps,
  202. fontSize: 15,
  203. isFontRegular: true,
  204. textColor: context.appColors.textBlack,
  205. ),
  206. MyTextView(
  207. "\$${state.detail?.booking?.depositRefund ?? ""}",
  208. fontSize: 15,
  209. marginTop: 5,
  210. isFontRegular: true,
  211. textColor: context.appColors.textPrimary,
  212. ),
  213. Divider(height: 0.5, color: context.appColors.dividerDefault).marginOnly(top: 14, bottom: 14),
  214. //押金付款于时间
  215. Row(
  216. mainAxisSize: MainAxisSize.min,
  217. children: [
  218. MyTextView(
  219. S.current.hold_started_on,
  220. fontSize: 15,
  221. isFontRegular: true,
  222. textColor: context.appColors.textBlack,
  223. ),
  224. MyTextView(
  225. " ${state.detail?.booking?.date ?? ""}",
  226. fontSize: 15,
  227. isFontMedium: true,
  228. textColor: context.appColors.textBlack,
  229. ),
  230. ],
  231. ).marginOnly(top: 5),
  232. //押金退款于时间
  233. Row(
  234. mainAxisSize: MainAxisSize.min,
  235. children: [
  236. MyTextView(
  237. S.current.released_on,
  238. fontSize: 15,
  239. isFontRegular: true,
  240. textColor: context.appColors.textBlack,
  241. ),
  242. MyTextView(
  243. " ${state.detail?.booking?.depositRefundAt ?? ""}",
  244. fontSize: 15,
  245. isFontMedium: true,
  246. textColor: context.appColors.textBlack,
  247. ),
  248. ],
  249. ).marginOnly(top: 5),
  250. ],
  251. ),
  252. ),
  253. const SizedBox(height: 23),
  254. ],
  255. ),
  256. );
  257. }
  258. //Item的列表
  259. Widget _buildDetailItem(
  260. BuildContext context,
  261. WidgetRef ref,
  262. String title,
  263. String iconPath,
  264. double iconWidth,
  265. double iconHeight,
  266. String line1Txt,
  267. String? line1Content,
  268. String? line2Txt,
  269. String? line2Content,
  270. ) {
  271. return Container(
  272. width: double.infinity,
  273. height: 92.5,
  274. padding: const EdgeInsets.only(left: 20, right: 20),
  275. margin: const EdgeInsets.only(left: 15, right: 15, top: 7.5, bottom: 7.5),
  276. decoration: BoxDecoration(
  277. color: context.appColors.whiteBG,
  278. borderRadius: BorderRadius.circular(6.0), // 圆角
  279. boxShadow: [
  280. BoxShadow(
  281. color: const Color(0xFFB8BFD9).withOpacity(0.3), // 阴影颜色
  282. offset: const Offset(0, 3), // 阴影的偏移量
  283. blurRadius: 8.0, // 模糊半径
  284. spreadRadius: 3.0, // 扩散半径
  285. ),
  286. ],
  287. ),
  288. child: Center(
  289. child: Column(
  290. crossAxisAlignment: CrossAxisAlignment.start,
  291. mainAxisSize: MainAxisSize.min,
  292. children: [
  293. MyTextView(
  294. title,
  295. textColor: context.appColors.textBlack,
  296. fontSize: 16,
  297. marginBottom: 7,
  298. isFontMedium: true,
  299. ),
  300. Row(
  301. mainAxisSize: MainAxisSize.max,
  302. children: [
  303. MyAssetImage(
  304. iconPath,
  305. width: iconWidth,
  306. height: iconHeight,
  307. ).marginOnly(right: 15),
  308. Column(
  309. mainAxisSize: MainAxisSize.min,
  310. children: [
  311. Row(
  312. children: [
  313. MyTextView(
  314. line1Txt,
  315. textColor: context.appColors.textBlack,
  316. fontSize: 14,
  317. isFontRegular: true,
  318. ).expanded(),
  319. MyTextView(
  320. line1Content ?? "",
  321. textColor: context.appColors.textBlack,
  322. fontSize: 14,
  323. isFontRegular: true,
  324. ),
  325. ],
  326. ),
  327. Visibility(
  328. visible: line2Txt != null,
  329. child: Row(
  330. children: [
  331. MyTextView(
  332. line2Txt ?? "",
  333. textColor: context.appColors.textBlack,
  334. fontSize: 14,
  335. isFontRegular: true,
  336. ).expanded(),
  337. MyTextView(
  338. line2Content ?? "",
  339. textColor: context.appColors.textBlack,
  340. fontSize: 14,
  341. isFontRegular: true,
  342. ),
  343. ],
  344. ).marginOnly(top: 6),
  345. ),
  346. ],
  347. ).expanded(),
  348. ],
  349. ),
  350. ],
  351. ),
  352. ),
  353. );
  354. }
  355. }