import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/my_appbar.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:intl/intl.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:shimmer/shimmer.dart'; import '../../generated/l10n.dart'; import '../../retrofit/business_api.dart'; import '../../retrofit/data/balance_consumption_ranking_list.dart'; import '../../retrofit/data/base_data.dart'; import '../../retrofit/data/store_total_money_info.dart'; import '../../utils/business_instance.dart'; import '../../utils/flutter_utils.dart'; import '../../view_widget/classic_header.dart'; import '../../view_widget/my_footer.dart'; import '../../view_widget/no_data_view.dart'; class ConsumerRankingPage extends StatefulWidget { final Map arguments; ConsumerRankingPage({this.arguments}); @override State createState() { return _ConsumerRankingPage(); } } class _ConsumerRankingPage extends State { String titleName; String selectTimeDate = ""; String selectTimeDateNum = "${DateFormat("yyyy-MM-dd HH:mm:ss").format(DateTime.now().subtract(Duration(days: 2)))} 至 " "${DateFormat("yyyy-MM-dd HH:mm:ss").format(DateTime.now())}"; final TextEditingController editingController = TextEditingController(); FocusNode _focusNode = FocusNode(); bool isKeyBoardShow = false; final RefreshController refreshController = RefreshController(); BusinessApiService businessService; String networkError = ""; int networkStatus = 0; List records = []; StoreTotalMoneyInfo storeTotalMoneyInfo; int _pageNum = 1; String total = "0"; int _loadCount = 0; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { setState(() { print("object: ${MediaQuery.of(context).viewInsets.bottom}"); if (MediaQuery.of(context).viewInsets.bottom == 0) { if (isKeyBoardShow) { isKeyBoardShow = false; //关闭键盘 软键盘关闭了, 清除输入控件的焦点, 否则重新进入页面会导致软键盘再弹出问题 FocusScope.of(context).requestFocus(FocusNode()); } } else { isKeyBoardShow = true; } }); }); titleName = widget?.arguments["titleName"] ?? ""; _onRefresh(); } ///离开页面记着销毁和清除 @override void dispose() { super.dispose(); refreshController.dispose(); _focusNode.unfocus(); } _onRefresh({bool isShowLoad = true}) async { if (isShowLoad) EasyLoading.show( status: S.current.zhengzaijiazai, maskType: EasyLoadingMaskType.black); queryStoreMoney(isRefresh:false); queryStoreTotalMoney(); } addLoadCount() { _loadCount += 1; if (_loadCount == 2) { _loadCount = 0; EasyLoading.dismiss(); if (refreshController.isRefresh) refreshController.refreshCompleted(); if (mounted) setState(() {}); } } ///查询会员余额统计/消费排名 queryStoreMoney({keyword,isRefresh = true}) async { try { if (isRefresh) EasyLoading.show( status: S.current.zhengzaijiazai, maskType: EasyLoadingMaskType.black); if (businessService == null) { businessService = BusinessApiService(Dio(), context: context, token: BusinessInstance.instance.businessToken, tenant: BusinessInstance.instance.businessTenant, storeId: widget.arguments["storeId"]); } BaseData baseData = await businessService.storeMoney({ "startTime": titleName == "消费排名" ? (selectTimeDate != ""?selectTimeDate.replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "").substring(0,19):selectTimeDateNum.substring(0,19)):"", "endTime": titleName == "消费排名" ? (selectTimeDate!=""?selectTimeDate.replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "").substring(22,41):selectTimeDateNum.substring(24,43)):"", "keyword": titleName == "消费排名" ? "" : (keyword ?? ""), "type":titleName == "消费排名" ? 1:0, "pageNum": _pageNum, "pageSize": 10, }).catchError((error) { networkError = AppUtils.dioErrorTypeToString(error.type); networkStatus = -1; setState(() {}); refreshController.refreshFailed(); refreshController.loadFailed(); }); if (!mounted) return; if (baseData != null && baseData.isSuccess) { records.addAll(baseData?.data?.records ?? []); if ((baseData?.data?.records ?? []).isEmpty || records.length.toString() == baseData.data.pages) refreshController.loadNoData(); else refreshController.loadComplete(); networkStatus = 1; } } finally { if(isRefresh){ setState(() {}); EasyLoading.dismiss(); }else addLoadCount(); } } ///会员余额统计(总会员数,总余额数)查询/消费排名(消费会员数量,销售金额)查询 queryStoreTotalMoney({keyword}) async { try { if (businessService == null) { businessService = BusinessApiService(Dio(), context: context, token: BusinessInstance.instance.businessToken, tenant: BusinessInstance.instance.businessTenant, storeId: widget.arguments["storeId"]); } BaseData baseData = await businessService.storeTotalMoney({ "startTime": titleName == "消费排名" ? selectTimeDateNum.substring(0,19):"", "endTime": titleName == "消费排名" ? selectTimeDateNum.substring(24,43):"", }).catchError((error) { networkError = AppUtils.dioErrorTypeToString(error.type); networkStatus = -1; setState(() {}); refreshController.refreshFailed(); refreshController.loadFailed(); }); if (!mounted) return; if (baseData != null && baseData.isSuccess) { storeTotalMoneyInfo = baseData.data; networkStatus = 1; } } finally { addLoadCount(); } } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, appBar: MyAppBar( title: titleName, titleColor: Colors.black, background: Colors.white, leadingColor: Colors.black, brightness: Brightness.dark, ), body: networkStatus == -1 ? noNetwork() : Container( child: SmartRefresher( controller: refreshController, enablePullDown: true, enablePullUp: records.length == 0 ? false : true, header: MyHeader( color: Color(0xFF30415B), ), footer: CustomFooter( builder: (context, mode) { return MyFooter(mode); }, ), onRefresh: () { _pageNum = 1; records.clear(); _onRefresh(isShowLoad: false); }, onLoading: () { _pageNum++; queryStoreMoney(); }, physics: BouncingScrollPhysics(), scrollController: ScrollController(), child: Column( children: [ Container( width: double.infinity, padding: EdgeInsets.only(bottom: 16.h), decoration: BoxDecoration( color: Colors.white, ), child: Column( children: [ titleName == "消费排名" ? timeSelect() : vipBalanceStatisticsSearch(), titleName == "消费排名" ? Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: Column( children: [ Padding( padding: EdgeInsets.only(bottom: 15.h), child: Text( "消费会员数量", style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, color: Color(0xFF0D0D0D), ), ), ), Text( (storeTotalMoneyInfo?.paySumCount ?? 0).toString(), style: TextStyle( fontSize: 14.sp, fontWeight: MyFontWeight.bold, color: Color(0xFF0D0D0D), ), ), ], )), Expanded( child: Column( children: [ Padding( padding: EdgeInsets.only(bottom: 15.h), child: Text( "销售金额", style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, color: Color(0xFF0D0D0D), ), ), ), Text( storeTotalMoneyInfo?.storeTotalMoney ?? "0", style: TextStyle( fontSize: 14.sp, fontWeight: MyFontWeight.bold, color: Color(0xFF0D0D0D), ), ), ], )), ], ) : Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: Column( children: [ Padding( padding: EdgeInsets.only(bottom: 15.h), child: Text( "总会员数", style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, color: Color(0xFF0D0D0D), ), ), ), Text( (storeTotalMoneyInfo?.memberCount ?? 0).toString(), style: TextStyle( fontSize: 14.sp, fontWeight: MyFontWeight.bold, color: Color(0xFF0D0D0D), ), ), ], )), Expanded( child: Column( children: [ Padding( padding: EdgeInsets.only(bottom: 15.h), child: Text( "总余额数", style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, color: Color(0xFF0D0D0D), ), ), ), Text( storeTotalMoneyInfo?.memberTotalBalance ?? "0", style: TextStyle( fontSize: 14.sp, fontWeight: MyFontWeight.bold, color: Color(0xFF0D0D0D), ), ), ], )), ], ) ], ), ), Expanded(child: networkStatus == 0 ? Container( margin: EdgeInsets.only(bottom: 35.h,top:6.h), child: ListView.builder( itemCount: 10, physics: BouncingScrollPhysics(), shrinkWrap: true, itemBuilder: (context, position) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () {}, child: consumerRankingItemSm(), ); }, )) : ((records == null || records.length == 0) ? NoDataView( src: "assets/image/bs_no data_logo.webp", isShowBtn: false, text: "暂无相关数据", fontSize: 16.sp, margin: EdgeInsets.all(20.h), ) : Container( margin: EdgeInsets.only(bottom: 35.h,top:6.h), child: ListView.builder( itemCount: records?.length ?? 0, physics: BouncingScrollPhysics(), shrinkWrap: true, itemBuilder: (context, position) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () {}, child: consumerRankingItem( records[position]), ); }, ), )),) ], ), ), ), ); } ///时间选择 Widget timeSelect() { return Container( color: Colors.white, child: GestureDetector( onTap: () { Navigator.of(context).pushNamed('/router/custom_page', arguments: {"beyondDateRange": "0"}).then((value) { selectTimeDate = value; queryStoreMoney(); }); }, child: Container( decoration: BoxDecoration( color: Color(0xFFF7F8FA), borderRadius: BorderRadius.circular(2), ), margin: EdgeInsets.only(left: 18.w, right: 18.w, top: 11.h, bottom: 17.h), padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 12.h), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( (selectTimeDate == "" || selectTimeDate == null) ? "${selectTimeDateNum.substring(0,16)} 至 ${selectTimeDateNum.substring(24,40)}" : "${selectTimeDate.replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "").substring(0,16)} 至" " ${selectTimeDate.replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "").substring(22,38)} ", style: TextStyle( fontSize: 14.sp, color: Color(0xFF30415B), fontWeight: MyFontWeight.regular), ), ], ), ), ), ); } /// 搜索框 Widget vipBalanceStatisticsSearch() { return Container( color: Colors.white, child: Container( height: 40.h, margin: EdgeInsets.only(left: 18.w, right: 18.w, top: 12.h, bottom: 12.h), decoration: BoxDecoration( color: Color(0xFFF7F8FA), borderRadius: BorderRadius.circular(2), ), child: TextField( focusNode: _focusNode, textInputAction: TextInputAction.search, onEditingComplete: () { FocusScope.of(context).requestFocus(FocusNode()); records.clear(); queryStoreMoney(keyword: editingController?.text ?? ""); }, style: TextStyle( fontSize: 15.sp, fontWeight: MyFontWeight.regular, color: Color(0xFF808080), ), controller: editingController, decoration: InputDecoration( hintText: "会员手机号或姓名", hintStyle: TextStyle( color: Color(0xFF808080), fontSize: 15.sp, fontWeight: MyFontWeight.regular), contentPadding: EdgeInsets.symmetric( vertical: 12.h, ), prefixIcon: Image.asset( "assets/image/bs_goods_search.webp", width: 20, height: 20, ), border: InputBorder.none, ), ), ), ); } ///消费排行list Widget consumerRankingItem(Records records) { return Container( padding: EdgeInsets.only(top: 12.h, bottom: 12.h, left: 16.w), margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 6.h), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Color(0x0F06152E), offset: Offset(0, 2), blurRadius: 4, spreadRadius: 0, ) ], borderRadius: BorderRadius.circular(8), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.only(bottom: 16.h), child: Text( "${records?.name ?? ""}(${records?.phone})", style: TextStyle( fontSize: 14.sp, fontWeight: MyFontWeight.bold, color: Color(0xFF0D0D0D), ), ), ), Text.rich( TextSpan( children: [ TextSpan( text: "消费:", style: TextStyle( color: Color(0xFF666666), fontSize: 14.sp, fontWeight: MyFontWeight.regular, ), ), TextSpan( text: "¥${records?.money ?? ""}", style: TextStyle( color: Color(0xFFFA5151), fontSize: 14.sp, fontWeight: MyFontWeight.medium, ), ), ], ), ), ], ), ); } Widget consumerRankingItemSm() { return Container( padding: EdgeInsets.only(top: 12.h, bottom: 12.h, left: 16.w), margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 6.h), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Color(0x0F06152E), offset: Offset(0, 2), blurRadius: 4, spreadRadius: 0, ) ], borderRadius: BorderRadius.circular(8), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( margin: EdgeInsets.only(bottom: 16.h), decoration: BoxDecoration( color: Color(0XFFD8D8D8), borderRadius: BorderRadius.circular(2), ), width: 149.w, height: 20.h, ), ), Row( children: [ Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( margin: EdgeInsets.only(right:10.w), decoration: BoxDecoration( color: Color(0XFFD8D8D8), borderRadius: BorderRadius.circular(2), ), width: 42.w, height: 20.h, ), ), Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( decoration: BoxDecoration( color: Color(0XFFD8D8D8), borderRadius: BorderRadius.circular(2), ), width: 60.w, height: 20.h, ), ), ], ) ], ), ); } Widget noNetwork() { return Container( color: Colors.white, width: double.infinity, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( networkError.substring(0, networkError.indexOf(",")), style: TextStyle( fontSize: 14.sp, color: Color(0xFF0D0D0D), fontWeight: MyFontWeight.bold), ), Padding( padding: EdgeInsets.symmetric(vertical: 10.h), child: Text( "请检查网络设置或稍后重试", style: TextStyle( fontSize: 12.sp, color: Color(0xFF7A797F), fontWeight: MyFontWeight.regular), ), ), GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { _onRefresh(); }, child: Container( decoration: BoxDecoration( color: Color(0xFF30415B), borderRadius: BorderRadius.circular(15), ), padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 3.h), child: Text( "重试", style: TextStyle( fontSize: 14.sp, color: Colors.white, fontWeight: MyFontWeight.regular), )), ) ], ), ); } }