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

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;
}