facility_detail_page.dart 12 KB

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