member_page.dart 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. import 'dart:io';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/gestures.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter/src/widgets/framework.dart';
  6. import 'package:flutter_screenutil/flutter_screenutil.dart';
  7. import 'package:get/get.dart';
  8. import 'package:get/get_core/src/get_main.dart';
  9. import 'package:location/base/base_page.dart';
  10. import 'package:location/module/member/member_controller.dart';
  11. import 'package:location/resource/assets.gen.dart';
  12. import 'package:location/resource/colors.gen.dart';
  13. import 'package:location/utils/common_expand.dart';
  14. import 'package:location/utils/project_expand.dart';
  15. import 'package:location/widget/auto_scroll_list_view.dart';
  16. import '../../data/bean/member_status_info.dart';
  17. import '../../data/bean/pay_item_bean.dart';
  18. import '../../data/consts/payment_type.dart';
  19. import '../../resource/fonts.gen.dart';
  20. import '../../resource/string.gen.dart';
  21. import '../../router/app_pages.dart';
  22. import '../../utils/date_util.dart';
  23. import '../../widget/animated_switcher_widget.dart';
  24. import 'member_evaluate_bean.dart';
  25. import 'member_header_cycle_widget.dart';
  26. ///进入会员类型
  27. enum MemberPageType {
  28. ///通用进入
  29. universalAccessEnter,
  30. ///倒计时试用完会员进入
  31. afeterTrialMemberEnter,
  32. ///加好友进入
  33. addFriendToEnter,
  34. }
  35. class MemberPage extends BasePage<MemberController> {
  36. MemberPage({super.key,this.pageType});
  37. late MemberPageType? pageType = MemberPageType.universalAccessEnter;
  38. static void start({MemberPageType? enterTyp = MemberPageType.universalAccessEnter}) {
  39. Get.toNamed(RoutePath.member,arguments: enterTyp);
  40. }
  41. @override
  42. bool immersive() {
  43. return true;
  44. }
  45. @override
  46. bool statusBarDarkFont() {
  47. return false;
  48. }
  49. @override
  50. Widget buildBody(BuildContext context) {
  51. return PopScope(
  52. canPop: false,
  53. onPopInvokedWithResult: (bool didPop, dynamic result) async {
  54. controller.onPopBack();
  55. },
  56. child: Stack(
  57. children: [
  58. SingleChildScrollView(
  59. physics: const ClampingScrollPhysics(),
  60. controller: controller.scrollController,
  61. child: Stack(
  62. children: [
  63. MemberHeaderCycleWidget(),
  64. Column(
  65. children: [
  66. SizedBox(height: 249.w + MediaQuery.of(Get.context!).padding.top),
  67. Container(
  68. decoration: BoxDecoration(
  69. color: ColorName.white,
  70. borderRadius: BorderRadius.only(
  71. topLeft: Radius.circular(20.w),
  72. topRight: Radius.circular(20.w)),
  73. ),
  74. child: Stack(
  75. children: [
  76. Container(
  77. decoration: BoxDecoration(
  78. borderRadius: BorderRadius.only(
  79. topLeft: Radius.circular(20.w),
  80. topRight: Radius.circular(20.w)),
  81. image: DecorationImage(
  82. image: Assets.images.iconMemberVipMiddleBg.provider(),
  83. fit: BoxFit.fill,
  84. )
  85. ),
  86. width: double.infinity,
  87. height: 174,
  88. ),
  89. Container(
  90. width: double.infinity,
  91. decoration: BoxDecoration(
  92. borderRadius: BorderRadius.only(
  93. topLeft: Radius.circular(20.w),
  94. topRight: Radius.circular(20.w)),
  95. image: DecorationImage(image: Assets.images.iconMemberVipMiddleBg.provider())
  96. ),
  97. child: Column(
  98. crossAxisAlignment: CrossAxisAlignment.start,
  99. children: [
  100. SizedBox(height: 15.w),
  101. buildUserInfoView(),
  102. SizedBox(height: 26.w),
  103. SizedBox(height: 23.w),
  104. buildGoodsList(),
  105. SizedBox(height: 12.w),
  106. buildPrivacyPolicyView(),
  107. buildPayWayView(),
  108. SizedBox(height: 30.w),
  109. Padding(
  110. padding: EdgeInsets.only(left: 12.w),
  111. child: Text(StringName.memberEquityIntroduction,
  112. style: TextStyle(
  113. fontSize: 16.sp,
  114. color: ColorName.black90,
  115. fontWeight: FontWeight.bold)),
  116. ),
  117. SizedBox(height: 19.w),
  118. buildFunctionList(),
  119. SizedBox(height: 40.w),
  120. Padding(
  121. padding: EdgeInsets.only(left: 12.w),
  122. child: Text(StringName.memberUserEvaluate,
  123. style: TextStyle(
  124. fontSize: 16.sp,
  125. color: ColorName.black90,
  126. fontWeight: FontWeight.bold)),
  127. ),
  128. SizedBox(height: 8.w),
  129. buildUserEvaluateList(),
  130. SizedBox(height: 20.w),
  131. Container(
  132. padding: EdgeInsets.all(12.w),
  133. decoration: BoxDecoration(
  134. color: '#F7F7F7'.color,
  135. borderRadius: BorderRadius.circular(6.w)),
  136. margin: EdgeInsets.symmetric(horizontal: 12.w),
  137. child: Text(StringName.memberTips,
  138. style: TextStyle(
  139. fontSize: 12.sp, color: '#A7A7A7'.color)),
  140. ),
  141. SizedBox(height: 100.w)
  142. ],
  143. ),
  144. )
  145. ],
  146. ),
  147. )
  148. ],
  149. ),
  150. ],
  151. )
  152. /*Stack(
  153. children: [
  154. Assets.images.bgMemberHeader.image(width: double.infinity),
  155. SafeArea(
  156. child: Column(
  157. children: [
  158. SizedBox(height: 249.w + MediaQuery.of(Get.context!).padding.top),
  159. buildUserInfoView(),
  160. SizedBox(height: 26.w),
  161. Container(
  162. width: double.infinity,
  163. decoration: BoxDecoration(
  164. borderRadius: BorderRadius.only(
  165. topLeft: Radius.circular(14.w),
  166. topRight: Radius.circular(14.w)),
  167. gradient: LinearGradient(
  168. begin: Alignment.topCenter,
  169. end: Alignment.bottomCenter,
  170. stops: [0.0, 0.1],
  171. colors: ['#EFE9FF'.color, Colors.white])),
  172. child: Column(
  173. crossAxisAlignment: CrossAxisAlignment.start,
  174. children: [
  175. SizedBox(height: 23.w),
  176. buildGoodsList(),
  177. SizedBox(height: 12.w),
  178. buildPrivacyPolicyView(),
  179. buildPayWayView(),
  180. SizedBox(height: 30.w),
  181. Padding(
  182. padding: EdgeInsets.only(left: 12.w),
  183. child: Text(StringName.memberEquityIntroduction,
  184. style: TextStyle(
  185. fontSize: 16.sp,
  186. color: ColorName.black90,
  187. fontWeight: FontWeight.bold)),
  188. ),
  189. SizedBox(height: 19.w),
  190. buildFunctionList(),
  191. SizedBox(height: 40.w),
  192. Padding(
  193. padding: EdgeInsets.only(left: 12.w),
  194. child: Text(StringName.memberUserEvaluate,
  195. style: TextStyle(
  196. fontSize: 16.sp,
  197. color: ColorName.black90,
  198. fontWeight: FontWeight.bold)),
  199. ),
  200. SizedBox(height: 8.w),
  201. buildUserEvaluateList(),
  202. SizedBox(height: 20.w),
  203. Container(
  204. padding: EdgeInsets.all(12.w),
  205. decoration: BoxDecoration(
  206. color: '#F7F7F7'.color,
  207. borderRadius: BorderRadius.circular(6.w)),
  208. margin: EdgeInsets.symmetric(horizontal: 12.w),
  209. child: Text(StringName.memberTips,
  210. style: TextStyle(
  211. fontSize: 12.sp, color: '#A7A7A7'.color)),
  212. ),
  213. SizedBox(height: 100.w)
  214. ],
  215. ),
  216. )
  217. ],
  218. ),
  219. )
  220. ],
  221. ),*/
  222. ),
  223. buildHeadBar(),
  224. buildMemberBottomView()
  225. ],
  226. ),
  227. );
  228. }
  229. Widget buildGoodsList() {
  230. return Obx(() {
  231. return SizedBox(
  232. height: 123.w,
  233. child: ListView.builder(
  234. padding: EdgeInsets.only(left: 12.w),
  235. physics: const BouncingScrollPhysics(
  236. parent: AlwaysScrollableScrollPhysics()),
  237. scrollDirection: Axis.horizontal,
  238. itemBuilder: (BuildContext ctx, int index) {
  239. return Obx(() {
  240. final item = controller.goodsList[index];
  241. bool isSelected = controller.selectedGoods?.id == item.id;
  242. return GestureDetector(
  243. behavior: HitTestBehavior.translucent,
  244. onTap: () => controller.onGoodsItemClick(item),
  245. child: Container(
  246. margin: EdgeInsets.only(right: 10.w),
  247. width: 138.w,
  248. height: 123.w,
  249. child: Stack(
  250. children: [
  251. Container(
  252. width: double.infinity,
  253. height: double.infinity,
  254. decoration: BoxDecoration(
  255. color: isSelected
  256. ? '#6BC4BAFF'.color
  257. : ColorName.white20,
  258. borderRadius: BorderRadius.circular(18.w),
  259. border: Border.all(
  260. color: isSelected
  261. ? '#C4BAFF'.color
  262. : '#E8E8E8'.color,
  263. width: 3.w)),
  264. padding: EdgeInsets.only(left: 10.w),
  265. child: Column(
  266. crossAxisAlignment: CrossAxisAlignment.start,
  267. children: [
  268. Spacer(flex: 2),
  269. Text(
  270. item.name,
  271. style: TextStyle(
  272. fontSize: 14.sp,
  273. color: ColorName.black90,
  274. fontWeight: FontWeight.bold),
  275. ),
  276. SizedBox(height: 3.w),
  277. Text('¥${item.originalAmount.divideBy100()}',
  278. style: TextStyle(
  279. decoration: TextDecoration.lineThrough,
  280. fontSize: 10.sp,
  281. color: ColorName.black60)),
  282. Spacer(flex: 1),
  283. RichText(
  284. text: TextSpan(
  285. style: TextStyle(
  286. color: isSelected
  287. ? '#EA1231'.color
  288. : ColorName.black80,
  289. fontWeight: FontWeight.bold),
  290. children: [
  291. TextSpan(
  292. text: '¥',
  293. style: TextStyle(
  294. fontSize: 20.sp, height: 1)),
  295. TextSpan(
  296. text: item.amount.divideBy100(),
  297. style: TextStyle(
  298. fontSize: 34.sp,
  299. height: 1,
  300. fontFamily: FontFamily.oppoSans))
  301. ])),
  302. Padding(
  303. padding: EdgeInsets.only(left: 7.w),
  304. child: Text(item.description ?? '',
  305. style: TextStyle(
  306. fontSize: 12.sp,
  307. color: ColorName.black40)),
  308. ),
  309. Spacer(
  310. flex: 1,
  311. )
  312. ],
  313. ),
  314. ),
  315. Visibility(
  316. visible: item.tag?.isNotEmpty == true,
  317. child: Positioned(
  318. top: 0,
  319. right: 0,
  320. child: Container(
  321. decoration: BoxDecoration(
  322. gradient: LinearGradient(colors: [
  323. '#A26CFF'.color,
  324. '#FF7CD8'.color,
  325. '#898BFF'.color
  326. ]),
  327. borderRadius: BorderRadius.only(
  328. topRight: Radius.circular(11.w),
  329. bottomLeft: Radius.circular(11.w))),
  330. padding: EdgeInsets.symmetric(
  331. horizontal: 10.w, vertical: 4.w),
  332. child: Text(item.tag ?? '',
  333. style: TextStyle(
  334. fontSize: 12.sp,
  335. color: Colors.white)),
  336. ),
  337. ))
  338. ],
  339. )),
  340. );
  341. });
  342. },
  343. itemCount: controller.goodsList.length),
  344. );
  345. });
  346. }
  347. Widget buildMemberBottomView() {
  348. return Obx(() {
  349. return Visibility(
  350. visible: controller.memberStatusInfo == null ||
  351. controller.memberStatusInfo?.permanent == false,
  352. child: Align(
  353. alignment: Alignment.bottomCenter,
  354. child: Container(//top: 98.w,
  355. alignment: Alignment.bottomCenter,
  356. height: 190.w + MediaQuery.of(Get.context!).padding.bottom,
  357. padding: EdgeInsets.only(
  358. left: 12.w, right: 12.w, bottom: 17.w + MediaQuery.of(Get.context!).padding.bottom),
  359. decoration: BoxDecoration(
  360. gradient: LinearGradient(
  361. begin: Alignment.bottomCenter, // 0deg 相当于从底部开始
  362. end: Alignment.topCenter,
  363. colors: [
  364. Colors.white, // #FFF
  365. "#00FFFFFF".color,
  366. ],
  367. stops: [0.4368, 1.0], // 对应 43.68% 和 100%
  368. ),
  369. ),
  370. child: Obx(() {
  371. return Column(
  372. mainAxisAlignment: MainAxisAlignment.end,
  373. children: [
  374. Container(
  375. width: double.infinity, // 设置容器宽度
  376. height: 50.w, // 设置容器高度
  377. padding: EdgeInsets.only(left: 20.w),
  378. decoration: BoxDecoration(
  379. image: DecorationImage(
  380. image: Assets.images.iconMemberSettlementBg.provider(),
  381. fit: BoxFit.fill,
  382. ),
  383. ),
  384. // 实现内阴影效果
  385. child: Row(
  386. children: [
  387. Transform.translate(
  388. offset: Offset(0, 3), // 向下偏移4像素
  389. child: Text('¥',
  390. style: TextStyle(
  391. fontSize: 14.sp,
  392. color: '#FFF8EF'.color,
  393. fontWeight: FontWeight.bold)),
  394. ),
  395. SizedBox(width: 3.w,),
  396. Text(
  397. controller.selectedGoods?.amount.divideBy100() ?? '--',
  398. style: TextStyle(
  399. fontSize: 24.sp,
  400. color: '#FFF8EF'.color,
  401. fontWeight: FontWeight.bold),
  402. ),
  403. SizedBox(width: 3.w,),
  404. Text("/",
  405. style: TextStyle(
  406. fontSize: 12.sp,
  407. fontWeight: FontWeight.w400,
  408. color: "#FFF8EF".color),),
  409. Text('原价${controller.selectedGoods?.originalAmount.divideBy100()}',
  410. style: TextStyle(
  411. decoration: TextDecoration.lineThrough,
  412. decorationColor: Colors.white,
  413. decorationThickness: 1.0,
  414. fontSize: 12.sp,
  415. fontWeight: FontWeight.w400,
  416. color: "#FFF8EF".color)),
  417. Spacer(),
  418. GestureDetector(
  419. onTap: controller.onBuyClick,
  420. child: Container(
  421. decoration: BoxDecoration(
  422. image: DecorationImage(
  423. image: Assets.images.iconMemberSettlementConfirm.provider(),
  424. fit: BoxFit.fill,
  425. )
  426. ),
  427. // width: 164.w,
  428. // height: 44.w,
  429. padding: EdgeInsets.only(left: 64.w,right: 29.w),
  430. child: Center(
  431. child: Text(
  432. controller.memberStatusInfo?.expired == false
  433. ? StringName.memberVipRenew
  434. : StringName.memberVipUnlock,
  435. style: TextStyle(
  436. fontSize: 18.sp,
  437. color: "#9B3800".color,
  438. fontWeight: FontWeight.bold),
  439. ),
  440. ),
  441. ),
  442. )
  443. ],
  444. ),
  445. ),
  446. SizedBox(height: 8.w,),
  447. buildPrivacyPolicyView(),
  448. ],
  449. );
  450. }),
  451. ),
  452. ),
  453. );
  454. });
  455. }
  456. Widget buildUserInfoView() {
  457. return Row(
  458. children: [
  459. SizedBox(width: 20.w),
  460. Assets.images.iconMemberAvatar.image(width: 40.w, height: 40.w),
  461. SizedBox(width: 10.w),
  462. Column(
  463. crossAxisAlignment: CrossAxisAlignment.start,
  464. children: [
  465. Obx(() {
  466. return GestureDetector(
  467. onTap: controller.onLoginClick,
  468. child: Text(
  469. controller.phone?.isNotEmpty == true
  470. ? controller.getUserName(controller.phone!)
  471. : StringName.mineAccountGoLogin,
  472. style: TextStyle(
  473. fontSize: 13.sp,
  474. color: "#333333".color,
  475. fontWeight: FontWeight.bold)),
  476. );
  477. }),
  478. buildMemberCardVipDesc()
  479. ],
  480. ),
  481. Spacer(),
  482. Container(
  483. decoration: BoxDecoration(
  484. color: '#272F51'.color,
  485. border: Border.all(color: '#99CAB0F0'.color, width: 1.w),
  486. borderRadius: BorderRadius.circular(100.w),
  487. ),
  488. padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 6.w),
  489. child: Obx(() {
  490. return Text(
  491. MemberStatusInfo.getLevelDesc(controller.memberStatusInfo),
  492. style: TextStyle(fontSize: 12.sp, color: '#D2CCFF'.color));
  493. })),
  494. SizedBox(width: 18.w)
  495. ],
  496. );
  497. }
  498. Widget buildMemberCardVipDesc() {
  499. return Obx(() {
  500. String desc = '';
  501. if (!controller.isLogin) {
  502. desc = StringName.memberCardNoLoginDesc;
  503. } else if (controller.memberStatusInfo == null ||
  504. controller.memberStatusInfo?.expired == true) {
  505. desc = StringName.memberCardNoVipDesc;
  506. } else if (controller.memberStatusInfo?.expired == false &&
  507. controller.memberStatusInfo?.permanent == true) {
  508. desc = StringName.memberCardPermanentVipDesc;
  509. } else {
  510. desc =
  511. '${DateUtil.fromMillisecondsSinceEpoch('yyyy.MM.dd', controller.memberStatusInfo?.endTimestamp ?? 0)} ${StringName.memberCardExpirationDesc}';
  512. }
  513. return Text(desc,
  514. style: TextStyle(fontSize: 11.sp, color: ColorName.black50,fontWeight: FontWeight.w400));
  515. });
  516. }
  517. Widget buildHeadBar() {
  518. return Obx(() {
  519. return Stack(
  520. children: [
  521. IgnorePointer(
  522. child: Container(
  523. color: ColorName.colorPrimary.withOpacity(controller.toolBarOpacity),
  524. child: SafeArea(
  525. child: SizedBox(
  526. width: double.infinity,
  527. height: 56.w,
  528. ),
  529. ),
  530. ),
  531. ),
  532. SafeArea(
  533. child: SizedBox(
  534. width: double.infinity,
  535. height: 56.w,
  536. child: Stack(alignment: Alignment.center, children: [
  537. Positioned(
  538. left: 15.w,
  539. child: GestureDetector(
  540. onTap: () => controller.onPopBack(),
  541. child: Assets.images.iconMemberVipBack
  542. .image(width: 26.w, height: 26..w),
  543. )),
  544. Container(
  545. padding: EdgeInsets.only(left: 51.w,right: 12.w),
  546. child: buildVerticalSlideshowWidget())
  547. ]),
  548. ),
  549. ),
  550. ],
  551. );
  552. });
  553. }
  554. Widget buildVerticalSlideshowWidget() {
  555. return Row(
  556. children: [
  557. Visibility(visible: !Platform.isIOS, child: Spacer()),
  558. Container(
  559. width: 192.w,
  560. height: 26.w,
  561. decoration: BoxDecoration(
  562. color: ColorName.black40,
  563. borderRadius: BorderRadius.circular(87.w),
  564. ),
  565. child: Center(
  566. child: AnimatedSwitcherWidget(
  567. controller: controller.switcherController)),
  568. ),
  569. Spacer(),
  570. Visibility(
  571. visible: Platform.isIOS && controller.accountRepository.isLogin.value,
  572. child: GestureDetector(
  573. onTap: controller.clickRecoverSubscribe,
  574. child: Container(
  575. height: 26.w,
  576. decoration: BoxDecoration(
  577. color: ColorName.black40,
  578. borderRadius: BorderRadius.circular(26.w / 2.0),
  579. ),
  580. padding: EdgeInsets.symmetric(horizontal: 10.w),
  581. child: Row(
  582. children: [
  583. Assets.images.iconAppleRecoverSubscribe.image(width: 14.w,height: 14.w),
  584. Text(StringName.appleRecoverSubscribeTxt,
  585. style: TextStyle(
  586. fontSize: 11.sp,
  587. color: ColorName.white,
  588. fontWeight: FontWeight.w500)),
  589. ],
  590. ),
  591. ),
  592. )
  593. )
  594. ],
  595. );
  596. }
  597. Widget buildPrivacyPolicyView() {
  598. return Padding(
  599. padding: EdgeInsets.only(left: 12.w),
  600. child: RichText(
  601. text: TextSpan(
  602. style: TextStyle(fontSize: 12.sp, color: ColorName.black40),
  603. children: [
  604. TextSpan(text: '购买前请先阅读'),
  605. TextSpan(
  606. recognizer: TapGestureRecognizer()
  607. ..onTap = () {
  608. controller.onPrivacyPolicyClick();
  609. },
  610. text: '隐私政策',
  611. style: TextStyle(
  612. color: ColorName.black60,
  613. decoration: TextDecoration.underline)),
  614. TextSpan(text: '&'),
  615. TextSpan(
  616. recognizer: TapGestureRecognizer()
  617. ..onTap = () {
  618. controller.onTermOfServiceClick();
  619. },
  620. text: '服务条款',
  621. style: TextStyle(
  622. color: ColorName.black60,
  623. decoration: TextDecoration.underline)),
  624. ])),
  625. );
  626. }
  627. Widget buildFunctionList() {
  628. return SizedBox(
  629. height: 80.w,
  630. child: AutoScrollListView(
  631. padding: EdgeInsets.only(left: 12.w),
  632. itemBuilder: (ctx, index) {
  633. final item = controller.funList[index];
  634. return Padding(
  635. padding: EdgeInsets.only(right: 20.w),
  636. child: Column(
  637. children: [
  638. Image.asset(item.iconPath, width: 36.w, height: 36.w),
  639. Spacer(flex: 3),
  640. Text(item.funName,
  641. style: TextStyle(
  642. fontSize: 12.8.sp,
  643. color: ColorName.black90,
  644. fontWeight: FontWeight.bold)),
  645. Spacer(flex: 2),
  646. Text(item.funDesc,
  647. style: TextStyle(
  648. fontSize: 10.6.sp,
  649. color: ColorName.black50,
  650. )),
  651. ],
  652. ),
  653. );
  654. },
  655. itemCount: controller.funList.length));
  656. }
  657. Widget buildUserEvaluateList() {
  658. return Column(
  659. children: [
  660. for (int index = 0; index < controller.evaluateList.length; index++)
  661. buildUserEvaluateItem(controller.evaluateList[index],
  662. index == controller.evaluateList.length - 1)
  663. ],
  664. );
  665. }
  666. Widget buildUserEvaluateItem(MemberEvaluateBean item, bool isLast) {
  667. return Column(
  668. crossAxisAlignment: CrossAxisAlignment.start,
  669. children: [
  670. SizedBox(height: 20.w),
  671. Row(
  672. children: [
  673. SizedBox(width: 12.w),
  674. Image.asset(item.avatarPath, width: 24.w, height: 24.w),
  675. SizedBox(width: 8.w),
  676. Text(
  677. item.userName,
  678. style: TextStyle(fontSize: 14.sp, color: Colors.black),
  679. )
  680. ],
  681. ),
  682. SizedBox(height: 1.w),
  683. Padding(
  684. padding: EdgeInsets.only(left: 44.w, right: 12.w),
  685. child: Text(
  686. item.userEvaluate,
  687. style: TextStyle(fontSize: 14.sp, color: '#BF000000'.color),
  688. )),
  689. SizedBox(height: 20.w),
  690. Visibility(
  691. child: Container(
  692. margin: EdgeInsets.only(left: 26.w),
  693. width: 288.w,
  694. color: '#21000000'.color,
  695. height: 1.w),
  696. )
  697. ],
  698. );
  699. }
  700. Widget buildPayWayView() {
  701. return Obx(() {
  702. return Visibility(
  703. visible: Platform.isIOS ? false : controller.payItemList.isNotEmpty,
  704. child: Container(
  705. margin: EdgeInsets.only(top: 7.w),
  706. child: Column(
  707. children: [
  708. for (PayItemBean item in controller.payItemList)
  709. buildPayWayItem(item)
  710. ],
  711. ),
  712. ),
  713. );
  714. });
  715. }
  716. Widget buildPayWayItem(PayItemBean item) {
  717. return GestureDetector(
  718. behavior: HitTestBehavior.translucent,
  719. onTap: () => controller.onPayWayItemClick(item),
  720. child: Obx(() {
  721. bool isSelected = controller.selectedPayWay?.id == item.id;
  722. return Container(
  723. padding: EdgeInsets.symmetric(vertical: 10.w),
  724. child: Row(
  725. children: [
  726. SizedBox(width: 12.w),
  727. Image.asset(
  728. getPaymentIconPath(
  729. payMethod: item.payMethod, payPlatform: item.payPlatform),
  730. width: 24.w,
  731. height: 24.w),
  732. SizedBox(width: 6.w),
  733. Text(item.title,
  734. style: TextStyle(fontSize: 14.sp, color: ColorName.black90)),
  735. Spacer(),
  736. Image.asset(
  737. isSelected
  738. ? Assets.images.iconCbSelected.path
  739. : Assets.images.iconCbUnSelect.path,
  740. width: 20.w,
  741. height: 20.w),
  742. SizedBox(width: 20.w),
  743. ],
  744. ),
  745. );
  746. }),
  747. );
  748. }
  749. }