mine_page.dart 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/src/widgets/framework.dart';
  4. import 'package:flutter_screenutil/flutter_screenutil.dart';
  5. import 'package:get/get.dart';
  6. import 'package:get/get_core/src/get_main.dart';
  7. import 'package:location/base/base_page.dart';
  8. import 'package:location/resource/assets.gen.dart';
  9. import 'package:location/resource/colors.gen.dart';
  10. import 'package:location/resource/string.gen.dart';
  11. import 'package:location/utils/common_expand.dart';
  12. import '../../router/app_pages.dart';
  13. import '../../utils/date_util.dart';
  14. import '../../widget/common_view.dart';
  15. import 'mine_controller.dart';
  16. class MinePage extends BasePage<MineController> {
  17. const MinePage({super.key});
  18. static void start() {
  19. Get.toNamed(RoutePath.mine);
  20. }
  21. @override
  22. bool immersive() {
  23. return true;
  24. }
  25. @override
  26. Color backgroundColor() {
  27. return '#FAFAFA'.color;
  28. }
  29. @override
  30. Widget buildBody(BuildContext context) {
  31. return Stack(
  32. children: [
  33. Assets.images.bgPageBackground.image(width: double.infinity),
  34. SafeArea(
  35. child: SingleChildScrollView(
  36. child: Column(children: [
  37. SizedBox(height: 70.w),
  38. Row(
  39. children: [
  40. SizedBox(width: 12.w),
  41. Obx(() {
  42. return controller.isLogin
  43. ? Assets.images.iconMineLogged
  44. .image(width: 54.w, height: 54.w)
  45. : Assets.images.iconMineNoLogin
  46. .image(width: 54.w, height: 54.w);
  47. }),
  48. SizedBox(width: 10.w),
  49. buildLoginInfo(),
  50. Spacer(),
  51. Obx(() {
  52. return Visibility(
  53. visible: controller.isOpenFreeMember == true,
  54. child: GestureDetector(
  55. onTap: controller.onMemberTryOutClick,
  56. child: buildMemberTryOutView()));
  57. })
  58. ],
  59. ),
  60. SizedBox(height: 20.w),
  61. buildExperienceContent(),
  62. SizedBox(height: 16.w),
  63. buildFunList()
  64. ]),
  65. ),
  66. ),
  67. buildBackBtn(),
  68. ],
  69. );
  70. }
  71. Widget buildMineFunItem(
  72. ImageProvider icon, String funName, VoidCallback onTap) {
  73. return GestureDetector(
  74. behavior: HitTestBehavior.translucent,
  75. onTap: onTap,
  76. child: Container(
  77. padding: EdgeInsets.symmetric(vertical: 15.w, horizontal: 12.w),
  78. child: Row(
  79. children: [
  80. Image(image: icon, width: 24.w, height: 24.w),
  81. SizedBox(width: 6.w),
  82. Text(funName,
  83. style: TextStyle(fontSize: 15.sp, color: '#202020'.color)),
  84. Spacer(),
  85. Assets.images.iconMineFunArrow.image(width: 20.w, height: 20.w)
  86. ],
  87. ),
  88. ),
  89. );
  90. }
  91. Widget buildExperienceContent() {
  92. return Stack(
  93. children: [
  94. Column(
  95. children: [
  96. AspectRatio(
  97. aspectRatio: 332 / 57, child: SizedBox(width: double.infinity)),
  98. Obx(() {
  99. return Visibility(
  100. visible: controller.isOpenFreeMember == true,
  101. child: GestureDetector(
  102. onTap: controller.onMemberTryOutClick,
  103. child: Stack(
  104. children: [
  105. Container(
  106. margin: EdgeInsets.symmetric(horizontal: 14.w),
  107. width: double.infinity,
  108. height: 50.w,
  109. decoration: BoxDecoration(
  110. borderRadius: BorderRadius.only(
  111. bottomLeft: Radius.circular(8.w),
  112. bottomRight: Radius.circular(8.w)),
  113. gradient: LinearGradient(
  114. begin: Alignment.centerLeft,
  115. end: Alignment.centerRight,
  116. colors: ['#FFF8DA'.color, '#FFF1BA'.color]),
  117. ),
  118. ),
  119. Positioned(
  120. bottom: 0,
  121. left: 0,
  122. right: 0,
  123. child: Container(
  124. margin: EdgeInsets.symmetric(horizontal: 14.w),
  125. height: 32.w,
  126. child: Row(
  127. children: [
  128. SizedBox(width: 15.w),
  129. Assets.images.iconExperiment
  130. .image(width: 16.w, height: 16.w),
  131. SizedBox(width: 4.w),
  132. Text(StringName.memberExperienceVip,
  133. style: TextStyle(
  134. fontSize: 13.sp, color: '#8A5F03'.color)),
  135. Spacer(),
  136. Text(StringName.memberExperienceVipReceive,
  137. style: TextStyle(
  138. fontSize: 13.sp, color: '#8A5F03'.color)),
  139. Assets.images.iconMemberVipReceiveArrow
  140. .image(width: 16.w, height: 16.w),
  141. SizedBox(width: 13.w),
  142. ],
  143. ),
  144. ),
  145. )
  146. ],
  147. ),
  148. ),
  149. );
  150. })
  151. ],
  152. ),
  153. buildMemberCard()
  154. ],
  155. );
  156. }
  157. Widget buildLoginInfo() {
  158. return GestureDetector(
  159. behavior: HitTestBehavior.opaque,
  160. onTap: () => controller.onLoginClick(),
  161. child: Column(
  162. mainAxisAlignment: MainAxisAlignment.center,
  163. crossAxisAlignment: CrossAxisAlignment.start,
  164. children: [
  165. Row(
  166. children: [
  167. Obx(() {
  168. String desc = "";
  169. if (controller.isLogin &&
  170. controller.phone?.isNotEmpty == true) {
  171. desc = controller.getUserName(controller.phone!);
  172. } else {
  173. desc = StringName.mineAccountGoLogin;
  174. }
  175. return Text(desc,
  176. style: TextStyle(
  177. fontSize: 16.sp,
  178. color: '#333333'.color,
  179. fontWeight: FontWeight.bold));
  180. }),
  181. SizedBox(width: 6.w),
  182. Obx(() {
  183. return Visibility(
  184. visible: controller.isLogin &&
  185. controller.memberStatusInfo != null &&
  186. controller.memberStatusInfo?.expired == false,
  187. child: Assets.images.iconVip.image(width: 28.w));
  188. })
  189. ],
  190. ),
  191. SizedBox(height: 6.w),
  192. buildLoginDesc(),
  193. ],
  194. ),
  195. );
  196. }
  197. Container buildMemberTryOutView() {
  198. return Container(
  199. margin: EdgeInsets.only(right: 16.w),
  200. decoration: BoxDecoration(
  201. color: '#267B7DFF'.color, borderRadius: BorderRadius.circular(26.w)),
  202. padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 5.w),
  203. child: Text(StringName.memberTryOut,
  204. style: TextStyle(fontSize: 12.sp, color: '#8163FF'.color)),
  205. );
  206. }
  207. Widget buildBackBtn() {
  208. return SafeArea(
  209. child: GestureDetector(
  210. onTap: controller.onBack,
  211. child: Container(
  212. margin: EdgeInsets.only(top: 16.w, left: 14.w),
  213. child: CommonView.getBackBtnView())),
  214. );
  215. }
  216. Widget buildLoginDesc() {
  217. return Obx(() {
  218. String txt = '';
  219. if (!controller.isLogin) {
  220. txt = StringName.mineNotLoginDesc;
  221. } else if (controller.memberStatusInfo != null &&
  222. controller.memberStatusInfo?.expired == false) {
  223. txt = StringName.mineVip;
  224. } else {
  225. txt = StringName.mineOpenVip;
  226. }
  227. return Text(txt,
  228. style: TextStyle(fontSize: 13.sp, color: '#727272'.color));
  229. });
  230. }
  231. Widget buildMemberCard() {
  232. return GestureDetector(
  233. onTap: controller.onMemberCardClick,
  234. child: AspectRatio(
  235. aspectRatio: 332 / 75,
  236. child: Container(
  237. margin: EdgeInsets.symmetric(horizontal: 14.w),
  238. decoration: BoxDecoration(
  239. image: DecorationImage(
  240. image: Assets.images.bgMineMemberCard.provider(),
  241. fit: BoxFit.fill)),
  242. child: Row(
  243. children: [
  244. SizedBox(width: 14.w),
  245. Column(
  246. crossAxisAlignment: CrossAxisAlignment.start,
  247. mainAxisAlignment: MainAxisAlignment.center,
  248. children: [
  249. Row(
  250. children: [
  251. Assets.images.iconMineUnlockVip.image(width: 68.w),
  252. SizedBox(width: 6.5.w),
  253. Assets.images.iconMineSmallVip
  254. .image(width: 21.6.w, height: 21.6.w),
  255. ],
  256. ),
  257. SizedBox(height: 6.w),
  258. buildMemberCardVipDesc()
  259. ],
  260. ),
  261. Spacer(),
  262. buildBuyMemberCardBtn()
  263. ],
  264. ),
  265. ),
  266. ),
  267. );
  268. }
  269. Widget buildMemberCardVipDesc() {
  270. return Obx(() {
  271. String desc = '';
  272. if (!controller.isLogin) {
  273. desc = StringName.memberCardNoLoginDesc;
  274. } else if (controller.memberStatusInfo == null ||
  275. controller.memberStatusInfo?.expired == true) {
  276. desc = StringName.memberCardNoVipDesc;
  277. } else if (controller.memberStatusInfo?.expired == false &&
  278. controller.memberStatusInfo?.permanent == true) {
  279. desc = StringName.memberCardPermanentVipDesc;
  280. } else {
  281. desc =
  282. '${DateUtil.fromMillisecondsSinceEpoch('yyyy.MM.dd', controller.memberStatusInfo?.endTimestamp ?? 0)} ${StringName.memberCardExpirationDesc}';
  283. }
  284. return Text(desc,
  285. style: TextStyle(fontSize: 12.sp, color: ColorName.white80));
  286. });
  287. }
  288. Widget buildBuyMemberCardBtn() {
  289. return Obx(() {
  290. String txt = "";
  291. if (!controller.isLogin ||
  292. controller.memberStatusInfo == null ||
  293. controller.memberStatusInfo?.expired == true) {
  294. txt = StringName.memberVipUnlock;
  295. } else if (controller.memberStatusInfo?.expired == false &&
  296. controller.memberStatusInfo?.permanent == true) {
  297. txt = StringName.mineMemberPermanent;
  298. } else {
  299. txt = StringName.memberVipRenew;
  300. }
  301. return Container(
  302. margin: EdgeInsets.only(right: 20.w),
  303. decoration: BoxDecoration(
  304. color: ColorName.white, borderRadius: BorderRadius.circular(26.w)),
  305. padding: EdgeInsets.symmetric(horizontal: 13.w, vertical: 6.w),
  306. child: Text(txt,
  307. style: TextStyle(
  308. fontSize: 12.sp,
  309. color: '#5558FC'.color,
  310. fontWeight: FontWeight.bold)),
  311. );
  312. });
  313. }
  314. Widget buildFunList() {
  315. return Container(
  316. decoration: BoxDecoration(
  317. color: ColorName.white, borderRadius: BorderRadius.circular(12.w)),
  318. margin: EdgeInsets.symmetric(horizontal: 12.w),
  319. padding: EdgeInsets.symmetric(vertical: 5.w),
  320. child: Column(
  321. children: [
  322. buildMineFunItem(
  323. Assets.images.iconMineUrgentContact.provider(),
  324. StringName.mineUrgentContact,
  325. () => controller.onUrgentContactClick()),
  326. buildMineFunItem(Assets.images.iconMineFunShare.provider(),
  327. StringName.mineFunShare, () => controller.onShareClick()),
  328. buildMineFunItem(
  329. Assets.images.iconMineFunCustomerService.provider(),
  330. StringName.mineFunCustomerService,
  331. () => controller.onCustomerServiceClick()),
  332. buildMineFunItem(
  333. Assets.images.iconMineFunPermissionSetting.provider(),
  334. StringName.mineFunPermissionSetting,
  335. () => controller.onPermissionSettingClick()),
  336. buildMineFunItem(
  337. Assets.images.iconMineFunAccountFeedback.provider(),
  338. StringName.mineFunAccountFeedback,
  339. () => controller.onAccountFeedbackClick()),
  340. buildMineFunItem(Assets.images.iconMineFunAbout.provider(),
  341. StringName.mineFunAbout, () => controller.onAboutClick()),
  342. Obx(() {
  343. return Visibility(
  344. visible: controller.isLogin,
  345. child: buildMineFunItem(
  346. Assets.images.iconMineFunLogoutAccount.provider(),
  347. StringName.mineFunLogoutAccount,
  348. () => controller.onLogoutAccountClick()),
  349. );
  350. }),
  351. Obx(() {
  352. return Visibility(
  353. visible: controller.isLogin,
  354. child: buildMineFunItem(
  355. Assets.images.iconMineFunExitAccount.provider(),
  356. StringName.mineFunExitAccount,
  357. () => controller.onFunExitAccountClick()),
  358. );
  359. }),
  360. ],
  361. ),
  362. );
  363. }
  364. }