main_user_page.dart 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. import 'package:flutter_riverpod/flutter_riverpod.dart';
  4. import 'package:flutter_screenutil/flutter_screenutil.dart';
  5. import 'package:go_router/go_router.dart';
  6. import 'package:news_app/constant/size_res.dart';
  7. import 'package:news_app/main.dart';
  8. import 'package:news_app/model/user_model.dart';
  9. import 'package:news_app/widget/load_image.dart';
  10. import 'package:news_app/widget/my_txt.dart';
  11. import '../../constant/color_res.dart';
  12. import '../../constant/config.dart';
  13. import '../../gen/assets.gen.dart';
  14. /// @author: bo.zeng
  15. /// @email: cnhbwds@gmail.com
  16. /// @date: 2025 2025/4/9 16:00
  17. /// @description:
  18. class MainUserPage extends ConsumerStatefulWidget {
  19. const MainUserPage({super.key});
  20. @override
  21. ConsumerState<MainUserPage> createState() => _MainUserPageState();
  22. }
  23. class _MainUserPageState extends ConsumerState<MainUserPage>
  24. with AutomaticKeepAliveClientMixin {
  25. @override
  26. void initState() {
  27. super.initState();
  28. //获取用户积分信息
  29. ref.read(globalUserProvider.notifier).fetchUserInfo();
  30. eventBus.on<String>().listen((event){
  31. if (event == "mainCall") {
  32. ref.read(globalUserProvider.notifier).fetchUserInfo();
  33. }
  34. });
  35. }
  36. @override
  37. Widget build(BuildContext context) {
  38. super.build(context);
  39. UserModel user = ref.watch(globalUserProvider);
  40. return Scaffold(
  41. backgroundColor: Colors.white,
  42. appBar: AppBar(
  43. // 移除阴影
  44. scrolledUnderElevation: 0,
  45. // 禁用滚动时的阴影变化
  46. title: myTxt(text: "我的", fontSize: 18.sp, fontWeight: FontWeight.bold),
  47. centerTitle: true,
  48. systemOverlayStyle: SystemUiOverlayStyle(
  49. statusBarColor: colorDCEAFE,
  50. statusBarIconBrightness: Brightness.dark,
  51. ),
  52. backgroundColor: colorDCEAFE,
  53. ),
  54. body: SingleChildScrollView(
  55. child: Stack(
  56. children: [
  57. Container(
  58. decoration: BoxDecoration(
  59. gradient: LinearGradient(
  60. begin: Alignment.topCenter,
  61. end: Alignment.bottomCenter,
  62. colors: [colorDCEAFE, colorDCEAFE, colorFDFEFF],
  63. ),
  64. ),
  65. width: screenWidth,
  66. height: 500.h,
  67. ),
  68. Column(
  69. children: [
  70. // 用户信息区域
  71. _buildUserInfoSection(context, ref),
  72. // 我的积分、积分商城卡片
  73. if (user.isShow == 1) Padding(
  74. padding: EdgeInsets.symmetric(horizontal: 5.w),
  75. child: Row(
  76. children: [
  77. Expanded(child: _buildScoreCard()),
  78. Expanded(child: _buildScoreShopCard()),
  79. ],
  80. ),
  81. ),
  82. // 功能列表
  83. _buildFunctionList(),
  84. _buildFunctionList2(),
  85. ],
  86. ),
  87. ],
  88. ),
  89. ),
  90. );
  91. }
  92. // 构建用户信息区域
  93. Widget _buildUserInfoSection(BuildContext context, WidgetRef ref) {
  94. UserModel user = ref.watch(globalUserProvider);
  95. return GestureDetector(
  96. onTap: () {
  97. context.push("/user/editProfile");
  98. },
  99. child: Container(
  100. padding: EdgeInsets.all(20.w),
  101. color: colorDCEAFE,
  102. child: Row(
  103. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  104. children: [
  105. Row(
  106. children: [
  107. Container(
  108. width: 66.w,
  109. height: 66.w,
  110. decoration: BoxDecoration(
  111. border: Border.all(color: Colors.white, width: 2.w),
  112. borderRadius: BorderRadius.circular(33.r),
  113. ),
  114. child: ClipOval(
  115. child: LoadImage(
  116. key: Key(Uri.encodeFull(user.avatar ?? '')),
  117. user.avatar ?? '',
  118. width: 66.w,
  119. height: 66.w,
  120. holderImg: "user_avatar",
  121. ),
  122. ),
  123. // CircleAvatar(
  124. // radius: 30,
  125. // backgroundImage: AssetImage(
  126. // Assets.images.userAvatar.path,
  127. // ), // 替换为实际头像路径
  128. // ),
  129. ),
  130. const SizedBox(width: 16),
  131. Column(
  132. crossAxisAlignment: CrossAxisAlignment.start,
  133. children: [
  134. Text(
  135. user.nickName ?? "",
  136. style: TextStyle(
  137. fontSize: 16.sp,
  138. fontWeight: FontWeight.bold,
  139. ),
  140. ),
  141. const SizedBox(height: 4),
  142. Text(
  143. user.description ?? "",
  144. style: TextStyle(
  145. fontSize: 12.sp,
  146. color: Colors.grey[600],
  147. ),
  148. ),
  149. ],
  150. ),
  151. ],
  152. ),
  153. Icon(Icons.arrow_forward_ios_rounded, color: color666666),
  154. ],
  155. ),
  156. ),
  157. );
  158. }
  159. Widget _buildScoreCard() {
  160. UserModel user = ref.watch(globalUserProvider);
  161. return GestureDetector(
  162. onTap: () {
  163. context.push("/user/score");
  164. },
  165. child: Stack(
  166. alignment: Alignment.centerLeft,
  167. children: [
  168. Image.asset(
  169. Assets.images.userScoreBg.path,
  170. height: 98.h,
  171. fit: BoxFit.fill,
  172. ),
  173. Positioned(
  174. left: 10.w,
  175. right: 10.w,
  176. child: Row(
  177. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  178. children: [
  179. Column(
  180. mainAxisAlignment: MainAxisAlignment.start,
  181. children: [
  182. Row(
  183. children: [
  184. SizedBox(width: 12.w),
  185. Image.asset(Assets.images.starIcon.path, width: 20.w),
  186. SizedBox(width: 5.w),
  187. myTxt(
  188. text: "我的积分",
  189. color: Colors.white,
  190. fontSize: 14.sp,
  191. ),
  192. ],
  193. ),
  194. myTxt(
  195. text: user.credit ?? '13045',
  196. color: Colors.white,
  197. fontWeight: FontWeight.bold,
  198. fontSize: 24.sp,
  199. ),
  200. ],
  201. ),
  202. Icon(Icons.chevron_right, color: Colors.white, size: 30.w),
  203. ],
  204. ),
  205. ),
  206. ],
  207. ),
  208. );
  209. }
  210. Widget _buildScoreShopCard() {
  211. return GestureDetector(
  212. onTap: () {
  213. context.push("/user/shop");
  214. },
  215. child: Stack(
  216. alignment: Alignment.centerLeft,
  217. children: [
  218. Image.asset(
  219. Assets.images.userScoreShop.path,
  220. height: 98.h,
  221. fit: BoxFit.fill,
  222. ),
  223. Positioned(
  224. left: 10.w,
  225. right: 10.w,
  226. child: Row(
  227. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  228. children: [
  229. Column(
  230. mainAxisAlignment: MainAxisAlignment.start,
  231. crossAxisAlignment: CrossAxisAlignment.start,
  232. children: [
  233. Row(
  234. children: [
  235. SizedBox(width: 12.w),
  236. Image.asset(Assets.images.starIcon.path, width: 20.w),
  237. SizedBox(width: 5.w),
  238. myTxt(
  239. text: "积分商城",
  240. color: Colors.white,
  241. fontSize: 14.sp,
  242. ),
  243. ],
  244. ),
  245. Padding(
  246. padding: EdgeInsets.only(top: 10.h, left: 10.w),
  247. child: myTxt(
  248. text: '海量礼品等你来兑',
  249. color: Colors.white,
  250. fontWeight: FontWeight.bold,
  251. fontSize: 12.sp,
  252. ),
  253. ),
  254. ],
  255. ),
  256. Icon(Icons.chevron_right, color: Colors.white, size: 30.w),
  257. ],
  258. ),
  259. ),
  260. ],
  261. ),
  262. );
  263. }
  264. // 构建功能列表
  265. Widget _buildFunctionList() {
  266. final List<Map<String, dynamic>> functionItems = [
  267. {'icon': Assets.images.activityIcon.path, 'title': '我的活动'},
  268. {'icon': Assets.images.messageIcon.path, 'title': '消息中心'},
  269. {'icon': Assets.images.favoriteIcon.path, 'title': '我的收藏'},
  270. {'icon': Assets.images.favoriteIcon.path, 'title': '阅读历史'},
  271. //{'icon': Icons.history_outlined, 'title': '历史阅读'},
  272. // {'icon': Icons.settings_outlined, 'title': '设置'},
  273. // {'icon': Icons.share, 'title': '分享APP'},
  274. // {'icon': Icons.feedback_outlined, 'title': '意见反馈'},
  275. ];
  276. return Card(
  277. margin: EdgeInsets.all(10.w),
  278. child: ListView.separated(
  279. physics: const NeverScrollableScrollPhysics(),
  280. shrinkWrap: true,
  281. padding: EdgeInsets.symmetric(horizontal: 15.w),
  282. itemCount: functionItems.length,
  283. separatorBuilder:
  284. (context, index) => Divider(height: 0.5.h, color: Colors.grey[200]),
  285. itemBuilder: (context, index) {
  286. final item = functionItems[index];
  287. return GestureDetector(
  288. behavior: HitTestBehavior.opaque,
  289. onTap: () {
  290. _itemClick(item["title"]);
  291. },
  292. child: SizedBox(
  293. height: 45.h,
  294. child: Row(
  295. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  296. children: [
  297. Row(
  298. children: [
  299. Image.asset(
  300. item['icon'],
  301. color: color333333,
  302. width: 24.w,
  303. ),
  304. SizedBox(width: 5.w),
  305. myTxt(
  306. text: item['title'],
  307. fontSize: 16.sp,
  308. color: color333333,
  309. ),
  310. ],
  311. ),
  312. Icon(Icons.chevron_right, color: Colors.grey),
  313. ],
  314. ),
  315. ),
  316. );
  317. },
  318. ),
  319. );
  320. }
  321. Widget _buildFunctionList2() {
  322. final List<Map<String, dynamic>> functionItems = [
  323. // {'icon': Icons.card_giftcard, 'title': '我的活动'},
  324. // {'icon': Icons.message_outlined, 'title': '消息中心'},
  325. // {'icon': Icons.collections_bookmark_outlined, 'title': '我的收藏'},
  326. //{'icon': Icons.history_outlined, 'title': '历史阅读'},
  327. {'icon': Assets.images.settingIcon.path, 'title': '设置'},
  328. {'icon': Assets.images.shareIcon.path, 'title': '分享APP'},
  329. {'icon': Assets.images.feedbackIcon.path, 'title': '意见反馈'},
  330. ];
  331. return Card(
  332. margin: EdgeInsets.all(10.w),
  333. child: ListView.separated(
  334. physics: const NeverScrollableScrollPhysics(),
  335. shrinkWrap: true,
  336. padding: EdgeInsets.symmetric(horizontal: 15.w),
  337. itemCount: functionItems.length,
  338. separatorBuilder:
  339. (context, index) => Divider(height: 0.5.h, color: Colors.grey[200]),
  340. itemBuilder: (context, index) {
  341. final item = functionItems[index];
  342. return GestureDetector(
  343. behavior: HitTestBehavior.opaque,
  344. onTap: () {
  345. _itemClick(item["title"]);
  346. },
  347. child: SizedBox(
  348. height: 45.h,
  349. child: Row(
  350. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  351. children: [
  352. Row(
  353. children: [
  354. Image.asset(
  355. item['icon'],
  356. color: color333333,
  357. width: 24.w,
  358. ),
  359. SizedBox(width: 5.w),
  360. myTxt(
  361. text: item['title'],
  362. fontSize: 16.sp,
  363. color: color333333,
  364. ),
  365. ],
  366. ),
  367. Icon(Icons.chevron_right, color: Colors.grey),
  368. ],
  369. ),
  370. ),
  371. );
  372. },
  373. ),
  374. );
  375. }
  376. void _itemClick(String title) {
  377. switch (title) {
  378. case "我的活动":
  379. context.push("/user/activity");
  380. break;
  381. case "消息中心":
  382. context.push('/user/msgCenter');
  383. break;
  384. case "我的收藏":
  385. context.push("/user/favorite");
  386. break;
  387. case "阅读历史":
  388. context.push("/user/readHistory");
  389. break;
  390. case "设置":
  391. context.push("/user/setting");
  392. break;
  393. case "分享APP":
  394. context.push("/user/share");
  395. break;
  396. case "意见反馈":
  397. context.push("/user/feedback");
  398. break;
  399. }
  400. }
  401. @override
  402. bool get wantKeepAlive => true;
  403. }