diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..efe8a43 Binary files /dev/null and b/.DS_Store differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK.podspec b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK.podspec index 60e22d0..b5adbfa 100644 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK.podspec +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK.podspec @@ -46,5 +46,6 @@ TODO: Add long description of the pod here. s.dependency 'AMapNavi-NO-IDFA' s.dependency 'AMapLocation-NO-IDFA' s.dependency 'AMapSearch-NO-IDFA' + s.dependency 'MBProgressHUD' end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/cal_ruoute_icon@3x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/cal_ruoute_icon@3x.png new file mode 100644 index 0000000..65a78f1 Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/cal_ruoute_icon@3x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/car@2x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/car@2x.png new file mode 100644 index 0000000..04019bc Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/car@2x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/ic_fuel@3x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/ic_fuel@3x.png new file mode 100644 index 0000000..a928c03 Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/ic_fuel@3x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/ic_tag@2x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/ic_tag@2x.png new file mode 100644 index 0000000..dcae650 Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/ic_tag@2x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/locationing_arrow_icon@3x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/locationing_arrow_icon@3x.png new file mode 100644 index 0000000..7aff0d6 Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/locationing_arrow_icon@3x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/my_location_icon@3x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/my_location_icon@3x.png new file mode 100644 index 0000000..3488026 Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/my_location_icon@3x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/pre_cost_icon@3x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/pre_cost_icon@3x.png new file mode 100644 index 0000000..5b4ca78 Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/pre_cost_icon@3x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/pre_distance_icon@3x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/pre_distance_icon@3x.png new file mode 100644 index 0000000..aeb9896 Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/pre_distance_icon@3x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/pre_time_icon@3x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/pre_time_icon@3x.png new file mode 100644 index 0000000..1803f2c Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/pre_time_icon@3x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/search_icon@3x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/search_icon@3x.png new file mode 100644 index 0000000..47cb9b9 Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/search_icon@3x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/station_normal_icon@3x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/station_normal_icon@3x.png new file mode 100644 index 0000000..720eec2 Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/station_normal_icon@3x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/station_select_icon@3x.png b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/station_select_icon@3x.png new file mode 100644 index 0000000..9654ffa Binary files /dev/null and b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Assets/AMapNavIOSSDK.bundle/station_select_icon@3x.png differ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ACustomAnnotationView.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ACustomAnnotationView.h new file mode 100644 index 0000000..4d6453a --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ACustomAnnotationView.h @@ -0,0 +1,17 @@ +// +// ACustomAnnotationView.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/17. +// + +#import +#import "AMapNavCommonUtil.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ACustomAnnotationView : MAAnnotationView + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ACustomAnnotationView.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ACustomAnnotationView.m new file mode 100644 index 0000000..5f81c4b --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ACustomAnnotationView.m @@ -0,0 +1,177 @@ +// +// ACustomAnnotationView.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/17. +// + +#import "ACustomAnnotationView.h" + +// ─── 布局常量 ───────────────────────────────────────────────────────────────── +static const CGFloat kIconSize = 30; // 图标宽高 +static const CGFloat kIconTextGap = 6.0; // 图标与文字间距 +static const CGFloat kMaxTextWidth = 100.0; // 文字区域最大宽度 +static const CGFloat kMaxTextLines = 2; // 最多行数 +static const CGFloat kVPad = 4.0; // 整体上下内边距(用于 centerOffset 微调) + +@interface ACustomAnnotationView () + +@property (nonatomic, strong) UIImageView *iconView; +@property (nonatomic, strong) UILabel *titleLabel; + +/// 当前是否选中(用于更新图标 & 文字样式) +@property (nonatomic, assign) BOOL isAnnotationSelected; + +@end + +@implementation ACustomAnnotationView + +#pragma mark - Init / Reuse + +- (instancetype)initWithAnnotation:(id)annotation + reuseIdentifier:(NSString *)reuseIdentifier { + self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; + if (self) { + self.backgroundColor = [UIColor clearColor]; + // 关闭 MAAnnotationView 自带的 image 渲染,避免干扰 + self.image = nil; + [self _buildSubviews]; + [self _updateFromAnnotation]; + [self setNeedsLayout]; + } + return self; +} + +- (void)setAnnotation:(id)annotation { + [super setAnnotation:annotation]; + [self _updateFromAnnotation]; + [self setNeedsLayout]; +} + +#pragma mark - Build + +- (void)_buildSubviews { + // ── 图标 ────────────────────────────────────────────────── + if (!self.iconView) { + UIImageView *iv = [[UIImageView alloc] init]; + iv.contentMode = UIViewContentModeScaleAspectFit; + [self addSubview:iv]; + self.iconView = iv; + } + + // ── 文字 ────────────────────────────────────────────────── + if (!self.titleLabel) { + UILabel *lbl = [[UILabel alloc] init]; + lbl.numberOfLines = kMaxTextLines; + lbl.lineBreakMode = NSLineBreakByTruncatingTail; + lbl.textAlignment = NSTextAlignmentLeft; + [self addSubview:lbl]; + self.titleLabel = lbl; + } + + // 初始化为默认(未选中)样式 + [self _applyStyle:NO]; +} + +/// 根据选中状态切换图标 & 文字样式 +- (void)_applyStyle:(BOOL)selected { + if (selected) { + self.iconView.image = [AMapNavCommonUtil imageWithName3x:@"station_select_icon"]; + self.titleLabel.font = [UIFont boldSystemFontOfSize:14]; + self.titleLabel.textColor = [UIColor colorWithWhite:0.12 alpha:1.0]; + } else { + self.iconView.image = [AMapNavCommonUtil imageWithName3x:@"station_normal_icon"]; + self.titleLabel.font = [UIFont systemFontOfSize:13]; + self.titleLabel.textColor = [UIColor colorWithWhite:0.25 alpha:1.0]; + } +} + +#pragma mark - Data + +- (void)_updateFromAnnotation { + NSString *text = nil; + id ann = self.annotation; + if ([ann respondsToSelector:@selector(title)]) { + text = ann.title; + } + if (text.length == 0) { + text = @"加氢站"; + } + self.titleLabel.text = text; +} + +#pragma mark - Selection(MAAnnotationView 官方选中回调) + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + self.isAnnotationSelected = selected; + [self _applyStyle:selected]; + [self setNeedsLayout]; +} + +#pragma mark - Layout + +- (void)layoutSubviews { + [super layoutSubviews]; + + // 文字最大 100pt、最多 2 行 + CGSize textConstraint = CGSizeMake(kMaxTextWidth, + CGFLOAT_MAX); + CGSize textFit = [self.titleLabel sizeThatFits:textConstraint]; + // 高度上限:2 行 + CGFloat lineH = self.titleLabel.font.lineHeight; + CGFloat maxTextH = lineH * kMaxTextLines + + self.titleLabel.font.leading * (kMaxTextLines - 1); + CGFloat textW = MIN(textFit.width, kMaxTextWidth); + CGFloat textH = MIN(textFit.height, maxTextH); + + CGFloat totalW = kIconSize + kIconTextGap + textW; + CGFloat totalH = MAX(kIconSize, textH) + kVPad * 2; + + // 更新自身 bounds + self.bounds = CGRectMake(0, 0, totalW, totalH); + + // 图标:垂直居中 + CGFloat iconY = (totalH - kIconSize) * 0.5; + self.iconView.frame = CGRectMake(0, iconY, kIconSize, kIconSize); + + // 文字:垂直居中 + CGFloat textY = (totalH - textH) * 0.5; + self.titleLabel.frame = CGRectMake(kIconSize + 1, textY, textW, textH); + + // 锚点:让图标底部对齐地图坐标点 + // MAAnnotationView 的 centerOffset 以 (0,0)=中心 为原点 + // 默认选中图标底部对准坐标:向上偏移 totalH/2 + self.centerOffset = CGPointMake(totalW / 2.0 - kIconSize / 2.0, + -(totalH / 2.0)); +} + +#pragma mark - Hit Test + +- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { + UIView *hit = [super hitTest:point withEvent:event]; + if (hit == self || [hit isDescendantOfView:self]) { + return self; + } + return hit; +} + +#pragma mark - Touch + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + [super touchesBegan:touches withEvent:event]; + + id annotation = self.annotation; + if (!annotation) return; + + UIView *sv = self.superview; + while (sv && ![sv isKindOfClass:[MAMapView class]]) { + sv = sv.superview; + } + MAMapView *mapView = (MAMapView *)sv; + if (!mapView) return; + +// [mapView deselectAnnotation:annotation animated:NO]; +} + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapNavSDKHeader.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapNavSDKHeader.h index e2a6a10..eea9824 100644 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapNavSDKHeader.h +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapNavSDKHeader.h @@ -8,5 +8,44 @@ #ifndef AMapNavSDKHeader_h #define AMapNavSDKHeader_h +//#define kAMapSDKDebugFlag +// iPhone X +#define AMP_iPhoneX (UIApplication.sharedApplication.keyWindow.safeAreaInsets.bottom > 0 ? YES : NO) + +// Status bar height. +#define AMP_StatusBarHeight (AMP_iPhoneX ? 44.f : 20.f) + +// Navigation bar height. +#define AMP_NavigationBarHeight 44.f + +// Tabbar height. +#define AMP_TabbarHeight (AMP_iPhoneX ? (49.f+34.f + 5) : 49.f) + +// Tabbar safe bottom margin. +#define AMP_TabbarSafeBottomMargin (AMP_iPhoneX ? 34.f : 0.f) + + +#pragma mark - url +///获取站点列表 +#define kGetStationListUrl @"https://beta-esg.api.lnh2e.com/appointment/station/getNearbyHydrogenStationsByLocation" + +///单个站点详情 +#define kGetStationDetailtUrl @"https://beta-esg.api.lnh2e.com/appointment/station/getStationInfoByArea" + + +///获取途经点 +/** + 请求方式:post 暂时调不通 + { +    "longitude":"121.254139", +     "latitude":"31.214628", +     "plateNumber":"浙F32111F", + "hydrogenSiteId":""//加氢站DI } + + */ +#define kGetRoutePointtUrl @"https://beta-esg.api.lnh2e.com/appointment/truck/truckRouteAlgorithm" + + +#import "ANavPointModel.h" #endif /* AMapNavSDKHeader_h */ diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapNavSDKManager.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapNavSDKManager.h index 638593a..e2e227b 100644 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapNavSDKManager.h +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapNavSDKManager.h @@ -9,8 +9,6 @@ #import "ARoutePlaneController.h" -#define kAMapSDKDebugFlag - NS_ASSUME_NONNULL_BEGIN @interface AMapNavSDKManager : NSObject diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ARoutePlaneController.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ARoutePlaneController.h index 66d956a..3a34308 100644 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ARoutePlaneController.h +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ARoutePlaneController.h @@ -13,6 +13,12 @@ #import +#import "ACustomAnnotationView.h" +#import "AMapNavSDKHeader.h" +#import "ACustomPointAnnotation.h" +#import "ATripCalcResponse.h" +#import "AMapNavCommonUtil.h" + NS_ASSUME_NONNULL_BEGIN @interface ARoutePlaneController : ABaseViewController diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ARoutePlaneController.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ARoutePlaneController.m index 4a09f4a..6c7dc49 100644 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ARoutePlaneController.m +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ARoutePlaneController.m @@ -18,14 +18,21 @@ #import "AMapPrivacyUtility.h" +#import "AStationDetailPopupController.h" + #define kRouteIndicatorViewHeight 64.f #import "AMapHyStationModel.h" #import "AMapNavHttpUtil.h" +#import "ACustomStepView.h" +#import "ABottomBarView.h" -@interface ARoutePlaneController () +@interface ARoutePlaneController () @property (nonatomic, strong) UITextField *textField; +/// 底部搜索+规划路线栏 +@property (nonatomic, strong) ABottomBarView *bottomBarView; + @property (nonatomic, strong) MAMapView *mapView; @property (nonatomic,strong) AMapLocationManager *locationService; //定位服务 @@ -42,6 +49,7 @@ @property (nonatomic, strong) AMapPOI *startPoi; @property (nonatomic, strong) AMapPOI *dstPoi; +@property (nonatomic, strong) AMapPOI *defaultDstPoi; //默认的附近点 @property (nonatomic, strong) AMapNaviCompositeManager *compositeManager;//nav @property (nonatomic, assign) BOOL calRouteSuccess; @@ -54,6 +62,14 @@ @property (nonatomic , strong)NSArray * hyStationArr;//站点数据 @property (nonatomic , assign)BOOL startQueryCurrnetNodeFlag;//开始查询当前节点; +@property (nonatomic , strong)ACustomStepView * stepView; + +/// 当前弹出的站点详情弹框 +@property (nonatomic , strong)AStationDetailPopupController * stationDetailPopup; +@property (nonatomic, strong) ANavPointModel *pointModel; //当前选的目的点 +@property (nonatomic, strong) ATripCalcDataModel * tjdPathInfoModel;//途经点信息 + +@property (nonatomic, strong) CLLocationManager * locationManager; @end @implementation ARoutePlaneController @@ -89,14 +105,14 @@ #pragma mark - request -(void)requestHyListWithParms:(NSDictionary*)dic { - NSString * url = @"https://beta-esg.api.lnh2e.com/appointment/station/getNearbyHydrogenStationsByLocation"; + NSString * url = kGetStationListUrl; /** //汽车公园有数据 "longitude": "121.30461400", "latitude": "31.17321100" */ -// NSDictionary * dic = @{@"longitude":@"121.16661700" , @"latitude":@"31.27981600"}; + NSDictionary * dic2 = @{@"longitude":@"121.16661700" , @"latitude":@"31.27981600"}; [AMapNavHttpUtil postRequestWithURL:url parameters:dic requestHeader:@{@"Content-Type":@"application/json; charset=UTF-8"} successHandler:^(NSDictionary * _Nonnull data, NSURLResponse * _Nonnull response) { @@ -120,7 +136,7 @@ } -(void)requestHyDetailWithParms:(NSDictionary*)dic { - NSString * url = @"https://beta-esg.api.lnh2e.com/appointment/station/getStationInfoByArea"; + NSString * url = kGetStationDetailtUrl; [AMapNavHttpUtil postRequestWithURL:url parameters:dic requestHeader:@{@"Content-Type":@"application/json; charset=UTF-8"} successHandler:^(NSDictionary * _Nonnull data, NSURLResponse * _Nonnull response) { AMapHyResponse * resp = [AMapHyResponse mj_objectWithKeyValues:data]; @@ -135,6 +151,58 @@ } failureHandler:^(NSError * _Nonnull error) { NSLog(@">>>>>>>请求站点err:%@" ,error.debugDescription); }]; + +} + + +-(void)requestRoutePathWithParms:(NSDictionary*)dic completeHandle:(void(^)(ATripCalcDataModel * tjd))blk { + + NSString * token = [[NSUserDefaults standardUserDefaults]valueForKey:@"flutter.token"]; + NSString * carNo = [[NSUserDefaults standardUserDefaults]valueForKey:@"flutter.plateNumber"]; + if (stringIsEmpty(token) || stringIsEmpty(carNo)) { + [AMapNavCommonUtil showMsg:@"车牌或token为空,请重新登录"]; return; + } + + if (stringIsEmpty(self.pointModel.stationID)) { + [AMapNavCommonUtil showMsg:@"站点ID不能为空"]; return; + } + + NSMutableDictionary * dic2 = [NSMutableDictionary dictionary]; + dic2[@"longitude"] = [NSString stringWithFormat:@"%f" , self.pointModel.coordinate.longitude]; + dic2[@"latitude"] = [NSString stringWithFormat:@"%f" , self.pointModel.coordinate.latitude]; + dic2[@"plateNumber"] = carNo; + dic2[@"hydrogenSiteId"] = [NSString stringWithFormat:@"%@" , self.pointModel.stationID]; + + NSDictionary * headDic = @{ + @"Content-Type":@"application/json; charset=UTF-8", + @"asoco-token" : token + }; + + + + [AMapNavCommonUtil showLoadingWithMsg:@""]; + + NSString * url = kGetRoutePointtUrl; + [AMapNavHttpUtil postRequestWithURL:url parameters:dic2 requestHeader:headDic successHandler:^(NSDictionary * _Nonnull data, NSURLResponse * _Nonnull response) { + + ATripCalcResponse * resp = [ATripCalcResponse mj_objectWithKeyValues:data]; + if (resp.code == 200 && resp.data) { + self.tjdPathInfoModel = resp.data; + + if (blk) { + blk(resp.data); + } + }else { + [AMapNavCommonUtil showMsg:data[@"message"]]; + } + + [AMapNavCommonUtil dismiss]; + + } failureHandler:^(NSError * _Nonnull error) { + NSLog(@">>>>>>>请求途经点:%@" ,error.debugDescription); + [AMapNavCommonUtil dismiss]; + [AMapNavCommonUtil showMsg:error.debugDescription]; + }]; } @@ -145,15 +213,15 @@ aoi.location = [AMapGeoPoint locationWithLatitude:[model.latitude doubleValue] longitude:[model.longitude doubleValue]]; aoi.name = model.name; + aoi.address = model.address; + aoi.uid = model.ID; self.dstPoi = aoi; + self.defaultDstPoi = [aoi copy]; ///地址栏 [self updateUIWithData:aoi textField:self.dstTf]; - - ///地图显示 - [self updateMapAnnotationWithData:@[model]]; } -(void)updateMapAnnotationWithData:(NSArray *)dataArr { @@ -165,13 +233,16 @@ ///添加标注 NSMutableArray * points = [NSMutableArray arrayWithCapacity:dataArr.count]; for (AMapHyStationModel * model in dataArr) { - MAPointAnnotation *pointAnnotation = [[MAPointAnnotation alloc] init]; + ACustomPointAnnotation *pointAnnotation = [[ACustomPointAnnotation alloc] init]; if (!(model.latitude && model.longitude)) { continue; } pointAnnotation.coordinate = CLLocationCoordinate2DMake([model.latitude doubleValue], [model.longitude doubleValue]); pointAnnotation.title = model.name; + pointAnnotation.subtitle = model.address; + pointAnnotation.stationID = model.ID; + [points addObject:pointAnnotation]; } @@ -192,95 +263,89 @@ } -#pragma mark - +#pragma mark - init -(void)initSubview { - UITextField * startTf = [[UITextField alloc] init]; - startTf.borderStyle = UITextBorderStyleRoundedRect; - startTf.placeholder = @"起点"; + + // ── 地图全屏 ───────────────────────────────────────────── + [self.mapView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + + // ── 底部栏(搜索框 + 规划路线按钮) ────────────────────── + ABottomBarView *bottomBar = [[ABottomBarView alloc] init]; + bottomBar.delegate = self; + [self.view addSubview:bottomBar]; + self.bottomBarView = bottomBar; + + [bottomBar mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(self.view); + make.bottom.equalTo(self.view); + }]; + + // ── 兼容旧逻辑:保留 startTf / dstTf 属性(隐藏,不再显示) ── + // startTf/dstTf 只用作数据载体,不加入视图层级 + UITextField *startTf = [[UITextField alloc] init]; startTf.tag = 100; - startTf.delegate = self; - startTf.font = [UIFont systemFontOfSize:13]; - [self.view addSubview:startTf]; - - [startTf mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.mas_equalTo(self.view).offset(kRoutePlanStatusBarHeight + 35); - make.left.mas_equalTo(self.view).offset(5); - make.width.mas_equalTo(@120); - make.height.mas_equalTo(@32); - }]; - self.startTf = startTf; - - UITextField * dstTf = [[UITextField alloc] init]; - dstTf.borderStyle = UITextBorderStyleRoundedRect; - dstTf.placeholder = @"终点"; + + UITextField *dstTf = [[UITextField alloc] init]; dstTf.tag = 200; - dstTf.delegate = self; - dstTf.font = [UIFont systemFontOfSize:13]; - - [self.view addSubview:dstTf]; - - [dstTf mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerY.mas_equalTo(startTf); - make.left.mas_equalTo(startTf.mas_right).offset(15); -// make.right.mas_equalTo(self.view).offset(-5); - make.width.height.mas_equalTo(startTf); - }]; self.dstTf = dstTf; - - UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom]; - [btn setTitle:@"规划线路" forState:UIControlStateNormal]; - btn.backgroundColor = [UIColor whiteColor]; - btn.titleLabel.font = [UIFont systemFontOfSize:14]; - - btn.layer.borderColor = [UIColor blueColor].CGColor; - btn.layer.borderWidth = 1; - btn.layer.cornerRadius = 5; - - [btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; - [btn addTarget:self action:@selector(calRoutePath) forControlEvents:UIControlEventTouchUpInside]; - [self.view addSubview:btn]; - [btn mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(dstTf.mas_right).offset(12); - make.top.mas_equalTo(startTf); - make.right.mas_equalTo(self.view).offset(-5); - make.height.mas_equalTo(@30); - }]; - - - UIButton * navBtn = [UIButton buttonWithType:UIButtonTypeCustom]; - [navBtn setTitle:@"导航>" forState:UIControlStateNormal]; - navBtn.backgroundColor = [UIColor whiteColor]; - navBtn.titleLabel.font = [UIFont systemFontOfSize:14]; - - navBtn.layer.borderColor = [UIColor blueColor].CGColor; - navBtn.layer.borderWidth = 1; - navBtn.layer.cornerRadius = 6; - - [navBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; + + // ── 旧版导航按钮(保留,hidden 状态,供兼容逻辑使用) ───── + UIButton *navBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + navBtn.hidden = YES; [navBtn addTarget:self action:@selector(navAction) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:navBtn]; [navBtn mas_makeConstraints:^(MASConstraintMaker *make) { -// make.left.equalTo(self.view).offset(12); -// make.centerX.equalTo(self.view); make.right.equalTo(self.view).offset(-15); make.bottom.equalTo(self.view).offset(-118); make.height.mas_equalTo(@30); make.width.mas_equalTo(@60); }]; + + [self.view bringSubviewToFront:bottomBar]; + + // ── 放大缩小控件 ────────────────────────────────────────── + ACustomStepView *stepView = [[ACustomStepView new] initWithValue:self.mapView.zoomLevel maxValue:18.5 min:3.5]; + [self.view addSubview:stepView]; + [stepView mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(self.view).offset(-15); + make.width.equalTo(@40); + make.height.equalTo(@81); + make.top.equalTo(self.view).offset(100); + }]; + + [stepView addObserver:self forKeyPath:@"value" options:NSKeyValueObservingOptionNew context:nil]; + self.stepView = stepView; + + ///当前位置按钮 + UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom]; + [btn setImage:[AMapNavCommonUtil imageWithName3x:@"my_location_icon"] forState:UIControlStateNormal]; + btn.backgroundColor = [UIColor lightGrayColor]; + btn.titleLabel.font = [UIFont systemFontOfSize:14]; + btn.layer.cornerRadius = 20; - [self.mapView mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.right.equalTo(self.view); -// make.top.equalTo(startTf.mas_bottom).offset(5); - make.top.equalTo(self.view).offset(0); -// make.bottom.equalTo(navBtn.mas_top).offset(-3); - make.bottom.equalTo(self.view).offset(0); + [btn addTarget:self action:@selector(updateUserLocalAction) forControlEvents:UIControlEventTouchUpInside]; + + [self.view addSubview:btn]; + [btn mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(self.view).offset(-10); + make.width.height.equalTo(@40); + make.bottom.equalTo(bottomBar.mas_top).offset(-85); }]; - [self.view bringSubviewToFront:navBtn]; } +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if ([keyPath isEqualToString:@"value"]) { + self.mapView.zoomLevel = [change[NSKeyValueChangeNewKey] doubleValue]; + } + +} + + - (void)initDriveManager { //请在 dealloc 函数中执行 [AMapNaviDriveManager destroyInstance] 来销毁单例 @@ -299,19 +364,9 @@ self.mapView.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; // 定位精度 _mapView.showsScale= YES; - CGFloat ze = self.mapView.zoomLevel; - self.mapView.zoomLevel = 9; - - // 2. 禁用所有不必要的动画和自动调整 -// self.mapView.autoresizesSubviews = NO; -// [self.mapView setShowsWorldMap:NO]; // 不显示世界地图 - - // 3. 固定缩放级别 -// [self.mapView setMinZoomLevel:6.0]; -// [self.mapView setMaxZoomLevel:20.0]; -// [self.mapView setZoomLevel:10.0 animated:NO]; + _mapView.logoCenter = CGPointMake(CGRectGetWidth(self.view.bounds)-55, 450); + self.mapView.zoomLevel = 11; - // 4. 禁用自动调整 // [self.mapView setAutoCheckMapBoundary:NO]; @@ -325,34 +380,6 @@ } } - ///TEST -// MAPointAnnotation *pointAnnotation = [[MAPointAnnotation alloc] init]; -// pointAnnotation.coordinate = CLLocationCoordinate2DMake(31.19, 121.32); -// pointAnnotation.title = @"嘉兴经开站"; -// [_mapView addAnnotation:pointAnnotation]; -// -// MAPointAnnotation *pointAnnotation2 = [[MAPointAnnotation alloc] init]; -// pointAnnotation2.coordinate = CLLocationCoordinate2DMake(30.81669400, 120.94291800); -// pointAnnotation2.title = @"测试站点1"; -// [_mapView addAnnotation:pointAnnotation2]; - - - - UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom]; - [btn setImage:[AMapNavCommonUtil imageWithName:@"icon_local"] forState:UIControlStateNormal]; - btn.backgroundColor = [UIColor lightGrayColor]; - btn.titleLabel.font = [UIFont systemFontOfSize:14]; - btn.layer.cornerRadius = 20; - - [btn addTarget:self action:@selector(updateUserLocalAction) forControlEvents:UIControlEventTouchUpInside]; - - [self.view addSubview:btn]; - [btn mas_makeConstraints:^(MASConstraintMaker *make) { - make.right.equalTo(self.view).offset(-10); - make.width.height.equalTo(@40); - make.top.equalTo(self.view).offset(150); - }]; - } } @@ -394,9 +421,20 @@ if (!_locationService) { _locationService = [[AMapLocationManager alloc] init]; _locationService.delegate = self; - _locationService.desiredAccuracy = kCLLocationAccuracyBest; // 最高精度模式 + _locationService.desiredAccuracy = kCLLocationAccuracyBestForNavigation; // 最高精度模式 _locationService.distanceFilter = 5; _locationService.locatingWithReGeocode = YES; + +// CLLocationManager * mgr; +// // 2. 检查是否为模糊定位(iOS 14+) +// if (@available(iOS 14.0, *)) { +// if (mgr.accuracyAuthorization == CLAccuracyAuthorizationReducedAccuracy) { +// // 弹窗申请临时精确权限(需配置 purposeKey) +// [mgr requestTemporaryFullAccuracyAuthorizationWithPurposeKey:@"YourPurposeKey" completion:nil]; +// +// } +// } + } return _locationService; } @@ -405,7 +443,8 @@ - (void)dealloc { [self.locationService stopUpdatingLocation]; - + [self.stepView removeObserver:self forKeyPath:@"value"]; + } - (AMapNaviCompositeManager *)compositeManager { @@ -450,125 +489,123 @@ } } -#pragma mark - Action -///选择方式 --(void)navAction { - [self showSelectNavType]; -} - --(void)showSelectNavType { - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"选择导航类型" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; - UIAlertAction *sure = [UIAlertAction actionWithTitle:@"SDK导航" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { - [self navigationType_sdk]; - }]; - UIAlertAction *sure2 = [UIAlertAction actionWithTitle:@"高德地图导航" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { - - [self navigationType_app]; - }]; - - UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { - }]; - - [alert addAction:sure]; - [alert addAction:sure2]; - [alert addAction:cancel]; - - [self presentViewController:alert animated:YES completion:nil]; -} - --(void)navigationType_app { - - NSURL* scheme = [NSURL URLWithString:@"iosamap://"]; - BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:scheme]; - if (!canOpen) { - [self showAlertWithMessage:@"请先安装高德地图客户端"]; return; - } - - NSString *myLocationScheme = [NSString stringWithFormat:@"iosamap://navi?sourceApplication=ANavDemo&lat=31.2304&lon=121.4737&t=0&dev=1"]; - - NSString *encodedUrlString = [myLocationScheme stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; - - NSURL *gaodeUrl = [NSURL URLWithString:encodedUrlString]; - - - [[UIApplication sharedApplication] openURL:gaodeUrl options:@{} completionHandler:^(BOOL res) { - - }]; - -} - --(void)navigationType_sdk { - id delegate = [AMapNaviDriveManager sharedInstance].delegate; - if (!delegate) { - [AMapNaviDriveManager sharedInstance].delegate = self; - } - - - NSDictionary * routes = [AMapNaviDriveManager sharedInstance].naviRoutes; - if (!routes) { - NSLog(@"暂无路线信息!!!!!!!!!"); - self.isStartNav = YES; - [self calRoutePath]; - - return; - } - - - AMapNaviCompositeUserConfig *config = [[AMapNaviCompositeUserConfig alloc] init]; - -// [config setRoutePlanPOIType:AMapNaviRoutePlanPOITypeEnd location:[AMapNaviPoint locationWithLatitude:32.21 longitude:121.34] name:@"故宫22" POIId:nil]; - - [config setStartNaviDirectly:YES]; //直接进入导航界面 - [config setNeedCalculateRouteWhenPresent:NO];//不在算路 - [config setMultipleRouteNaviMode:NO];//直接单线路径导航 -// [config setNeedDestoryDriveManagerInstanceWhenDismiss:NO]; - - self.isStartNav = NO; - - [self.compositeManager presentRoutePlanViewControllerWithOptions:config]; - -} - - #pragma mark - 计算线路 ///计算线路 --(void)calRoutePath { -// [self.mapView removeOverlays:self.mapView.overlays]; -// self.startTf.text = @"click calpath"; -// return; - - [self initAnnotations]; - +-(void)calRoutePathWithWayPonts:(NSArray *) naviList { AMapNaviPoint * startPoint = [AMapNaviPoint locationWithLatitude:self.startPoi.location.latitude longitude:self.startPoi.location.longitude]; - AMapNaviPoint * endPoint = [AMapNaviPoint locationWithLatitude:self.dstPoi.location.latitude longitude:self.dstPoi.location.longitude]; + + AMapPOI *_dstPoi = self.dstPoi ? self.dstPoi : self.defaultDstPoi; + AMapNaviPoint * endPoint = [AMapNaviPoint locationWithLatitude:_dstPoi.location.latitude longitude:_dstPoi.location.longitude]; + + if (!(self.startPoi && _dstPoi)) { + [AMapNavCommonUtil showMsg:@"计算线路,起始点缺失"]; + return; + } AMapNaviDrivingStrategy strategy = ConvertDrivingPreferenceToDrivingStrategy(0, 0, 0, 0, 0); + strategy = AMapNaviDrivingStrategyMultipleDefault;//使用默认策略 id delegate = [AMapNaviDriveManager sharedInstance].delegate; if (!delegate) { [AMapNaviDriveManager sharedInstance].delegate = self; } + NSArray *wayPoints = [self getWayPointWithPoint:naviList]; + + [[AMapNaviDriveManager sharedInstance] setVehicleInfo:[self getCarInfo]]; [[AMapNaviDriveManager sharedInstance] calculateDriveRouteWithStartPoints:@[startPoint] endPoints:@[endPoint] - wayPoints:nil + wayPoints:wayPoints drivingStrategy:strategy]; } - -- (void)driveManagerOnCalculateRouteSuccess:(AMapNaviDriveManager *)driveManager -{ - NSLog(@"onCalculateRouteSuccess"); - //算路成功后显示路径 - [self showNaviRoutes]; +-(NSArray *)getWayPointWithPoint:(NSArray *) naviList { + NSMutableArray *wayPoints = [NSMutableArray array]; + + for (int i = 0; i < naviList.count; i++) { + ANaviPathInfoModel * item = naviList[i]; + + AMapNaviPoint * res = [AMapNaviPoint locationWithLatitude:[item.latitude doubleValue] longitude:[item.longitude doubleValue]]; + [wayPoints addObject:res]; + } + + return wayPoints; } +-(AMapNaviVehicleInfo*)getCarInfo { + AMapNaviVehicleInfo * car = [AMapNaviVehicleInfo new]; + + ATruckModel * truckInfo = self.tjdPathInfoModel.truckDto; + if (!truckInfo) { + return car; + } + + // 车牌号 + if (truckInfo.mcarNumber.length > 0) { + car.vehicleId = truckInfo.mcarNumber; + } + + // 是否躲避限行 + car.isETARestriction = truckInfo.isRestriction; + + // 车辆类型(mcarType 与高德 type 定义一致) + car.type = truckInfo.mcarType; + + // 货车大小分类(mvehicleSize:4 = 重型货车,对应高德 size:4) + car.size = truckInfo.mvehicleSize; + + // 轴数 + car.axisNums = truckInfo.mvehicleAxis; + + // 车身宽度(单位:米) + if (truckInfo.mvehicleWidth.length > 0) { + car.width = [[NSDecimalNumber decimalNumberWithString:truckInfo.mvehicleWidth] floatValue]; + } + + // 车身高度(单位:米) + if (truckInfo.mvehicleHeight.length > 0) { + car.height = [[NSDecimalNumber decimalNumberWithString:truckInfo.mvehicleHeight] floatValue]; + } + + // 车身长度(单位:米) + if (truckInfo.mvehicleLength.length > 0) { + car.length = [[NSDecimalNumber decimalNumberWithString:truckInfo.mvehicleLength] floatValue]; + } + + //总重 + if (truckInfo.mvehicleLoad.length > 0) { + car.load = [[NSDecimalNumber decimalNumberWithString:truckInfo.mvehicleLoad] floatValue]; + } + + // 核定载重 + if (truckInfo.mvehicleWeight.length > 0) { + car.weight = [[NSDecimalNumber decimalNumberWithString:truckInfo.mvehicleWeight] floatValue]; + } + + return car; +} + +///算路成功后回调 +- (void)driveManagerOnCalculateRouteSuccess:(AMapNaviDriveManager *)driveManager +{ + NSDictionary * lines = [AMapNaviDriveManager sharedInstance].naviRoutes ; + NSLog(@"onCalculateRouteSuccess:%@" , lines); + //算路成功后显示路径 + [self gd_navWithCalulatedPath]; +} + +- (void)driveManager:(AMapNaviDriveManager *)driveManager error:(NSError *)error { + ///算路失败,直接去高德规划页面 + [self gd_calPathWithNoStationId:self.pointModel]; +} + +#pragma mark 显示线路[废弃] - (void)showNaviRoutes { if ([[AMapNaviDriveManager sharedInstance].naviRoutes count] <= 0) @@ -600,10 +637,9 @@ coords[i].longitude = [coordinate longitude]; } - MAPolyline *polyline = [MAPolyline polylineWithCoordinates:coords count:count]; - - SelectableOverlay *selectablePolyline = [[SelectableOverlay alloc] initWithOverlay:polyline]; - [selectablePolyline setRouteID:[aRouteID integerValue]]; + // SelectableOverlay 继承 MAPolyline,直接用坐标初始化,避免 renderer overlay 不匹配警告 + SelectableOverlay *selectablePolyline = [SelectableOverlay overlayWithCoordinates:coords count:count]; + selectablePolyline.routeID = [aRouteID integerValue]; [self.mapView addOverlay:selectablePolyline]; free(coords); @@ -623,9 +659,9 @@ [self selectNaviRouteWithID:routeId]; ///如果已开始导航,直接进入导航 - if (self.isStartNav) { - [self navigationType_sdk]; - } +// if (self.isStartNav) { +// [self gd_navWithCalulatedPath]; +// } } @@ -678,6 +714,92 @@ }]; } +#pragma mark - 导航 +///选择方式 +-(void)navAction { + [self gd_navWithCalulatedPath]; //直接导航 +} + +-(void)showSelectNavType { + UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"选择导航类型" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; + UIAlertAction *sure = [UIAlertAction actionWithTitle:@"SDK导航" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + [self gd_navWithCalulatedPath]; + }]; + UIAlertAction *sure2 = [UIAlertAction actionWithTitle:@"高德地图导航" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + + [self navigationType_app]; + }]; + + UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { + }]; + + [alert addAction:sure]; + [alert addAction:sure2]; + [alert addAction:cancel]; + + [self presentViewController:alert animated:YES completion:nil]; +} + +-(void)navigationType_app { + + NSURL* scheme = [NSURL URLWithString:@"iosamap://"]; + BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:scheme]; + if (!canOpen) { + [self showAlertWithMessage:@"请先安装高德地图客户端"]; return; + } + + NSString *myLocationScheme = [NSString stringWithFormat:@"iosamap://navi?sourceApplication=ANavDemo&lat=31.2304&lon=121.4737&t=0&dev=1"]; + + NSString *encodedUrlString = [myLocationScheme stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; + + NSURL *gaodeUrl = [NSURL URLWithString:encodedUrlString]; + + + [[UIApplication sharedApplication] openURL:gaodeUrl options:@{} completionHandler:^(BOOL res) { + + }]; + +} + +///使用算好的路,直接导航 +-(void)gd_navWithCalulatedPath { + id delegate = [AMapNaviDriveManager sharedInstance].delegate; + if (!delegate) { + [AMapNaviDriveManager sharedInstance].delegate = self; + } + + AMapNaviCompositeUserConfig *config = [[AMapNaviCompositeUserConfig alloc] init]; + + [config setRoutePlanPOIType:AMapNaviRoutePlanPOITypeStart location:[AMapNaviPoint locationWithLatitude:self.startPoi.location.latitude longitude:self.startPoi.location.longitude] name:self.startPoi.name POIId:nil]; + + ///车辆信息 + [config setVehicleInfo:[self getCarInfo]]; + + //直接进入导航,不在算路 + [config setStartNaviDirectly:YES]; //直接进入导航界面 + [config setNeedCalculateRouteWhenPresent:NO];//不在算路 + [config setMultipleRouteNaviMode:NO];//直接单线路径导航 +// [config setNeedDestoryDriveManagerInstanceWhenDismiss:NO]; + + [self.compositeManager presentRoutePlanViewControllerWithOptions:config]; +} + +///SDK计算线路 +-(void)gd_calPathWithNoStationId: (ANavPointModel *) dst { + + AMapNaviCompositeUserConfig *config = [[AMapNaviCompositeUserConfig alloc] init]; + + [config setRoutePlanPOIType:AMapNaviRoutePlanPOITypeEnd location:[AMapNaviPoint locationWithLatitude:dst.coordinate.latitude longitude:dst.coordinate.longitude] name:dst.name POIId:nil]; + [config setVehicleInfo:[self getCarInfo]]; + +// [config setStartNaviDirectly:YES]; //直接进入导航界面 + [config setNeedCalculateRouteWhenPresent:NO];//不在算路 +// [config setMultipleRouteNaviMode:NO];//直接单线路径导航 +// [config setNeedDestoryDriveManagerInstanceWhenDismiss:NO]; + + [self.compositeManager presentRoutePlanViewControllerWithOptions:config]; +} + #pragma mark - AMapLocationManagerDelegate - (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode { @@ -702,6 +824,8 @@ #ifdef kAMapSDKDebugFlag aoi.location = [AMapGeoPoint locationWithLatitude:31.23 longitude:121.48 ]; aoi.name =@"人民大道185号"; + self.latitude = 31.23; + self.longitude = 121.48 ; #else aoi.location = [AMapGeoPoint locationWithLatitude:self.latitude longitude:self.longitude ]; aoi.name = reGeocode.POIName; @@ -735,6 +859,24 @@ - (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation { + // 当前位置:用 car 图标替换系统默认蓝点 + if ([annotation isKindOfClass:[MAUserLocation class]]) + { + static NSString *userLocationIdentifier = @"UserLocationCarIdentifier"; + MAAnnotationView *userView = [mapView dequeueReusableAnnotationViewWithIdentifier:userLocationIdentifier]; + if (userView == nil) + { + userView = [[MAAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:userLocationIdentifier]; + userView.canShowCallout = NO; + } + else + { + userView.annotation = annotation; + } + userView.image = [AMapNavCommonUtil imageWithName:@"car"]; + return userView; + } + if ([annotation isKindOfClass:[NaviPointAnnotation class]]) { static NSString *annotationIdentifier = @"NaviPointAnnotationIdentifier"; @@ -764,20 +906,25 @@ return pointAnnotationView; } - if ( [annotation isMemberOfClass:[MAPointAnnotation class]]) + // 处理普通点标注(排除用户定位点) + if ([annotation isKindOfClass:[ACustomPointAnnotation class]] && + ![annotation isKindOfClass:[MAUserLocation class]]) { - MAUserLocation *user = (MAUserLocation *)annotation; - static NSString *pointReuseIndentifier = @"pointReuseIndentifier"; - MAPinAnnotationView*annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndentifier]; + ACustomAnnotationView *annotationView = (ACustomAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndentifier]; if (annotationView == nil) { - annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndentifier]; + annotationView = [[ACustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndentifier]; } - annotationView.canShowCallout= YES; //设置气泡可以弹出,默认为NO - annotationView.animatesDrop = NO; //设置标注动画显示,默认为NO - annotationView.draggable = NO; //设置标注可以拖动,默认为NO - annotationView.pinColor = MAPinAnnotationColorPurple; + else + { + // 复用时必须更新 annotation,否则可能不刷新/不显示 + annotationView.annotation = annotation; + } +// annotationView.canShowCallout= YES; //设置气泡可以弹出,默认为NO +// annotationView.animatesDrop = NO; //设置标注动画显示,默认为NO +// annotationView.draggable = NO; //设置标注可以拖动,默认为NO +// annotationView.pinColor = MAPinAnnotationColorPurple; // 设置自定义的气泡背景色 if (@available(iOS 14.0, *)) { @@ -798,12 +945,13 @@ { if ([overlay isKindOfClass:[SelectableOverlay class]]) { - SelectableOverlay * selectableOverlay = (SelectableOverlay *)overlay; - id actualOverlay = selectableOverlay.overlay; + SelectableOverlay *selectableOverlay = (SelectableOverlay *)overlay; - MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:actualOverlay]; + // SelectableOverlay 继承自 MAPolyline,直接用自身初始化 renderer + // renderer.overlay == overlay,避免 MAMapKit 的 overlay 不匹配警告 + MAPolylineRenderer *polylineRenderer = [[MAPolylineRenderer alloc] initWithPolyline:selectableOverlay]; - polylineRenderer.lineWidth = 8.f; + polylineRenderer.lineWidth = 8.f; polylineRenderer.strokeColor = selectableOverlay.isSelected ? selectableOverlay.selectedColor : selectableOverlay.regularColor; return polylineRenderer; @@ -818,7 +966,7 @@ # if 0 for (MAAnnotationView *view in views) { // 检查是否为需要的标注类型,例如大头针标注 - if ([view.annotation isMemberOfClass:[MAPointAnnotation class]]) { + if ([view.annotation isMemberOfClass:[ACustomPointAnnotation class]]) { // 延迟零点几秒执行,以确保视图添加动画完成(可选,但可使效果更平滑) dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 选中该标注,从而使其气泡弹出 @@ -830,24 +978,45 @@ } - (void)mapView:(MAMapView *)mapView didSelectAnnotationView:(MAAnnotationView *)view { - NSLog(@"didSelectAnnotationView: %s" , __func__); + + id pointAnnotation = view.annotation; + if ([pointAnnotation isMemberOfClass:ACustomPointAnnotation.class]) { + ACustomPointAnnotation *point = (ACustomPointAnnotation *)view.annotation; + + NSLog(@"point: %@" , point.title); + + AMapPOI * aoi = [[AMapPOI alloc] init]; + aoi.location = [AMapGeoPoint locationWithLatitude:point.coordinate.latitude longitude:point.coordinate.longitude]; + aoi.name = point.title; + aoi.address = point.subtitle; + aoi.uid = point.stationID; + + self.dstPoi = aoi; + + [self updateUIWithData:aoi textField:self.dstTf]; + + + // 同步更新底部栏目的地文字 + self.bottomBarView.destinationText = aoi.name; + } } - // 当标注被取消选中时调用 - (void)mapView:(MAMapView *)mapView didDeselectAnnotationView:(MAAnnotationView *)view { - if ([view.annotation isMemberOfClass:[MAPointAnnotation class]]) { - // 可以立即或稍作延迟后重新选中 -// [mapView selectAnnotation:view.annotation animated:NO]; + if ([view.annotation isMemberOfClass:[ACustomPointAnnotation class]]) { + // 清空目的地信息 & 底部栏 + self.dstPoi = nil; + self.dstTf.text = nil; + self.bottomBarView.destinationText = nil; } } //选中一个点 - (void)mapView:(MAMapView *)mapView didAnnotationViewCalloutTapped:(MAAnnotationView *)view { id pointAnnotation = view.annotation; - if ([pointAnnotation isMemberOfClass:MAPointAnnotation.class]) { - MAPointAnnotation *point = (MAPointAnnotation *)view.annotation; + if ([pointAnnotation isMemberOfClass:ACustomPointAnnotation.class]) { + ACustomPointAnnotation *point = (ACustomPointAnnotation *)view.annotation; NSLog(@"point: %@" , point.title); @@ -880,26 +1049,113 @@ } -#pragma mark - UITextFieldDelegate -- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { +#pragma mark - 弹框 +-(void)willRequestTJDInfo { + ///调用接口获取途经点 + /// + + AMapPOI *_dstPoi = self.dstPoi ? self.dstPoi : self.defaultDstPoi; + if (!_dstPoi) { + return; + } + + AMapGeoPoint * point = _dstPoi.location; + ANavPointModel *navPoint = [ANavPointModel instanceWithCoordinate:CLLocationCoordinate2DMake(point.latitude, point.longitude) + name:_dstPoi.name + address:_dstPoi.address]; + navPoint.stationID = _dstPoi.uid; + self.pointModel = navPoint; + + ///有_stationID 请求接口;无:不走接口,直接调整高德规划路线; + if (!navPoint.stationID) { + [self gd_calPathWithNoStationId:navPoint]; + return; + }else { + __weak typeof(self) weakSelf = self; + [self requestRoutePathWithParms:nil completeHandle:^(ATripCalcDataModel *tjd) { + [weakSelf showDstInfoPop:navPoint]; + }]; + + } + +} - ASearchAddressController * vc = [[ASearchAddressController alloc] init]; +-(void)showDstInfoPop:(ANavPointModel *) navPoint { - UINavigationController * nav = [[UINavigationController alloc]initWithRootViewController:vc]; - //UIModalPresentationOverFullScreen/UIModalPresentationFullScreen触发离开 - nav.modalPresentationStyle = UIModalPresentationOverFullScreen; - nav.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + // --- 弹出站点详情弹框 --- + if (!self.stationDetailPopup) { + AStationDetailPopupController *popup = [[AStationDetailPopupController alloc] init]; + popup.delegate = self; + self.stationDetailPopup = popup; + } + + self.stationDetailPopup.pointModel = navPoint; - __weak typeof(self)weakSelf = self; - vc.selectAddressBlk = ^(AMapPOI * _Nonnull poi) { - [weakSelf updateUIWithData:poi textField:textField]; + ///费用 + self.stationDetailPopup.estimatedCost = self.tjdPathInfoModel.algorithmPath.hydrogenCost; + ///时间 + self.stationDetailPopup.estimatedTime = [NSString stringWithFormat:@"%.f" , self.tjdPathInfoModel.pathDto.duration / 60.0]; + + ///距离 + self.stationDetailPopup.driveDistance = [NSString stringWithFormat:@"%.1f" , self.tjdPathInfoModel.pathDto.distance / 1000.0] ; + ///油费 + self.stationDetailPopup.tollFee = self.tjdPathInfoModel.pathDto.tolls; + + [self.stationDetailPopup presentInViewController:self]; + +} + +#pragma mark - AStationDetailPopupDelegate + +- (void)stationDetailPopupDidTapStartNavi:(AStationDetailPopupController *)popup { + self.stationDetailPopup = nil; + ///点击开始导航: + ///1、有途经点,计算路线,然后再直接导航 + ///2、没有途经点,不用计算路线,直接跳转高德规划页面,然后规划页面中点击导航; + ATripCalcDataModel * tjd = self.tjdPathInfoModel; + if (tjd && tjd.pathDto && tjd.pathDto.naviList) { + NSArray * arr = tjd.pathDto.naviList; + if ([arr isKindOfClass:NSArray.class] && arr.count > 0) { + [self calRoutePathWithWayPonts:arr]; + }else { + [self gd_calPathWithNoStationId:self.pointModel]; + } + + }else { + [self gd_calPathWithNoStationId:self.pointModel]; + } +} + +- (void)stationDetailPopupDidTapClose:(AStationDetailPopupController *)popup { + self.stationDetailPopup = nil; +} + +#pragma mark - ABottomBarViewDelegate + +- (void)bottomBarViewDidTapCalRoute:(ABottomBarView *)barView { + + //详情弹框 + [self willRequestTJDInfo]; + +} + +- (void)bottomBarViewDidTapSearchField:(ABottomBarView *)barView { + // 弹出地址搜索页,选中后更新目的地输入框 + ASearchAddressController *vc = [[ASearchAddressController alloc] init]; + UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; + nav.modalPresentationStyle = UIModalPresentationFullScreen; + + __weak typeof(self) weakSelf = self; + vc.selectAddressBlk = ^(AMapPOI *poi) { + __strong typeof(weakSelf) strongSelf = weakSelf; + // 更新底部栏显示文字 + strongSelf.bottomBarView.destinationText = poi.name; + // 同步旧属性(供 calRoutePath 使用) + poi.uid = nil; + [strongSelf updateUIWithData:poi textField:strongSelf.dstTf]; }; - - [self presentViewController:nav animated:YES completion:^{ - - }]; - return NO; + [self presentViewController:nav animated:YES completion:nil]; } -(void)updateUIWithData: (AMapPOI*)poi textField: (UITextField*)tf { diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ASearchAddressController.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ASearchAddressController.m index eb87923..c0ce3a8 100644 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ASearchAddressController.m +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ASearchAddressController.m @@ -45,7 +45,10 @@ - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - [self.inputAddressTf becomeFirstResponder]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self.inputAddressTf becomeFirstResponder]; + }); + } -(void)initSubview { diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AStationDetailPopupController.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AStationDetailPopupController.h new file mode 100644 index 0000000..ce2a216 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AStationDetailPopupController.h @@ -0,0 +1,55 @@ +// +// AStationDetailPopupController.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/22. +// + +#import +#import "ANavPointModel.h" +#import "AMapNavSDKHeader.h" + +NS_ASSUME_NONNULL_BEGIN + +@class AStationDetailPopupController; + +@protocol AStationDetailPopupDelegate + +@optional +/// 点击"开始导航" +- (void)stationDetailPopupDidTapStartNavi:(AStationDetailPopupController *)popup; +/// 点击关闭 +- (void)stationDetailPopupDidTapClose:(AStationDetailPopupController *)popup; + +@end + +@interface AStationDetailPopupController : UIViewController + +@property (nonatomic, strong, nullable) ANavPointModel *pointModel; + +/// 预计加氢费用(元),可由外部传入;若 nil 则隐藏 +@property (nonatomic, copy, nullable) NSString *estimatedCost; + +/// 预计时间,如 @"15分钟";若 nil 则隐藏 +@property (nonatomic, copy, nullable) NSString *estimatedTime; + +/// 行驶里程,如 @"23.5公里";若 nil 则隐藏 +@property (nonatomic, copy, nullable) NSString *driveDistance; + +/// 过路费,如 @"30元";若 nil 则隐藏 +@property (nonatomic, copy, nullable) NSString *tollFee; + +@property (nonatomic, weak, nullable) id delegate; + +/// 以半透明蒙层方式弹出在目标控制器上 +- (void)presentInViewController:(UIViewController *)parentVC; + +/// 关闭弹框 +- (void)dismiss; + +/// 关闭弹框,动画结束后执行 completion(用于关闭后再 present 其他页面) +- (void)dismissWithCompletion:(nullable void(^)(void))completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AStationDetailPopupController.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AStationDetailPopupController.m new file mode 100644 index 0000000..9ba560a --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AStationDetailPopupController.m @@ -0,0 +1,485 @@ +// +// AStationDetailPopupController.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/22. +// + +#import "AStationDetailPopupController.h" +#import "ABaseViewController.h" +#import "AMapNavCommonUtil.h" +#import + +// 主题绿色(开始导航按钮背景) +static inline UIColor *AStationThemeGreen(void) { + return [UIColor colorWithRed:0x1A/255.0 green:0x7C/255.0 blue:0x43/255.0 alpha:1.0]; +} + +@interface AStationDetailPopupController () + +/// 背景蒙层 +@property (nonatomic, strong) UIControl *maskControl; + +/// 弹框卡片容器 +@property (nonatomic, strong) UIView *cardView; + +/// 站点名称 +@property (nonatomic, strong) UILabel *stationNameLabel; + +/// 预计加氢费用(名称右侧) +@property (nonatomic, strong) UIImageView *costIconView; +@property (nonatomic, strong) UILabel *costLabel; + +/// 地址 +@property (nonatomic, strong) UILabel *addressLabel; + +/// 分割线 +@property (nonatomic, strong) UIView *separator; + +/// 预计时间行 +@property (nonatomic, strong) UIImageView *timeIconView; +@property (nonatomic, strong) UILabel *timeLabel; + +/// 行驶里程 +@property (nonatomic, strong) UIImageView *distanceIconView; +@property (nonatomic, strong) UILabel *distanceLabel; + +/// 过路费 +@property (nonatomic, strong) UIImageView *tollIconView; +@property (nonatomic, strong) UILabel *tollLabel; + +/// 关闭按钮 +@property (nonatomic, strong) UIButton *closeButton; + +/// 开始导航按钮 +@property (nonatomic, strong) UIButton *startNaviButton; + +/// 卡片 bottom constraint(动画用) +@property (nonatomic, strong) MASConstraint *cardBottomConstraint; + +@end + +@implementation AStationDetailPopupController + +#pragma mark - Life Cycle + +- (void)viewDidLoad { + [super viewDidLoad]; + self.view.backgroundColor = [UIColor clearColor]; + [self _buildUI]; + [self _setupMasonryConstraints]; + [self _updateUI]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self _playShowAnimation]; +} + +#pragma mark - Public + +- (void)presentInViewController:(UIViewController *)parentVC { + self.modalPresentationStyle = UIModalPresentationOverCurrentContext; + self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + [parentVC presentViewController:self animated:NO completion:nil]; +} + +- (void)dismiss { + [self dismissWithCompletion:nil]; +} + +- (void)dismissWithCompletion:(void(^)(void))completion { + [self _playDismissAnimationWithCompletion:^{ + [self dismissViewControllerAnimated:NO completion:completion]; + }]; +} + +#pragma mark - Setter Override(弹出前赋值 或 弹出后动态更新) + +- (void)setPointModel:(ANavPointModel *)pointModel { + _pointModel = pointModel; + if (self.isViewLoaded) [self _updateUI]; +} + +- (void)setEstimatedCost:(NSString *)estimatedCost { + _estimatedCost = [estimatedCost copy]; + if (self.isViewLoaded) [self _updateUI]; +} + +- (void)setEstimatedTime:(NSString *)estimatedTime { + _estimatedTime = [estimatedTime copy]; + if (self.isViewLoaded) [self _updateUI]; +} + +- (void)setDriveDistance:(NSString *)driveDistance { + _driveDistance = [driveDistance copy]; + if (self.isViewLoaded) [self _updateUI]; +} + +- (void)setTollFee:(NSString *)tollFee { + _tollFee = [tollFee copy]; + if (self.isViewLoaded) [self _updateUI]; +} + +#pragma mark - Build UI + +/** + 卡片结构: + ┌──────────────────────────────────── [✕] ┐ + │ 站点名称(加粗) 预计加氢费用:--元 │ ← 同行,间距20pt + │ 地址(灰色小字,多行) │ + │ ──────────────────────────────────────── │ + │ [icon] 预计时间:-- 分钟 │ + │ [icon] 行驶里程:-- 公里 [icon] 过路费:-- 元 │ + │ ╔════════════════════════════════════╗ │ + │ ║ 开始导航 ║ │ + │ ╚════════════════════════════════════╝ │ + │ (距底部30pt) │ + └─────────────────────────────────────────┘ +*/ +- (void)_buildUI { + // ── 蒙层 ── + UIControl *mask = [[UIControl alloc] init]; + mask.backgroundColor = [UIColor colorWithWhite:0 alpha:0.35]; + [mask addTarget:self action:@selector(_onMaskTapped) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:mask]; + self.maskControl = mask; + + // ── 卡片 ── + UIView *card = [[UIView alloc] init]; + card.backgroundColor = [UIColor whiteColor]; + card.layer.cornerRadius = 16; + card.layer.masksToBounds = NO; + card.layer.shadowColor = [UIColor blackColor].CGColor; + card.layer.shadowOpacity = 0.15; + card.layer.shadowRadius = 12; + card.layer.shadowOffset = CGSizeMake(0, -4); + [self.view addSubview:card]; + self.cardView = card; + + // ── 关闭按钮 ── + UIButton *closeBtn = [UIButton buttonWithType:UIButtonTypeCustom]; +// [closeBtn setTitle:@"✕" forState:UIControlStateNormal]; + [closeBtn setImage: [AMapNavCommonUtil imageWithName:@"icon_close"] forState:UIControlStateNormal]; + + [closeBtn setTitleColor:[UIColor colorWithWhite:0.5 alpha:1] forState:UIControlStateNormal]; + closeBtn.titleLabel.font = [UIFont systemFontOfSize:16]; + [closeBtn addTarget:self action:@selector(_onCloseTapped) forControlEvents:UIControlEventTouchUpInside]; + [card addSubview:closeBtn]; + self.closeButton = closeBtn; + + // ── 站点名称 ── + UILabel *nameLabel = [[UILabel alloc] init]; + nameLabel.font = [UIFont boldSystemFontOfSize:18]; + nameLabel.textColor = [UIColor colorWithWhite:0.1 alpha:1]; + nameLabel.numberOfLines = 2; +// nameLabel.adjustsFontSizeToFitWidth = YES; + nameLabel.minimumScaleFactor = 0.8; + [card addSubview:nameLabel]; + self.stationNameLabel = nameLabel; + + // ── 预计加氢费用(名称右侧,间距20pt) ── + UILabel *costLabel = [[UILabel alloc] init]; + costLabel.font = [UIFont systemFontOfSize:14]; + costLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1]; + costLabel.numberOfLines = 1; + costLabel.textAlignment = NSTextAlignmentLeft; +// [costLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; +// [costLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; + [card addSubview:costLabel]; + self.costLabel = costLabel; + + // ── 地址 ── + UILabel *addrLabel = [[UILabel alloc] init]; + addrLabel.font = [UIFont systemFontOfSize:13]; + addrLabel.textColor = [UIColor colorWithWhite:0.5 alpha:1]; + addrLabel.numberOfLines = 2; + [card addSubview:addrLabel]; + self.addressLabel = addrLabel; + + UIImageView *costIcon = [[UIImageView alloc] init]; + costIcon.contentMode = UIViewContentModeScaleAspectFit; + costIcon.image = [AMapNavCommonUtil imageWithName3x:@"ic_fuel"]; + [card addSubview:costIcon]; + self.costIconView = costIcon; + + // ── 分割线 ── + UIView *sep = [[UIView alloc] init]; + sep.backgroundColor = [UIColor colorWithWhite:0.88 alpha:1]; + [card addSubview:sep]; + self.separator = sep; + + // ── 预计时间图标 ── + UIImageView *timeIcon = [[UIImageView alloc] init]; + timeIcon.contentMode = UIViewContentModeScaleAspectFit; + timeIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_time_icon"]; + [card addSubview:timeIcon]; + self.timeIconView = timeIcon; + + // ── 预计时间文字 ── + UILabel *timeLabel = [[UILabel alloc] init]; + timeLabel.font = [UIFont systemFontOfSize:14]; + timeLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1]; + [card addSubview:timeLabel]; + self.timeLabel = timeLabel; + + // ── 行驶里程图标 ── + UIImageView *distIcon = [[UIImageView alloc] init]; + distIcon.contentMode = UIViewContentModeScaleAspectFit; + distIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_distance_icon"]; + [card addSubview:distIcon]; + self.distanceIconView = distIcon; + + // ── 行驶里程文字 ── + UILabel *distLabel = [[UILabel alloc] init]; + distLabel.font = [UIFont systemFontOfSize:14]; + distLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1]; + [card addSubview:distLabel]; + self.distanceLabel = distLabel; + + // ── 过路费图标 ── + UIImageView *tollIcon = [[UIImageView alloc] init]; + tollIcon.contentMode = UIViewContentModeScaleAspectFit; + tollIcon.image = [AMapNavCommonUtil imageWithName3x:@"pre_cost_icon"]; + [card addSubview:tollIcon]; + self.tollIconView = tollIcon; + + // ── 过路费文字 ── + UILabel *tollLabel = [[UILabel alloc] init]; + tollLabel.font = [UIFont systemFontOfSize:14]; + tollLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1]; + [card addSubview:tollLabel]; + self.tollLabel = tollLabel; + + // ── 开始导航按钮 ── + UIButton *naviBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + [naviBtn setTitle:@"开始导航" forState:UIControlStateNormal]; + [naviBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + naviBtn.titleLabel.font = [UIFont boldSystemFontOfSize:17]; + naviBtn.backgroundColor = AStationThemeGreen(); + naviBtn.layer.cornerRadius = 24; + [naviBtn addTarget:self action:@selector(_onStartNaviTapped) forControlEvents:UIControlEventTouchUpInside]; + [card addSubview:naviBtn]; + self.startNaviButton = naviBtn; +} + +#pragma mark - Masonry Constraints + +- (void)_setupMasonryConstraints { + UIView *card = self.cardView; + CGFloat iconSize = 16; + + // ── 蒙层:铺满父视图 ── + [self.maskControl mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.view); + }]; + + // ── 卡片:左右各16,底部距 safeArea 30pt ── + // 初始状态卡片在屏幕下方(动画起点),top 留空,先用 bottom 约束做弹入 + [card mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(16); + make.right.equalTo(self.view).offset(-16); + // 动画起点:卡片顶部 = 父视图底部(完全隐藏在屏幕外) + make.top.equalTo(self.view.mas_bottom).offset(0); + }]; + + // ── 关闭按钮:右上角 ── + [self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(card).offset(8); + make.right.equalTo(card).offset(-15); + make.width.height.mas_equalTo(40); + }]; + + // ── 第一行:站点名称(左,内容自适应)+ 预计加氢费用(紧跟nameLabel右侧20pt) ── + // nameLabel:内容有多宽占多宽,宽度上限55%,防止过长把费用挤掉 + [self.stationNameLabel setContentHuggingPriority:UILayoutPriorityDefaultLow + forAxis:UILayoutConstraintAxisHorizontal]; + [self.stationNameLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(card).offset(25); + make.left.equalTo(card).offset(16); +// make.width.lessThanOrEqualTo(card).multipliedBy(0.45); + make.right.equalTo(self.closeButton.mas_left).offset(-12); + }]; + + // ── 地址(名称下方,6pt间距) ── + [self.addressLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.stationNameLabel.mas_bottom).offset(10); + make.left.equalTo(card).offset(16); + make.right.equalTo(card).offset(-16); + }]; + + // ── 分割线(地址下方,12pt间距) ── + [self.separator mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.addressLabel.mas_bottom).offset(15); + make.left.equalTo(card).offset(16); + make.right.equalTo(card).offset(-16); + make.height.mas_equalTo(0.5); + }]; + + // ── 预计时间行(分割线下方,14pt) ── + [self.timeIconView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.separator.mas_bottom).offset(15); + make.left.equalTo(card).offset(16); + make.width.height.mas_equalTo(iconSize); + }]; + + [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.timeIconView); + make.left.equalTo(self.timeIconView.mas_right).offset(6); +// make.right.equalTo(card).offset(-16); + make.height.mas_equalTo(24); + }]; + + ///cost + [self.costIconView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.timeIconView); + make.left.equalTo(self.timeLabel.mas_right).offset(30); + make.width.height.mas_equalTo(iconSize); + }]; + + [self.costLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.costIconView); + make.left.equalTo(self.costIconView.mas_right).offset(6); + make.right.lessThanOrEqualTo(card).offset(-10); + }]; + + + // ── 行驶里程 + 过路费行(时间行下方,12pt) ── + [self.distanceIconView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.timeIconView.mas_bottom).offset(15); + make.left.equalTo(card).offset(16); + make.width.height.mas_equalTo(iconSize); + }]; + + [self.distanceLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.distanceIconView); + make.left.equalTo(self.distanceIconView.mas_right).offset(6); + // 宽度约为可用区域的一半(另一半留给过路费) + make.width.mas_lessThanOrEqualTo(130); + make.height.mas_equalTo(24); + }]; + + [self.tollIconView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.distanceIconView); + make.left.equalTo(self.costIconView.mas_left); + make.width.height.mas_equalTo(iconSize); + }]; + + [self.tollLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.distanceIconView); + make.left.equalTo(self.tollIconView.mas_right).offset(6); +// make.right.equalTo(card).offset(-16); + make.height.mas_equalTo(24); + }]; + + // ── 开始导航按钮(里程行下方18pt,距卡片底部30pt) ── + [self.startNaviButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.distanceIconView.mas_bottom).offset(50); + make.left.equalTo(card).offset(16); + make.right.equalTo(card).offset(-16); + make.height.mas_equalTo(48); + make.bottom.equalTo(card).offset(-AMP_TabbarSafeBottomMargin); // 卡片底部内间距30pt + }]; +} + +#pragma mark - Data Update + +- (void)_updateUI { + self.stationNameLabel.text = (self.pointModel.name.length > 0) + ? self.pointModel.name : @"--"; + + self.costLabel.text = (self.estimatedCost.length > 0) + ? [NSString stringWithFormat:@"预计加氢费用:%@元", self.estimatedCost] + : @"预计加氢费用:--元"; + + self.addressLabel.text = (self.pointModel.address.length > 0) + ? self.pointModel.address : @"--"; + + // ── 预计时间(始终显示,无值显示"-- 分钟") ── + self.timeLabel.text = (self.estimatedTime.length > 0) + ? [NSString stringWithFormat:@"预计时间:%@分钟", self.estimatedTime] + : @"预计时间:--分钟"; + + // ── 行驶里程(始终显示,无值显示"-- 公里") ── + self.distanceLabel.text = (self.driveDistance.length > 0) + ? [NSString stringWithFormat:@"行驶里程:%@公里", self.driveDistance] + : @"行驶里程:--公里"; + + // ── 过路费(始终显示,无值显示"-- 元") ── + self.tollLabel.text = (self.tollFee.length > 0) + ? [NSString stringWithFormat:@"过路费:%@元", self.tollFee] + : @"过路费:--元"; +} + +#pragma mark - Animation + +/** + 弹入动画:更新 top 约束将卡片滑入至距底部 30pt(含 safeArea) +*/ +- (void)_playShowAnimation { + // 目标状态:卡片底部紧贴 safeArea 底部,再往上留 30pt + [self.cardView mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(0); + make.right.equalTo(self.view).offset(-0); + make.bottom.equalTo(self.view).offset(0); + }]; + + self.maskControl.alpha = 0; + [UIView animateWithDuration:0.36 + delay:0 + usingSpringWithDamping:0.82 + initialSpringVelocity:0.5 + options:UIViewAnimationOptionCurveEaseOut + animations:^{ + self.maskControl.alpha = 1; + [self.view layoutIfNeeded]; + } completion:nil]; +} + +- (void)_playDismissAnimationWithCompletion:(void(^)(void))completion { + [self.cardView mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(16); + make.right.equalTo(self.view).offset(-16); + make.top.equalTo(self.view.mas_bottom).offset(20); + }]; + + [UIView animateWithDuration:0.25 + delay:0 + options:UIViewAnimationOptionCurveEaseIn + animations:^{ + self.maskControl.alpha = 0; + [self.view layoutIfNeeded]; + } completion:^(BOOL finished) { + if (completion) completion(); + }]; +} + +#pragma mark - Actions + +- (void)_onMaskTapped { + if ([self.delegate respondsToSelector:@selector(stationDetailPopupDidTapClose:)]) { + [self.delegate stationDetailPopupDidTapClose:self]; + } + [self dismiss]; +} + +- (void)_onCloseTapped { + if ([self.delegate respondsToSelector:@selector(stationDetailPopupDidTapClose:)]) { + [self.delegate stationDetailPopupDidTapClose:self]; + } + [self dismiss]; +} + +- (void)_onStartNaviTapped { + // 先关闭弹框(等动画完全结束),再通知 delegate 弹出导航页 + // 避免两个 presentViewController 同时进行导致导航页面无法显示 + __weak typeof(self) weakSelf = self; + [self dismissWithCompletion:^{ + __strong typeof(weakSelf) strongSelf = weakSelf; + if ([strongSelf.delegate respondsToSelector:@selector(stationDetailPopupDidTapStartNavi:)]) { + [strongSelf.delegate stationDetailPopupDidTapStartNavi:strongSelf]; + } + }]; +} + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AAlgorithmPathModel.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AAlgorithmPathModel.h new file mode 100644 index 0000000..fa7c6e0 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AAlgorithmPathModel.h @@ -0,0 +1,67 @@ +// +// AAlgorithmPathModel.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface AAlgorithmPathModel : NSObject + +/// 单程 +@property (nonatomic, copy, nullable) NSString *tripRecommendationId; +@property (nonatomic, copy, nullable) NSString *staId; +@property (nonatomic, copy, nullable) NSString *tripOneWayPathId; +@property (nonatomic, copy, nullable) NSString *tripReturnPathId; + +/// 里程(公里) +@property (nonatomic, copy, nullable) NSString *oneWayDis; +@property (nonatomic, copy, nullable) NSString *returnDis; +@property (nonatomic, copy, nullable) NSString *roundTripDis; + +/// 时长(分钟) +@property (nonatomic, copy, nullable) NSString *oneWayTime; +@property (nonatomic, copy, nullable) NSString *returnTime; +@property (nonatomic, copy, nullable) NSString *roundTripTime; + +/// 总成本(元) +@property (nonatomic, copy, nullable) NSString *oneWayCost; +@property (nonatomic, copy, nullable) NSString *returnCost; +@property (nonatomic, copy, nullable) NSString *roundTripCost; + +/// 人工成本(元) +@property (nonatomic, copy, nullable) NSString *oneWayLaborCost; +@property (nonatomic, copy, nullable) NSString *returnLaborCost; +@property (nonatomic, copy, nullable) NSString *roundTripLaborCost; + +/// 高速成本(元) +@property (nonatomic, copy, nullable) NSString *oneWayChargerouteCost; +@property (nonatomic, copy, nullable) NSString *returnChargerouteCost; +@property (nonatomic, copy, nullable) NSString *roundTripChargerouteCost; + +/// 氢耗(公斤) +@property (nonatomic, copy, nullable) NSString *oneWayHydrogenConsumption; +@property (nonatomic, copy, nullable) NSString *returnLaborHydrogenConsumption; +@property (nonatomic, copy, nullable) NSString *roundTripHydrogenConsumption; + +/// 氢气成本(元) +@property (nonatomic, copy, nullable) NSString *oneWayHydrogenCost; +@property (nonatomic, copy, nullable) NSString *returnLaborHydrogenCost; +@property (nonatomic, copy, nullable) NSString *roundTripHydrogenCost; + +/// 加氢站相关 +@property (nonatomic, copy, nullable) NSString *hydrogenCost; // 氢气总成本(元) +@property (nonatomic, copy, nullable) NSString *hydrogenStaServiceTime; // 站服务总时长(分钟) +@property (nonatomic, copy, nullable) NSString *hydrogenStaRefuelingTime;// 实际加油时长(分钟) +@property (nonatomic, copy, nullable) NSString *hydrogenStaQueueTime; // 排队时长(分钟) +@property (nonatomic, copy, nullable) NSString *hydrogenStaServiceTimeCost; // 站服务时间成本(元) +@property (nonatomic, copy, nullable) NSString *hydrogenStaRefuelingTimeCost;// 加油时间成本(元) +@property (nonatomic, copy, nullable) NSString *hydrogenStaQueueTimeCost; // 排队时间成本(元) + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AAlgorithmPathModel.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AAlgorithmPathModel.m new file mode 100644 index 0000000..e328cc7 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AAlgorithmPathModel.m @@ -0,0 +1,12 @@ +// +// AAlgorithmPathModel.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import "AAlgorithmPathModel.h" + +@implementation AAlgorithmPathModel + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ACustomPointAnnotation.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ACustomPointAnnotation.h new file mode 100644 index 0000000..8bd3f82 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ACustomPointAnnotation.h @@ -0,0 +1,17 @@ +// +// ACustomPointAnnotation.h +// Pods +// +// Created by admin on 2026/3/25. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ACustomPointAnnotation : MAPointAnnotation +@property (nonatomic, copy, nullable) NSString *stationID; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ACustomPointAnnotation.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ACustomPointAnnotation.m new file mode 100644 index 0000000..11cae88 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ACustomPointAnnotation.m @@ -0,0 +1,12 @@ +// +// ACustomPointAnnotation.m +// Pods +// +// Created by admin on 2026/3/25. +// + +#import "ACustomPointAnnotation.h" + +@implementation ACustomPointAnnotation + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapHyStationModel.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AMapHyStationModel.h similarity index 95% rename from ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapHyStationModel.h rename to ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AMapHyStationModel.h index 2c1b0cc..e02ae96 100644 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapHyStationModel.h +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AMapHyStationModel.h @@ -34,6 +34,8 @@ NS_ASSUME_NONNULL_BEGIN */ @interface AMapHyStationModel : NSObject +@property (nonatomic, copy, nullable) NSString *ID; +@property (nonatomic, copy, nullable) NSString *hydrogenId; @property (nonatomic, copy) NSString *name; @property (nonatomic, copy, nullable) NSString *shortName; @property (nonatomic, copy, nullable) NSString *siteNo; diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapHyStationModel.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AMapHyStationModel.m similarity index 78% rename from ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapHyStationModel.m rename to ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AMapHyStationModel.m index b6c161f..fcf3f84 100644 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/AMapHyStationModel.m +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/AMapHyStationModel.m @@ -8,6 +8,10 @@ #import "AMapHyStationModel.h" @implementation AMapHyStationModel ++ (NSDictionary *)mj_replacedKeyFromPropertyName +{ + return @{ @"ID" : @"id"}; +} @end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANavPointModel.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANavPointModel.h new file mode 100644 index 0000000..d4ae31f --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANavPointModel.h @@ -0,0 +1,26 @@ +// +// ANavPointModel.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ANavPointModel : NSObject +@property (nonatomic, copy, nullable) NSString *name; +@property (nonatomic, copy, nullable) NSString *address; +@property (nonatomic, copy, nullable) NSString *stationID; + +///经纬度 +@property (nonatomic, assign) CLLocationCoordinate2D coordinate; + +///初始化 ++ (instancetype)instanceWithCoordinate:(CLLocationCoordinate2D)coordinate name:(NSString *)name address:(NSString *)address; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANavPointModel.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANavPointModel.m new file mode 100644 index 0000000..8a328a1 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANavPointModel.m @@ -0,0 +1,22 @@ +// +// ANavPointModel.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import "ANavPointModel.h" + +@implementation ANavPointModel +///初始化 ++ (instancetype)instanceWithCoordinate:(CLLocationCoordinate2D)coordinate name:(NSString *)name address:(NSString *)address { + ANavPointModel *instance = [[ANavPointModel alloc] init]; + if (instance) { + instance.coordinate = coordinate; + instance.name = name; + instance.address = address; + } + return instance; +} + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANaviPathInfoModel.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANaviPathInfoModel.h new file mode 100644 index 0000000..56408a9 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANaviPathInfoModel.h @@ -0,0 +1,32 @@ +// +// ANaviPathInfoModel.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + { + "name": "浙江省嘉兴市平湖市乍浦镇滨海大道中国石化滨海大道加油加气站", + "poiId": "", + "coordinate": { + "longitude": "121.070434", + "latitude": "30.596124" + } + } + */ +@interface ANaviPathInfoModel : NSObject + +@property (nonatomic, copy, nullable) NSString *name; +@property (nonatomic, copy, nullable) NSString *poiId; +@property (nonatomic, copy, nullable) NSString *longitude; +@property (nonatomic, copy, nullable) NSString *latitude; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANaviPathInfoModel.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANaviPathInfoModel.m new file mode 100644 index 0000000..0138b10 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ANaviPathInfoModel.m @@ -0,0 +1,20 @@ +// +// ANaviPathInfoModel.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import "ANaviPathInfoModel.h" + +@implementation ANaviPathInfoModel + ++ (NSDictionary *)mj_replacedKeyFromPropertyName { + // JSON 中 coordinate 是嵌套对象,展开为 longitude/latitude + return @{ + @"longitude": @"coordinate.longitude", + @"latitude": @"coordinate.latitude" + }; +} + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/APathModel.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/APathModel.h new file mode 100644 index 0000000..75ae288 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/APathModel.h @@ -0,0 +1,29 @@ +// +// APathModel.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import +#import +#import "ANaviPathInfoModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@class ANaviPathInfoModel; + +@interface APathModel : NSObject + +@property (nonatomic, assign) CGFloat distance; // 总距离(米) +@property (nonatomic, assign) CGFloat duration; // 总时长(秒) +@property (nonatomic, copy, nullable) NSString *strategy; // 路线策略,如"避免拥堵" +@property (nonatomic, copy, nullable) NSString *tolls; // 高速费(元) +@property (nonatomic, assign) CGFloat toll_distance; // 高速里程(米) +@property (nonatomic, assign) NSInteger restriction; // 限行标志,-1 无 +@property (nonatomic, assign) NSInteger traffic_lights; // 红绿灯数量 +@property (nonatomic, strong) NSArray *naviList; // 途经点列表 + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/APathModel.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/APathModel.m new file mode 100644 index 0000000..a9c26ca --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/APathModel.m @@ -0,0 +1,17 @@ +// +// APathModel.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import "APathModel.h" +#import "ANaviPathInfoModel.h" + +@implementation APathModel + ++ (NSDictionary *)mj_objectClassInArray { + return @{@"naviList": [ANaviPathInfoModel class]}; +} + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ASiteModel.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ASiteModel.h new file mode 100644 index 0000000..942ec0f --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ASiteModel.h @@ -0,0 +1,64 @@ +// +// ASiteModel.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + { + "innerSiteId": "202304241822210001", + "name": "滨海大道加油加气站", + "shortName": "滨海", + "siteNo": "000001", + "city": "浙江省-嘉兴市", + "address": "嘉兴市平湖市滨海大道1515号", + "contact": "陆平", + "phone": "18666666666", + "type": "", + "coOpMode": "签约", + "booking": "无需预约", + "siteStatus": "0", + "siteStatusName": "营运中", + "startBusiness": "08:00:00", + "endBusiness": "20:00:00", + "billingMethod": "月付款", + "term": "1703952000000", + "remark": "", + "longitude": "121.07112700", + "latitude": "30.59577700", + "distance": "" + } + */ +@interface ASiteModel : NSObject + +@property (nonatomic, copy, nullable) NSString *innerSiteId; +@property (nonatomic, copy) NSString *name; +@property (nonatomic, copy, nullable) NSString *shortName; +@property (nonatomic, copy, nullable) NSString *siteNo; +@property (nonatomic, copy, nullable) NSString *city; +@property (nonatomic, copy, nullable) NSString *address; +@property (nonatomic, copy, nullable) NSString *contact; +@property (nonatomic, copy, nullable) NSString *phone; +@property (nonatomic, copy, nullable) NSString *type; +@property (nonatomic, copy, nullable) NSString *coOpMode; +@property (nonatomic, copy, nullable) NSString *booking; +@property (nonatomic, copy, nullable) NSString *siteStatus; +@property (nonatomic, copy, nullable) NSString *siteStatusName; +@property (nonatomic, copy, nullable) NSString *startBusiness; +@property (nonatomic, copy, nullable) NSString *endBusiness; +@property (nonatomic, copy, nullable) NSString *billingMethod; +@property (nonatomic, copy, nullable) NSString *term; +@property (nonatomic, copy, nullable) NSString *remark; +@property (nonatomic, copy, nullable) NSString *longitude; +@property (nonatomic, copy, nullable) NSString *latitude; +@property (nonatomic, copy, nullable) NSString *distance; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ASiteModel.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ASiteModel.m new file mode 100644 index 0000000..d805fbf --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ASiteModel.m @@ -0,0 +1,12 @@ +// +// ASiteModel.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import "ASiteModel.h" + +@implementation ASiteModel + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATripCalcResponse.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATripCalcResponse.h new file mode 100644 index 0000000..c996fb2 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATripCalcResponse.h @@ -0,0 +1,65 @@ +// +// ATripCalcResponse.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import +#import + +#import "AAlgorithmPathModel.h" +#import "APathModel.h" +#import "ASiteModel.h" +#import "ANaviPathInfoModel.h" +#import "ATruckModel.h" + + +NS_ASSUME_NONNULL_BEGIN + +@class ATruckModel; +@class ASiteModel; +@class APathModel; +@class AAlgorithmPathModel; + +#pragma mark - data 节点 + +/** + { + "truckDto": { ... }, + "truckDtoStr": null, + "destinationSite": { ... }, + "pathDto": { ... }, + "algorithmPath": { ... }, + "isInvokeAlgorithm": true + } + */ +@interface ATripCalcDataModel : NSObject + +@property (nonatomic, strong, nullable) ATruckModel *truckDto; +@property (nonatomic, copy, nullable) NSString *truckDtoStr; +@property (nonatomic, strong, nullable) ASiteModel *destinationSite; +@property (nonatomic, strong, nullable) APathModel *pathDto; +@property (nonatomic, strong, nullable) AAlgorithmPathModel *algorithmPath; +@property (nonatomic, assign) BOOL isInvokeAlgorithm; + +@end + +#pragma mark - 根响应 + +/** + { + "code": 200, + "msg": "操作成功!", + "data": { ... } + } + */ +@interface ATripCalcResponse : NSObject + +@property (nonatomic, assign) NSInteger code; +@property (nonatomic, copy, nullable) NSString *msg; +@property (nonatomic, strong, nullable) ATripCalcDataModel *data; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATripCalcResponse.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATripCalcResponse.m new file mode 100644 index 0000000..2d0aaf7 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATripCalcResponse.m @@ -0,0 +1,33 @@ +// +// ATripCalcResponse.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import "ATripCalcResponse.h" +#import "ATruckModel.h" +#import "ASiteModel.h" +#import "APathModel.h" +#import "AAlgorithmPathModel.h" + +@implementation ATripCalcDataModel + ++ (NSDictionary *)mj_objectClassInArray { + return @{ + @"truckDto": [ATruckModel class], + @"destinationSite": [ASiteModel class], + @"pathDto": [APathModel class], + @"algorithmPath": [AAlgorithmPathModel class] + }; +} + +@end + +@implementation ATripCalcResponse + ++ (NSDictionary *)mj_objectClassInArray { + return @{@"data":[ATripCalcDataModel class]}; +} + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATruckModel.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATruckModel.h new file mode 100644 index 0000000..6c2705f --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATruckModel.h @@ -0,0 +1,58 @@ +// +// ATruckModel.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + { + "isRestriction": true, + "mvehicleSizeName": "重型货车", + "mvehicleAxisUnit": "轴", + "mcarNumber": "浙F32111F", + "mcarType": 0, + "mvehicleHeight": "3.8", + "mvehicleHeightUnit": "M", + "mvehicleWeight": null, + "mvehicleWeightUnit": "T", + "mvehicleLoad": "49.0", + "mvehicleLoadUnit": "T", + "mvehicleLoadSwitch": false, + "mvehicleWidth": "0.0", + "mvehicleWidthUnit": "M", + "mvehicleLength": "7.6", + "mvehicleLengthUnit": "M", + "mvehicleSize": 4, + "mvehicleAxis": 5 + } + */ +@interface ATruckModel : NSObject + +@property (nonatomic, assign) BOOL isRestriction; +@property (nonatomic, copy, nullable) NSString *mvehicleSizeName; +@property (nonatomic, copy, nullable) NSString *mvehicleAxisUnit; +@property (nonatomic, copy, nullable) NSString *mcarNumber; +@property (nonatomic, assign) NSInteger mcarType; +@property (nonatomic, copy, nullable) NSString *mvehicleHeight; +@property (nonatomic, copy, nullable) NSString *mvehicleHeightUnit; +@property (nonatomic, copy, nullable) NSString *mvehicleWeight; +@property (nonatomic, copy, nullable) NSString *mvehicleWeightUnit; +@property (nonatomic, copy, nullable) NSString *mvehicleLoad; +@property (nonatomic, copy, nullable) NSString *mvehicleLoadUnit; +@property (nonatomic, assign) BOOL mvehicleLoadSwitch; +@property (nonatomic, copy, nullable) NSString *mvehicleWidth; +@property (nonatomic, copy, nullable) NSString *mvehicleWidthUnit; +@property (nonatomic, copy, nullable) NSString *mvehicleLength; +@property (nonatomic, copy, nullable) NSString *mvehicleLengthUnit; +@property (nonatomic, assign) NSInteger mvehicleSize; +@property (nonatomic, assign) NSInteger mvehicleAxis; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATruckModel.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATruckModel.m new file mode 100644 index 0000000..be75452 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Model/ATruckModel.m @@ -0,0 +1,12 @@ +// +// ATruckModel.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import "ATruckModel.h" + +@implementation ATruckModel + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/AMapNavCommonUtil.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/AMapNavCommonUtil.h index fb0e2ca..e1f7894 100644 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/AMapNavCommonUtil.h +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/AMapNavCommonUtil.h @@ -6,13 +6,33 @@ // #import +#import NS_ASSUME_NONNULL_BEGIN @interface AMapNavCommonUtil : NSObject -+(UIImage *)imageWithName:(NSString *)name; +/// 显示加载转圈(nil 消息时不显示文字) ++ (void)showLoadingWithMsg:(nullable NSString *)msg; +/// 关闭所有 MBProgressHUD ++ (void)dismiss; + +/// 显示提示,自动 2.0s 后消失 ++ (void)showMsg:(NSString *)msg; + + +/// 获取图片(2x) ++ (UIImage *)imageWithName:(NSString *)name; + +/// 获取图片(3x) ++ (UIImage *)imageWithName3x:(NSString *)name; + +/// 判断字符串是否为空 +BOOL stringIsEmpty(NSString *str); + +/// 判断字符串是否非空 +BOOL stringIsNotEmpty(NSString *str); @end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/AMapNavCommonUtil.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/AMapNavCommonUtil.m index 585f05b..2d34da4 100644 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/AMapNavCommonUtil.m +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/AMapNavCommonUtil.m @@ -6,9 +6,117 @@ // #import "AMapNavCommonUtil.h" +#import + +/// 共享 HUD 实例 +static MBProgressHUD *_sharedHUD = nil; @implementation AMapNavCommonUtil +#pragma mark - MBProgressHUD + ++ (UIWindow *)_keyWindow { + if (@available(iOS 13.0, *)) { + for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) { + if (scene.activationState == UISceneActivationStateForegroundActive) { + for (UIWindow *window in scene.windows) { + if (window.isKeyWindow) return window; + } + } + } + } + return [UIApplication sharedApplication].keyWindow; +} + ++ (void)showLoadingWithMsg:(NSString *)msg { + dispatch_async(dispatch_get_main_queue(), ^{ +// [self dismiss]; + + UIWindow *window = [self _keyWindow]; + if (!window) return; + + MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES]; + hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor; + hud.bezelView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.75]; + hud.contentColor = [UIColor whiteColor]; + + if (msg.length > 0) { + hud.label.text = msg; + hud.label.font = [UIFont systemFontOfSize:14]; + } + + hud.removeFromSuperViewOnHide = YES; + _sharedHUD = hud; + }); +} + ++ (void)dismiss { + dispatch_async(dispatch_get_main_queue(), ^{ + if (_sharedHUD) { + [_sharedHUD hideAnimated:YES]; + _sharedHUD = nil; + } else { + //兜底:隐藏所有 HUD(防止有遗漏) + UIWindow *window = [self _keyWindow]; + if (window) { + [MBProgressHUD hideHUDForView:window animated:YES]; + } + } + }); +} + ++ (void)showMsg:(NSString *)msg { + if (msg.length == 0) return; + + dispatch_async(dispatch_get_main_queue(), ^{ + UIWindow *window = [self _keyWindow]; + if (!window) return; + + MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES]; + hud.mode = MBProgressHUDModeText; + hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor; + hud.bezelView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.75]; + hud.contentColor = [UIColor whiteColor]; + hud.label.text = msg; + hud.label.font = [UIFont systemFontOfSize:14]; + hud.removeFromSuperViewOnHide = YES; + + // 2.0s 后自动消失 + [hud hideAnimated:YES afterDelay:2.0]; + }); +} + +#pragma mark - 字符串判断 + + +BOOL stringIsEmpty (NSString *str) +{ + if (str == nil || str == NULL) + { + return YES; + } + if ([str isKindOfClass:[NSNull class]]) + { + return YES; + } + if ([str isKindOfClass:[NSString class]]) + { + NSString * newStr = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + NSSet *emptySet = [NSSet setWithObjects:@"", @"null", @"(null)", @"", @"NULL", @"无",@"kZero", nil]; + if ([emptySet containsObject:str] || [emptySet containsObject:newStr]) { + return YES; + } else { + return [newStr length] == 0; + } + } + return NO; +} + +BOOL stringIsNotEmpty (NSString *str) +{ + return ! stringIsEmpty(str); +} + #pragma mark - 获取图片 +(UIImage *)imageWithName:(NSString *)name { @@ -22,6 +130,15 @@ return arrowImage; } - ++(UIImage *)imageWithName3x:(NSString *)name { + NSURL * url = [[NSBundle mainBundle] URLForResource:@"AMapNavIOSSDK" withExtension:@"bundle"]; + NSBundle *containnerBundle = [NSBundle bundleWithURL:url]; + + NSString * path = [containnerBundle pathForResource:[NSString stringWithFormat:@"%@@3x.png" , name] ofType:nil]; + + UIImage * arrowImage = [[UIImage imageWithContentsOfFile:path] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + + return arrowImage; +} @end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/SelectableOverlay.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/SelectableOverlay.h index 37c4b10..3b631ad 100755 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/SelectableOverlay.h +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/SelectableOverlay.h @@ -9,16 +9,16 @@ #import #import -@interface SelectableOverlay : MABaseOverlay +/// 继承 MAPolyline,自身就是 Polyline,renderer 用 self 初始化不会产生 overlay 不匹配警告 +@interface SelectableOverlay : MAPolyline @property (nonatomic, assign) NSInteger routeID; @property (nonatomic, assign, getter = isSelected) BOOL selected; -@property (nonatomic, strong) UIColor * selectedColor; -@property (nonatomic, strong) UIColor * regularColor; +@property (nonatomic, strong) UIColor *selectedColor; +@property (nonatomic, strong) UIColor *regularColor; -@property (nonatomic, strong) id overlay; - -- (id)initWithOverlay:(id) overlay; +/// 用坐标数组和数量初始化(对应原来的 MAPolyline polylineWithCoordinates:count:) ++ (instancetype)overlayWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count; @end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/SelectableOverlay.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/SelectableOverlay.m index 9c2aea9..a8d0789 100755 --- a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/SelectableOverlay.m +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Tools/SelectableOverlay.m @@ -10,32 +10,14 @@ @implementation SelectableOverlay -#pragma mark - MAOverlay Protocol - -- (CLLocationCoordinate2D)coordinate ++ (instancetype)overlayWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count { - return [self.overlay coordinate]; -} - -- (MAMapRect)boundingMapRect -{ - return [self.overlay boundingMapRect]; -} - -#pragma mark - Life Cycle - -- (id)initWithOverlay:(id)overlay -{ - self = [super init]; - if (self) - { - self.overlay = overlay; - self.selected = NO; - self.selectedColor = [UIColor colorWithRed:0.05 green:0.39 blue:0.9 alpha:0.8]; - self.regularColor = [UIColor colorWithRed:0.5 green:0.6 blue:0.9 alpha:0.8]; - } - - return self; + // MAPolyline 的指定工厂方法,返回 SelectableOverlay 实例 + SelectableOverlay *overlay = (SelectableOverlay *)[super polylineWithCoordinates:coords count:count]; + overlay.selected = NO; + overlay.selectedColor = [UIColor colorWithRed:0.05 green:0.39 blue:0.9 alpha:0.8]; + overlay.regularColor = [UIColor colorWithRed:0.5 green:0.6 blue:0.9 alpha:0.8]; + return overlay; } @end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ABottomBarView.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ABottomBarView.h new file mode 100644 index 0000000..dede542 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ABottomBarView.h @@ -0,0 +1,32 @@ +// +// ABottomBarView.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import +#import "AMapNavSDKHeader.h" + +NS_ASSUME_NONNULL_BEGIN + +@class ABottomBarView; + +@protocol ABottomBarViewDelegate +/// 点击「规划路线」按钮 +- (void)bottomBarViewDidTapCalRoute:(ABottomBarView *)barView; +/// 输入框开始编辑(外部弹起搜索页) +- (void)bottomBarViewDidTapSearchField:(ABottomBarView *)barView; +@end + +/// 底部搜索+规划路线栏 +@interface ABottomBarView : UIView + +@property (nonatomic, weak) id delegate; + +/// 目的地文本(外部赋值后自动更新输入框) +@property (nonatomic, copy, nullable) NSString *destinationText; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ABottomBarView.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ABottomBarView.m new file mode 100644 index 0000000..047e079 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ABottomBarView.m @@ -0,0 +1,204 @@ +// +// ABottomBarView.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/25. +// + +#import "ABottomBarView.h" +#import "AMapNavCommonUtil.h" +#import + +// 主题绿 +static inline UIColor *ABottomBarThemeGreen(void) { + return [UIColor colorWithRed:0x1A/255.0 green:0x6E/255.0 blue:0x45/255.0 alpha:1.0]; +} + +@interface ABottomBarView () + +/// 白色圆角背景卡片 +@property (nonatomic, strong) UIView *cardView; + +/// 搜索图标 +@property (nonatomic, strong) UIImageView *searchIconView; + +/// 目的地输入框 +@property (nonatomic, strong) UITextField *searchField; + +/// 规划路线按钮 +@property (nonatomic, strong) UIButton *calRouteButton; + +@end + +@implementation ABottomBarView + +#pragma mark - Init + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.backgroundColor = [UIColor clearColor]; + [self _buildUI]; + } + return self; +} + +- (instancetype)init { + return [self initWithFrame:CGRectZero]; +} + +#pragma mark - Build UI + +- (void)_buildUI { + // ── 背景卡片 ────────────────────────────────────────── + UIView *card = [[UIView alloc] init]; +// card.backgroundColor = [UIColor colorWithRed:0.96 green:0.97 blue:0.98 alpha:0.96]; + card.backgroundColor = [UIColor whiteColor]; + card.layer.cornerRadius = 16; + // 顶部阴影 + card.layer.shadowColor = [UIColor blackColor].CGColor; + card.layer.shadowOpacity = 0.10; + card.layer.shadowRadius = 10; + card.layer.shadowOffset = CGSizeMake(0, -3); + card.layer.masksToBounds = NO; + [self addSubview:card]; + self.cardView = card; + + [card mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self); + }]; + + // ── 搜索框容器(白色圆角行) ────────────────────────── + UIView *searchRow = [[UIView alloc] init]; + searchRow.backgroundColor = [UIColor whiteColor]; + searchRow.layer.cornerRadius = 5; + searchRow.layer.masksToBounds = YES; + searchRow.layer.borderColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1].CGColor; + searchRow.layer.borderWidth = 1; + [card addSubview:searchRow]; + + [searchRow mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(card).offset(-18); + make.left.equalTo(card).offset(16); + make.right.equalTo(card).offset(-16); + make.height.mas_equalTo(50); + }]; + + // ── 搜索图标 ────────────────────────────────────────── + UIImageView *searchIcon = [[UIImageView alloc] init]; + searchIcon.contentMode = UIViewContentModeScaleAspectFit; + searchIcon.image = [AMapNavCommonUtil imageWithName3x:@"search_icon"]; + [searchRow addSubview:searchIcon]; + self.searchIconView = searchIcon; + + [searchIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(searchRow); + make.left.equalTo(searchRow).offset(12); + make.width.height.mas_equalTo(18); + }]; + + // ── 目的地输入框 ────────────────────────────────────── + UITextField *field = [[UITextField alloc] init]; + field.placeholder = @"请输入目的地,不输入则自动匹配附近成本最低加氢站"; + field.font = [UIFont systemFontOfSize:14]; + field.textColor = [UIColor colorWithWhite:0.1 alpha:1]; + field.borderStyle = UITextBorderStyleNone; + field.backgroundColor = [UIColor clearColor]; + field.delegate = self; + // placeholder 颜色 + if (field.placeholder) { + field.attributedPlaceholder = [[NSAttributedString alloc] + initWithString:field.placeholder + attributes:@{NSForegroundColorAttributeName: + [UIColor colorWithWhite:0.65 alpha:1], + NSFontAttributeName: + [UIFont systemFontOfSize:13]}]; + } + [searchRow addSubview:field]; + self.searchField = field; + + [field mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(searchRow); + make.left.equalTo(searchIcon.mas_right).offset(8); + make.right.equalTo(searchRow).offset(-12); + make.top.bottom.equalTo(searchRow); + }]; + + // ── 规划路线按钮 ────────────────────────────────────── + UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; + btn.backgroundColor = ABottomBarThemeGreen(); + btn.layer.cornerRadius = 24; + btn.layer.masksToBounds = YES; + + // 左侧图标 + UIImageView *routeIcon = [[UIImageView alloc] init]; + routeIcon.contentMode = UIViewContentModeScaleAspectFit; + routeIcon.image = [AMapNavCommonUtil imageWithName3x:@"cal_ruoute_icon"]; + routeIcon.userInteractionEnabled = NO; + [btn addSubview:routeIcon]; + + // 标题 + UILabel *titleLbl = [[UILabel alloc] init]; + titleLbl.text = @"规划路线"; + titleLbl.textColor = [UIColor whiteColor]; + titleLbl.font = [UIFont boldSystemFontOfSize:16]; + titleLbl.userInteractionEnabled = NO; + [btn addSubview:titleLbl]; + + // 图标和文字水平居中整体 + [routeIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(btn); + make.right.equalTo(titleLbl.mas_left).offset(-8); + make.width.height.mas_equalTo(22); + }]; + + [titleLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(btn); + // 两者整体水平居中:titleLbl 向右偏移 (22+8)/2 = 15pt + make.centerX.equalTo(btn).offset(15); + }]; + + [btn addTarget:self action:@selector(_onCalRouteTapped) forControlEvents:UIControlEventTouchUpInside]; + [card addSubview:btn]; + self.calRouteButton = btn; + + CGFloat off_y = AMP_TabbarHeight; +#ifdef kAMapSDKDebugFlag + off_y = 0; +#endif + + [btn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(searchRow.mas_bottom).offset(20); + make.left.equalTo(card).offset(16); + make.right.equalTo(card).offset(-16); + make.height.mas_equalTo(48); + make.bottom.equalTo(card).offset(-40 - off_y); + }]; +} + +#pragma mark - Public + +- (void)setDestinationText:(NSString *)destinationText { + _destinationText = destinationText; + self.searchField.text = destinationText; +} + +#pragma mark - Actions + +- (void)_onCalRouteTapped { + if ([self.delegate respondsToSelector:@selector(bottomBarViewDidTapCalRoute:)]) { + [self.delegate bottomBarViewDidTapCalRoute:self]; + } +} + +#pragma mark - UITextFieldDelegate + +- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { + // 不弹起键盘,直接通知外部展示搜索页 + if ([self.delegate respondsToSelector:@selector(bottomBarViewDidTapSearchField:)]) { + [self.delegate bottomBarViewDidTapSearchField:self]; + } + return NO; +} + +@end diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ACustomStepView.h b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ACustomStepView.h new file mode 100644 index 0000000..b1d3a8d --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ACustomStepView.h @@ -0,0 +1,21 @@ +// +// ACustomStepView.h +// AMapNavIOSSDK +// +// Created by admin on 2026/3/11. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ACustomStepView : UIView + +@property (nonatomic, readonly , assign) CGFloat value; // 当前值 + + +- (instancetype)initWithValue:(CGFloat)currentValue maxValue:(CGFloat)maxValue min:(CGFloat)minValue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ACustomStepView.m b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ACustomStepView.m new file mode 100644 index 0000000..0625ec6 --- /dev/null +++ b/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/View/ACustomStepView.m @@ -0,0 +1,121 @@ +// +// ACustomStepView.m +// AMapNavIOSSDK +// +// Created by admin on 2026/3/11. +// + +#import "ACustomStepView.h" +#import + +#define kStepValue 0.5 + +@interface ACustomStepView () +@property CGFloat value; +@property CGFloat maxValue; +@property CGFloat minValue; +@end + +@implementation ACustomStepView + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.backgroundColor = [UIColor whiteColor]; + self.layer.cornerRadius = 4; + self.layer.masksToBounds = YES; + self.clipsToBounds = YES; + self.layer.borderColor = [UIColor colorWithRed:225/255.0 green:225/255.0 blue:225/255.0 alpha:1].CGColor; + self.layer.borderWidth = 1; + + [self setupSubviews]; + + self.value = 0; // 初始值 + } + return self; +} + +- (instancetype)initWithValue:(CGFloat)currentValue maxValue:(CGFloat)maxValue min:(CGFloat)minValue { +// self = [super initWithFrame:CGRectZero]; + + if (self) { + _value = currentValue; + _maxValue = maxValue; + _minValue = minValue; + } + + + return self; +} + +- (void)setupSubviews { + // 减按钮 + UIButton *minusButton = [UIButton buttonWithType:UIButtonTypeSystem]; + [minusButton setTitle:@"-" forState:UIControlStateNormal]; + minusButton.titleLabel.font = [UIFont boldSystemFontOfSize:20]; + [minusButton addTarget:self action:@selector(decrement:) forControlEvents:UIControlEventTouchUpInside]; + [minusButton setTintColor:[UIColor colorWithRed:0x35/255.0 green:0x35/255.0 blue:0x35/255.0 alpha:1]]; + [self addSubview:minusButton]; + + // 加按钮 + UIButton *plusButton = [UIButton buttonWithType:UIButtonTypeSystem]; + [plusButton setTitle:@"+" forState:UIControlStateNormal]; + plusButton.titleLabel.font = [UIFont boldSystemFontOfSize:20]; + [plusButton setTintColor:[UIColor colorWithRed:0x35/255.0 green:0x35/255.0 blue:0x35/255.0 alpha:1]]; + + [plusButton addTarget:self action:@selector(increment:) forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:plusButton]; + + [plusButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.top.right.equalTo(self); + make.height.equalTo(@40); + }]; + + UIView * line = [[UIView alloc] init]; + line.backgroundColor = [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1]; + [self addSubview:line]; + [line mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(self); + make.top.equalTo(plusButton.mas_bottom); + make.height.equalTo(@1); + }]; + + + [minusButton mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(self); + make.top.equalTo(plusButton.mas_bottom); + make.height.equalTo(plusButton); + }]; + + +} + +// 减1操作 +- (void)decrement:(UIButton *)sender { + if (self.value <= self.minValue) { + return; + } + if (self.value - kStepValue < self.minValue) { + self.value = self.minValue; + return; + } + + self.value = self.value - kStepValue; +} + +// 加1操作 +- (void)increment:(UIButton *)sender { + if (self.value >= self.maxValue) { + return; + } + if (self.value + kStepValue > self.maxValue) { + self.value = self.maxValue; + return; + } + + self.value = self.value + kStepValue; + +} + + +@end diff --git a/ln_jq_app/ios/Podfile b/ln_jq_app/ios/Podfile index 42199c1..3cfdd14 100644 --- a/ln_jq_app/ios/Podfile +++ b/ln_jq_app/ios/Podfile @@ -35,6 +35,8 @@ target 'Runner' do use_frameworks! :linkage => :static pod 'AMapNavIOSSDK' , :path => './AMapNavIOSSDK' + ## 本地仓库 +# pod 'AMapNavIOSSDK' , :path => '../../../../demo/ANavDemo' flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) diff --git a/ln_jq_app/ios/Podfile.lock b/ln_jq_app/ios/Podfile.lock index f26e170..26bdefa 100644 --- a/ln_jq_app/ios/Podfile.lock +++ b/ln_jq_app/ios/Podfile.lock @@ -17,6 +17,7 @@ PODS: - AMapNavi-NO-IDFA - AMapSearch-NO-IDFA - Masonry + - MBProgressHUD - MJExtension - AMapSearch-NO-IDFA (9.7.4): - AMapFoundation-NO-IDFA (>= 1.8.0) @@ -42,6 +43,7 @@ PODS: - image_picker_ios (0.0.1): - Flutter - Masonry (1.1.0) + - MBProgressHUD (1.2.0) - MJExtension (3.4.2) - mobile_scanner (7.0.0): - Flutter @@ -49,9 +51,6 @@ PODS: - OrderedSet (6.0.3) - package_info_plus (0.4.5): - Flutter - - path_provider_foundation (0.0.1): - - Flutter - - FlutterMacOS - permission_handler_apple (9.3.0): - Flutter - shared_preferences_foundation (0.0.1): @@ -73,7 +72,6 @@ DEPENDENCIES: - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - mobile_scanner (from `.symlinks/plugins/mobile_scanner/darwin`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) @@ -90,6 +88,7 @@ SPEC REPOS: - AMapNavi-NO-IDFA - AMapSearch-NO-IDFA - Masonry + - MBProgressHUD - MJExtension - OrderedSet @@ -118,8 +117,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/mobile_scanner/darwin" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" - path_provider_foundation: - :path: ".symlinks/plugins/path_provider_foundation/darwin" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" shared_preferences_foundation: @@ -131,30 +128,30 @@ SPEC CHECKSUMS: AlicloudELS: fbf821383330465a5af84a033f36f263ae46ca41 AlicloudPush: 52cbf38ffc20c07f039cbc72d5738745fd986215 AlicloudUTDID: 5d2f22d50e11eecd38f30bc7a48c71925ea90976 - aliyun_push_flutter: 0fc2f048a08687ef256c0cfdd72dd7a550ef3347 + aliyun_push_flutter: ab0bf7112ef3797f506770a7a9f47f004635a9f6 AMapFoundation-NO-IDFA: 6ce0ef596d4eb8d934ff498e56747b6de1247b05 AMapLocation-NO-IDFA: 590fd42af0c8ea9eac26978348221bbc16be4ef9 AMapNavi-NO-IDFA: 22edfa7d6a81d75c91756e31b6c26b7746152233 - AMapNavIOSSDK: ca325c9ac3378daea6a6be4bd8c34fe48d3ac896 + AMapNavIOSSDK: 092382d55290f43b282ffcc522c274996794e2bc AMapSearch-NO-IDFA: 53b2193244be8f07f3be0a4d5161200236960587 - connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd - device_info_plus: 71ffc6ab7634ade6267c7a93088ed7e4f74e5896 + connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d + device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 - flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99 - flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf - flutter_pdfview: 32bf27bda6fd85b9dd2c09628a824df5081246cf - geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e - image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326 + flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4 + flutter_native_splash: df59bb2e1421aa0282cb2e95618af4dcb0c56c29 + flutter_pdfview: 2e4d13ffb774858562ffbdfdb61b40744b191adc + geolocator_apple: 66b711889fd333205763b83c9dcf0a57a28c7afd + image_picker_ios: 4f2f91b01abdb52842a8e277617df877e40f905b Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 + MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406 MJExtension: e97d164cb411aa9795cf576093a1fa208b4a8dd8 - mobile_scanner: 9157936403f5a0644ca3779a38ff8404c5434a93 + mobile_scanner: 77265f3dc8d580810e91849d4a0811a90467ed5e OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 - package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 - path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880 - permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d - shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb - url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b + package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 + permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 + shared_preferences_foundation: 5086985c1d43c5ba4d5e69a4e8083a389e2909e6 + url_launcher_ios: bb13df5870e8c4234ca12609d04010a21be43dfa -PODFILE CHECKSUM: 97188da9dab9d4b3372eb4c16e872fbd555fdbea +PODFILE CHECKSUM: b4931d4490f04261e0fda802d44e275ab3619244 COCOAPODS: 1.16.2 diff --git a/ln_jq_app/ios/Runner.xcodeproj/project.pbxproj b/ln_jq_app/ios/Runner.xcodeproj/project.pbxproj index 27a8385..6ed39fa 100644 --- a/ln_jq_app/ios/Runner.xcodeproj/project.pbxproj +++ b/ln_jq_app/ios/Runner.xcodeproj/project.pbxproj @@ -357,14 +357,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; diff --git a/ln_jq_app/lib/common/token_interceptor.dart b/ln_jq_app/lib/common/token_interceptor.dart index dbb5562..70414f7 100644 --- a/ln_jq_app/lib/common/token_interceptor.dart +++ b/ln_jq_app/lib/common/token_interceptor.dart @@ -24,6 +24,7 @@ class TokenInterceptor extends Interceptor { if (!options.headers.containsKey(tokenKey)) { // 使用我们自定义的 key 添加 token options.headers[tokenKey] = token; + print("head.token: $token"); } } diff --git a/ln_jq_app/pubspec.lock b/ln_jq_app/pubspec.lock index 33eec3f..53e8a81 100644 --- a/ln_jq_app/pubspec.lock +++ b/ln_jq_app/pubspec.lock @@ -6,7 +6,7 @@ packages: description: name: aliyun_push_flutter sha256: fd1a13ab37f30274e1eaa9c0f68001bf268f8f2e1c83730b4520aa4dff46ce70 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.6" ansicolor: @@ -14,7 +14,7 @@ packages: description: name: ansicolor sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.3" archive: @@ -22,7 +22,7 @@ packages: description: name: archive sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.0.9" args: @@ -30,7 +30,7 @@ packages: description: name: args sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.7.0" asn1lib: @@ -38,23 +38,23 @@ packages: description: name: asn1lib sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.6.5" async: dependency: transitive description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" - url: "https://pub.flutter-io.cn" + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 + url: "https://pub.dev" source: hosted - version: "2.13.0" + version: "2.13.1" badges: dependency: transitive description: name: badges sha256: a7b6bbd60dce418df0db3058b53f9d083c22cdb5132a052145dc267494df0b84 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.2" boolean_selector: @@ -62,7 +62,7 @@ packages: description: name: boolean_selector sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.2" characters: @@ -70,7 +70,7 @@ packages: description: name: characters sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.4.0" clock: @@ -78,15 +78,23 @@ packages: description: name: clock sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.2" + code_assets: + dependency: transitive + description: + name: code_assets + sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687" + url: "https://pub.dev" + source: hosted + version: "1.0.0" collection: dependency: transitive description: name: collection sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.19.1" connectivity_plus: @@ -94,7 +102,7 @@ packages: description: name: connectivity_plus sha256: b5e72753cf63becce2c61fd04dfe0f1c430cc5278b53a1342dc5ad839eab29ec - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.1.5" connectivity_plus_platform_interface: @@ -102,7 +110,7 @@ packages: description: name: connectivity_plus_platform_interface sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.1" convert: @@ -110,7 +118,7 @@ packages: description: name: convert sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.2" cross_file: @@ -118,7 +126,7 @@ packages: description: name: cross_file sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.3.5+2" crypto: @@ -126,7 +134,7 @@ packages: description: name: crypto sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.7" csslib: @@ -134,23 +142,23 @@ packages: description: name: csslib sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.2" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.flutter-io.cn" + sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd" + url: "https://pub.dev" source: hosted - version: "1.0.8" + version: "1.0.9" dbus: dependency: transitive description: name: dbus sha256: d0c98dcd4f5169878b6cf8f6e0a52403a9dff371a3e2f019697accbf6f44a270 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.7.12" decimal: @@ -158,7 +166,7 @@ packages: description: name: decimal sha256: fc706a5618b81e5b367b01dd62621def37abc096f2b46a9bd9068b64c1fa36d0 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.4" device_info_plus: @@ -166,7 +174,7 @@ packages: description: name: device_info_plus sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "10.1.2" device_info_plus_platform_interface: @@ -174,7 +182,7 @@ packages: description: name: device_info_plus_platform_interface sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "7.0.3" dio: @@ -182,7 +190,7 @@ packages: description: name: dio sha256: aff32c08f92787a557dd5c0145ac91536481831a01b4648136373cddb0e64f8c - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.9.2" dio_web_adapter: @@ -190,7 +198,7 @@ packages: description: name: dio_web_adapter sha256: "2f9e64323a7c3c7ef69567d5c800424a11f8337b8b228bad02524c9fb3c1f340" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.2" dropdown_button2: @@ -198,7 +206,7 @@ packages: description: name: dropdown_button2 sha256: b0fe8d49a030315e9eef6c7ac84ca964250155a6224d491c1365061bc974a9e1 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.9" encrypt: @@ -206,7 +214,7 @@ packages: description: name: encrypt sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.0.3" event_bus: @@ -214,7 +222,7 @@ packages: description: name: event_bus sha256: "1a55e97923769c286d295240048fc180e7b0768902c3c2e869fe059aafa15304" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.1" extended_image: @@ -222,7 +230,7 @@ packages: description: name: extended_image sha256: "69d4299043334ecece679996e47d0b0891cd8c29d8da0034868443506f1d9a78" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "8.3.1" extended_image_library: @@ -230,7 +238,7 @@ packages: description: name: extended_image_library sha256: e61dafd94400fff6ef7ed1523d445ff3af137f198f3228e4a3107bc5b4bec5d1 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.0.6" fake_async: @@ -238,7 +246,7 @@ packages: description: name: fake_async sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.3" ffi: @@ -246,7 +254,7 @@ packages: description: name: ffi sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.0" file: @@ -254,7 +262,7 @@ packages: description: name: file sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "7.0.1" file_selector_linux: @@ -262,7 +270,7 @@ packages: description: name: file_selector_linux sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.9.4" file_selector_macos: @@ -270,7 +278,7 @@ packages: description: name: file_selector_macos sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.9.5" file_selector_platform_interface: @@ -278,7 +286,7 @@ packages: description: name: file_selector_platform_interface sha256: "35e0bd61ebcdb91a3505813b055b09b79dfdc7d0aee9c09a7ba59ae4bb13dc85" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.7.0" file_selector_windows: @@ -286,7 +294,7 @@ packages: description: name: file_selector_windows sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.9.3+5" fixnum: @@ -294,7 +302,7 @@ packages: description: name: fixnum sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.1" flutter: @@ -307,7 +315,7 @@ packages: description: name: flutter_easyloading sha256: ba21a3c883544e582f9cc455a4a0907556714e1e9cf0eababfcb600da191d17c - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.5" flutter_inappwebview: @@ -315,7 +323,7 @@ packages: description: name: flutter_inappwebview sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.1.5" flutter_inappwebview_android: @@ -323,7 +331,7 @@ packages: description: name: flutter_inappwebview_android sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.3" flutter_inappwebview_internal_annotations: @@ -331,7 +339,7 @@ packages: description: name: flutter_inappwebview_internal_annotations sha256: e30fba942e3debea7b7e6cdd4f0f59ce89dd403a9865193e3221293b6d1544c6 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.0" flutter_inappwebview_ios: @@ -339,7 +347,7 @@ packages: description: name: flutter_inappwebview_ios sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.2" flutter_inappwebview_macos: @@ -347,7 +355,7 @@ packages: description: name: flutter_inappwebview_macos sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.2" flutter_inappwebview_platform_interface: @@ -355,7 +363,7 @@ packages: description: name: flutter_inappwebview_platform_interface sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.0+1" flutter_inappwebview_web: @@ -363,7 +371,7 @@ packages: description: name: flutter_inappwebview_web sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.2" flutter_inappwebview_windows: @@ -371,7 +379,7 @@ packages: description: name: flutter_inappwebview_windows sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.6.0" flutter_lints: @@ -379,7 +387,7 @@ packages: description: name: flutter_lints sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.0.0" flutter_localizations: @@ -392,7 +400,7 @@ packages: description: name: flutter_native_splash sha256: "4fb9f4113350d3a80841ce05ebf1976a36de622af7d19aca0ca9a9911c7ff002" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.7" flutter_pdfview: @@ -400,23 +408,23 @@ packages: description: name: flutter_pdfview sha256: c0b2cc4ebf461a5a4bb9312a165222475a7d93845c7a0703f4abb7f442eb6d54 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.4.3" flutter_plugin_android_lifecycle: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: ee8068e0e1cd16c4a82714119918efdeed33b3ba7772c54b5d094ab53f9b7fd1 - url: "https://pub.flutter-io.cn" + sha256: "38d1c268de9097ff59cf0e844ac38759fc78f76836d37edad06fa21e182055a0" + url: "https://pub.dev" source: hosted - version: "2.0.33" + version: "2.0.34" flutter_screenutil: dependency: transitive description: name: flutter_screenutil sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.9.3" flutter_spinkit: @@ -424,7 +432,7 @@ packages: description: name: flutter_spinkit sha256: "77850df57c00dc218bfe96071d576a8babec24cf58b2ed121c83cca4a2fdce7f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.2.2" flutter_svg: @@ -432,7 +440,7 @@ packages: description: name: flutter_svg sha256: "1ded017b39c8e15c8948ea855070a5ff8ff8b3d5e83f3446e02d6bb12add7ad9" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.4" flutter_test: @@ -450,7 +458,7 @@ packages: description: name: geoclue sha256: c2a998c77474fc57aa00c6baa2928e58f4b267649057a1c76738656e9dbd2a7f - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.1.1" geolocator: @@ -458,7 +466,7 @@ packages: description: name: geolocator sha256: "79939537046c9025be47ec645f35c8090ecadb6fe98eba146a0d25e8c1357516" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "14.0.2" geolocator_android: @@ -466,7 +474,7 @@ packages: description: name: geolocator_android sha256: "179c3cb66dfa674fc9ccbf2be872a02658724d1c067634e2c427cf6df7df901a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.0.2" geolocator_apple: @@ -474,7 +482,7 @@ packages: description: name: geolocator_apple sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.13" geolocator_linux: @@ -482,7 +490,7 @@ packages: description: name: geolocator_linux sha256: c4e966f0a7a87e70049eac7a2617f9e16fd4c585a26e4330bdfc3a71e6a721f3 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.3" geolocator_platform_interface: @@ -490,7 +498,7 @@ packages: description: name: geolocator_platform_interface sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.2.6" geolocator_web: @@ -498,7 +506,7 @@ packages: description: name: geolocator_web sha256: b1ae9bdfd90f861fde8fd4f209c37b953d65e92823cb73c7dee1fa021b06f172 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.1.3" geolocator_windows: @@ -506,7 +514,7 @@ packages: description: name: geolocator_windows sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.5" get: @@ -514,7 +522,7 @@ packages: description: name: get sha256: "5ed34a7925b85336e15d472cc4cfe7d9ebf4ab8e8b9f688585bf6b50f4c3d79a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.7.3" get_storage: @@ -522,7 +530,7 @@ packages: description: name: get_storage sha256: "39db1fffe779d0c22b3a744376e86febe4ade43bf65e06eab5af707dc84185a2" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.1" getx_scaffold: @@ -530,23 +538,39 @@ packages: description: name: getx_scaffold sha256: caf11b370c20840352230f50221bcef1454b30ec56cce10ba25741fbbdf0a806 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.2" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.dev" + source: hosted + version: "2.1.3" gsettings: dependency: transitive description: name: gsettings sha256: "1b0ce661f5436d2db1e51f3c4295a49849f03d304003a7ba177d01e3a858249c" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.8" + hooks: + dependency: transitive + description: + name: hooks + sha256: e79ed1e8e1929bc6ecb6ec85f0cb519c887aa5b423705ded0d0f2d9226def388 + url: "https://pub.dev" + source: hosted + version: "1.0.2" html: dependency: transitive description: name: html sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.15.6" http: @@ -554,7 +578,7 @@ packages: description: name: http sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.6.0" http_client_helper: @@ -562,7 +586,7 @@ packages: description: name: http_client_helper sha256: "8a9127650734da86b5c73760de2b404494c968a3fd55602045ffec789dac3cb1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.0" http_parser: @@ -570,7 +594,7 @@ packages: description: name: http_parser sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.1.2" image: @@ -578,7 +602,7 @@ packages: description: name: image sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.8.0" image_picker: @@ -586,39 +610,39 @@ packages: description: name: image_picker sha256: "784210112be18ea55f69d7076e2c656a4e24949fa9e76429fe53af0c0f4fa320" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.2.1" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: eda9b91b7e266d9041084a42d605a74937d996b87083395c5e47835916a86156 - url: "https://pub.flutter-io.cn" + sha256: "9eae0cbd672549dacc18df855c2a23782afe4854ada5190b7d63b30ee0b0d3fd" + url: "https://pub.dev" source: hosted - version: "0.8.13+14" + version: "0.8.13+15" image_picker_for_web: dependency: transitive description: name: image_picker_for_web sha256: "66257a3191ab360d23a55c8241c91a6e329d31e94efa7be9cf7a212e65850214" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.1" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: "956c16a42c0c708f914021666ffcd8265dde36e673c9fa68c81f7d085d9774ad" - url: "https://pub.flutter-io.cn" + sha256: b9c4a438a9ff4f60808c9cf0039b93a42bb6c2211ef6ebb647394b2b3fa84588 + url: "https://pub.dev" source: hosted - version: "0.8.13+3" + version: "0.8.13+6" image_picker_linux: dependency: transitive description: name: image_picker_linux sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.2" image_picker_macos: @@ -626,7 +650,7 @@ packages: description: name: image_picker_macos sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.2+1" image_picker_platform_interface: @@ -634,7 +658,7 @@ packages: description: name: image_picker_platform_interface sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.11.1" image_picker_windows: @@ -642,7 +666,7 @@ packages: description: name: image_picker_windows sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.2" intl: @@ -650,7 +674,7 @@ packages: description: name: intl sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.19.0" js: @@ -658,7 +682,7 @@ packages: description: name: js sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.7.2" leak_tracker: @@ -666,7 +690,7 @@ packages: description: name: leak_tracker sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "11.0.2" leak_tracker_flutter_testing: @@ -674,7 +698,7 @@ packages: description: name: leak_tracker_flutter_testing sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.10" leak_tracker_testing: @@ -682,7 +706,7 @@ packages: description: name: leak_tracker_testing sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.2" lints: @@ -690,15 +714,23 @@ packages: description: name: lints sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.1.1" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" lottie: dependency: transitive description: name: lottie sha256: "8ae0be46dbd9e19641791dc12ee480d34e1fd3f84c749adc05f3ad9342b71b95" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.3.2" matcher: @@ -706,7 +738,7 @@ packages: description: name: matcher sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.12.17" material_color_utilities: @@ -714,23 +746,23 @@ packages: description: name: material_color_utilities sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c - url: "https://pub.flutter-io.cn" + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: name: mime sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.0" mobile_scanner: @@ -738,7 +770,7 @@ packages: description: name: mobile_scanner sha256: c92c26bf2231695b6d3477c8dcf435f51e28f87b1745966b1fe4c47a286171ce - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "7.2.0" modal_bottom_sheet: @@ -746,23 +778,39 @@ packages: description: name: modal_bottom_sheet sha256: eac66ef8cb0461bf069a38c5eb0fa728cee525a531a8304bd3f7b2185407c67e - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.0" + native_toolchain_c: + dependency: transitive + description: + name: native_toolchain_c + sha256: "6ba77bb18063eebe9de401f5e6437e95e1438af0a87a3a39084fbd37c90df572" + url: "https://pub.dev" + source: hosted + version: "0.17.6" nm: dependency: transitive description: name: nm sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.5.0" + objective_c: + dependency: transitive + description: + name: objective_c + sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52" + url: "https://pub.dev" + source: hosted + version: "9.3.0" package_info_plus: dependency: transitive description: name: package_info_plus sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "8.3.1" package_info_plus_platform_interface: @@ -770,7 +818,7 @@ packages: description: name: package_info_plus_platform_interface sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.1" path: @@ -778,7 +826,7 @@ packages: description: name: path sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.9.1" path_parsing: @@ -786,7 +834,7 @@ packages: description: name: path_parsing sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.0" path_provider: @@ -794,31 +842,31 @@ packages: description: name: path_provider sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.5" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e - url: "https://pub.flutter-io.cn" + sha256: "149441ca6e4f38193b2e004c0ca6376a3d11f51fa5a77552d8bd4d2b0c0912ba" + url: "https://pub.dev" source: hosted - version: "2.2.22" + version: "2.2.23" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4" - url: "https://pub.flutter-io.cn" + sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" + url: "https://pub.dev" source: hosted - version: "2.5.1" + version: "2.6.0" path_provider_linux: dependency: transitive description: name: path_provider_linux sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.1" path_provider_platform_interface: @@ -826,7 +874,7 @@ packages: description: name: path_provider_platform_interface sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.2" path_provider_windows: @@ -834,7 +882,7 @@ packages: description: name: path_provider_windows sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.0" permission_handler: @@ -842,7 +890,7 @@ packages: description: name: permission_handler sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "11.4.0" permission_handler_android: @@ -850,7 +898,7 @@ packages: description: name: permission_handler_android sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "12.1.0" permission_handler_apple: @@ -858,7 +906,7 @@ packages: description: name: permission_handler_apple sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "9.4.7" permission_handler_html: @@ -866,7 +914,7 @@ packages: description: name: permission_handler_html sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.1.3+5" permission_handler_platform_interface: @@ -874,7 +922,7 @@ packages: description: name: permission_handler_platform_interface sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.3.0" permission_handler_windows: @@ -882,7 +930,7 @@ packages: description: name: permission_handler_windows sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.1" petitparser: @@ -890,7 +938,7 @@ packages: description: name: petitparser sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "7.0.2" photo_view: @@ -898,7 +946,7 @@ packages: description: name: photo_view sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.15.0" platform: @@ -906,7 +954,7 @@ packages: description: name: platform sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.6" plugin_platform_interface: @@ -914,7 +962,7 @@ packages: description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.8" pointycastle: @@ -922,7 +970,7 @@ packages: description: name: pointycastle sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.9.1" posix: @@ -930,15 +978,23 @@ packages: description: name: posix sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.5.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" pull_to_refresh: dependency: "direct main" description: name: pull_to_refresh sha256: bbadd5a931837b57739cf08736bea63167e284e71fb23b218c8c9a6e042aad12 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.0" rational: @@ -946,31 +1002,31 @@ packages: description: name: rational sha256: cb808fb6f1a839e6fc5f7d8cb3b0a10e1db48b3be102de73938c627f0b636336 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.3" shared_preferences: dependency: "direct main" description: name: shared_preferences - sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64" - url: "https://pub.flutter-io.cn" + sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf + url: "https://pub.dev" source: hosted - version: "2.5.4" + version: "2.5.5" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "8374d6200ab33ac99031a852eba4c8eb2170c4bf20778b3e2c9eccb45384fb41" - url: "https://pub.flutter-io.cn" + sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53 + url: "https://pub.dev" source: hosted - version: "2.4.21" + version: "2.4.23" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.5.6" shared_preferences_linux: @@ -978,23 +1034,23 @@ packages: description: name: shared_preferences_linux sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.1" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" - url: "https://pub.flutter-io.cn" + sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9" + url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" shared_preferences_web: dependency: transitive description: name: shared_preferences_web sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.3" shared_preferences_windows: @@ -1002,7 +1058,7 @@ packages: description: name: shared_preferences_windows sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.1" sky_engine: @@ -1015,7 +1071,7 @@ packages: description: name: slider_captcha sha256: "0fc2e0e8af7bf0e7ece23b8213e6becf841dd7839a40ad4b2a5071eaf5135774" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.2" source_span: @@ -1023,7 +1079,7 @@ packages: description: name: source_span sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.10.2" stack_trace: @@ -1031,7 +1087,7 @@ packages: description: name: stack_trace sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.12.1" stream_channel: @@ -1039,7 +1095,7 @@ packages: description: name: stream_channel sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.4" string_scanner: @@ -1047,7 +1103,7 @@ packages: description: name: string_scanner sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.4.1" term_glyph: @@ -1055,23 +1111,23 @@ packages: description: name: term_glyph sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" - url: "https://pub.flutter-io.cn" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.7" typed_data: dependency: transitive description: name: typed_data sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.4.0" universal_io: @@ -1079,7 +1135,7 @@ packages: description: name: universal_io sha256: f63cbc48103236abf48e345e07a03ce5757ea86285ed313a6a032596ed9301e2 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.1" url_launcher: @@ -1087,31 +1143,31 @@ packages: description: name: url_launcher sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.3.2" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611" - url: "https://pub.flutter-io.cn" + sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572" + url: "https://pub.dev" source: hosted - version: "6.3.28" + version: "6.3.29" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad - url: "https://pub.flutter-io.cn" + sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" + url: "https://pub.dev" source: hosted - version: "6.3.6" + version: "6.4.1" url_launcher_linux: dependency: transitive description: name: url_launcher_linux sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.2" url_launcher_macos: @@ -1119,7 +1175,7 @@ packages: description: name: url_launcher_macos sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.5" url_launcher_platform_interface: @@ -1127,23 +1183,23 @@ packages: description: name: url_launcher_platform_interface sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.2" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" - url: "https://pub.flutter-io.cn" + sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f + url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" url_launcher_windows: dependency: transitive description: name: url_launcher_windows sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.5" uuid: @@ -1151,23 +1207,23 @@ packages: description: name: uuid sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.5.3" vector_graphics: dependency: transitive description: name: vector_graphics - sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 - url: "https://pub.flutter-io.cn" + sha256: "7076216a10d5c390315fbe536a30f1254c341e7543e6c4c8a815e591307772b1" + url: "https://pub.dev" source: hosted - version: "1.1.19" + version: "1.1.20" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.13" vector_graphics_compiler: @@ -1175,7 +1231,7 @@ packages: description: name: vector_graphics_compiler sha256: "5a88dd14c0954a5398af544651c7fb51b457a2a556949bfb25369b210ef73a74" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.2.0" vector_math: @@ -1183,7 +1239,7 @@ packages: description: name: vector_math sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.0" vm_service: @@ -1191,7 +1247,7 @@ packages: description: name: vm_service sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "15.0.2" web: @@ -1199,7 +1255,7 @@ packages: description: name: web sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.1" win32: @@ -1207,7 +1263,7 @@ packages: description: name: win32 sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.15.0" win32_registry: @@ -1215,7 +1271,7 @@ packages: description: name: win32_registry sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.5" xdg_directories: @@ -1223,7 +1279,7 @@ packages: description: name: xdg_directories sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.0" xml: @@ -1231,7 +1287,7 @@ packages: description: name: xml sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.6.1" yaml: @@ -1239,9 +1295,9 @@ packages: description: name: yaml sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.3" sdks: - dart: ">=3.9.0 <4.0.0" - flutter: ">=3.35.0" + dart: ">=3.10.3 <4.0.0" + flutter: ">=3.38.4"