Forráskód Böngészése

[new]完善常用点地址选择功能

zk 3 hónapja
szülő
commit
2b6c9f9798

+ 1 - 0
assets/string/base/string.xml

@@ -448,4 +448,5 @@
     <string name="select_address_current_location">[当前位置]</string>
     <string name="location_amap_co">合作单位:高德软件有限公司 审图号 GS(2021)6375号</string>
     <string name="current_location">[当前位置]</string>
+    <string name="select_address_please">请在列表下方选择一个详细地址</string>
 </resources>

+ 1 - 1
lib/data/api/atmob_api.dart

@@ -271,7 +271,7 @@ abstract class AtmobApi {
   Future<BaseResponse<ItemListResponse>> guideItemList(
       @Body() MemberListRequest request);
 
-  @POST("/s/v1/point/common/list")
+  @POST("/s/v1/frequent/point/info/list")
   Future<BaseResponse<CommonPointResponse>> commonPointList(
       @Body() AppBaseRequest request);
 }

+ 1 - 1
lib/data/api/atmob_api.g.dart

@@ -2061,7 +2061,7 @@ class _AtmobApi implements AtmobApi {
     )
         .compose(
           _dio.options,
-          '/s/v1/point/common/list',
+          '/s/v1/frequent/point/info/list',
           queryParameters: queryParameters,
           data: _data,
         )

+ 34 - 3
lib/data/bean/common_point_bean.dart

@@ -4,13 +4,44 @@ part 'common_point_bean.g.dart';
 
 @JsonSerializable()
 class CommonPointBean {
+  @JsonKey(name: 'id')
+  final int id;
+
   @JsonKey(name: 'title')
   final String title;
 
-  @JsonKey(name: 'address')
-  final String? address;
+  @JsonKey(name: 'radius')
+  final int radius;
+
+  @JsonKey(name: 'lng')
+  final double lng;
+
+  @JsonKey(name: 'lat')
+  final double lat;
+
+  @JsonKey(name: 'addr')
+  final String? addr;
+
+  @JsonKey(name: 'startTime')
+  final String? startTime;
+
+  @JsonKey(name: 'endTime')
+  final String? endTime;
+
+  @JsonKey(name: 'weeks')
+  final String? weeks;
 
-  CommonPointBean(this.title, this.address);
+  CommonPointBean({
+    required this.id,
+    required this.title,
+    required this.radius,
+    required this.lng,
+    required this.lat,
+    this.addr,
+    this.startTime,
+    this.endTime,
+    this.weeks,
+  });
 
   factory CommonPointBean.fromJson(Map<String, dynamic> json) =>
       _$CommonPointBeanFromJson(json);

+ 17 - 3
lib/data/bean/common_point_bean.g.dart

@@ -8,12 +8,26 @@ part of 'common_point_bean.dart';
 
 CommonPointBean _$CommonPointBeanFromJson(Map<String, dynamic> json) =>
     CommonPointBean(
-      json['title'] as String,
-      json['address'] as String?,
+      id: (json['id'] as num).toInt(),
+      title: json['title'] as String,
+      radius: (json['radius'] as num).toInt(),
+      lng: (json['lng'] as num).toDouble(),
+      lat: (json['lat'] as num).toDouble(),
+      addr: json['addr'] as String?,
+      startTime: json['startTime'] as String?,
+      endTime: json['endTime'] as String?,
+      weeks: json['weeks'] as String?,
     );
 
 Map<String, dynamic> _$CommonPointBeanToJson(CommonPointBean instance) =>
     <String, dynamic>{
+      'id': instance.id,
       'title': instance.title,
-      'address': instance.address,
+      'radius': instance.radius,
+      'lng': instance.lng,
+      'lat': instance.lat,
+      'addr': instance.addr,
+      'startTime': instance.startTime,
+      'endTime': instance.endTime,
+      'weeks': instance.weeks,
     };

+ 0 - 30
lib/module/commonpoint/common_point_controller.dart

@@ -28,36 +28,6 @@ class CommonPointController extends BaseController {
       commonPointList.assignAll(response.list ?? []);
     }).catchError((error) {
       ErrorHandler.toastError(error);
-      //增加模拟数据
-      commonPointList.assignAll([
-        CommonPointBean('家里', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('公司', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('外派公司', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean('约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-        CommonPointBean(
-            '约会地点', '广州市海珠区滨江东路江怡路嘉仕花园名仕阁310广州市海珠区滨江东路江怡路嘉仕花园名仕阁310'),
-      ]);
     });
   }
 

+ 1 - 1
lib/module/commonpoint/common_point_page.dart

@@ -200,7 +200,7 @@ class CommonPointPage extends BasePage<CommonPointController> {
               Text(item.title,
                   style: TextStyle(fontSize: 14.sp, color: ColorName.black90)),
               SizedBox(height: 6.w),
-              Text(item.address ?? '',
+              Text(item.addr ?? '',
                   style: TextStyle(
                       overflow: TextOverflow.ellipsis,
                       fontSize: 12.sp,

+ 76 - 24
lib/module/commonpoint/select_address/common_point_select_address_controller.dart

@@ -16,7 +16,7 @@ import '../../../data/bean/user_info.dart';
 import '../../../dialog/common_confirm_dialog_impl.dart';
 import '../../../dialog/location_permission_dialog.dart';
 import '../../../resource/string.gen.dart';
-import '../../../utils/de_bounce.dart';
+import '../../../utils/action_limiter.dart';
 import '../../../utils/permission_util.dart';
 import '../../../utils/toast_util.dart';
 
@@ -47,7 +47,14 @@ class CommonPointSelectAddressController extends BaseController {
 
   final refreshController = RefreshController(initialRefresh: false);
 
-  final Debounce _searchDebounce = Debounce(debounceTime: 500);
+  final Rxn<PoiItem> _currentRangeCenterLocation = Rxn<PoiItem>();
+
+  PoiItem? get currentRangeCenterLocation => _currentRangeCenterLocation.value;
+
+  bool _isUserSelectLocation = false;
+
+  final ActionLimiter _debounceLimiter =
+      ActionLimiter(milliseconds: 300, mode: LimitMode.debounce);
 
   final AccountRepository accountRepository;
 
@@ -67,24 +74,26 @@ class CommonPointSelectAddressController extends BaseController {
   @override
   void onReady() {
     super.onReady();
+    circleOptions.radius = commonPointRange;
     _updateCurrentLocation();
     mapController.setOnCameraChangeListener(
       (camera) {
+        circleOptions
+          ..longitude = camera.position.longitude
+          ..latitude = camera.position.latitude;
+
         if (_isRangeChanging) {
           return;
         }
-        if (camera.function == CameraChangeType.onCameraChange) {
-          //暂时隐藏范围
-          if (circleOptions.visible == true) {
-            circleOptions.visible = false;
-            _updateOrAddCircle();
+        if (camera.function == CameraChangeType.onCameraChangeFinish) {
+          AtmobLog.d('zk', 'onCameraChangeFinish ');
+          circleOptions.visible = true;
+          if (!_isUserSelectLocation) {
+            _currentRangeCenterLocation.value = null;
+          } else {
+            _isUserSelectLocation = false;
           }
-        } else {
-          circleOptions
-            ..radius = commonPointRange
-            ..longitude = camera.position.longitude
-            ..visible = true
-            ..latitude = camera.position.latitude;
+
           _updateOrAddCircle();
           if (_isFirstMoveCamera) {
             _isFirstMoveCamera = false;
@@ -93,17 +102,32 @@ class CommonPointSelectAddressController extends BaseController {
           //重新还原数据
           _resetPoiQuery();
           _poiSearch();
+        } else {
+          //暂时隐藏范围
+          if (circleOptions.visible == true) {
+            circleOptions.visible = false;
+            _updateOrAddCircle();
+          }
         }
       },
     );
   }
 
+  void onSearchTextChange(String txt) {
+    if (_poiQuery.keyWord == txt) {
+      return;
+    }
+    _poiQuery.keyWord = txt;
+    _resetPoiQuery();
+    _poiSearch();
+  }
+
   void _resetPoiQuery() {
     _pageNum = 1;
   }
 
   void _poiSearch() async {
-    _searchDebounce.onClick(() {
+    _debounceLimiter.run(() {
       AtmobLog.d('zk', '_poiSearch: $_poiQuery');
       FlutterMap.paginatePoiSearch(
               pageNum: _pageNum,
@@ -145,15 +169,6 @@ class CommonPointSelectAddressController extends BaseController {
     Get.back();
   }
 
-  void setCommonPointRange(double value) {
-    _commonPointRange.value = value;
-    circleOptions.radius = value;
-    if (circleOptions.visible == true) {
-      _updateOrAddCircle();
-      _moveCameraToBounds();
-    }
-  }
-
   _moveCameraToBounds() {
     final latLngBounds = CameraUpdateUtil.getBounds(circleOptions.latitude,
         circleOptions.longitude, circleOptions.radius ?? 0);
@@ -190,12 +205,23 @@ class CommonPointSelectAddressController extends BaseController {
     searchFocusNode.requestFocus();
   }
 
+  void setCommonPointRange(double value) {
+    _commonPointRange.value = value;
+    circleOptions.radius = value;
+    if (circleOptions.visible == true) {
+      _updateOrAddCircle();
+      _moveCameraToBounds();
+    }
+  }
+
   void setCommonPointRangeStart() {
     _isRangeChanging = true;
   }
 
   void setCommonPointRangeEnd() {
     _isRangeChanging = false;
+    _resetPoiQuery();
+    _poiSearch();
   }
 
   void moveToCurrentLocation() async {
@@ -225,6 +251,11 @@ class CommonPointSelectAddressController extends BaseController {
   void _showCurrentRange(MapLocation location) {
     circleOptions.latitude = location.latitude;
     circleOptions.longitude = location.longitude;
+    _isUserSelectLocation = true;
+    _currentRangeCenterLocation.value = PoiItem(
+        latitude: location.latitude,
+        longitude: location.longitude,
+        address: location.address);
     _moveCameraToBounds();
   }
 
@@ -253,10 +284,31 @@ class CommonPointSelectAddressController extends BaseController {
     }
   }
 
-  onPoiItemClick(PoiItem item) {}
+  onPoiItemClick(PoiItem item) async {
+    _resetPoiQuery();
+    circleOptions
+      ..longitude = item.longitude
+      ..latitude = item.latitude;
+    _currentRangeCenterLocation.value = item;
+    _isUserSelectLocation = true;
+    _moveCameraToBounds();
+    if (sheetController.state?.isExpanded == true) {
+      await sheetController.scrollTo(0, duration: Duration(milliseconds: 1));
+      sheetController.snapToExtent(0,
+          duration: const Duration(milliseconds: 250));
+    }
+  }
 
   void onLoadMorePoiData() {
     _pageNum++;
     _poiSearch();
   }
+
+  void onSelectAddressDone() {
+    if (currentRangeCenterLocation == null) {
+      ToastUtil.show(StringName.selectAddressPlease);
+      return;
+    }
+    Get.back(result: currentRangeCenterLocation);
+  }
 }

+ 60 - 57
lib/module/commonpoint/select_address/common_point_select_address_page.dart

@@ -150,20 +150,23 @@ class CommonPointSelectAddressPage
                 onTap: controller.backClick,
                 child: CommonView.getBackBtnView()),
             Spacer(),
-            Container(
-                width: 50.w,
-                height: 28.w,
-                decoration: BoxDecoration(
-                  color: ColorName.white,
-                  borderRadius: BorderRadius.circular(8.r),
-                ),
-                child: Center(
-                  child: Text(StringName.selectAddressDone,
-                      style: TextStyle(
-                          fontSize: 12.sp,
-                          color: ColorName.black90,
-                          fontWeight: FontWeight.bold)),
-                )),
+            GestureDetector(
+              onTap: controller.onSelectAddressDone,
+              child: Container(
+                  width: 50.w,
+                  height: 28.w,
+                  decoration: BoxDecoration(
+                    color: ColorName.white,
+                    borderRadius: BorderRadius.circular(8.r),
+                  ),
+                  child: Center(
+                    child: Text(StringName.selectAddressDone,
+                        style: TextStyle(
+                            fontSize: 12.sp,
+                            color: ColorName.black90,
+                            fontWeight: FontWeight.bold)),
+                  )),
+            ),
           ],
         ),
       ),
@@ -194,7 +197,7 @@ class CommonPointSelectAddressPage
         child: CustomScrollView(
           controller: scrollController,
           slivers: [
-            SliverToBoxAdapter(child: buildCurrentLocationView()),
+            SliverToBoxAdapter(child: buildRangeCenterLocationView()),
             Obx(() {
               return SliverList.builder(
                   itemBuilder: (ctx, index) =>
@@ -207,49 +210,46 @@ class CommonPointSelectAddressPage
     );
   }
 
-  Widget buildCurrentLocationView() {
-    return GestureDetector(
-      onTap: controller.moveToCurrentLocation,
-      child: Container(
-        decoration: BoxDecoration(
-          color: '#F2F5FE'.color,
-          borderRadius: BorderRadius.circular(8.r),
-          border: Border.all(
-            color: '#D0D9F4'.color,
-            width: 0.5.w,
-          ),
-        ),
-        margin: EdgeInsets.only(left: 12.w, right: 12.w, bottom: 8.w, top: 4.w),
-        padding: EdgeInsets.symmetric(horizontal: 13.w, vertical: 8.w),
-        child: Row(
-          crossAxisAlignment: CrossAxisAlignment.start,
-          children: [
-            Container(
-                margin: EdgeInsets.only(top: 3.w),
-                child:
-                    Assets.images.iconSelectCurrentLocation.image(width: 10.w)),
-            SizedBox(width: 8.w),
-            Column(
-              crossAxisAlignment: CrossAxisAlignment.start,
-              children: [
-                Text(StringName.currentLocation,
-                    style: TextStyle(
-                        fontSize: 12.sp,
-                        color: ColorName.black90,
-                        fontWeight: FontWeight.bold)),
-                SizedBox(height: 4.w),
-                Obx(() {
-                  return Text(
-                      addressCheck(
-                          controller.mineUserInfo.lastLocation.value?.address),
-                      style:
-                          TextStyle(fontSize: 10.sp, color: ColorName.black50));
-                })
-              ],
-            )
-          ],
+  Widget buildRangeCenterLocationView() {
+    return Container(
+      decoration: BoxDecoration(
+        color: '#F2F5FE'.color,
+        borderRadius: BorderRadius.circular(8.r),
+        border: Border.all(
+          color: '#D0D9F4'.color,
+          width: 0.5.w,
         ),
       ),
+      margin: EdgeInsets.only(left: 12.w, right: 12.w, bottom: 8.w, top: 4.w),
+      padding: EdgeInsets.symmetric(horizontal: 13.w, vertical: 8.w),
+      child: Row(
+        crossAxisAlignment: CrossAxisAlignment.start,
+        children: [
+          Container(
+              margin: EdgeInsets.only(top: 3.w),
+              child:
+                  Assets.images.iconSelectCurrentLocation.image(width: 10.w)),
+          SizedBox(width: 8.w),
+          Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [
+              Text(StringName.currentLocation,
+                  style: TextStyle(
+                      fontSize: 12.sp,
+                      color: ColorName.black90,
+                      fontWeight: FontWeight.bold)),
+              SizedBox(height: 4.w),
+              Obx(() {
+                return Text(
+                    controller.currentRangeCenterLocation?.address ??
+                        StringName.selectAddressPlease,
+                    style:
+                        TextStyle(fontSize: 10.sp, color: ColorName.black50));
+              })
+            ],
+          )
+        ],
+      ),
     );
   }
 
@@ -304,6 +304,7 @@ class CommonPointSelectAddressPage
                         keyboardType: TextInputType.text,
                         textAlignVertical: TextAlignVertical.center,
                         textInputAction: TextInputAction.next,
+                        onChanged: (txt) => controller.onSearchTextChange(txt),
                         decoration: InputDecoration(
                             hintText:
                                 StringName.selectAddressPleaseEnterPlaceName,
@@ -421,7 +422,9 @@ class CommonPointSelectAddressPage
 
   Widget buildPoiSearchItem(PoiItem item) {
     return GestureDetector(
-      onTap: controller.onPoiItemClick(item),
+      onTap: () {
+        controller.onPoiItemClick(item);
+      },
       child: Container(
         margin: EdgeInsets.only(left: 12.w, right: 12.w, bottom: 8.w, top: 4.w),
         padding: EdgeInsets.only(left: 13.w, top: 8.w, bottom: 8.w),

+ 3 - 0
lib/resource/string.gen.dart

@@ -394,6 +394,8 @@ class StringName {
   static String get locationAmapCo =>
       'location_amap_co'.tr; // 合作单位:高德软件有限公司 审图号 GS(2021)6375号
   static String get currentLocation => 'current_location'.tr; // [当前位置]
+  static String get selectAddressPlease =>
+      'select_address_please'.tr; // 请在列表下方选择一个详细地址
 }
 class StringMultiSource {
   StringMultiSource._();
@@ -772,6 +774,7 @@ class StringMultiSource {
       'select_address_current_location': '[当前位置]',
       'location_amap_co': '合作单位:高德软件有限公司 审图号 GS(2021)6375号',
       'current_location': '[当前位置]',
+      'select_address_please': '请在列表下方选择一个详细地址',
     },
   };
 }

+ 41 - 0
lib/utils/action_limiter.dart

@@ -0,0 +1,41 @@
+import 'dart:async';
+import 'package:flutter/foundation.dart';
+
+enum LimitMode {
+  debounce, //防抖
+  throttle, //节流
+}
+
+class ActionLimiter {
+  final int milliseconds;
+  final LimitMode mode;
+
+  Timer? _debounceTimer;
+  DateTime? _lastActionTime;
+
+  ActionLimiter({
+    this.milliseconds = 300,
+    this.mode = LimitMode.debounce,
+  });
+
+  void run(VoidCallback action) {
+    if (mode == LimitMode.debounce) {
+      // 防抖:只执行最后一次
+      _debounceTimer?.cancel();
+      _debounceTimer = Timer(Duration(milliseconds: milliseconds), action);
+    } else if (mode == LimitMode.throttle) {
+      // 节流:间隔内只执行一次
+      final now = DateTime.now();
+      if (_lastActionTime == null ||
+          now.difference(_lastActionTime!) >
+              Duration(milliseconds: milliseconds)) {
+        _lastActionTime = now;
+        action();
+      }
+    }
+  }
+
+  void dispose() {
+    _debounceTimer?.cancel();
+  }
+}

+ 3 - 2
plugins/map_amap_android/android/src/main/java/com/atmob/map_amap_android/poi/PoiHelper.java

@@ -40,6 +40,7 @@ public class PoiHelper {
             String ctgr = ParamUtil.getString(queryMap, "ctgr");
             String city = ParamUtil.getString(queryMap, "city");
 
+//            LogUtil.d(TAG, "paginatePoiSearch: keyWord=" + keyWord + " ctgr=" + ctgr + " city=" + city + " pageSize=" + pageSize + " pageNum=" + pageNum);
 
             PoiSearchV2.Query query = new PoiSearchV2.Query(keyWord, ctgr, city);
             query.setPageSize(pageSize);
@@ -58,7 +59,7 @@ public class PoiHelper {
                     }
                     double latitude = ParamUtil.getDouble(center, "latitude", 0);
                     double longitude = ParamUtil.getDouble(center, "longitude", 0);
-                    LogUtil.d(TAG, "paginatePoiSearch: latitude=" + latitude + " longitude=" + longitude + " radius=" + radius);
+//                    LogUtil.d(TAG, "paginatePoiSearch: latitude=" + latitude + " longitude=" + longitude + " radius=" + radius);
                     final PoiSearchV2.SearchBound searchBound = new PoiSearchV2.SearchBound(new LatLonPoint(latitude, longitude), radius);
                     poiSearch.setBound(searchBound);
                 }
@@ -81,7 +82,7 @@ public class PoiHelper {
                             resultMap.put("latitude", poiItemV2.getLatLonPoint().getLatitude());
                             resultMap.put("longitude", poiItemV2.getLatLonPoint().getLongitude());
                             list.add(resultMap);
-                            LogUtil.d(TAG, "onPoiSearched: resultMap=" + resultMap);
+//                            LogUtil.d(TAG, "onPoiSearched: resultMap=" + resultMap);
                         }
                         try {
                             result.success(list);