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.
 
 
 
 
 
 

607 lines
21 KiB

import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:huixiang/constant.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/generated/l10n.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/utils/shared_preference.dart';
import 'package:huixiang/view_widget/classic_header.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';
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();
apiService = ApiService(Dio(),
context: context,
token: SharedInstance.instance.token,
showLoading: false);
creditGoods();
}
queryUser() async {
BaseData<UserInfo>? baseData = await apiService?.queryInfo().catchError((onError) {
return BaseData<UserInfo>()..isSuccess = false;
});
if ((baseData?.isSuccess ?? false) && baseData!.data != null) {
userInfo = baseData.data;
SharedInstance.instance.saveUser(baseData.data!);
}
}
creditGoods({bool isLoading = true}) async {
try {
if (isLoading)
S.current.zhengzaijiazai.loading;
apiService = ApiService(Dio(),
context: context,
token: SharedInstance.instance.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();
return BaseData<PageInfo<Goods>>()..isSuccess = false;
});
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();
return BaseData<PageInfo<GoodsCategory>>()..isSuccess = false;
});
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();
return BaseData<PageInfo<Goods>>()..isSuccess = false;
});
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 {
setState(() {});
}
}
_onRefresh() {
creditGoods(isLoading: false);
}
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
backgroundColor: Colors.white,
body: NestedScrollView(
headerSliverBuilder: (context, inner) {
return [
SliverAppBar(
pinned: true,
backgroundColor: Color(0xFF277D4B),
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,
),
),
),
toolbarHeight: kToolbarHeight,
collapsedHeight: kToolbarHeight + MediaQuery.of(context).padding.top,
flexibleSpace: FlexibleSpaceBar(
background: Stack(
children: [
Positioned.fill(
top: kToolbarHeight + MediaQuery.of(context).padding.top,
child: Container(
// padding: EdgeInsets.only(top: 40.h),
height: 172.h - (kToolbarHeight + MediaQuery.of(context).padding.top),
decoration: BoxDecoration(
color: Colors.white,
),
padding: EdgeInsets.only(bottom: 75.h),
child: Container(
decoration: BoxDecoration(
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.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,
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)
? 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,
padding: EdgeInsets.only(
left: 12.w,
right: 12.w,
top: 16.h,
bottom: 16.h,
),
shrinkWrap: true,
physics: BouncingScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//一行的Widget数量
crossAxisCount: 2,
//水平子Widget之间间距
crossAxisSpacing: 12.w,
//垂直子Widget之间间距
mainAxisSpacing: 12.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;
}