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:flutter_html/flutter_html.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_swiper/flutter_swiper.dart'; import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/retrofit/data/activity.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:huixiang/retrofit/data/miNiDetail.dart'; import 'package:huixiang/retrofit/data/shoppingCart.dart'; import 'package:huixiang/retrofit/data/store_info.dart'; import 'package:huixiang/retrofit/min_api.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/store/store_view/people_num.dart'; import 'package:huixiang/store/store_view/red_dot_page.dart'; import 'package:huixiang/store/store_view/shop_car.dart'; import 'package:huixiang/utils/font_weight.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/round_button.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../view_widget/border_text.dart'; import '../view_widget/request_permission.dart'; import '../view_widget/settlement_tips_dialog.dart'; class ShopDetailsPage extends StatefulWidget { final Map arguments; ShopDetailsPage({this.arguments}); @override State createState() { return _ShopDetailsPage(); } } class _ShopDetailsPage extends State { ApiService apiService; MinApiService minService; final ScrollController scrollController = ScrollController(); final RefreshController refreshController = RefreshController(); String id; MiNiDetail miNiDetail; ShoppingCart shopCarGoods; bool dialogShowing = false; StoreInfo storeInfo; String parentCode = ""; int tableId = 0; String tenant; String minToken; String pName; String pid; String cName; String cid; List selectSkus = []; List activitys; int counts = 1; String selectedPrice = ""; String storeId; String parentId; int numberOfPeople = 0; int index; bool isSetMeal; int scIndex = 0; int skuMinQty = 0; int singleNum = 0; String goodsSkuId; bool isCounts = false; GlobalKey _key = GlobalKey(); Offset _endOffset; double rightOffset = 23.0; int _jumpType = -1; @override void initState() { super.initState(); id = widget.arguments["id"]; storeId = widget.arguments["storeId"]; scrollController.addListener(() { if(scIndex == 0 && scrollController.offset > (MediaQuery.of(context).size.height >= 750 ? 392.h : 400.h)){ setState(() { scIndex = 1; }); }else if(scIndex == 1 && scrollController.offset <= (MediaQuery.of(context).size.height >= 750 ? 392.h : 400.h)){ setState(() { scIndex = 0; }); } }); WidgetsBinding.instance.addPostFrameCallback((c) { // 获取「购物车」的位置 _endOffset = (_key.currentContext.findRenderObject() as RenderBox) .localToGlobal(Offset.zero)+ Offset(rightOffset, 0.0); }); // SharedPreferences.getInstance().then((value) { // String minToken = value.getString("minToken"); // String tenant = value.getString("tenant"); // String storeId = value.getString("storeId"); // minService = MinApiService(Dio(), // context: context, // token: minToken, // tenant: tenant, // storeId: storeId, // showLoading: true); // queryMiNiDetail(id); // queryShopCar().then((value) { // this.shopCarGoods = value; // setState(() {}); // }); // }); queryStoreInfo(); buildCount(); } @override void dispose() { super.dispose(); refreshController.dispose(); scrollController.dispose(); } /// 查询店铺信息 queryStoreInfo() async { EasyLoading.show( status: S.current.zhengzaijiazai, maskType: EasyLoadingMaskType.black); if (apiService == null){ SharedPreferences value = await SharedPreferences.getInstance(); apiService = ApiService( Dio(), context: context, token: value.getString("token"), ); if (value.getString("miNiDetail${id}") != null) { miNiDetail = MiNiDetail.fromJson(jsonDecode(value.getString('miNiDetail${id}'))); setState(() {}); } } BaseData baseData = await apiService.queryStoreInfo(storeId).catchError((error) { debugPrint(error); }); if (baseData != null && baseData.isSuccess) { storeInfo = StoreInfo.fromJson(baseData.data); activitys = storeInfo.informationVOPageVO.list .map((e) => Activity.fromJson(e)) .toList(); if (mounted) { setState(() {}); } minLogin(); } // EasyLoading.dismiss(); } /// 小程序登录 minLogin() async { apiService.minLogin(storeId).catchError((onError) { debugPrint(onError); }).then((baseData) { if (baseData != null && baseData.isSuccess) { Map minStoreInfo = baseData.data; String minToken = minStoreInfo["token"]; String tenant = storeInfo.tenantCode; String storeId = storeInfo.id; SharedPreferences.getInstance().then( (value) => { value.setString('minToken', minToken), value.setString('tenant', tenant), value.setString('storeId', storeId), }, ); minService = MinApiService( Dio(), context: context, token: minToken, tenant: tenant, storeId: storeId, ); queryMiNiDetail(id); queryShopCar().then((value) { this.shopCarGoods = value; setState(() {}); }); // EasyLoading.dismiss(); } }); } ///商品详情 queryMiNiDetail(id) async { BaseData baseData = await minService.miNiDetail(id).catchError((error) { refreshController.refreshFailed(); }); if (baseData != null && baseData.isSuccess) { setState(() { miNiDetail = baseData.data; miNiDetail.attrList.forEach((element) { selectSkus.add(element.attrValueList[0].attrValue); if (baseData.data.productSkuVOList[0].productSetMeals.length == 0) { _jumpType = 0; } else { _jumpType = 1; } }); }); SharedPreferences.getInstance().then( (value) => { value.setString('miNiDetail${id}', jsonEncode(baseData.data)), }, ); EasyLoading.dismiss(); refreshController.refreshCompleted(); } else { refreshController.refreshFailed(); } } _onRefresh() { queryMiNiDetail(id); } ///获取父订单(火锅订单加菜前调用) getParentInfo() async { BaseData baseData = await minService.getParentInfo("$tableId").catchError((error) { debugPrint(error); }); if (baseData != null && baseData.isSuccess) { if (baseData.data != null) { parentId = baseData.data["id"]; parentCode = baseData.data["parentCode"]; } else { ///TODO: 没有父订单, queryStoreInfo1(); } } } ///显示选择人数的弹窗 showPeopleNum(String tableName) async { var people = await showDialog( context: context, barrierDismissible: false, builder: (context) { return PeopleNumView(tableName); }, ); if (people != null && people > 0) { setState(() { this.numberOfPeople = people; }); } else { Navigator.of(context).pop(); } } ///获取桌子信息 queryStoreInfo1() async { BaseData baseData = await minService.queryStoreInfo1({ "getCoupon": true, "storeId": storeId, "tableId": tableId, }).catchError((error) { debugPrint(error); }); if (baseData != null && baseData.isSuccess) { StoreInfo storeInfo = StoreInfo.fromJson(baseData.data); if (storeInfo.storeTable != null) { showPeopleNum(storeInfo.storeTable.tableName); } } } ///计算个数 int count() { if (shopCarGoods == null || shopCarGoods.shoppingCartSkuItemList == null || shopCarGoods.shoppingCartSkuItemList.length == 0) return 0; int count = 0; shopCarGoods.shoppingCartSkuItemList.forEach((element) { count += element.buyNum; }); return count; } ///去下单结算页面 toDownOrder() async { int num = count(); if (parentId == null || parentId == "") { if (num == 0) { SmartDialog.showToast("请先选择您要购买的商品!~", alignment: Alignment.center); return; } } await Navigator.of(context).pushNamed( '/router/settlement', arguments: { "storeInfo": storeInfo, "tableId": tableId, "parentCode": parentCode, "parentId": parentId, // "pName": pName, "pid": pid, // "cName": cName, "cid": cid, "shoppingCart": shopCarGoods, "numberOfPeople": numberOfPeople, "distance": widget.arguments["distance"], "subscribeParam": miNiDetail?.subscribeParam, }, ); if ((miNiDetail?.subscribeParam?.isEnableSubscribe ?? false) == true) { clearShopCar(); this.shopCarGoods = await queryShopCar(); } if (tableId > 0) { getParentInfo(); } queryShopCar().then((value) { this.shopCarGoods = value; setState(() {}); }); } /// 购物车的key,用于刷新UI GlobalKey shopCartKey = GlobalKey(); ///购物车弹窗 showShoppingCart() { queryShopCar().then((value) { this.shopCarGoods = value; dialogShowing = true; //使用showModalBottomSheet加载弹窗才有效 showModalBottomSheet( backgroundColor: Colors.transparent, context: context, //点击背景弹窗是否关闭 // isDismissible: true, builder: (_) { return ShopCar( shopCartKey, this.shopCarGoods, clearShopCar, toDownOrder, shopCartAdd, shopCartReduce, ); }); // SmartDialog.show( // widget: ShopCar( // shopCartKey, // this.shopCarGoods, // clearShopCar, // toDownOrder, // shopCartAdd, // shopCartReduce, // ), // onDismiss: () { // dialogShowing = false; // }, // alignmentTemp: Alignment.bottomCenter, // ); }); } ///清空购物车 clearShopCar() async { BaseData baseData = await minService.clearShoppingCart(storeId); if (baseData.isSuccess) { shopCarGoods = null; singleNum = 0; setState(() {}); } } ///选规格 _queryMiNiDetail(String id, int count) async { //加红点抛物线动画,故单规格加购时不显示加载中 // EasyLoading.show( status: S.current.zhengzaijiazai, maskType: EasyLoadingMaskType.black); if (count < 0) { shopCarGoods.shoppingCartSkuItemList.forEach((element) { if (element.productId == id) { shopCartReduce(element); setState(() {}); } }); return; } BaseData baseData = await minService.miNiDetail(id); if (baseData != null && baseData.isSuccess) { showStoreSelector(baseData.data, id, count); }else{ SmartDialog.showToast(baseData.msg); } // EasyLoading.dismiss(); } ///选规格弹窗 showStoreSelector(MiNiDetail miNiDetail, String id, int count) async { if (miNiDetail.attrList != null && miNiDetail.attrList.length == 1 && miNiDetail.attrList[0].attrValueList.length == 1) { _addShopCar(miNiDetail, [], count); } else { setState(() { buildCount(); }); selectSpecsShowBottomSheet(); } } ///添加购物车 Future _addShopCar(MiNiDetail miNiDetail, selectSkus, int count) async { ProductSkuVOListBean productSku; if (selectSkus != null && selectSkus.length == 0) { productSku = miNiDetail.productSkuVOList.first; } else { productSku = miNiDetail.productSkuVOList.firstWhere((element) { bool gg = true; selectSkus.forEach((element1) { if (element.skuNameStr.indexOf(element1) < 0) { gg = false; return gg; } }); return gg; }); } if (productSku == null) return; String skuId = productSku.id; String skuValue = selectSkus .toString() .replaceAll("[", "") .replaceAll("]", "") .replaceAll(",", ""); if ((miNiDetail.subscribeParam.isEnableSubscribe ?? false) == true) { clearShopCar(); } if (miNiDetail != null) { BaseData> baseDate = await minService.addShoppingCart({ "storeId": storeInfo.id, "storeName": storeInfo.storeName ?? "", "numberOfPeople": numberOfPeople, "tableId": tableId, "parentId": parentId, "parentCode": parentCode, "shoppingCartSkuItemList": [ { "buyNum": count, "id": skuId, "productId": miNiDetail.id, "productName": miNiDetail.productName, "skuName": skuValue, "storeId": storeInfo.id, "skuPrice": productSku.skuPrice, "skuStock": productSku.skuStock, "tableId": tableId, }, ], }); EasyLoading.dismiss(); if (baseDate != null && baseDate.isSuccess) { queryShopCar().then((value) { this.shopCarGoods = value; if ((miNiDetail.subscribeParam.isEnableSubscribe ?? false) == true) toDownOrder(); setState(() {}); }); } else { SmartDialog.show( widget: SettlementTips( () {}, text: "${baseDate.msg.replaceAll("~", ",") + "请重新加购商品"}", ), ); } } } ///查询购物车 Future queryShopCar() async { pName = ""; //活动 pid = ""; //活动 cName = ""; //优惠券 cid = ""; //优惠券 BaseData> baseDate = await minService.getShoppingCart(tableId); if (baseDate != null && baseDate.isSuccess && baseDate.data != null && baseDate.data.length > 0) { if (baseDate.data[0].selectDiscount == 1) { baseDate.data[0].couponList.forEach((element) { if (element.isMaxCoupon) { // cName = element.promotionName; cid = element.id; } }); } else if (baseDate.data[0].selectDiscount == 2) { baseDate.data[0].promotionInfoList.forEach((element) { if (element.isMaxPromotion) { // pName = element.name; pid = element.id; } }); } baseDate.data[0].shoppingCartSkuItemList.forEach((element) { if((goodsSkuId == element.id)){ singleNum = element.buyNum; }else{ if(id == element.productId){ singleNum = element.buyNum; }else{ singleNum = 0; } } }); return baseDate.data[0]; } else { return null; } } ///购物车➕1 Future shopCartAdd( ShoppingCartSkuItemListBean cartSkuItem) async { Map shopCarTemp = shopCarGoods.toJson(); cartSkuItem.buyNum += 1; shopCarTemp["shoppingCartSkuItemList"] = [cartSkuItem.toJson()]; BaseData> baseDate = await minService.shoppingCartSingle(shopCarTemp); if (baseDate.isSuccess) { this.shopCarGoods = await queryShopCar(); if (shopCartKey != null) { shopCartKey.currentState.setState(() {}); } setState(() {}); } return this.shopCarGoods; } ///购物车➖1 Future shopCartReduce( ShoppingCartSkuItemListBean cartSkuItem,{int count = 1}) async { Map shopCarTemp = shopCarGoods.toJson(); cartSkuItem.buyNum -= (count>0) ? ((cartSkuItem.minQty>1 && cartSkuItem.buyNum == cartSkuItem.minQty) ? cartSkuItem.minQty: count) : -count; shopCarTemp["shoppingCartSkuItemList"] = [cartSkuItem.toJson()]; BaseData> baseDate = await minService.shoppingCartSingle(shopCarTemp); if (baseDate.isSuccess) { EasyLoading.dismiss(); this.shopCarGoods = await queryShopCar(); if (shopCartKey?.currentState != null) { shopCartKey.currentState.setState(() {}); } setState(() {}); } return this.shopCarGoods; } ///商品➕1 add(MiNiDetail miNiDetail, selectSkus) async { ProductSkuVOListBean productSku = miNiDetail.productSkuVOList.firstWhere((element) { return skuY(element, selectSkus); }); if (productSku == null) return; String skuId = productSku.id; if (shopCarGoods == null) { await _addShopCar(miNiDetail, selectSkus, 2); return; } int shopSkuIndex = shopCarGoods.shoppingCartSkuItemList .indexWhere((element) => skuId == element.id); Map shopCarTemp = shopCarGoods.toJson(); shopCarGoods.tableId = "$tableId"; if (shopSkuIndex >= 0) { shopCarGoods.shoppingCartSkuItemList[shopSkuIndex].buyNum += 1; ShoppingCartSkuItemListBean cartSkuItem = shopCarGoods .shoppingCartSkuItemList .firstWhere((element) => skuId == element.id); shopCarTemp["shoppingCartSkuItemList"] = [cartSkuItem.toJson()]; } else { await _addShopCar(miNiDetail, selectSkus, 2); return; } BaseData> baseDate = await minService.shoppingCartSingle(shopCarTemp); if (baseDate.isSuccess) { queryShopCar().then((value) { this.shopCarGoods = value; setState(() {}); }); } } ///商品➖1 reduce(MiNiDetail miNiDetail, selectSkus) async { ProductSkuVOListBean productSku = miNiDetail.productSkuVOList.firstWhere((element) { return skuY(element, selectSkus); }); if (productSku == null) return; String skuId = productSku.id; if (shopCarGoods == null) { await _addShopCar(miNiDetail, selectSkus, 2); return; } ShoppingCartSkuItemListBean shopSkuItem = shopCarGoods .shoppingCartSkuItemList .firstWhere((element) => skuId == element.id); int shopSkuIndex = shopCarGoods.shoppingCartSkuItemList .indexWhere((element) => skuId == element.id); if (shopSkuItem != null) { if (shopSkuItem.buyNum > 1) { shopCarGoods.shoppingCartSkuItemList[shopSkuIndex].buyNum -= (skuMinQty > 1 && skuMinQty ==shopSkuItem.buyNum) ? skuMinQty:1; } } else { await _addShopCar(miNiDetail, selectSkus, 2); return; } shopCarGoods.tableId = "$tableId"; Map shopCarTemp = shopCarGoods.toJson(); ShoppingCartSkuItemListBean cartSkuItem = shopCarGoods .shoppingCartSkuItemList .firstWhere((element) => skuId == element.id); shopCarTemp["shoppingCartSkuItemList"] = [cartSkuItem.toJson()]; BaseData> baseDate = await minService.shoppingCartSingle(shopCarTemp); if (baseDate.isSuccess) { queryShopCar().then((value) { this.shopCarGoods = value; setState(() {}); }); } } bool skuY(ProductSkuVOListBean productSku, selectSkus) { bool gg = true; selectSkus.forEach((element1) { if (productSku.skuNameStr.indexOf(element1) < 0) { gg = false; return gg; } }); return gg; } buildCount() { counts = 1; ProductSkuVOListBean productSku; try { productSku = miNiDetail.productSkuVOList.firstWhere((element) { return skuY(element, selectSkus); }); } catch (ex) { return; } if (productSku == null) return; selectedPrice = productSku.skuPrice; String skuId = productSku.id; skuMinQty = productSku.minQty; if (shopCarGoods == null || shopCarGoods.shoppingCartSkuItemList == null) return; int shopSkuIndex = shopCarGoods.shoppingCartSkuItemList .indexWhere((element) => skuId == element.id); if (shopSkuIndex >= 0) { counts = shopCarGoods.shoppingCartSkuItemList[shopSkuIndex].buyNum; } } @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ Column( children: [ Expanded( child: SmartRefresher( controller: refreshController, enablePullDown: true, enablePullUp: false, header: MyHeader(), footer: CustomFooter( builder: (context, mode) { return MyFooter(mode); }, ), onRefresh: () { setState(() { _onRefresh(); }); }, physics: BouncingScrollPhysics(), scrollController: scrollController, child: SingleChildScrollView( physics: BouncingScrollPhysics(), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ buildProduct(), SizedBox( height: 16.h, ), Container( width: double.infinity, color: Colors.white, child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.only(left: 14.w, top: 16.h), child: Text( "商品详情", style: TextStyle( fontSize: 15.sp, fontWeight: MyFontWeight.semi_bold, color: Color(0xFF000000), ), ), ), SizedBox( height: 14.h, ), Container( color: Colors.white, child: Html( data: miNiDetail?.details ?? "", style: { 'body': Style( backgroundColor: Colors.white, padding: EdgeInsets.symmetric(horizontal:12.w), fontSize: FontSize(14.sp), lineHeight: LineHeight.rem(1.5), margin: EdgeInsets.all(0)), 'p': Style( margin: EdgeInsets.all(0), fontSize: FontSize(14.sp), lineHeight: LineHeight.rem(1.5), padding: EdgeInsets.all(0), ), }, customImageRenders: { networkSourceMatcher(): networkImageRender( loadingWidget: () { return Container(); }, ), }, ), ), ], ), ) ], ), ), ), flex: 1, ), // if (count() != 0) Stack( alignment: Alignment.bottomLeft, children: [ Container( margin: EdgeInsets.symmetric(horizontal: 14), height: 45.h, // color: Color(0xFFFAFAFA), decoration: BoxDecoration( color: Color(0xFF383A38), borderRadius: BorderRadius.circular(100), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( width: 45.w, ), Text.rich( TextSpan(children: [ TextSpan( text: "¥ ", style: TextStyle( fontSize: 12.sp, color: Color(0xFFFFFFFF), fontWeight: MyFontWeight.bold), ), TextSpan( text: shopCarGoods != null ? shopCarGoods.cartSum : "0.0", style: TextStyle( fontSize: 20.sp, color: Color(0xFFFFFFFF), fontFamily: 'JDZhengHT', fontWeight: MyFontWeight.medium), ), ]), ), Spacer(), GestureDetector( onTap: () { toDownOrder(); }, child: RoundButton( width: 103.w, height: 54.h, text: S.current.jiesuan, textColor: Colors.white, fontWeight: MyFontWeight.bold, backgroup: Color(0xFF32A060), radius: 100, fontSize: 16.sp, padding: EdgeInsets.symmetric(vertical: 5.h), ), ), ], ), ), Stack( children: [ InkWell( onTap: () { if (count() != 0) showShoppingCart(); }, child: Image.asset( "assets/image/shopping_bag.webp", width: 57.w, height: 57.w, fit: BoxFit.fitWidth, key: _key, ), ), if (count() != 0) Positioned( right: 5, // top: 14, child: RoundButton( width: 17.w, height: 17.h, text: "${count()}", textColor: Colors.white, fontWeight: MyFontWeight.regular, backgroup: Color(0xFFF65720), fontSize: 12.sp, radius: 100, ), ), ], ), ], ), SizedBox( height: 30.h, ) ], ), if (scIndex == 1) Container( color: Colors.white, padding: EdgeInsets.only( top: MediaQuery.of(context).padding.top + 10.h, left: 14.w, right: 14.w, bottom: 10.h), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( miNiDetail?.price ?? "", style: TextStyle( fontSize: 24.sp, fontFamily: 'JDZhengHT', fontWeight: MyFontWeight.semi_bold, color: Color(0xFFF85400), ), ), SizedBox( width: 2.w, ), Text( miNiDetail?.applyPrice ?? "", style: TextStyle( fontSize: 16.sp, fontFamily: 'JDZhengHT', decoration: TextDecoration.lineThrough, fontWeight: MyFontWeight.regular, color: Color(0xFFA29E9E), ), ), if((widget?.arguments["minQty"] ?? 0).toInt() > 1) Container( height: 20.h, padding: EdgeInsets.symmetric(horizontal:6.w), margin: EdgeInsets.only(left: 16.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(2), border: Border.all( width: 1, color: Color(0xFFF65720), style: BorderStyle.solid, ), ), alignment: Alignment.center, child: Text( "${widget?.arguments["minQty"] ?? 0 ?? "0"}份起购", style: TextStyle( color: Color(0xFFF65720), fontSize: 12.sp, fontWeight: MyFontWeight.regular, ), ), ), Spacer(), Builder( builder: (context) { return GestureDetector( onTap: () async { if (storeInfo.posType.code == "NORMALSTORE" && tableId == 0) { showDeleteDialog(); } else if (_jumpType == 1) { await Navigator.of(context).pushNamed( '/router/product_meals_sku', arguments: { "id": id, "storeId": storeId, "tableId": tableId }); queryShopCar().then((value) { this.shopCarGoods = value; setState(() {}); }); } else { if (miNiDetail.attrList != null && miNiDetail.attrList.length == 1 && miNiDetail.attrList[0].attrValueList.length == 1){ /// 点击的时候获取当前 widget 的位置,传入 overlayEntry var _overlayEntry = OverlayEntry(builder: (_) { RenderBox box = context.findRenderObject(); var offset = box.localToGlobal(Offset.zero); return RedDotPage( startPosition: offset, endPosition: _endOffset, ); }); // 显示Overlay Overlay.of(context).insert(_overlayEntry); // 等待动画结束 Future.delayed(Duration(milliseconds: 800), () { _overlayEntry.remove(); _overlayEntry = null; }); } _queryMiNiDetail(id,(skuMinQty > 1 ? counts : ((widget.arguments["minQty"]??0) > 1 && singleNum==0) ? (widget.arguments["minQty"]??0):counts)); } }, child: Container( width: 92.w, height: 32.h, decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: Color(0xFF32A060), ), margin: EdgeInsets.only(bottom: 8), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( "assets/image/goods_shopp.webp", fit: BoxFit.fill, width: 18, height: 18, ), SizedBox( width: 2, ), Text( ((miNiDetail?.subscribeParam?.isEnableSubscribe ?? false) == true) ? S.of(context).lijiyuyue : (isSetMeal ?? false) == true ? "选套餐" : "加入购物车", style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, color: Color(0xFFFFFFFF), ), ), ], ), ), );},) ], ), ) ], ), ); } Widget buildProduct() { return Container( decoration: BoxDecoration( borderRadius: BorderRadius.vertical( bottom: Radius.circular(8.h), ), boxShadow: [ BoxShadow( color: Colors.black.withAlpha(12), offset: Offset(0, 3), blurRadius: 14, spreadRadius: 0, ) ], color: Color(0xFFFFFFFF)), child: Column( children: [ swiper(), Container( padding: EdgeInsets.only( top: 16.h, left: 14.w, right: 14.w, bottom: 16.h), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ if(scIndex == 0) Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( miNiDetail?.price ?? "", style: TextStyle( fontSize: 24.sp, fontFamily: 'JDZhengHT', fontWeight: MyFontWeight.semi_bold, color: Color(0xFFF85400), ), ), SizedBox( width: 2.w, ), Text( miNiDetail?.applyPrice ?? "", style: TextStyle( fontSize: 16.sp, fontFamily: 'JDZhengHT', decoration: TextDecoration.lineThrough, fontWeight: MyFontWeight.regular, color: Color(0xFFA29E9E), ), ), if((widget?.arguments["minQty"] ?? 0).toInt() > 1) Container( padding: EdgeInsets.symmetric(horizontal:6.w,vertical: 2.h), margin: EdgeInsets.only(left: 16.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(2), border: Border.all( width: 1, color: Color(0xFFF65720), style: BorderStyle.solid, ), ), alignment: Alignment.center, child: Text( "${widget?.arguments["minQty"] ?? 0}份起购", style: TextStyle( color: Color(0xFFF65720), fontSize: 12.sp, fontWeight: MyFontWeight.regular, ), ), ), Spacer(), Builder( builder: (context) { return GestureDetector( onTap: () async { if (storeInfo.posType.code == "NORMALSTORE" && tableId == 0) { showDeleteDialog(); } else if (_jumpType == 1) { await Navigator.of(context).pushNamed( '/router/product_meals_sku', arguments: { "id": id, "storeId": storeId, "tableId": tableId }); queryShopCar().then((value) { this.shopCarGoods = value; setState(() {}); }); } else { if (miNiDetail.attrList != null && miNiDetail.attrList.length == 1 && miNiDetail.attrList[0].attrValueList.length == 1){ /// 点击的时候获取当前 widget 的位置,传入 overlayEntry var _overlayEntry = OverlayEntry(builder: (_) { RenderBox box = context.findRenderObject(); var offset = box.localToGlobal(Offset.zero); return RedDotPage( startPosition: offset, endPosition: _endOffset, ); }); // 显示Overlay Overlay.of(context).insert(_overlayEntry); // 等待动画结束 Future.delayed(Duration(milliseconds: 800), () { _overlayEntry.remove(); _overlayEntry = null; }); } _queryMiNiDetail(id,(skuMinQty > 1 ? counts : ((widget.arguments["minQty"]??0) > 1 && singleNum==0) ? (widget.arguments["minQty"]??0):counts)); } }, child: Container( width: 92.w, height: 32.h, decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: Color(0xFF32A060), ), margin: EdgeInsets.only(bottom: 8), child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( "assets/image/goods_shopp.webp", fit: BoxFit.fill, width: 18, height: 18, ), SizedBox( width: 2, ), Text( ((miNiDetail?.subscribeParam?.isEnableSubscribe ?? false) == true) ? S.of(context).lijiyuyue : (isSetMeal ?? false) == true ? "选套餐" : "加入购物车", style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, color: Color(0xFFFFFFFF), ), ), ], ), ), );},), ], ), Text( miNiDetail?.productName ?? "", style: TextStyle( fontSize: 15.sp, fontWeight: MyFontWeight.semi_bold, color: Color(0xFF000000), ), ), SizedBox( height: 12.h, ), Text( miNiDetail?.shortName ?? "", style: TextStyle( fontSize: 12.sp, height: 1.5, fontWeight: MyFontWeight.regular, color: Color(0xFF4D4D4D), ), ), ], ), ), ], ), ); } Widget swiper() { return Container( child: AspectRatio( aspectRatio: 375 / 375, child: Stack( children: [ Swiper( pagination: SwiperPagination( alignment: Alignment.bottomCenter, builder: DotSwiperPaginationBuilder( size: 8, activeSize: 8, space: 5, activeColor: Colors.black, color: Colors.black.withAlpha(76), ), ), itemBuilder: (context, position) { return MImage( miNiDetail?.imgs != null ? miNiDetail.imgs[position] : "", fit: BoxFit.cover, radius: BorderRadius.zero, height: 375, width: 375, errorSrc: "assets/image/default_2_1.webp", fadeSrc: "assets/image/default_2_1.webp", ); }, itemCount: miNiDetail?.imgs?.length ?? 1, ), GestureDetector( onTap: () { Navigator.of(context).pop(); }, child: Container( margin: EdgeInsets.only(left: 16, top: 52), padding: EdgeInsets.all(5), child: Image.asset( "assets/image/integral_return.webp", ), ), ), ], ), ), ); } ///选择規格弹窗 selectSpecsShowBottomSheet() { showModalBottomSheet( builder: (BuildContext context) { return StatefulBuilder(builder: ( context, state, ) { return Container( alignment: Alignment.topCenter, padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 16), height: MediaQuery.of(context).size.height / 3 * 2, width: double.infinity, decoration: BoxDecoration( color: Color(0xFFFAFAFA), borderRadius: BorderRadius.only( topLeft: Radius.circular(8), topRight: Radius.circular(8), ), ), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ ClipRRect( child: MImage( miNiDetail.imgs[0], fit: BoxFit.cover, width: 70, height: 70, errorSrc: "assets/image/default_2_1.webp", fadeSrc: "assets/image/default_2_1.webp", ), borderRadius: BorderRadius.circular(4), ), SizedBox( width: 10.w, ), Expanded( child: Container( height: 70, child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( miNiDetail?.productName ?? "", style: TextStyle( fontSize: 13.sp, fontWeight: FontWeight.bold, color: Color(0xFF000000), ), ), GestureDetector( onTap: () { Navigator.of(context).pop(); }, child: Image.asset( "assets/image/cancel.webp", fit: BoxFit.cover, height: 24, width: 24, ), ), ], ), if(skuMinQty > 1) Row(children: [ Container( padding: EdgeInsets.symmetric(horizontal:4.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(2), border: Border.all( width: 1, color: Color(0xFFF65720), style: BorderStyle.solid, ), ), alignment: Alignment.center, child: Text( "${skuMinQty}份起购", style: TextStyle( color: Color(0xFFF65720), fontSize: 10.sp, fontWeight: MyFontWeight.regular, ), ), ), Spacer() ]), Text( "¥${miNiDetail?.price ?? ""}", style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.bold, color: Color(0xFFF65720), ), ), ], ), )), ], ), if (miNiDetail.attrList != null && miNiDetail.attrList.length > 0) SizedBox( height: 10, ), if (miNiDetail.attrList != null && miNiDetail.attrList.length > 0) Expanded( child: ListView.builder( itemCount: miNiDetail.attrList.length, scrollDirection: Axis.vertical, physics: BouncingScrollPhysics(), padding: EdgeInsets.zero, itemBuilder: (context, position) { return attrItem( (attrValue) { state(() { // if(selectSkus.length > position) selectSkus[position] = attrValue; buildCount(); }); }, miNiDetail.attrList[position], position, ); }, ), ), SizedBox( height: 24, ), Column( crossAxisAlignment: CrossAxisAlignment.start, // mainAxisAlignment: MainAxisAlignment.start, children: [ Text( S.of(context).shuliang, style: TextStyle( color: Color(0xFFB3B3B3), fontSize: 12.sp, fontWeight: MyFontWeight.regular, ), ), if(skuMinQty > 1 && (counts ==1 || counts ==0)) Row( children: [ GestureDetector( behavior: HitTestBehavior.opaque, onTap: () async { state(() { isCounts = true; counts += skuMinQty-1; _addShopCar(miNiDetail, selectSkus, counts); }); }, child:Container( margin: EdgeInsets.only(right: 8.w, top: 14.h,bottom: 24.h), child: RoundButton( text:"${skuMinQty}份起购", textColor: Colors.white, fontWeight: MyFontWeight.medium, radius: 3, backgroup: Color(0xFF32A060), fontSize: 11.sp, padding: EdgeInsets.symmetric( vertical: 5.h, horizontal: 3.w), ), )), Spacer() ], ), if((skuMinQty > 1 && counts !=1) || skuMinQty == 0 || skuMinQty == 1) Row( children: [ GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { state(() { if (counts > 1) setState(() { counts -= (skuMinQty > 1 && skuMinQty == counts) ? (skuMinQty - 1) : 1; }); isCounts = true; reduce(miNiDetail, selectSkus); }); }, child: Container( padding:EdgeInsets.only(right:8.w,top: 10.h,bottom: 24.h), child: Icon( Icons.remove, color: Color(0xFF32A060), size: 24, ))), Padding( padding: EdgeInsets.only(right: 8.w,bottom: 14.h), child: Text( "$counts", style: TextStyle( color: Colors.black, fontSize: 14.sp, fontWeight: MyFontWeight.medium, ), ), ), GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { state(() { counts += 1; isCounts = true; add(miNiDetail, selectSkus); }); }, child: Container( padding:EdgeInsets.only(right:20.w,top: 10.h,bottom: 24.h), child: Icon( Icons.add, color: Color(0xFF32A060), size: 24, ), )), ], ) ], ), RoundButton( width: double.infinity, height: 54.h, text: ((miNiDetail?.subscribeParam?.isEnableSubscribe ?? false) == true) ? S.of(context).lijiyuyue : "加入购物车", textColor: Colors.white, fontWeight: MyFontWeight.semi_bold, radius: 27, backgroup:Color(0xFF32A060), fontSize: 16.sp, callback: () { state(() { if(skuMinQty > 1 && counts == 1){ SmartDialog.show( widget: SettlementTips( () {}, text: "请选择购买数量", ), ); return; } if(!isCounts || counts == 1){ _addShopCar(miNiDetail, selectSkus,1); counts = 1; isCounts = false; } Navigator.of(context).pop(); }); }, ), ], ), ); }); }, backgroundColor: Colors.transparent, context: context); } Widget attrItem(Function fc, AttrListBean attrListBean, position) { if (attrListBean.attrValueList != null && attrListBean.attrValueList.length > 0) return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.only(top: 16, bottom: 16), child: Text( attrListBean.attrName, style: TextStyle( color: Color(0xFFB3B3B3), fontSize: 14.sp, fontWeight: MyFontWeight.regular, ), ), ), sweetnessStore(fc, attrListBean.attrValueList, position), // sweetnessStore(fc, attrListBean.attrValueList, position), ], ); else { return Container(); } } Widget sweetnessStore(Function fc, List arrays, position) { return Wrap( runSpacing: 10.0, spacing: 10.0, children: arrays.take(arrays.length).map((AttrValueListBean tag) { return GestureDetector( onTap: () { fc(tag.attrValue); }, child: sweetnessItem( tag.attrValue, (selectSkus.length > position && tag.attrValue == selectSkus[position]), )); }).toList()); } Widget sweetnessItem(String name, bool isCheck) { return Container( padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 12.0), decoration: BoxDecoration( color: !isCheck ? Color(0xFFF2F2F2) : Color(0xFFF0FAF4), border: Border.all( width: !isCheck ? 0 : 1, color: !isCheck ? Color(0xFFF2F2F2) : Color(0xFF32A060), style: BorderStyle.solid, ), borderRadius: const BorderRadius.all( Radius.circular(4.0), ), ), child: Text( name, overflow: TextOverflow.ellipsis, style: TextStyle( color: !isCheck ? Color(0xFF4D4D4D) : Color(0xFF32A060), fontSize: 14.sp, fontWeight: MyFontWeight.regular, ), )); } ///扫码提示弹窗 showDeleteDialog() { showDialog( context: context, builder: (context) { return AlertDialog( content: Container( width: MediaQuery.of(context).size.width - 84.w, height: 130.h, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( "您即将进行扫码点餐", style: TextStyle( fontSize: 17.sp, fontWeight: FontWeight.bold, color: Colors.black, ), ), SizedBox( height: 30.h, ), Row( children: [ Expanded( child: InkWell( child: BorderText( text: S.of(context).quxiao, textColor: Color(0xFF32A060), fontSize: 16.sp, fontWeight: FontWeight.bold, borderColor: Color(0xFF32A060), radius: 4, padding: EdgeInsets.all(12), borderWidth: 1, ), onTap: () { Navigator.of(context).pop(); }, ), flex: 1, ), SizedBox( width: 16.w, ), Expanded( child: InkWell( child: RoundButton( text: S.of(context).queding, textColor: Colors.white, radius: 4, padding: EdgeInsets.all(12), backgroup: Color(0xFF32A060), fontSize: 16.sp, fontWeight: FontWeight.bold, ), onTap: () { toScan(); Navigator.of(context).pop(); }, ), flex: 1, ), ], ) ], ), ), ); }, ); } ///扫码 toScan() async { if (await Permission.camera.isPermanentlyDenied) { showCupertinoDialog( context: context, builder: (context) { return RequestPermission( "assets/image/icon_camera_permission_tips.webp", S.of(context).ninxiangjiquanxianweikaiqi, S.of(context).weilekaipaizhaoxuanzhetouxiang, S.of(context).kaiqiquanxian, (result) async { if (result) { await openAppSettings(); } }, heightRatioWithWidth: 0.82, ); }); } else if (await Permission.camera.isGranted) { var result = await Navigator.of(context).pushNamed('/router/qr_scan'); // String result = "http://pos.app.gznl.top/placeorder/?tableId=1315906639160672256&tenantCode=1166&shopId=1300372027722432512"; // 新版桌子码跳转 // http://miniscan.lotus-wallet.com/placeorder?tenant_code=1194&table_id=1669609340031467520&store_id=1637659387134738432 Uri uri = Uri.parse(result); String tableId = uri.queryParameters["tableId"] ?? uri.queryParameters["table_id"]; String tenantCode = uri.queryParameters["tenantCode"] ?? uri.queryParameters["tenant_code"]; String shopId = uri.queryParameters["shopId"] ?? uri.queryParameters["store_id"]; if (tableId != null && tableId != "" && tenantCode != null && tenantCode != "" && shopId != null && shopId != "") { Navigator.of(context).pushReplacementNamed( '/router/store_order', arguments: { "id": shopId, "tenant": tenantCode, "storeName": "", "tableId": int.tryParse(tableId), }, ); } } else { await Permission.camera.request(); } } }