You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
598 lines
20 KiB
598 lines
20 KiB
import 'dart:convert'; |
|
import 'package:dio/dio.dart'; |
|
import 'package:flutter/material.dart'; |
|
import 'package:flutter_easyloading/flutter_easyloading.dart'; |
|
import 'package:huixiang/generated/l10n.dart'; |
|
import 'package:huixiang/data/base_data.dart'; |
|
import 'package:huixiang/data/goods.dart'; |
|
import 'package:huixiang/data/goods_category.dart'; |
|
import 'package:huixiang/data/page.dart'; |
|
import 'package:huixiang/data/user_info.dart'; |
|
import 'package:huixiang/retrofit/retrofit_api.dart'; |
|
import 'package:huixiang/utils/flutter_utils.dart'; |
|
import 'package:huixiang/utils/font_weight.dart'; |
|
import 'package:huixiang/view_widget/classic_header.dart'; |
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|
import 'package:huixiang/view_widget/custom_image.dart'; |
|
import 'package:huixiang/view_widget/my_footer.dart'; |
|
import 'package:huixiang/view_widget/my_tab.dart'; |
|
import 'package:huixiang/view_widget/no_data_view.dart'; |
|
import 'package:pull_to_refresh/pull_to_refresh.dart'; |
|
import 'package:shared_preferences/shared_preferences.dart'; |
|
|
|
class WelfareExchange extends StatefulWidget { |
|
@override |
|
State<StatefulWidget> createState() { |
|
return _WelfareExchange(); |
|
} |
|
} |
|
|
|
class _WelfareExchange extends State<WelfareExchange> |
|
with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin { |
|
ApiService? apiService; |
|
final RefreshController refreshController = RefreshController(); |
|
int pageNum = 1; |
|
|
|
//排序类型枚举:1-自然排序,2-销量,3-价格 |
|
int orderType = 1; |
|
|
|
//是否降序排列 |
|
bool orderDesc = true; |
|
List<Goods> goods = []; |
|
List<Goods> gooods = []; |
|
List<GoodsCategory> gooodsCategorys = []; |
|
UserInfo? userInfo; |
|
String? categoryId; |
|
|
|
@override |
|
void dispose() { |
|
super.dispose(); |
|
refreshController.dispose(); |
|
} |
|
|
|
@override |
|
void initState() { |
|
super.initState(); |
|
SharedPreferences.getInstance().then((value) => { |
|
apiService = ApiService(Dio(), |
|
context: context, |
|
token: value.getString("token"), |
|
showLoading: false), |
|
creditGoods(), |
|
}); |
|
} |
|
|
|
queryUser() async { |
|
BaseData<UserInfo>? baseData = |
|
await apiService?.queryInfo().catchError((onError) {}); |
|
if (baseData?.isSuccess ?? false) { |
|
userInfo = baseData!.data; |
|
SharedPreferences.getInstance().then((value) => { |
|
value.setString('user', jsonEncode(baseData.data)), |
|
}); |
|
} |
|
} |
|
|
|
creditGoods({bool isLoading = true}) async { |
|
try { |
|
if (isLoading) |
|
EasyLoading.show( |
|
status: S.current.zhengzaijiazai, |
|
maskType: EasyLoadingMaskType.black); |
|
|
|
final SharedPreferences value = await SharedPreferences.getInstance(); |
|
apiService = ApiService(Dio(), |
|
context: context, |
|
token: value.getString('token'), |
|
showLoading: false); |
|
|
|
await queryUser(); |
|
|
|
BaseData<PageInfo<Goods>>? goodsData = await apiService?.creditGoods({ |
|
"orderDesc": true, |
|
"orderType": 1, |
|
"pageNum": 1, |
|
"pageSize": 100, |
|
"state": 1 |
|
}).catchError((onError) { |
|
refreshController.refreshFailed(); |
|
}); |
|
if (goodsData?.isSuccess ?? false) { |
|
gooods.clear(); |
|
gooods.addAll(goodsData?.data?.list ?? []); |
|
} |
|
|
|
BaseData<PageInfo<GoodsCategory>>? dataCategory = |
|
await apiService?.goodsCategory({ |
|
"current": 1, |
|
"map": {}, |
|
"model": {"pageNum": 1, "pageSize": 20, "searchKey": ""}, |
|
"order": "descending", |
|
"size": 20, |
|
"sort": "sortOrder" |
|
}).catchError((onError) { |
|
refreshController.loadFailed(); |
|
refreshController.refreshFailed(); |
|
}); |
|
|
|
if ((dataCategory?.isSuccess ?? false) && |
|
(dataCategory?.data?.records?.isNotEmpty ?? false)) { |
|
gooodsCategorys.clear(); |
|
gooodsCategorys.add(GoodsCategory()..name = S.of(context).quanbu); |
|
gooodsCategorys.addAll(dataCategory?.data?.records ?? []); |
|
} |
|
|
|
var param = { |
|
"categoryId": categoryId ?? "", |
|
"orderDesc": orderDesc, |
|
"orderType": orderType, |
|
"pageNum": pageNum, |
|
"pageSize": 100, |
|
"state": 1 |
|
}; |
|
BaseData<PageInfo<Goods>>? pageGoods = |
|
await apiService?.creditGoods(param).catchError((onError) { |
|
refreshController.loadFailed(); |
|
refreshController.refreshFailed(); |
|
}); |
|
if (pageGoods?.isSuccess ?? false) { |
|
if (pageNum == 1) { |
|
goods.clear(); |
|
} |
|
goods.addAll(pageGoods?.data?.list ?? []); |
|
refreshController.refreshCompleted(); |
|
refreshController.loadComplete(); |
|
if (pageGoods?.data?.pageNum == pageGoods?.data?.pages) { |
|
refreshController.loadNoData(); |
|
} else { |
|
pageNum += 1; |
|
} |
|
} else { |
|
refreshController.loadFailed(); |
|
refreshController.refreshFailed(); |
|
} |
|
} finally { |
|
EasyLoading.dismiss(); |
|
setState(() {}); |
|
} |
|
} |
|
|
|
_onRefresh() { |
|
creditGoods(isLoading: false); |
|
} |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
return Scaffold( |
|
backgroundColor: Colors.white, |
|
body: NestedScrollView( |
|
headerSliverBuilder: (context, inner) { |
|
return [ |
|
SliverAppBar( |
|
pinned: true, |
|
backgroundColor: Colors.white, |
|
elevation: 0, |
|
title: Text( |
|
S.of(context).fuliduihuan, |
|
style: |
|
TextStyle(fontWeight: FontWeight.w500, color: Colors.white), |
|
), |
|
centerTitle: true, |
|
leading: GestureDetector( |
|
onTap: () { |
|
Navigator.of(context).pop(); |
|
}, |
|
child: Container( |
|
alignment: Alignment.centerRight, |
|
margin: EdgeInsets.only(left: 10.w), |
|
padding: EdgeInsets.all(6), |
|
child: Icon( |
|
Icons.arrow_back_ios, |
|
color: Colors.white, |
|
size: 24, |
|
), |
|
), |
|
), |
|
flexibleSpace: FlexibleSpaceBar( |
|
background: Stack( |
|
children: [ |
|
Container( |
|
// padding: EdgeInsets.only(top: 40.h), |
|
height: 172.h, |
|
decoration: BoxDecoration( |
|
// border: Border.all(color: Colors.white,width: 0.5), |
|
color: Color(0xFF277D4B), |
|
shape: BoxShape.rectangle, |
|
borderRadius: BorderRadius.only( |
|
bottomRight: Radius.circular(40.r), |
|
bottomLeft: Radius.circular(40.r), |
|
), |
|
), |
|
), |
|
Container( |
|
alignment: Alignment.topCenter, |
|
margin: EdgeInsets.only(top: 110.h), |
|
child: pointUser(), |
|
), |
|
], |
|
)), |
|
expandedHeight: |
|
MediaQuery.of(context).size.height >= 750 ? 245.h : 258.h, |
|
bottom: PreferredSize( |
|
preferredSize: Size(double.infinity, 0), |
|
child: DefaultTabController( |
|
length: gooodsCategorys == null ? 0 : gooodsCategorys.length, |
|
child: Container( |
|
color: Colors.white, |
|
alignment: Alignment.centerLeft, |
|
child: TabBar( |
|
isScrollable: true, |
|
//可滚动 |
|
indicatorColor: Color(0xff39B54A), |
|
labelColor: Color(0xff32A060), |
|
dividerHeight: 0, |
|
tabAlignment:TabAlignment.start, |
|
labelStyle: TextStyle( |
|
fontSize: 14.sp, |
|
fontWeight: FontWeight.bold, |
|
), |
|
unselectedLabelStyle: TextStyle( |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.regular, |
|
), |
|
// controller: tabController, |
|
//未选中文字颜色 |
|
unselectedLabelColor: Color(0xff4D4D4D), |
|
indicatorSize: TabBarIndicatorSize.label, |
|
//指示器与文字等宽 |
|
tabs: gooodsCategorys |
|
?.map((e) => MyTab(text: "${e.name}")) |
|
.toList() ?? |
|
[], |
|
onTap: (index) { |
|
categoryId = gooodsCategorys[index].id; |
|
pageNum = 1; |
|
creditGoods(); |
|
}, |
|
), |
|
), |
|
), |
|
), |
|
), |
|
]; |
|
}, |
|
body: SmartRefresher( |
|
controller: refreshController, |
|
enablePullDown: true, |
|
enablePullUp: false, |
|
physics: ClampingScrollPhysics(), |
|
header: MyHeader(), |
|
footer: CustomFooter( |
|
builder: (context, mode) { |
|
return MyFooter(mode); |
|
}, |
|
), |
|
onRefresh: _onRefresh, |
|
child: Container( |
|
color: Colors.white, |
|
padding: EdgeInsets.only(top: 15.h), |
|
child: pointList(), |
|
)), |
|
), |
|
); |
|
} |
|
|
|
Widget pointUser() { |
|
return Container( |
|
decoration: BoxDecoration( |
|
color: Colors.white, |
|
borderRadius: BorderRadius.all(Radius.circular(4.r)), |
|
boxShadow: [ |
|
BoxShadow( |
|
color: Colors.black.withAlpha(12), |
|
offset: Offset(0, 1), |
|
blurRadius: 8, |
|
spreadRadius: 0, |
|
) |
|
]), |
|
margin: EdgeInsets.all(16), |
|
padding: EdgeInsets.all(16), |
|
child: Row( |
|
children: [ |
|
MImage( |
|
userInfo?.headimg ?? "", |
|
width: 50, |
|
height: 50, |
|
isCircle: true, |
|
fit: BoxFit.cover, |
|
errorSrc: "assets/image/default_user.webp", |
|
fadeSrc: "assets/image/default_user.webp", |
|
), |
|
Expanded( |
|
child: Container( |
|
margin: EdgeInsets.only(left: 12.w), |
|
height: 55.h, |
|
child: Column( |
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
userInfo == null |
|
? Text( |
|
S.of(context).denglu, |
|
style: TextStyle( |
|
fontSize: 16.sp, |
|
fontWeight: MyFontWeight.medium, |
|
color: Color(0xFF353535), |
|
), |
|
) |
|
: Text( |
|
userInfo?.nickname ?? "", |
|
style: TextStyle( |
|
fontSize: 16.sp, |
|
fontWeight: MyFontWeight.bold, |
|
color: Color(0xFF353535), |
|
), |
|
), |
|
SizedBox( |
|
height: 2.h, |
|
), |
|
userInfo == null |
|
? Text( |
|
S.of(context).weidengluxinxi, |
|
style: TextStyle( |
|
fontSize: 12.sp, |
|
fontWeight: MyFontWeight.regular, |
|
color: Color(0xFF353535), |
|
), |
|
) |
|
: Text( |
|
userInfo == null |
|
? "" |
|
: AppUtils.phoneEncode(userInfo?.phone ?? ""), |
|
style: TextStyle( |
|
fontSize: 12.sp, |
|
fontWeight: MyFontWeight.regular, |
|
color: Color(0xFF353535), |
|
), |
|
), |
|
], |
|
), |
|
), |
|
flex: 1, |
|
), |
|
userInfo == null |
|
? Icon( |
|
Icons.keyboard_arrow_right, |
|
size: 20, |
|
color: Colors.black, |
|
) |
|
: Container( |
|
margin: EdgeInsets.only(left: 15.w), |
|
height: 62.h, |
|
child: Column( |
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
Row( |
|
children: [ |
|
Text( |
|
"总积分", |
|
style: TextStyle( |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.medium, |
|
color: Color(0xFF4C4C4C), |
|
), |
|
), |
|
Padding( |
|
padding: EdgeInsets.only(left: 2.w), |
|
child: Text( |
|
"${userInfo?.points}" ?? "", |
|
style: TextStyle( |
|
fontSize: 16.sp, |
|
color: Color(0xFF32A060), |
|
fontFamily: 'JDZhengHT', |
|
fontWeight: MyFontWeight.medium, |
|
), |
|
), |
|
), |
|
SizedBox( |
|
width: 4.w, |
|
), |
|
Image.asset( |
|
"assets/image/icon_gold_coin.webp", |
|
width: 18, |
|
height: 18, |
|
), |
|
], |
|
), |
|
SizedBox( |
|
height: 4.h, |
|
), |
|
Row( |
|
children: [ |
|
Text( |
|
"总印章", |
|
style: TextStyle( |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.medium, |
|
color: Color(0xFF4C4C4C), |
|
), |
|
), |
|
Padding( |
|
padding: EdgeInsets.only(left: 2.w), |
|
child: Text( |
|
"${userInfo?.happyBean ?? 0}" ?? "", |
|
style: TextStyle( |
|
fontSize: 16.sp, |
|
color: Color(0xFF32A060), |
|
fontFamily: 'JDZhengHT', |
|
fontWeight: MyFontWeight.medium, |
|
), |
|
), |
|
), |
|
SizedBox( |
|
width: 4.w, |
|
), |
|
Image.asset( |
|
"assets/image/trading_logo.webp", |
|
width: 18, |
|
height: 18, |
|
), |
|
], |
|
), |
|
], |
|
), |
|
), |
|
], |
|
), |
|
); |
|
} |
|
|
|
Widget pointList() { |
|
return Container( |
|
child: (goods?.isEmpty ?? true) |
|
? NoDataView( |
|
src: "assets/image/xiao_fei.webp", |
|
isShowBtn: false, |
|
text: "当前分类暂无商品", |
|
fontSize: 16.sp, |
|
margin: EdgeInsets.only( |
|
top: 120.h, left: 60.w, right: 60.w, |
|
), |
|
) |
|
: GridView.builder( |
|
itemCount: goods?.length ?? 0, |
|
padding: EdgeInsets.only( |
|
left: 16.w, |
|
right: 16.w, |
|
top: 18.h, |
|
bottom: 16.h, |
|
), |
|
shrinkWrap: true, |
|
physics: BouncingScrollPhysics(), |
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( |
|
//一行的Widget数量 |
|
crossAxisCount: 2, |
|
//水平子Widget之间间距 |
|
crossAxisSpacing: 11.w, |
|
//垂直子Widget之间间距 |
|
mainAxisSpacing: 16.w, |
|
//子Widget宽高比例 0.59 |
|
childAspectRatio: 200 / (285 / 2 + (285 / 2) * AppUtils.textScale(context)), |
|
), |
|
itemBuilder: (context, index) { |
|
return GestureDetector( |
|
onTap: () { |
|
Navigator.of(context).pushNamed( |
|
'/router/integral_store_page', |
|
arguments: {"goodsId": goods[index].id}, |
|
); |
|
}, |
|
child: pointItem(goods[index]), |
|
); |
|
}, |
|
), |
|
); |
|
} |
|
|
|
Widget pointItem(Goods goods) { |
|
return Container( |
|
alignment: Alignment.center, |
|
decoration: BoxDecoration( |
|
color: Color(0xFFFFFFFF), |
|
borderRadius: BorderRadius.circular(4), |
|
boxShadow: [ |
|
BoxShadow( |
|
color: Colors.black.withAlpha(12), |
|
offset: Offset(0, 2), |
|
blurRadius: 4, |
|
spreadRadius: 0, |
|
), |
|
], |
|
), |
|
child: Stack( |
|
alignment: AlignmentDirectional.topEnd, |
|
fit: StackFit.loose, |
|
children: [ |
|
Column( |
|
mainAxisAlignment: MainAxisAlignment.start, |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
mainAxisSize: MainAxisSize.max, |
|
children: [ |
|
MImage( |
|
goods.mainImgPath ?? "", |
|
aspectRatio: 1.1, |
|
fit: BoxFit.cover, |
|
radius: BorderRadius.only( |
|
topLeft: Radius.circular(4), |
|
topRight: Radius.circular(4), |
|
), |
|
errorSrc: "assets/image/default_1.webp", |
|
fadeSrc: "assets/image/default_1.webp", |
|
), |
|
Expanded( |
|
child: Container( |
|
margin: EdgeInsets.only( |
|
right: 12.w, |
|
top: 10.h, |
|
), |
|
padding: EdgeInsets.only(bottom: 8.h, left: 8.w), |
|
child: Column( |
|
mainAxisAlignment: MainAxisAlignment.spaceAround, |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
Text( |
|
goods.name ?? "", |
|
overflow: TextOverflow.ellipsis, |
|
maxLines: 1, |
|
style: TextStyle( |
|
color: Color(0xFF0D0D0D), |
|
height: 1.2, |
|
fontWeight: MyFontWeight.regular, |
|
fontSize: 14.sp, |
|
), |
|
), |
|
Spacer(), |
|
Text( |
|
pointPrice(goods), |
|
overflow: TextOverflow.ellipsis, |
|
maxLines: 2, |
|
style: TextStyle( |
|
color: Color(0xFFE5600D), |
|
fontFamily: 'JDZhengHT', |
|
fontSize: 16.sp, |
|
fontWeight: MyFontWeight.semi_bold, |
|
), |
|
), |
|
], |
|
), |
|
), |
|
flex: 1, |
|
), |
|
], |
|
), |
|
], |
|
), |
|
); |
|
} |
|
|
|
String pointPrice(Goods goods) { |
|
if (goods.oneBean != "0") { |
|
return "${goods.oneBean}印章"; |
|
} else if (goods.onePrice != "0") { |
|
return S.of(context).jifen_("${goods.onePrice}"); |
|
} else if ((goods.onePrice == "0") && |
|
((goods.price != "0") || (goods.money != "0.00"))) { |
|
return (goods.price == "0" ? "" : S.of(context).jifen_("${goods.price}")) + |
|
(goods.money == "0" |
|
? "" |
|
: " + ${AppUtils.calculateDouble(double.tryParse("${goods.money}") ?? 0)}元"); |
|
} else if (goods.oneMoney != "0.00") { |
|
return "${AppUtils.calculateDouble(double.tryParse("${goods.oneMoney}") ?? 0)}元"; |
|
} |
|
return ""; |
|
} |
|
|
|
@override |
|
bool get wantKeepAlive => true; |
|
}
|
|
|