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.
 
 
 
 
 
 

585 lines
20 KiB

import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:huixiang/generated/l10n.dart';
import 'package:huixiang/retrofit/data/base_data.dart';
import 'package:huixiang/retrofit/data/goods.dart';
import 'package:huixiang/retrofit/data/goods_category.dart';
import 'package:huixiang/retrofit/data/page.dart';
import 'package:huixiang/retrofit/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 ScrollController scrollController = ScrollController();
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;
var _itemText = S.current.morenpaixu;
List<String> sortString = [
S.current.morenpaixu,
S.current.jifengaodaodi,
S.current.jifendidaogao,
];
@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")),
creditGoods(),
});
}
queryUser() async {
BaseData<UserInfo> baseData =
await apiService.queryInfo().catchError((onError) {});
if (baseData != null && baseData.isSuccess) {
userInfo = baseData.data;
setState(() {});
SharedPreferences.getInstance().then((value) => {
value.setString('user', jsonEncode(baseData.data)),
});
}
}
creditGoods() async {
// EasyLoading.show(status: S.current.zhengzaijiazai);
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": 10,
"state": 1
}).catchError((onError) {
refreshController.refreshFailed();
});
if (goodsData != null && goodsData.isSuccess) {
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 != null &&
dataCategory.isSuccess &&
dataCategory.data != null &&
dataCategory.data.records != null &&
dataCategory.data.records.length > 0) {
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": 10,
"state": 1
};
BaseData<PageInfo<Goods>> pageGoods =
await apiService.creditGoods(param).catchError((onError) {
refreshController.loadFailed();
refreshController.refreshFailed();
});
EasyLoading.dismiss();
if (pageGoods != null && pageGoods.isSuccess) {
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();
}
setState(() {});
}
_onRefresh() {
creditGoods();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: NestedScrollView(
headerSliverBuilder: (context, inner) {
return [
SliverAppBar(
pinned: true,
backgroundColor: Colors.white,
elevation: 0,
title: Text(
"福利兑换",
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: 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),
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 == null
? []
: gooodsCategorys
.map((e) => MyTab(text: e.name))
.toList(),
onTap: (index) {
categoryId = gooodsCategorys[index].id;
pageNum = 1;
creditGoods();
setState(() {});
},
),
),
),
),
),
];
},
body: SmartRefresher(
controller: refreshController,
enablePullDown: true,
enablePullUp: true,
physics: ClampingScrollPhysics(),
header: MyHeader(),
footer: CustomFooter(
builder: (context, mode) {
return MyFooter(mode);
},
),
onRefresh: _onRefresh,
child: Container(
color: Colors.white,
padding: EdgeInsets.only(top: 19.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 != null ? 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: 50.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.medium,
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: 50.h,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
GestureDetector(
onTap: () {
Navigator.of(context)
.pushNamed('/router/integral_detailed_page');
},
child: Row(
children: [
Text(
"积分明细",
style: TextStyle(
fontSize: 14.sp,
fontWeight: MyFontWeight.medium,
color: Color(0xFF4C4C4C),
),
),
Container(
width: 20,
height: 20,
margin: EdgeInsets.only(left: 4),
decoration: BoxDecoration(
color: Color(0xFF32A060),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
Icons.keyboard_arrow_right,
size: 20,
color: Colors.white,
),
),
],
),
),
SizedBox(
height: 4.h,
),
Expanded(child: Row(
children: [
Text(
(userInfo != null) ? "${userInfo.points}" : "",
style: TextStyle(
fontSize: 16.sp,
color: Color(0xFF32A060),
fontWeight: MyFontWeight.medium,
),
),
SizedBox(
width: 6.w,
),
Image.asset(
"assets/image/icon_gold_coin.webp",
width: 18,
height: 18,
)
],
))
],
),
)
],
),
);
}
Widget pointList() {
return Container(
child: (goods == null || goods.length == 0)
? 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 == null ? 0 : goods.length,
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),
fontSize: 16.sp,
fontWeight: MyFontWeight.semi_bold,
),
),
],
),
),
flex: 1,
),
],
),
],
),
);
}
String pointPrice(Goods goods) {
if (goods == null) return "";
if (goods?.onePrice != null && goods?.onePrice != "0") {
return S.of(context).jifen_(goods?.onePrice);
} else if ((goods?.onePrice == null || goods?.onePrice == "0") &&
((goods?.price != null && goods?.price != "0") ||
(goods?.money != null && goods?.money != "0.00"))) {
return (goods?.price == "0" || goods?.price == null
? ""
: S.of(context).jifen_(goods?.price)) +
(goods?.money == "0" || goods?.money == null
? ""
: " + ${AppUtils.calculateDouble(double.tryParse(goods?.money) ?? 0)}");
} else if (goods.oneMoney != null && goods.oneMoney != "0.00") {
return "${AppUtils.calculateDouble(double.tryParse(goods.oneMoney) ?? 0)}";
}
}
@override
bool get wantKeepAlive => true;
}