diff --git a/assets/map_style/chinese_cities.json b/assets/map_style/chinese_cities.json index 0b6d32b6..e9742bde 100644 --- a/assets/map_style/chinese_cities.json +++ b/assets/map_style/chinese_cities.json @@ -6,7 +6,7 @@ {"area": "广州"}, {"area": "成都"}, {"area": "杭州"}, - {"area": "南京"}, + {"area": "武汉"}, {"area": "重庆"} ], "A": [ diff --git a/lib/main.dart b/lib/main.dart index bbacd5b8..c28d609f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -442,5 +442,5 @@ Map routers = { '/router/trading_card_page': (context, {arguments}) => TradingCardPage(), '/router/union_select_city': (context, {arguments}) => - UnionSelectCity(), + UnionSelectCity(arguments:arguments), }; diff --git a/lib/retrofit/data/ip_data.dart b/lib/retrofit/data/ip_data.dart new file mode 100644 index 00000000..c0ff1f3c --- /dev/null +++ b/lib/retrofit/data/ip_data.dart @@ -0,0 +1,78 @@ +/// code : 200 +/// msg : "success" +/// ip : "27.17.85.129" +/// country : "中国" +/// province : "湖北" +/// city : "武汉市" +/// isp : "电信" + +class IpData { + IpData({ + num code, + String msg, + String ip, + String country, + String province, + String city, + String isp,}){ + _code = code; + _msg = msg; + _ip = ip; + _country = country; + _province = province; + _city = city; + _isp = isp; +} + + IpData.fromJson(dynamic json) { + _code = json['code']; + _msg = json['msg']; + _ip = json['ip']; + _country = json['country']; + _province = json['province']; + _city = json['city']; + _isp = json['isp']; + } + num _code; + String _msg; + String _ip; + String _country; + String _province; + String _city; + String _isp; +IpData copyWith({ num code, + String msg, + String ip, + String country, + String province, + String city, + String isp, +}) => IpData( code: code ?? _code, + msg: msg ?? _msg, + ip: ip ?? _ip, + country: country ?? _country, + province: province ?? _province, + city: city ?? _city, + isp: isp ?? _isp, +); + num get code => _code; + String get msg => _msg; + String get ip => _ip; + String get country => _country; + String get province => _province; + String get city => _city; + String get isp => _isp; + + Map toJson() { + final map = {}; + map['code'] = _code; + map['msg'] = _msg; + map['ip'] = _ip; + map['country'] = _country; + map['province'] = _province; + map['city'] = _city; + map['isp'] = _isp; + return map; + } + +} \ No newline at end of file diff --git a/lib/retrofit/retrofit_api.dart b/lib/retrofit/retrofit_api.dart index ccf4ac1c..6fbd44d8 100644 --- a/lib/retrofit/retrofit_api.dart +++ b/lib/retrofit/retrofit_api.dart @@ -41,6 +41,7 @@ import 'data/headlines_list.dart'; import 'data/headlines_list_details.dart'; import 'data/home_rank.dart'; import 'data/invitation_list.dart'; +import 'data/ip_data.dart'; import 'data/logistics.dart'; import 'data/member_Infor.dart'; import 'data/member_comment_list.dart'; @@ -66,9 +67,17 @@ import 'data/wx_pay.dart'; part 'retrofit_api.g.dart'; -const localBaseUrl = "http://192.168.10.15:8766/app/";///本地 +const localBaseUrl = "http://platform-api.test.yixinhuixiang.com/app/"; + +///本地 // const localBaseUrl = "http://platform.test.api.lotus-wallet.com/app/";///测试 -const serviceBaseUrl = "https://pos.platform.lotus-wallet.com/app/";///线上 +const serviceBaseUrl = "https://pos.platform.lotus-wallet.com/app/"; + +///线上 + +const ipBaseUrl = "https://api.ooomn.com"; + +///ip @RestApi(baseUrl: localBaseUrl) abstract class ApiService { @@ -78,6 +87,7 @@ abstract class ApiService { BuildContext context, String token, bool showLoading = false, + bool isIp = false, bool pay = true, }) { Map headers = @@ -85,6 +95,7 @@ abstract class ApiService { if (pay) { headers["Environment"] = "app"; } + if (isIp) baseUrl = ipBaseUrl; dio.options = BaseOptions( connectTimeout: 60000, receiveTimeout: 60000, @@ -113,14 +124,16 @@ abstract class ApiService { EasyLoading.dismiss(); } debugPrint("code = ${response.statusCode}"); - p(jsonEncode(response.data)); + + if (response.request.path != "/creditGoods/list") + p(jsonEncode(response.data)); // debugPrint(jsonEncode(response.data), wrapWidth: response.data.toString().length * 10); Map map = response.data; - if (map["code"] != 0) { - EasyLoading.dismiss(); - } + // if (map["code"] != 0) { + // EasyLoading.dismiss(); + // } if (map["code"] == 40005 || map["code"] == 40001) { if (!LoginTipsDialog().isShow) { print("show: ${LoginTipsDialog().isShow}"); @@ -166,11 +179,12 @@ abstract class ApiService { ///文件上传 @POST("/file/upload") @MultiPart() - Future> upload( - @Part(name: "file") File data, @Part(name: "folderId") int folderId,bool isVideo); + Future> upload(@Part(name: "file") File data, + @Part(name: "folderId") int folderId, bool isVideo); /// 周边搜索 - @GET("https://restapi.amap.com/v3/place/around?key=542b46afa8e4b88fe1eb3c4d0ba0872f&location={lat},{lng}&keywords={keywords}&offset={size}&page={page}&extensions=all") + @GET( + "https://restapi.amap.com/v3/place/around?key=542b46afa8e4b88fe1eb3c4d0ba0872f&location={lat},{lng}&keywords={keywords}&offset={size}&page={page}&extensions=all") Future searchPoi(@Path("lat") String lat, @Path("lng") String lng, @Path("keywords") String keywords, int size, int page); @@ -184,7 +198,8 @@ abstract class ApiService { ///发送验证码 @GET("/auth/sendVerify/{areaCode}/{mobile}") - Future sendVerify(@Path("areaCode") String areaCode, @Path("mobile") String mobile); + Future sendVerify( + @Path("areaCode") String areaCode, @Path("mobile") String mobile); ///积分商城商品列表 @POST("/creditGoods/list") @@ -298,11 +313,13 @@ abstract class ApiService { ///分页查看资讯列表 @POST("/information/list") - Future>> queryArticle(@Body() Map param); + Future>> queryArticle( + @Body() Map param); ///banner查询 @POST("/banner/page") - Future>> queryBanner(@Body() Map param); + Future>> queryBanner( + @Body() Map param); ///品牌信息 @GET("/home/brand") @@ -404,11 +421,13 @@ abstract class ApiService { /// 动态列表 @POST("/information/trend-list") - Future>> trendList(@Body() Map map); + Future>> trendList( + @Body() Map map); /// 我关注/粉丝的会员列表 @POST("/member/follow/list") - Future>> followList(@Body() Map map); + Future>> followList( + @Body() Map map); ///关注/取关会员 @PUT("/member/follow/{followId}") @@ -428,11 +447,13 @@ abstract class ApiService { ///课程章节列表 @GET("/course/catalogList/{courseId}") - Future>> catalogList(@Path("courseId") String courseId); + Future>> catalogList( + @Path("courseId") String courseId); /// 课程列表 @POST("/course/list") - Future>> courseList(@Body() Map map); + Future>> courseList( + @Body() Map map); ///课程的合集列表 @GET("/course/collectList") @@ -440,7 +461,8 @@ abstract class ApiService { ///合集包含的课程列表 @GET("/course/collect/{collectId}") - Future>> collect(@Path("collectId") String collectId); + Future>> collect( + @Path("collectId") String collectId); ///课程详情 @GET("/course/{id}") @@ -452,15 +474,18 @@ abstract class ApiService { /// APP查询所有成就徽章 并显示会员完成的 @POST("/app-memberAchievement/findBadges") - Future>> findBadges(@Body() Map map); + Future>> findBadges( + @Body() Map map); ///查看一个成就大类详情 - @GET("/app-memberAchievement/getAchievementDetail?achievementCategoryId={achievementCategoryId}") - Future>> getAchievementDetail(@Path("achievementCategoryId") String achievementCategoryId); + @GET( + "/app-memberAchievement/getAchievementDetail?achievementCategoryId={achievementCategoryId}") + Future>> getAchievementDetail( + @Path("achievementCategoryId") String achievementCategoryId); ///会员的权益列表 - @GET("/member/benefitList") - Future>> benefitList(); + @GET("/member/benefitList") + Future>> benefitList(); ///会员权益 @GET("/home/vipBenefit") @@ -480,7 +505,8 @@ abstract class ApiService { ///查看积分订单物流 @GET("/creditOrder/getAppShippingTrace?orderId={orderId}") - Future> getAppShippingTrace(@Path("orderId") String orderId); + Future> getAppShippingTrace( + @Path("orderId") String orderId); ///购买会员等级 @POST("/member/rankBuy") @@ -492,11 +518,13 @@ abstract class ApiService { ///文章合集详情 @GET("/information/category/{id}") - Future> headlinesDetails(@Path("id") String id); + Future> headlinesDetails( + @Path("id") String id); /// 我的邀请会员列表 @POST("/member/inviteMemberList") - Future>> inviteMemberList(@Body() Map map); + Future>> inviteMemberList( + @Body() Map map); ///核销优惠券 @GET("/coupon/wiped/{memberCouponId}") @@ -564,5 +592,10 @@ abstract class ApiService { ///兑换积分门店列表 @GET("/store/storeListByCreditId/{creditGoodsId}") - Future>> storeListByCreditId(@Path("creditGoodsId") String creditGoodsId); + Future>> storeListByCreditId( + @Path("creditGoodsId") String creditGoodsId); + + ///获取APP门店推广渠道 + @GET("/api/ip") + Future getIpInfo(); } diff --git a/lib/retrofit/retrofit_api.g.dart b/lib/retrofit/retrofit_api.g.dart index 4f03eb6d..32506277 100644 --- a/lib/retrofit/retrofit_api.g.dart +++ b/lib/retrofit/retrofit_api.g.dart @@ -2109,6 +2109,26 @@ class _ApiService implements ApiService { return value; } + @override + Future getIpInfo() async { + const _extra = {}; + final queryParameters = {}; + final _data = {}; + final _result = await _dio.request>( + '/api/ip', + queryParameters: queryParameters, + options: RequestOptions( + method: 'GET', + headers: {}, + extra: _extra, + baseUrl: baseUrl), + data: _data); + final value = IpData.fromJson( + _result.data, + ); + return value; + } + @override Future> orderVip(param) async { ArgumentError.checkNotNull(param, 'param'); diff --git a/lib/union/union_list.dart b/lib/union/union_list.dart index 1137804f..b00e8b0b 100644 --- a/lib/union/union_list.dart +++ b/lib/union/union_list.dart @@ -1,28 +1,32 @@ +import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.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/retrofit/data/store.dart'; import 'package:huixiang/utils/font_weight.dart'; -import 'package:huixiang/view_widget/border_text.dart'; -import 'package:huixiang/view_widget/classic_header.dart'; import 'package:huixiang/view_widget/custom_image.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:huixiang/view_widget/request_permission.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:shared_preferences/shared_preferences.dart'; import 'package:shimmer/shimmer.dart'; +import '../retrofit/data/base_data.dart'; +import '../retrofit/retrofit_api.dart'; +import '../utils/flutter_utils.dart'; +import '../view_widget/classic_header.dart'; import '../view_widget/no_data_view.dart'; class UnionList extends StatefulWidget { - final RefreshController refreshController; - final List storeList; - final Function onRefresh; - final Function queryStore; - - UnionList(this.refreshController,this.storeList,this.onRefresh,this.queryStore); + final String serviceType; + final BMFCoordinate latLng; + final String searchKey; + final String city; + UnionList(Key key, this.serviceType, this.latLng, this.searchKey, this.city) + : super(key: key); @override State createState() { @@ -30,89 +34,105 @@ class UnionList extends StatefulWidget { } } -class _UnionList extends State { - final TextEditingController editingController = TextEditingController(); +class _UnionList extends State with AutomaticKeepAliveClientMixin { + ApiService apiService; + List storeList; + final RefreshController _refreshController = RefreshController(); + + @override + bool get wantKeepAlive => true; + + @override + void initState() { + super.initState(); + queryStore(); + } + + queryStore() async { + if (apiService == null) { + SharedPreferences value = await SharedPreferences.getInstance(); + apiService = ApiService( + Dio(), + context: context, + token: value.getString("token"), + ); + } + BaseData> baseData = await apiService.queryStore({ + "city": widget.city ?? "", + // "district": district, + // "province": province, + "latitude": (widget.latLng?.latitude ?? "").toString(), + "longitude": (widget.latLng?.longitude ?? "").toString(), + if (widget.searchKey != "") "searchKey": widget.searchKey, + "serviceType": widget.serviceType, + "exchange": false, + }).catchError((error) { + SmartDialog.showToast(AppUtils.dioErrorTypeToString(error.type), + alignment: Alignment.center); + }); + if (baseData != null && baseData.isSuccess) { + storeList = baseData.data; + } + _refreshController.refreshCompleted(); + EasyLoading.dismiss(); + setState(() {}); + } @override Widget build(BuildContext context) { - return Column( - children: [ - // buildSearchItem(), - Container( - height: MediaQuery.of(context).size.height - - 103.h - - MediaQuery.of(context).padding.top, - child: SmartRefresher( - controller: widget.refreshController, - enablePullUp: false, - enablePullDown: true, - physics: BouncingScrollPhysics(), - header: MyHeader(), - onRefresh: widget.onRefresh, - child: (widget.storeList == null || widget.storeList.length == 0) - ? NoDataView( - src:"assets/image/di_zhi.webp", - isShowBtn: false, - text: "暂无店铺列表~", - fontSize: 16.sp, - margin: EdgeInsets.only(top: 120.h), - ):ListView.builder( - itemCount:widget.storeList == null ? 0 : widget.storeList.length, - padding: EdgeInsets.only( - top: 8.h, - bottom: 100.h, /* + (375.h - 88.h) + 4.h*/ - ), - physics: NeverScrollableScrollPhysics(), - itemBuilder: (context, position) { - return InkWell( - onTap: () { - // if (widget.storeList[position].posType.code == "NORMALSTORE") { - // showDeleteDialog(); - // } - // else - // if ( widget.storeList[position].storeName == "一心回乡商城") { - // Navigator.of(context).pushNamed( - // '/router/shopping_mall_home', - // arguments: { - // "type": 0, - // "id": widget.storeList[position].id, - // "tenant": widget.storeList[position].tenantCode, - // "storeName": widget.storeList[position].storeName - // }, - // ); - // } - // else - { - Navigator.of(context).pushNamed( - '/router/store_order', - arguments: { - "id": widget.storeList[position].id, - "tenant": widget.storeList[position].tenantCode, - "storeName": widget.storeList[position].storeName, - "distance":widget.storeList[position].distance - }, - ); - } - }, - child: - buildStoreItem(widget.storeList[position], position), - ); - })), - ) - ], + return SmartRefresher( + controller: _refreshController, + enablePullDown: true, + enablePullUp: false, + header: MyHeader(color: Colors.white,), + physics: BouncingScrollPhysics(), + onRefresh: queryStore, + child: (storeList == null || storeList.length == 0) + ? NoDataView( + src: "assets/image/di_zhi.webp", + isShowBtn: false, + text: "暂无店铺列表~", + fontSize: 16.sp, + margin: EdgeInsets.only(top: 120.h), + ) + : ListView.builder( + itemCount: storeList.length, + padding: EdgeInsets.only( + top: 8.h, + bottom: 100.h, + ), + itemBuilder: (context, position) { + return InkWell( + onTap: () { + { + Navigator.of(context).pushNamed( + '/router/store_order', + arguments: { + "id": storeList[position].id, + "tenant": storeList[position].tenantCode, + "storeName": storeList[position].storeName, + "distance": storeList[position].distance + }, + ); + } + }, + child: buildStoreItem(storeList[position], position), + ); + }, + ), ); } - Widget sm(){ + Widget sm() { return Container( - margin:EdgeInsets.symmetric(horizontal: 14.w,vertical: 8.h), + margin: EdgeInsets.symmetric(horizontal: 14.w, vertical: 8.h), width: double.infinity, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(6), ), height: 223.h, - child:Column( + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Shimmer.fromColors( @@ -124,19 +144,25 @@ class _UnionList extends State { height: 140.h, ), ), - Padding(padding: EdgeInsets.only(left: 6.w,bottom: 5.h,top: 12.h), - child: Shimmer.fromColors( - baseColor: Color(0XFFD8D8D8), - highlightColor: Color(0XFFD8D8D8), - child: Container( - decoration: BoxDecoration( - color: Color(0XFFD8D8D8), - borderRadius: BorderRadius.circular(2), + Padding( + padding: EdgeInsets.only(left: 6.w, bottom: 5.h, top: 12.h), + child: Shimmer.fromColors( + baseColor: Color(0XFFD8D8D8), + highlightColor: Color(0XFFD8D8D8), + child: Container( + decoration: BoxDecoration( + color: Color(0XFFD8D8D8), + borderRadius: BorderRadius.circular(2), + ), + width: 108.w, + height: 20.h, ), - width: 108.w, - height: 20.h, ), - ),),Padding(padding: EdgeInsets.only(left: 6.w,), + ), + Padding( + padding: EdgeInsets.only( + left: 6.w, + ), child: Shimmer.fromColors( baseColor: Color(0XFFD8D8D8), highlightColor: Color(0XFFD8D8D8), @@ -148,63 +174,9 @@ class _UnionList extends State { width: 260.w, height: 20.h, ), - ),), - ], - ), - ); - } - - Widget buildSearchItem() { - return Container( - height: 36.h, - margin: EdgeInsets.fromLTRB(6.w, 0, 14.w, 0), - padding: EdgeInsets.fromLTRB(0, 6.h, 0, 6.h), - decoration: BoxDecoration( - color: Color(0xFFF5FAF7), - borderRadius: BorderRadius.circular(4), - boxShadow: [ - BoxShadow( - color: Colors.black.withAlpha(12), - offset: Offset(0, 3), - blurRadius: 14, - spreadRadius: 0, - ), - ], - ), - child: TextField( - textInputAction: TextInputAction.search, - onEditingComplete: () { - FocusScope.of(context).requestFocus(FocusNode()); - widget.queryStore(editingController.text); - }, - controller: editingController, - cursorHeight: 25.h, - decoration: InputDecoration( - contentPadding: EdgeInsets.symmetric( - vertical: 12.h, - ), - prefixIcon:InkWell( - onTap: () { - widget.queryStore(editingController.text); - }, - child: Icon( - Icons.search, - size: 24, - color: Colors.black, - ), - ), - suffixIcon: InkWell( - onTap: () { - editingController.clear(); - }, - child: Icon( - Icons.close, - size: 19, - color: Colors.grey, ), ), - border: InputBorder.none, - ), + ], ), ); } @@ -275,62 +247,65 @@ class _UnionList extends State { ), Expanded( child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 40.h, - ), - Text( - store?.storeName ?? "", - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Color(0xFF0D0D0D), - fontSize: 14.sp, - fontWeight: MyFontWeight.bold, - ), + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 40.h, + ), + Text( + store?.storeName ?? "", + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Color(0xFF0D0D0D), + fontSize: 14.sp, + fontWeight: MyFontWeight.bold, + ), + ), + SizedBox( + height: 5.h, + ), + Expanded( + child: Text( + "${S.of(context).dizhi}:${store.address}", + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Color(0xFF4D4D4D), + fontSize: 12.sp, + fontWeight: MyFontWeight.regular, ), - SizedBox( - height: 5.h, + ), + ) + ], + )), + if (store.distance != null) + Container( + width: 59.w, + height: 18.h, + alignment: Alignment.center, + margin: EdgeInsets.only(top: 20.h), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(2), + color: Color(0xFF32A060), + ), + child: Visibility( + child: Text( + (store.distance ?? 0) > 1000 + ? S.of(context).gongli( + ((store.distance ?? 0) / 1000 * 100).toInt() / + 100.0) + : S.of(context).mi( + ((store.distance ?? 0) * 100).toInt() / + 100.0), + style: TextStyle( + color: Color(0xFFFFFFFF), + fontSize: 10.sp, ), - Expanded(child: Text( - "${S.of(context).dizhi}:${store.address}", - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Color(0xFF4D4D4D), - fontSize: 12.sp, - fontWeight: MyFontWeight.regular, - ), - ),) - ], - )), - if(store.distance != null) - Container( - width: 59.w, - height: 18.h, - alignment: Alignment.center, - margin: EdgeInsets.only(top: 20.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(2), - color: Color(0xFF32A060), - ), - child: Visibility( - child: Text( - (store.distance ?? 0) > 1000 - ? S.of(context).gongli( - ((store.distance ?? 0) / 1000 * 100).toInt() / - 100.0) - : S.of(context).mi( - ((store.distance ?? 0) * 100).toInt() / 100.0), - style: TextStyle( - color: Color(0xFFFFFFFF), - fontSize: 10.sp, ), + visible: store.distance != null, ), - visible: store.distance != null, ), - ), ], ), ), @@ -339,130 +314,4 @@ class _UnionList extends State { ), ); } - - ///扫码提示弹窗 - 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: "取消", - 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: "确定", - 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) { - // http://pos.app.gznl.top/placeorder/?tableId=1315903669597634560&tenantCode=1166&shopId=1300372027722432512 - // 新版桌子码跳转 - // http://miniscan.lotus-wallet.com/placeorder?tenant_code=1194&table_id=1669609340031467520&store_id=1637659387134738432 - var result = await Navigator.of(context).pushNamed('/router/qr_scan'); - // String result = await scanner.scan(); - 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).pushNamed( - '/router/store_order', - arguments: { - "id": shopId, - "tenant": tenantCode, - "storeName": "", - "tableId": int.tryParse(tableId), - }, - ); - } - } else { - await Permission.camera.request(); - } - } - } diff --git a/lib/union/union_page.dart b/lib/union/union_page.dart index 96214aac..5d80f3cb 100644 --- a/lib/union/union_page.dart +++ b/lib/union/union_page.dart @@ -4,36 +4,23 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_baidu_mapapi_map/flutter_baidu_mapapi_map.dart'; import 'package:flutter_baidu_mapapi_utils/flutter_baidu_mapapi_utils.dart'; import 'package:flutter_bmflocation/flutter_bmflocation.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/main.dart'; -import 'package:huixiang/retrofit/data/base_data.dart'; -import 'package:huixiang/retrofit/data/store.dart'; +import 'package:huixiang/retrofit/data/ip_data.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/union/union_list.dart'; import 'package:huixiang/utils/event_type.dart'; -import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/utils/location.dart'; -import 'package:huixiang/view_widget/border_text.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_tab.dart'; -import 'package:huixiang/view_widget/request_permission.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:shared_preferences/shared_preferences.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.dart'; -import '../utils/flutter_utils.dart'; -import '../view_widget/item_title.dart'; +import '../view_widget/no_data_view.dart'; class UnionPage extends StatefulWidget { final int initialIndex; @@ -51,19 +38,12 @@ class UnionPageState extends State AutomaticKeepAliveClientMixin, WidgetsBindingObserver, SingleTickerProviderStateMixin { - final RefreshController refreshController = - RefreshController(initialRefresh: false); - final RefreshController refreshController1 = - RefreshController(initialRefresh: false); - final RefreshController refreshController2 = - RefreshController(initialRefresh: false); - final RefreshController refreshController3 = - RefreshController(initialRefresh: false); - ApiService apiService; + final TextEditingController editingController = TextEditingController(); bool isKeyBoardShow = false; + TabController tabController; BMFCoordinate latLng; - final TextEditingController editingController = TextEditingController(); - String areaName = ""; + String areaName; + List _allKey = []; jumpIndex(jpIndex) { tabController.index = jpIndex; @@ -76,11 +56,6 @@ class UnionPageState extends State if (Location.getInstance() != null && Location.getInstance().aMapFlutterLocation != null) Location.getInstance().aMapFlutterLocation.stopLocation(); - - if (refreshController != null) refreshController.dispose(); - if (refreshController1 != null) refreshController1.dispose(); - if (refreshController2 != null) refreshController2.dispose(); - if (refreshController3 != null) refreshController3.dispose(); } @override @@ -105,78 +80,36 @@ class UnionPageState extends State @override void initState() { super.initState(); - if (tabController == null) - tabController = TabController( - length: 4, vsync: this, initialIndex: widget.initialIndex); - // tabController?.addListener(() { - // startLocation(); - // }); + tabController = TabController( + length: 4, vsync: this, initialIndex: widget.initialIndex); WidgetsBinding.instance.addObserver(this); - eventBus.on().listen((event) { if (event.type < 3) { setState(() {}); } }); - - getLatLng(); - startLocation(false); - } - - RefreshController tabRefresh() { - RefreshController tempRef; - if (tabController.index == 0) - tempRef = refreshController; - else if (tabController.index == 1) - tempRef = refreshController1; - else if (tabController.index == 2) - tempRef = refreshController2; - else if (tabController.index == 3) tempRef = refreshController3; - return tempRef; + queryIpInfo(); } - startLocation(bool isOnRefresh) async { - if (!isOnRefresh) EasyLoading.show(status: S.current.zhengzaijiazai); - Location.getInstance().startLocation(context, (BaiduLocation result) { + startLocation() async { + Location.getInstance().startLocation(context, (BaiduLocation result) async { if (result != null && result.latitude != null && result.longitude != null) { print("location: $result"); latLng = BMFCoordinate(result.latitude, result.longitude); - BMFCalculateUtils.coordConvert( + latLng = await BMFCalculateUtils.coordConvert( coordinate: latLng, fromType: BMF_COORD_TYPE.BD09LL, - toType: BMF_COORD_TYPE.COMMON) - .then((value) { - this.latLng = value; - saveLatLng( - value, result.province, result.city, result.district); - print("union: Location result ${value.latitude} " - "${value.longitude}"); - Location.getInstance().stopLocation(); - queryStore( - "${value.latitude}", - "${value.longitude}", - result.province, - result.city, - result.district, - "", - -1); - if (_mapController != null) - _mapController.updateMapOptions(BMFMapOptions( - center: value, - zoomLevel: 15, - )); - }); + toType: BMF_COORD_TYPE.COMMON); + await saveLatLng(latLng, result.province, result.city, result.district); + print("union: Location result ${latLng.latitude} " + "${latLng.longitude}"); + Location.getInstance().stopLocation(); } else { - getLatLng(); - // EasyLoading.dismiss(); - } - }).then((value) { - if (!value) { - EasyLoading.dismiss(); - tabRefresh().refreshCompleted(); + await getLatLng(); } + loadFinish(showLoading: false); }); } @@ -190,400 +123,163 @@ class UnionPageState extends State } getLatLng() async { - SharedPreferences.getInstance().then( - (value) => { - // apiService = ApiService(Dio(), - // context: context, - // token: value.getString('token'), - // showLoading: false), - if (value.containsKey("latitude") && - value.containsKey("longitude") && - value.containsKey("province") && - value.containsKey("city") && - value.containsKey("district")) - { - latLng = BMFCoordinate(double.tryParse(value.getString("latitude")), - double.tryParse(value.getString("longitude"))), - queryStore( - value.getString("latitude"), - value.getString("longitude"), - value.getString("province"), - value.getString("city"), - value.getString("district"), - "", - -1), - setState(() { - if (_mapController != null) { - _mapController.updateMapOptions(BMFMapOptions( - center: latLng, - zoomLevel: 15, - )); - } - }) - } - else - { - queryStore("", "", "", "", "", "", -1), - } - }, - ); + var tempLatLng = await SharedPreferences.getInstance(); + if (tempLatLng.containsKey("latitude") && + tempLatLng.containsKey("longitude") && + tempLatLng.containsKey("province") && + tempLatLng.containsKey("city") && + tempLatLng.containsKey("district")) { + latLng = BMFCoordinate(double.tryParse(tempLatLng.getString("latitude")), + double.tryParse(tempLatLng.getString("longitude"))); + } } - List storeList; - List storeList1; - List storeList2; - List storeList3; - - queryStore(latitude, longitude, province, city, district, searchKey, - int index) async { - if (apiService == null) { - SharedPreferences value = await SharedPreferences.getInstance(); - apiService = ApiService( - Dio(), - context: context, - token: value.getString("token"), - ); + queryIpInfo() async { + EasyLoading.show(status: S.current.zhengzaijiazai); + ApiService apiIpService = ApiService(Dio(), context: context, isIp: true); + IpData baseData = await apiIpService.getIpInfo().catchError((onError) {}); + if (baseData != null) { + areaName = baseData.city.replaceAll("市", ""); } - BaseData> baseData = await apiService.queryStore({ - "city": city, - // "district": district, - // "province": province, - "latitude": latitude, - "longitude": longitude, - if(searchKey != "") - "searchKey": searchKey, - "serviceType": (tabController.index == 0 && index == -1) || index == 0 - ? "" - : ((tabController.index == 1 && index == -1) || index == 1 - ? "EATSTORE" - : ((tabController.index == 2 && index == -1) || index == 2 - ? "DRINKSTORE" - : "HAPPYSTORE")), - "exchange":false, - }).catchError((error) { - SmartDialog.showToast(AppUtils.dioErrorTypeToString(error.type), - alignment: Alignment.center); - if (index == -1) tabRefresh().refreshFailed(); - }); - if (baseData != null && baseData.isSuccess) { - if (index == -1 && storeList == null) { - if (tabController.index != 0) - queryStore( - latitude, longitude, province, city, district, searchKey, 0); - if (tabController.index != 1) - queryStore( - latitude, longitude, province, city, district, searchKey, 1); - if (tabController.index != 2) - queryStore( - latitude, longitude, province, city, district, searchKey, 2); - if (tabController.index != 3) - queryStore( - latitude, longitude, province, city, district, searchKey, 3); - } - if ((tabController.index == 0 && index == -1) || index == 0) - storeList = baseData.data; - else if ((tabController.index == 1 && index == -1) || index == 1) - storeList1 = baseData.data; - else if ((tabController.index == 2 && index == -1) || index == 2) - storeList2 = baseData.data; - else if ((tabController.index == 3 && index == -1) || index == 3) - storeList3 = baseData.data; - if (index == -1) tabRefresh().refreshCompleted(); - } else { - if (index == -1) tabRefresh().refreshFailed(); - } - EasyLoading.dismiss(); - setState(() {}); + startLocation(); } - TabController tabController; + loadFinish({bool showLoading = true}) { + if (showLoading) EasyLoading.show(status: S.current.zhengzaijiazai); + _allKey = [GlobalKey(), GlobalKey(), GlobalKey(), GlobalKey()]; + setState(() {}); + } @override Widget build(BuildContext context) { super.build(context); return GestureDetector( - behavior: HitTestBehavior.translucent, - onTap: () { - FocusScope.of(context).requestFocus(FocusNode()); - }, - child:Stack( + behavior: HitTestBehavior.translucent, + onTap: () { + FocusScope.of(context).requestFocus(FocusNode()); + }, + child: Container( + child: Column( children: [ - Container( - decoration: BoxDecoration( - image: DecorationImage( - fit: BoxFit.fill, - image: AssetImage("assets/image/settlement_bg.webp"), + Row( + children: [ + Padding( + padding: EdgeInsets.only(left: 18.w, right: 10.w), + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + Navigator.of(context).pushNamed( + '/router/union_select_city', + arguments: {"cityName": areaName}).then((value) { + if (value != null) { + areaName = value; + loadFinish(); + } + }); + }, + child: Row( + children: [ + Text( + areaName ?? "", + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.bold, + color: Colors.white), + ), + Icon( + Icons.keyboard_arrow_down, + color: Colors.white, + size: 24, + ) + ], + ), + ), ), - ), - width: double.infinity, - height: 306.h, + Expanded(child: buildSearchItem()) + ], ), - Scaffold( - backgroundColor: Colors.transparent, - resizeToAvoidBottomInset: false, - appBar: PreferredSize( - preferredSize: Size(double.infinity, 100.h), - child: MyAppBar( - background: Color(0xFF32A060), - title: "", - leading: false, - brightness: Brightness.light, - bottom: PreferredSize( - preferredSize: Size(double.infinity, 38.h), - child:Align( - alignment: Alignment.centerLeft, - child: Theme( - data: ThemeData( - splashColor: Colors.transparent, // 点击时的水波纹颜色设置为透明 - highlightColor: Colors.transparent, // 点击时的背景高亮颜色设置为透明 - ), - child: TabBar( - controller: tabController, - isScrollable: true, - //可滚动 - indicatorColor: Colors.white, - labelColor: Colors.white, - labelStyle: TextStyle( - fontSize: 18.sp, - fontWeight: FontWeight.bold, - ), - unselectedLabelStyle: TextStyle( - fontSize: 15.sp, - fontWeight: FontWeight.normal, - ), - // controller: tabController, - //未选中文字颜色 - unselectedLabelColor: Colors.white, - indicatorSize: TabBarIndicatorSize.label, - //指示器与文字等宽 - tabs: [ - MyTab(text: S.of(context).quanbu), - MyTab(text: S.of(context).chi), - MyTab(text: S.of(context).he), - MyTab(text: S.of(context).wan), - ], - )), - ), - ), - titleChild:Row(children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: (){ - Navigator.of(context) - .pushNamed('/router/union_select_city') - .then((value) { - if (value != null) - setState(() { - areaName = value; - }); - }); - }, - child: Row( - children: [ - Text( - areaName ?? "武汉", - overflow: TextOverflow.ellipsis, - maxLines:1, - style: TextStyle( - fontSize: 14.sp, - fontWeight: FontWeight.bold, - color: Colors.white), - ), - Icon( - Icons.keyboard_arrow_down, - color: Colors.white, - size: 24, - ) - ], - ), - ), - SizedBox(width:10.w,), - Expanded(child:buildSearchItem()) - ],)), + Align( + alignment: Alignment.centerLeft, + child: TabBar( + controller: tabController, + isScrollable: true, + //可滚动 + indicatorColor: Colors.white, + labelColor: Colors.white, + labelStyle: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.bold, + ), + unselectedLabelStyle: TextStyle( + fontSize: 15.sp, + fontWeight: FontWeight.normal, + ), + //未选中文字颜色 + unselectedLabelColor: Colors.white, + indicatorSize: TabBarIndicatorSize.label, + //指示器与文字等宽 + tabs: [ + MyTab(text: S.of(context).quanbu), + MyTab(text: S.of(context).chi), + MyTab(text: S.of(context).he), + MyTab(text: S.of(context).wan), + ], ), - body: TabBarView( + ), + _allKey.isEmpty + ? NoDataView( + src: "assets/image/di_zhi.webp", + isShowBtn: false, + text: "暂无店铺列表~", + fontSize: 16.sp, + margin: EdgeInsets.only(top: 120.h), + ) + : Expanded( + child: TabBarView( controller: tabController, children: [ - UnionList(refreshController, storeList, () { - startLocation(true); - },(txt){ - queryStore("","","","","",txt,0); - }), - UnionList(refreshController1, storeList1, () { - startLocation(true); - },(txt){ - queryStore("","","","","",txt,0); - }), - UnionList(refreshController2, storeList2, () { - startLocation(true); - },(txt){ - queryStore("","","","","",txt,0); - }), - UnionList(refreshController3, storeList3, () { - startLocation(true); - },(txt){ - queryStore("","","","","",txt,0); - }), + UnionList(_allKey[0], "", latLng, + editingController.text, areaName), + UnionList(_allKey[1], "EATSTORE", latLng, + editingController.text, areaName), + UnionList(_allKey[2], "DRINKSTORE", latLng, + editingController.text, areaName), + UnionList(_allKey[3], "HAPPYSTORE", latLng, + editingController.text, areaName), ], ), - ), + ) ], - )); - // GestureDetector( - // onTap: () { - // FocusScope.of(context).requestFocus(FocusNode()); - // }, - // child: Scaffold( - // backgroundColor: Colors.white, - // resizeToAvoidBottomInset: false, - // appBar: MyAppBar( - // // titleChild: buildSearchItem(), - // title: "", - // leading: false, - // background: Colors.white, - // brightness: Brightness.light, - // ), - // body: Column( - // children: [ - // // Row( - // // mainAxisAlignment: MainAxisAlignment.start, - // // crossAxisAlignment: CrossAxisAlignment.end, - // // children: [ - // // Expanded(child:PreferredSize( - // // preferredSize: Size(double.infinity, 52.h), - // // child: Container( - // // padding: EdgeInsets.only(top:15.h), - // // color: Color(0xFFFAFAFA), - // // child: ItemTitle( - // // text: S.of(context).jingbilianmenghuiyuandian, - // // imgPath: "assets/image/icon_union_store.webp", - // // ), - // // ), - // // )), - // // GestureDetector( - // // onTap: (){ - // // setState(() { - // // var storeName = storeList.firstWhere((x)=>x.storeName == "一心回乡商城"); - // // if(storeName == null) - // // return; - // // Navigator.of(context).pushNamed( - // // '/router/shopping_mall_home', - // // arguments: { - // // "type":0, - // // "id":storeName.id, - // // "tenant": storeName.tenantCode, - // // "storeName":storeName.storeName - // // }, - // // ); - // // }); - // // }, - // // child:Container( - // // margin: EdgeInsets.only(right: 18), - // // height: 25.h, - // // width: 102.w, - // // color: Colors.white, - // // child:Row( - // // mainAxisAlignment: MainAxisAlignment.center, - // // crossAxisAlignment: CrossAxisAlignment.center, - // // children: [ - // // Text( - // // "一心回乡商城", - // // style: TextStyle( - // // fontSize: 12.sp, - // // fontWeight: MyFontWeight.regular, - // // color: Colors.black, - // // ), - // // ), - // // Icon( - // // Icons.keyboard_arrow_right, - // // size: 16, - // // ), - // // ], - // // ), - // // ), - // // ), - // // ], - // // ), - // buildItem() - // ], - // ), - // ), - // ); - } - - Widget buildItem( - RefreshController refreshController, - ) { - return Column( - children: [ - // buildSearchItem(), - Container( - height: MediaQuery.of(context).size.height - - 103.h - - MediaQuery.of(context).padding.top, - child: SmartRefresher( - controller: refreshController, - enablePullUp: false, - enablePullDown: true, - physics: BouncingScrollPhysics(), - header: MyHeader(), - onRefresh: () { - startLocation(false); - }, - child: ListView.builder( - itemCount: storeList == null ? 0 : storeList.length, - padding: EdgeInsets.only( - top: 8.h, - bottom: 84.h, /* + (375.h - 88.h) + 4.h*/ - ), - physics: NeverScrollableScrollPhysics(), - itemBuilder: (context, position) { - return InkWell( - onTap: () { - if (storeList[position].posType.code == "NORMALSTORE") { - showDeleteDialog(); - } else if (storeList[position].posType.code == - "RETAILSTORE" && - storeList[position].storeName == "一心回乡商城") { - Navigator.of(context).pushNamed( - '/router/shopping_mall_home', - arguments: { - "type": 0, - "id": storeList[position].id, - "tenant": storeList[position].tenantCode, - "storeName": storeList[position].storeName - }, - ); - } else { - Navigator.of(context).pushNamed( - '/router/store_order', - arguments: { - "id": storeList[position].id, - "tenant": storeList[position].tenantCode, - "storeName": storeList[position].storeName - }, - ); - } - }, - child: buildStoreItem(storeList[position], position), - ); - })), - ) - ], + ), + padding: + EdgeInsets.only(top: MediaQuery.of(context).padding.top + 17.h), + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Color(0xFF32A060), + Color(0xFF32A060), + Colors.white, + Colors.white, + ], + stops: [ + 0, + 0.2, + 0.4, + 1 + ]), + ), + ), ); } - BMFMapController _mapController; - - void onMapCreated(BMFMapController controller) { - _mapController = controller; - } - Widget buildSearchItem() { return Container( height: 36.h, margin: EdgeInsets.fromLTRB(6.w, 0, 14.w, 0), - padding: EdgeInsets.fromLTRB(0, 6.h, 0, 6.h), decoration: BoxDecoration( color: Color(0xFFF5FAF7), borderRadius: BorderRadius.circular(4), @@ -600,23 +296,21 @@ class UnionPageState extends State textInputAction: TextInputAction.search, onEditingComplete: () { FocusScope.of(context).requestFocus(FocusNode()); - queryStore("","","","","",editingController.text,0); + loadFinish(); }, controller: editingController, cursorHeight: 25.h, decoration: InputDecoration( contentPadding: EdgeInsets.symmetric( - vertical: 12.h, + vertical: 14.h, ), hintText: "搜索联盟会员店", hintStyle: TextStyle( fontSize: 12.sp, color: Color(0xFFB3B3B3), ), - prefixIcon:InkWell( - onTap: () { - queryStore("","","","","",editingController.text,0); - }, + prefixIcon: GestureDetector( + onTap: loadFinish, child: Image.asset( "assets/image/icon_search.webp", width: 16, @@ -629,334 +323,6 @@ class UnionPageState extends State ); } - Widget buildSliverAppBar(BMFMapWidget map) { - return SliverAppBar( - // 滑上去时搜索隐藏 - // floating: true, - // snap: true, - pinned: true, - backgroundColor: Color(0xFFFAFAFA), - elevation: 0, - automaticallyImplyLeading: false, - title: Container( - height: 36.h, - margin: EdgeInsets.fromLTRB(16.w, 0, 16.w, 0), - padding: EdgeInsets.fromLTRB(0, 6.h, 0, 6.h), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(4)), - boxShadow: [ - BoxShadow( - color: Colors.black.withAlpha(12), - offset: Offset(0, 3), - blurRadius: 14, - spreadRadius: 0, - ) - ]), - child: TextField( - textInputAction: TextInputAction.search, - onEditingComplete: () { - startLocation(false); - }, - controller: editingController, - cursorHeight: 30.h, - decoration: InputDecoration( - contentPadding: EdgeInsets.symmetric(vertical: 12.h), - prefixIcon: Icon( - Icons.search, - size: 24, - color: Colors.black, - ), - suffixIcon: InkWell( - onTap: () { - editingController.clear(); - }, - child: Icon( - Icons.close, - size: 19, - color: Colors.grey, - ), - ), - border: InputBorder.none, - ), - ), - ), - flexibleSpace: FlexibleSpaceBar( - background: Container( - child: map, - ), - ), - expandedHeight: 375.h, - bottom: PreferredSize( - preferredSize: Size(double.infinity, 52.h), - child: Container( - padding: EdgeInsets.only(top: 6.h), - color: Color(0xFFFAFAFA), - child: ItemTitle( - text: S.of(context).jingbilianmenghuiyuandian, - imgPath: "assets/image/icon_union_store.webp", - ), - ), - ), - ); - } - - Widget buildStoreItem(Store store, position) { - return Container( - margin: EdgeInsets.fromLTRB(16.w, 8.h, 16.w, 8.h), - // padding: EdgeInsets.fromLTRB(20.w, 20.h, 20.w, 20.h), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(8)), - boxShadow: [ - BoxShadow( - color: Colors.black.withAlpha(25), - offset: Offset(0, 1), - blurRadius: 12, - spreadRadius: 0, - ) - ]), - width: double.infinity, - height: 228.h, - child: Stack( - children: [ - Positioned( - top: 0, - left: 0, - right: 0, - child: ClipRRect( - child: MImage( - store.facade, - width: double.infinity, - height: 140.h, - fit: BoxFit.cover, - errorSrc: "assets/image/default_1.webp", - fadeSrc: "assets/image/default_1.webp", - ), - borderRadius: BorderRadius.vertical( - top: Radius.circular(4), - ), - ), - ), - Positioned( - bottom: 0, - left: 0, - right: 0, - child: Container(), - ), - Positioned( - bottom: 16.h, - left: 12.w, - right: 0, - child: Container( - height: 100.h, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - MImage( - store.logo, - width: 57, - height: 57, - fit: BoxFit.cover, - isCircle: true, - errorSrc: "assets/image/default_1.webp", - fadeSrc: "assets/image/default_1.webp", - ), - SizedBox( - width: 6.w, - ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 40.h, - ), - Text( - store.storeName, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Color(0xFF0D0D0D), - fontSize: 14.sp, - fontWeight: MyFontWeight.bold, - ), - ), - SizedBox( - height: 5.h, - ), - Text( - "${S.of(context).dizhi}:${store.address}", - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Color(0xFF4D4D4D), - fontSize: 12.sp, - fontWeight: MyFontWeight.regular, - ), - ), - ], - )), - Container( - width: 59.w, - height: 18.h, - alignment: Alignment.center, - margin: EdgeInsets.only(top: 20.h), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(2), - color: Color(0xFF32A060), - ), - child: Visibility( - child: Text( - (store.distance ?? 0) > 1000 - ? S.of(context).gongli( - ((store.distance ?? 0) / 1000 * 100).toInt() / - 100.0) - : S.of(context).mi( - ((store.distance ?? 0) * 100).toInt() / 100.0), - style: TextStyle( - color: Color(0xFFFFFFFF), - fontSize: 10.sp, - ), - ), - visible: store.distance != null, - ), - ), - ], - ), - ), - ), - ], - ), - ); - } - - ///扫码提示弹窗 - 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: "取消", - 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: "确定", - 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) { - // http://pos.app.gznl.top/placeorder/?tableId=1315903669597634560&tenantCode=1166&shopId=1300372027722432512 - // 新版桌子码跳转 - // http://miniscan.lotus-wallet.com/placeorder?tenant_code=1194&table_id=1669609340031467520&store_id=1637659387134738432 - var result = await Navigator.of(context).pushNamed('/router/qr_scan'); - // String result = await scanner.scan(); - 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).pushNamed( - '/router/store_order', - arguments: { - "id": shopId, - "tenant": tenantCode, - "storeName": "", - "tableId": int.tryParse(tableId), - }, - ); - } - } else { - await Permission.camera.request(); - } - } - @override bool get wantKeepAlive => true; } diff --git a/lib/union/union_select_city.dart b/lib/union/union_select_city.dart index ad582e09..710e6bf4 100644 --- a/lib/union/union_select_city.dart +++ b/lib/union/union_select_city.dart @@ -1,14 +1,20 @@ import 'dart:convert'; +import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:huixiang/view_widget/my_appbar.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; +import '../retrofit/data/ip_data.dart'; +import '../retrofit/retrofit_api.dart'; + class UnionSelectCity extends StatefulWidget { + final Map arguments; + + UnionSelectCity({this.arguments}); @override State createState() { return _UnionSelectCity(); @@ -18,25 +24,58 @@ class UnionSelectCity extends StatefulWidget { class _UnionSelectCity extends State { RefreshController refreshController = RefreshController(); Map areaMap; + ApiService apiIpService; + String ipName; + int ipState = 0; + List hotCity = []; List areaList = []; - final TextEditingController editingController = TextEditingController(); @override void initState() { super.initState(); areaCode(); + queryIpInfo(); } - void areaCode() async { + void areaCode({String searchTxt}) async { var value = await rootBundle.loadString('assets/map_style/chinese_cities.json'); + areaList.clear(); areaMap = jsonDecode(value); + hotCity = (areaMap["热门城市"] as List).map((e) { + return e["area"].toString(); + }).toList(); + areaMap.remove("热门城市"); + Map tempAreaMap = jsonDecode(value); areaMap.forEach((key, value) { - areaList.add(key); + if (searchTxt != null && searchTxt.trim() != "") + value.forEach((element) { + if (!element["area"].contains(searchTxt)) + (tempAreaMap[key] as List) + .removeWhere((el) => el["area"] == element["area"]); + }); + if (tempAreaMap[key].isNotEmpty) areaList.add(key); }); + areaMap = tempAreaMap; setState(() {}); } + queryIpInfo() async { + apiIpService = ApiService( + Dio(), + context: context, + isIp: true + ); + IpData baseData = await apiIpService.getIpInfo().catchError((onError) {}); + if (baseData != null) { + ipName = baseData.city.replaceAll("市", ""); + if(ipName != widget.arguments["cityName"] ){ + ipState=2; + setState((){}); + } + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -60,9 +99,9 @@ class _UnionSelectCity extends State { onTap: () { Navigator.of(context).pop(); }, - child:Container( - padding: EdgeInsets.only(right:21.w), - child: Icon( + child: Container( + padding: EdgeInsets.only(right: 21.w), + child: Icon( Icons.arrow_back_ios, color: Colors.black, ), @@ -70,206 +109,112 @@ class _UnionSelectCity extends State { Expanded(child: searchCityItem()) ], ), - Padding(padding:EdgeInsets.only(top: 16.h,bottom: 24.h), - child:Row( - children: [ - Padding(padding:EdgeInsets.only(right: 10.w), - child: Text( - "当前位置", - style: TextStyle( - color: Color(0xFFA29E9E), - fontWeight: MyFontWeight.medium, - fontSize: 16.sp, - ), - ),), - Image.asset( - "assets/image/icon_union_location.webp", - width:20, - height:20, - ), - Padding(padding:EdgeInsets.only(left:8.w,), - child: Text( - "当前位置", - style: TextStyle( - color: Color(0xFF4D4D4D), - fontWeight: MyFontWeight.medium, - fontSize: 16.sp, - ), - ),), - ], - )), - Padding(padding:EdgeInsets.only(bottom: 16.h), - child: Text( - "热门城市", - style: TextStyle( - color: Color(0xFFA29E9E), - fontWeight: MyFontWeight.medium, - fontSize: 16.sp, - ), - ),), - Padding(padding:EdgeInsets.only(right: 14.h,bottom: 14.h), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: (){ - Navigator.of(context).pop("上海");}, - child: Container( - decoration: BoxDecoration( - color: Color(0xFFF7F7F7), - borderRadius: BorderRadius.circular(4), - ), - padding: EdgeInsets.symmetric(horizontal:24.w,vertical:5.h), - child: Text( - "上海", - style: TextStyle( - color: Color(0xFF4D4D4D), - fontWeight: MyFontWeight.medium, - fontSize: 16.sp, - ), - ) - )), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: (){ - Navigator.of(context).pop("深圳");}, - child: Container( - decoration: BoxDecoration( - color: Color(0xFFF7F7F7), - borderRadius: BorderRadius.circular(4), - ), - padding: EdgeInsets.symmetric(horizontal:24.w,vertical:5.h), - child: Text( - "深圳", - style: TextStyle( - color: Color(0xFF4D4D4D), - fontWeight: MyFontWeight.medium, - fontSize: 16.sp, - ), - ) - )), GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: (){ - Navigator.of(context).pop("北京");}, - child: Container( - decoration: BoxDecoration( - color: Color(0xFFF7F7F7), - borderRadius: BorderRadius.circular(4), - ), - padding: EdgeInsets.symmetric(horizontal:24.w,vertical:5.h), - child: Text( - "北京", - style: TextStyle( - color: Color(0xFF4D4D4D), - fontWeight: MyFontWeight.medium, - fontSize: 16.sp, - ), - ) - )), GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: (){ - Navigator.of(context).pop("广州");}, - child: Container( - decoration: BoxDecoration( - color: Color(0xFFF7F7F7), - borderRadius: BorderRadius.circular(4), - ), - padding: EdgeInsets.symmetric(horizontal:24.w,vertical:5.h), - child: Text( - "广州", - style: TextStyle( - color: Color(0xFF4D4D4D), - fontWeight: MyFontWeight.medium, - fontSize: 16.sp, - ), - ) - )), - ], - ),), - Padding(padding:EdgeInsets.only(right: 14.h,), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: (){ - Navigator.of(context).pop("成都");}, - child: Container( - decoration: BoxDecoration( - color: Color(0xFFF7F7F7), - borderRadius: BorderRadius.circular(4), - ), - padding: EdgeInsets.symmetric(horizontal:24.w,vertical:5.h), + Padding( + padding: EdgeInsets.only(top: 16.h, bottom: 24.h), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.only(right: 10.w), child: Text( - "成都", + (ipState == 0||ipState == 1) ? "当前位置" : "已选:", style: TextStyle( - color: Color(0xFF4D4D4D), + color: Color(0xFFA29E9E), fontWeight: MyFontWeight.medium, fontSize: 16.sp, ), - ) - )), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: (){ - Navigator.of(context).pop("杭州");}, - child: Container( - decoration: BoxDecoration( - color: Color(0xFFF7F7F7), - borderRadius: BorderRadius.circular(4), ), - padding: EdgeInsets.symmetric(horizontal:24.w,vertical:5.h), + ), + Image.asset( + "assets/image/icon_union_location.webp", + width: 20, + height: 20, + ), + Expanded( + // padding: EdgeInsets.only( + // left: 8.w, + // ), child: Text( - "杭州", + (ipState== 1) ? (ipName??""):widget.arguments["cityName"] ?? "", style: TextStyle( color: Color(0xFF4D4D4D), fontWeight: MyFontWeight.medium, fontSize: 16.sp, ), - ) - )), - GestureDetector( + ), + ), + if(ipState == 2) + Icon( + Icons.gps_fixed, + color: Colors.grey, + size: 18, + ), + if(ipState == 2) + Padding(padding:EdgeInsets.only(left:5.w,right: 12.w), + child:GestureDetector( behavior: HitTestBehavior.opaque, onTap: (){ - Navigator.of(context).pop("南京");}, - child: Container( - decoration: BoxDecoration( - color: Color(0xFFF7F7F7), - borderRadius: BorderRadius.circular(4), - ), - padding: EdgeInsets.symmetric(horizontal:24.w,vertical:5.h), - child: Text( - "南京", + setState((){ + ipState = 1; + Navigator.of(context).pop(ipName); + }); + }, + child: Text( + "重新定位", style: TextStyle( color: Color(0xFF4D4D4D), fontWeight: MyFontWeight.medium, fontSize: 16.sp, ), - ) - )), - GestureDetector( + ), + ),) + ], + )), + Padding( + padding: EdgeInsets.only(bottom: 16.h), + child: Text( + "热门城市", + style: TextStyle( + color: Color(0xFFA29E9E), + fontWeight: MyFontWeight.medium, + fontSize: 16.sp, + ), + ), + ), + GridView.builder( + itemCount: hotCity.length, + padding: EdgeInsets.only(right: 14.h, bottom: 14.h), + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + crossAxisSpacing: 12.w, + mainAxisSpacing: 12.w, + childAspectRatio: 2.5, + ), + itemBuilder: (context, index) { + return GestureDetector( behavior: HitTestBehavior.opaque, - onTap: (){ - Navigator.of(context).pop("重庆");}, + onTap: () { + Navigator.of(context).pop(hotCity[index]); + setState((){}); + }, child: Container( decoration: BoxDecoration( color: Color(0xFFF7F7F7), borderRadius: BorderRadius.circular(4), ), - padding: EdgeInsets.symmetric(horizontal:24.w,vertical:5.h), + alignment: Alignment.center, child: Text( - "重庆", + hotCity[index], style: TextStyle( color: Color(0xFF4D4D4D), fontWeight: MyFontWeight.medium, fontSize: 16.sp, ), - ) - ), - ), - ], - ),) + ))); + }, + ), ], ), ), @@ -284,7 +229,7 @@ class _UnionSelectCity extends State { return Container( height: 36.h, margin: EdgeInsets.fromLTRB(6.w, 0, 14.w, 0), - padding: EdgeInsets.fromLTRB(0, 6.h, 0, 0), + // padding: EdgeInsets.fromLTRB(0, 6.h, 0, 0), decoration: BoxDecoration( color: Color(0xFFF1F1F1), borderRadius: BorderRadius.circular(6), @@ -302,12 +247,14 @@ class _UnionSelectCity extends State { onEditingComplete: () { FocusScope.of(context).requestFocus(FocusNode()); }, - controller: editingController, + onChanged: (txt) { + areaCode(searchTxt: txt); + }, cursorHeight: 25.h, decoration: InputDecoration( - // contentPadding: EdgeInsets.symmetric( - // vertical: 12.h, - // ), + contentPadding: EdgeInsets.symmetric( + vertical: 14.h, + ), hintText: "输入城市名进行搜索", hintStyle: TextStyle( fontSize: 12.sp, @@ -315,7 +262,7 @@ class _UnionSelectCity extends State { ), prefixIcon: InkWell( onTap: () {}, - child:Image.asset( + child: Image.asset( "assets/image/icon_search.webp", width: 16, height: 16, @@ -328,7 +275,7 @@ class _UnionSelectCity extends State { } Widget sortList() { - return ListView.builder( + return areaList.length != 0 ?ListView.builder( padding: EdgeInsets.zero, itemCount: areaList.length, scrollDirection: Axis.vertical, @@ -340,7 +287,15 @@ class _UnionSelectCity extends State { child: sortItem(position), ); }, - ); + ):Padding(padding:EdgeInsets.only(top:12.h), + child: Text( + "抱歉,未找到相关位置,可尝试修改后重试", + style: TextStyle( + color: Color(0xFF4D4D4D), + fontWeight: MyFontWeight.medium, + fontSize: 14.sp, + ), + )); } Widget sortItem(int position) { @@ -369,46 +324,51 @@ class _UnionSelectCity extends State { padding: EdgeInsets.only( top: 8.h, ), - child: Column( - children: (areaMap[areaList[position]] as List).map((e) { - return globalRoamingItem(e); - }).toList(), - ), + child: mapWidget(position), ) ], ); } - Widget globalRoamingItem(data) { + Widget mapWidget(position) { + int mapIndex = 0; + return Column( + children: (areaMap[areaList[position]] as List).map((e) { + mapIndex += 1; + return globalRoamingItem( + e, mapIndex == areaMap[areaList[position]].length); + }).toList(), + ); + } + + Widget globalRoamingItem(data, isLast) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { Navigator.of(context).pop(data["area"]); }, child: Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(left: 12.w), - child: Text( - data["area"], - style: TextStyle( - color: Color(0xFF000000), - fontWeight: MyFontWeight.regular, - fontSize: 14.sp, + width: double.infinity, + child: Text( + data["area"], + style: TextStyle( + color: Color(0xFF000000), + fontWeight: MyFontWeight.regular, + fontSize: 14.sp, + ), + ), + decoration: BoxDecoration( + border: isLast + ? null + : Border( + bottom: BorderSide( + width: 1.w, + color: Color(0xFFDCDCDC), + style: BorderStyle.solid, + ), ), - ), - ), - Container( - margin: EdgeInsets.symmetric(vertical: 16.h), - width: double.infinity, - height: 1.h, - color: Color(0xFFDCDCDC), - ) - ], ), + padding: EdgeInsets.only(top: 16.h, bottom: 16.h, left: 16.w), ), ); }