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/generated/l10n.dart'; import 'package:huixiang/order/order_utils.dart'; import 'package:huixiang/order/order_view/order_pay_selected.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:huixiang/retrofit/data/order_info.dart'; import 'package:huixiang/retrofit/data/order_product_vo.dart'; import 'package:huixiang/retrofit/data/page.dart'; import 'package:huixiang/retrofit/min_api.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/store/scan.dart'; import 'package:huixiang/utils/status_utils.dart'; import 'package:huixiang/view_widget/classic_header.dart'; import 'package:huixiang/view_widget/custom_image.dart'; import 'package:huixiang/view_widget/my_appbar.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:huixiang/view_widget/tips_dialog.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:shimmer/shimmer.dart'; import '../retrofit/data/user_info.dart'; class OrderHistoryPage extends StatefulWidget { final Map arguments; OrderHistoryPage({this.arguments}); @override State createState() { return _OrderHistoryPage(); } } class _OrderHistoryPage extends State with SingleTickerProviderStateMixin { List _pages; TabController tabController; @override void didChangeDependencies() { super.didChangeDependencies(); if (tabController == null) tabController = TabController( initialIndex: widget.arguments["status"], length: 4, vsync: this); _pages = [ OrderHistoryList(0), OrderHistoryList(1), OrderHistoryList(2), OrderHistoryList(3) ]; } @override Widget build(BuildContext context) { return DefaultTabController( length: 4, child: Scaffold( appBar: MyAppBar( title: S.of(context).dingdan, titleColor: Colors.black, titleSize: 18.sp, background: Color(0xFFFFFFFF), leadingColor: Colors.black, toolbarHeight: kToolbarHeight + MediaQuery.of(context).padding.top, bottom: PreferredSize( preferredSize: Size(double.infinity, 38.h), child: Theme( data: ThemeData( splashColor: Colors.transparent, // 点击时的水波纹颜色设置为透明 highlightColor: Colors.transparent, // 点击时的背景高亮颜色设置为透明 ), child: TabBar( controller: tabController, isScrollable: false, indicatorWeight: 2.w, indicatorSize: TabBarIndicatorSize.label, indicatorColor: Color(0xFF39B54A), indicatorPadding: EdgeInsets.only(top: 3.h), unselectedLabelStyle: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.normal, ), labelStyle: TextStyle( color: Colors.black, fontSize: 16.sp, fontWeight: FontWeight.bold, ), labelColor: Colors.black, tabs: [ MyTab( text: S.of(context).quanbu, ), MyTab( text: S.of(context).daifukuan, ), MyTab( text: S.of(context).weiwancheng, ), MyTab( text: S.of(context).yiwancheng, ) ], )), ), ), body: TabBarView( children: _pages, controller: tabController, ), ), ); } } class OrderHistoryList extends StatefulWidget { final int orderStatus; OrderHistoryList(this.orderStatus); @override State createState() { return _OrderHistoryList(); } } class _OrderHistoryList extends State with AutomaticKeepAliveClientMixin { final RefreshController refreshController = RefreshController(); bool isRemake = true; ApiService apiService; int current = 1; List orderInfos = []; UserInfo userInfo; int networkStatus = 0; @override void initState() { super.initState(); SharedPreferences.getInstance().then((value) => { apiService = ApiService(Dio(), // showLoading: true, context: context, token: value.getString("token")), queryOrder(), queryUserBalance(), }); } _onRefresh() { current = 1; queryOrder(); } queryOrder({bool isLoading = true}) async { try{ if(isLoading) EasyLoading.show(status: S.current.zhengzaijiazai,maskType: EasyLoadingMaskType.black); BaseData> baseData = await apiService.orderList({ "current": current, "model": {"status": widget.orderStatus}, "order": "descending", "size": 10, "sort": "id" }).catchError((onError) { networkStatus = -1; refreshController.refreshFailed(); refreshController.loadFailed(); }); if (baseData != null && baseData.isSuccess) { if (current == 1) { orderInfos.clear(); } orderInfos.addAll(baseData.data.records); // baseData.data.records.forEach((element) { // if(element.orderType==0||(element.orderType==1 && element.payStatus==1 && element.refundStatus == 0)||(element.orderType==2 && element.payStatus==1&& element.refundStatus == 0)||(element.orderType==3 && element.payStatus==1&& element.refundStatus == 0)) // orderInfos.add(element); // }); refreshController.refreshCompleted(); refreshController.loadComplete(); if (current * 10 > int.tryParse(baseData.data.total)) { refreshController.loadNoData(); } else { current += 1; } setState(() {}); networkStatus = 1; } else { if((baseData?.msg ?? "") != "") SmartDialog.showToast(baseData.msg,alignment: Alignment.center); refreshController.refreshFailed(); refreshController.loadFailed(); }}finally{ EasyLoading.dismiss(); } } minLogin(OrderInfo orderInfo) { apiService.minLogin(orderInfo.storeId).catchError((onError) { debugPrint(onError); }).then((baseData) { if (baseData != null && baseData.isSuccess) { Map minStoreInfo = baseData.data; String minToken = minStoreInfo["token"]; String tenant = orderInfo.tenantCode; String storeId = orderInfo.storeId; SharedPreferences.getInstance().then( (value) => { value.setString('minToken', minToken), value.setString('tenant', tenant), value.setString('storeId', storeId), }, ); paySelected( orderInfo, MinApiService( Dio(), context: context, token: minToken, tenant: tenant, storeId: storeId, )); } }); } queryDetails(id) async { if (apiService == null) { SharedPreferences value = await SharedPreferences.getInstance(); apiService = ApiService(Dio(), context: context, token: value.getString("token"), showLoading: true); } BaseData baseData = await apiService.orderDetail(id).catchError((error) {}); if (baseData != null && baseData.isSuccess) { return baseData.data; } } queryUserBalance() async { BaseData baseData = await apiService.queryInfo().catchError((onError) { }); if (baseData != null && baseData.isSuccess) { userInfo = baseData.data; if (mounted) setState(() {}); }else { SmartDialog.showToast(baseData.msg, alignment: Alignment.center); } } paySelected(OrderInfo orderInfo, MinApiService minService) async { var payChannel = await showModalBottomSheet( context: context, backgroundColor: Colors.transparent, builder: (context) { return OrderPaySelected(userInfo); }, ); if (payChannel != null && payChannel > 0) { orderInfo = await queryDetails(orderInfo.id); OrderUtils.carryOnPay( payChannel, minService, orderInfo, (BaseData baseData) { SmartDialog.showToast( baseData?.msg == "ok" ? "订单支付成功" : baseData?.msg, alignment: Alignment.center); Future.delayed(Duration(seconds: 3), () { _onRefresh(); }); }, ); } } payResult(BaseData baseData) {} orderCancel(String orderId) async { BaseData baseData = await apiService.orderCancel(orderId).catchError((onError) {}); if (baseData != null && baseData.isSuccess) { SmartDialog.showToast("订单取消成功"); _onRefresh(); }else{ if(baseData.msg != null) SmartDialog.showToast(baseData.msg,alignment: Alignment.center); } } aginOrder(OrderInfo orderInfo) { // Navigator.of(context).pushNamed( // '/router/union_detail_page', // arguments: {"id": storeId}, // ); // String storeId = (orderInfo != null && // orderInfo.storeVO != null) // ? (orderInfo.storeVO.id ?? "") // : ""; if (orderInfo.storeVO.posType.code == "NORMALSTORE") { Scan.toScan( context, orderInfo.storeVO.id, orderInfo.tenantCode, orderInfo.storeVO.storeName, ); } else { Navigator.of(context).pushNamed( '/router/store_order', arguments: { "id": orderInfo.storeVO.id, "tenant": orderInfo.tenantCode, "storeName": orderInfo.storeVO.storeName }, ); } } @override Widget build(BuildContext context) { super.build(context); return SmartRefresher( controller: refreshController, enablePullDown: true, enablePullUp: true, physics: BouncingScrollPhysics(), header: MyHeader(), footer: CustomFooter( builder: (context, mode) { return MyFooter(mode); }, ), onRefresh: _onRefresh, onLoading: (){ queryOrder(isLoading: false); }, child: networkStatus == 0 ? ListView.builder( itemCount: 10, physics: BouncingScrollPhysics(), shrinkWrap: true, itemBuilder: (context, position) { return orderItemSm(); }, ) : ((orderInfos != null && orderInfos.length > 0) ? ListView.builder( itemCount: orderInfos != null ? orderInfos.length : 0, itemBuilder: (context, position) { return InkWell( onTap: () { Navigator.of(context).pushNamed('/router/order_details', arguments: {"id": orderInfos[position].id,"jumpState":2}); }, child: orderItem(orderInfos[position]), ); }) : NoDataView( src: "assets/image/ding_dan.webp", isShowBtn: false, text: "目前暂无订单,快去下一单吧~", fontSize: 16.sp, margin: EdgeInsets.only(top: 120), )), ); } String orderAllGoods(OrderInfo orderInfo) { int count = 0; if (orderInfo.productList != null) { orderInfo.productList.forEach((element) { count += element.buyNum; }); } return count.toString(); } Widget orderItem(OrderInfo orderInfo) { return Container( margin: EdgeInsets.fromLTRB(16.w, 8.h, 16.w, 8.h), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4), boxShadow: [ BoxShadow( color: Colors.black.withAlpha(25), offset: Offset(0, 1), blurRadius: 12, spreadRadius: 0, ), ], ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ // (orderInfo != null && orderInfo.orderType == 0) // ? Container() // : Container( // width: 19, // height: 21, // margin: EdgeInsets.only(left: 12.w, top: 12.h), // alignment: Alignment.center, // decoration: BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.circular(2), // border: Border.all( // width: 1, // color: Color(0xFF32A060), // style: BorderStyle.solid, // )), // child: Text( // (orderInfo != null && orderInfo.orderType == 1) // ? "团" // : ((orderInfo != null && orderInfo.orderType == 2) // ? "秒" // : "砍"), // style: TextStyle( // fontSize: 12.sp, // fontWeight: FontWeight.bold, // color: Color(0xFF32A060), // ), // ), // ), // Container( // width: 19, // height: 21, // margin: EdgeInsets.only(left: 7.w, top: 12.h), // alignment: Alignment.center, // decoration: BoxDecoration( // color: Color(0xff32A060), // borderRadius: BorderRadius.circular(2), // ), // child: Text( // (orderInfo != null && orderInfo.isTakeOut == 0) // ? "自" // : ((orderInfo != null && orderInfo.isTakeOut == 1) // ? "外" // : "物"), // style: TextStyle( // fontSize: 12.sp, // fontWeight: FontWeight.bold, // color: Colors.white, // ), // ), // ), Expanded( child: Container( width: double.infinity, margin: EdgeInsets.only(left:12.w, top: 12.h), alignment: Alignment.centerLeft, child: Text( (orderInfo != null) ? orderInfo.storeName : "", style: TextStyle( fontWeight: FontWeight.bold, fontSize: 14.sp, color: Color(0xFF353535), ), ), ), flex: 1, ), Padding( padding: EdgeInsets.only(top: 12.h, right: 12.w), child: Text( (orderInfo != null && orderInfo.storeVO != null && orderInfo.storeVO.posType != null) ? StatusUtils.statusText( context, orderInfo.refundStatus, orderInfo.orderStatus, orderInfo.payStatus, orderInfo.sendStatus, orderInfo.isTakeOut) : "", style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.bold, color: (orderInfo == null) ? Color(0xFF32A060) : (orderInfo.refundStatus == 1 || orderInfo.orderStatus == -1 || orderInfo.orderStatus >= 5) ? Colors.grey : (orderInfo.orderStatus == 4) ? Color(0xFF32A060) : Color(0xffFE951E), ), ), ), ], ), Container( margin: EdgeInsets.only(left: 12.w,top:3.h), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( S.of(context).xiadanshijian_( (orderInfo != null) ? orderInfo.createTime : ""), style: TextStyle( fontSize: 10.sp, color: Color(0xFF727272), ), ), SizedBox( height: 8.h, ), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: goodsItem((orderInfo != null && orderInfo.productList != null) ? orderInfo.productList : null), ), flex: 1, ), Padding( padding: EdgeInsets.all(22.w), child: Image.asset( "assets/image/icon_order_more.webp", width: 24, height: 24, ), ) ], ), ], ), ), SizedBox( height: 12.h, ), Container( margin: EdgeInsets.only(right: 12.w, bottom: 12.h), child: Directionality( textDirection: TextDirection.rtl, child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text.rich( TextSpan( children: [ TextSpan( text: S.of(context).gong, style: TextStyle( fontSize: 12.sp, color: Color(0xFF868686), ), ), TextSpan( text: orderAllGoods(orderInfo), style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.bold, color: Colors.black, ), ), TextSpan( text: S.of(context).jian, style: TextStyle( fontSize: 12.sp, color: Color(0xFF868686), ), ), ], ), ), SizedBox( width: 4.w, ), Text.rich( TextSpan( children: [ TextSpan( text: S.of(context).heji, style: TextStyle( fontSize: 12.sp, color: Color(0xFF868686), ), ), TextSpan( // text: totalPrice(orderInfo), text: orderInfo.finalPayPrice, style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.bold, color: Colors.black, ), ), TextSpan( text: S.of(context).yuan, style: TextStyle( fontSize: 12.sp, color: Color(0xFF868686), ), ), ], ), ), ], ), SizedBox( height: 8.h, ), Row( children: (orderInfo != null) ? StatusUtils.statusBtn( context, orderInfo.payStatus, orderInfo.orderStatus, orderInfo.isTakeOut, orderInfo.sendStatus, orderInfo.refundStatus, orderInfo.dayFlowCode, (type) { if (type == 0) { aginOrder(orderInfo); } else if (type == 1) { SmartDialog.show( widget: Tips( () { SmartDialog.dismiss(); }, text: "暂不支持此功能", )); } else if (type == 2) { orderCancel(orderInfo.id); } else if (type == 3) { minLogin(orderInfo); } else if (type == 4) { Navigator.of(context).pushNamed( '/router/logistics_information_page', arguments: { "logisticsNum": orderInfo.logisticsNum, "logisticsName": orderInfo.logisticsName, "shipperCode": orderInfo.shipperCode, "productNum": orderInfo.productList.length, "skuImg": orderInfo.productList.length > 0 ? orderInfo.productList[0].skuImg : "" }); } }) : [], ), ], ), ), ), ], ), ); } String totalPrice(orderInfo) { if (orderInfo == null) return ""; double totalPrice = (double.tryParse(orderInfo.orderSum) + double.tryParse(orderInfo.postFee)); if (orderInfo.orderDetail != null && orderInfo.orderDetail.couponDTO != null) { totalPrice -= double.tryParse(orderInfo.orderDetail.couponDTO.money); } return "$totalPrice"; } List goodsItem(List products) { if (products == null) return []; if (products.length > 3) { products = products.sublist(0, 3); } return products .map( (e) => Container( margin: EdgeInsets.symmetric(horizontal: 2.w), child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: [ MImage( e.skuImg, width: 75.w, height: 75.w, fit: BoxFit.cover, errorSrc: "assets/image/default_1.webp", fadeSrc: "assets/image/default_1.webp", ), SizedBox( height: 4.h, ), if (isRemake) Container( width: 75.w, child: Text( e.productName, maxLines: 1, textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 10.sp, color: Color(0xFF353535), ), ), ), ], ), ), ) .toList(); } Widget orderItemSm() { return Container( margin: EdgeInsets.fromLTRB(16.w, 8.h, 16.w, 8.h), padding: EdgeInsets.only(top: 12,bottom: 13.h,left: 13.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4), boxShadow: [ BoxShadow( color: Colors.black.withAlpha(25), offset: Offset(0, 1), blurRadius: 12, spreadRadius: 0, ), ], ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width:213.w, height: 20.h, ), ), Padding( padding: EdgeInsets.only(right: 12.w), child: Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width:44.w, height: 20.h, ), ), ), ], ), Container( margin: EdgeInsets.only(top:5.h), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width:160.w, height: 16.h, ), ), SizedBox( height: 8.h, ), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: goodsItemSm(), flex: 1, ), Padding( padding: EdgeInsets.all(22.w), child: Image.asset( "assets/image/icon_order_more.webp", width: 24, height: 24, ), ) ], ), ], ), ), SizedBox( height: 12.h, ), Container( alignment: Alignment.centerRight, margin: EdgeInsets.only(right: 12.w, bottom: 12.h), child: Directionality( textDirection: TextDirection.rtl, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width:75.w, height: 20.h, ), ), SizedBox( width: 4.w, ), Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width:33.w, height: 17.h, ), ), ], ), SizedBox( height: 8.h, ), Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( decoration: BoxDecoration( color: Color(0XFFD8D8D8), borderRadius: BorderRadius.circular(10), ), width:72.w, height: 25.h, ), ) ], ), ), ), ], ), ); } Widget goodsItemSm(){ return Container( child: Row( children: [ Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width:75.w, height: 75.h, ), ), SizedBox(width: 8.w), Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width:75.w, height: 75.h, ), ), SizedBox(width: 8.w), Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), child: Container( color: Color(0XFFD8D8D8), width:75.w, height: 75.h, ), ), ], ) ); } @override bool get wantKeepAlive => true; }