diff --git a/XinjiangProject/XinjiangProject/Project/AppDelegate/AppDelegate.m b/XinjiangProject/XinjiangProject/Project/AppDelegate/AppDelegate.m index 11aaa70..e4df276 100644 --- a/XinjiangProject/XinjiangProject/Project/AppDelegate/AppDelegate.m +++ b/XinjiangProject/XinjiangProject/Project/AppDelegate/AppDelegate.m @@ -19,7 +19,7 @@ //前缀请求 //初始化高德地图 - [self configureAPIKey]; + [self configureAPIKey]; [self initService]; //初始化window [self initWindow]; diff --git a/XinjiangProject/XinjiangProject/Project/Base/XJBaseWebViewVC.m b/XinjiangProject/XinjiangProject/Project/Base/XJBaseWebViewVC.m index c97ed01..56d11f8 100644 --- a/XinjiangProject/XinjiangProject/Project/Base/XJBaseWebViewVC.m +++ b/XinjiangProject/XinjiangProject/Project/Base/XJBaseWebViewVC.m @@ -154,8 +154,10 @@ } - (void)finishActivity { - - + // H5 调用 finishActivity 的默认行为:pop 返回上一页 + // 语义等同于 Android 的 finish(),即关闭当前页面 + // 子类如需特殊处理(如 dismiss、发通知等),override 此方法即可 + [self.navigationController popViewControllerAnimated:YES]; } @@ -189,7 +191,7 @@ WkJSMessageType messageType = [[dic objectForKey:@"messageType"] intValue]; switch (messageType) { case WkJSMessageTypeBack:{ -// [self.navigationController popViewControllerAnimated:YES]; + [self.navigationController popViewControllerAnimated:YES]; } break; default: @@ -199,6 +201,12 @@ } else if ([message.name isEqualToString:@"htmlBack"]) { [[NSNotificationCenter defaultCenter] postNotificationName:@"fromWebToReloadData" object:nil]; + + } else if ([message.name isEqualToString:@"finishActivity"]) { + // JS 调用 window.webkit.messageHandlers.finishActivity.postMessage({}) 时触发 + // 调用 finishActivity 方法,子类可 override 实现各自的关闭逻辑 + // 基类默认实现为空,不做任何操作 + [self finishActivity]; } } @@ -230,6 +238,65 @@ [self hiddenAllMBProgressHUD]; } +#pragma mark - 白屏修复 + +/** + * 拦截所有导航请求,处理非 HTTP/HTTPS scheme。 + * + * 问题根源: + * 银行 H5 点击支付/跳转按钮时,会触发 alipay:// weixin:// tel:// 等 URL Scheme。 + * WKWebView 默认会尝试自己加载这些 scheme,加载失败后清空页面内容 → 永久白屏。 + * + * 解决方案: + * 在此方法中拦截非 HTTP/HTTPS 的请求,交由系统(UIApplication)处理, + * WKWebView 自身取消该次导航,页面内容保持不变。 + */ +- (void)webView:(WKWebView *)webView + decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction + decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { + + NSURL *url = navigationAction.request.URL; + NSString *scheme = url.scheme.lowercaseString; + + // HTTP / HTTPS:正常加载,交给 WKWebView 处理 + if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) { + decisionHandler(WKNavigationActionPolicyAllow); + return; + } + + // about:blank:WKWebView 内部使用,直接放行 + if ([scheme isEqualToString:@"about"]) { + decisionHandler(WKNavigationActionPolicyAllow); + return; + } + + // 其他 scheme(alipay:// weixin:// tel:// mailto:// 等): + // 交由系统打开对应 App 或拨号,WKWebView 取消此次导航,避免白屏 + if ([[UIApplication sharedApplication] canOpenURL:url]) { + [[UIApplication sharedApplication] openURL:url + options:@{} + completionHandler:nil]; + } + decisionHandler(WKNavigationActionPolicyCancel); +} + +/** + * WebContent 进程被系统终止时的兜底处理。 + * + * 触发场景: + * 设备内存严重不足时,系统会强制 kill 掉 WKWebView 的 WebContent 进程。 + * 此时 WKWebView 会立即变成空白页,且无法响应任何操作。 + * 若不处理,用户只能退出页面重新进入。 + * + * 解决方案: + * 检测到进程终止后,重新加载当前 URL,让用户无感知恢复。 + */ +- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView { + NSLog(@"[XJBaseWebViewVC] WebContent 进程被系统终止,自动 reload"); + // 重新加载,恢复页面内容 + [webView reload]; +} + diff --git a/XinjiangProject/XinjiangProject/Project/HomeV2/EmptyFunctionDevelopmentVC.h b/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/EmptyFunctionDevelopmentVC.h similarity index 100% rename from XinjiangProject/XinjiangProject/Project/HomeV2/EmptyFunctionDevelopmentVC.h rename to XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/EmptyFunctionDevelopmentVC.h diff --git a/XinjiangProject/XinjiangProject/Project/HomeV2/EmptyFunctionDevelopmentVC.m b/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/EmptyFunctionDevelopmentVC.m similarity index 100% rename from XinjiangProject/XinjiangProject/Project/HomeV2/EmptyFunctionDevelopmentVC.m rename to XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/EmptyFunctionDevelopmentVC.m diff --git a/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJBankWebDetailViewController.h b/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJBankWebDetailViewController.h new file mode 100644 index 0000000..65a1e48 --- /dev/null +++ b/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJBankWebDetailViewController.h @@ -0,0 +1,16 @@ +// +// XJBankWebDetailViewController.h +// XinjiangProject +// +// Created by Apple on 2026/3/11. +// + +#import "XJBaseWebViewVC.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface XJBankWebDetailViewController : XJBaseWebViewVC + +@end + +NS_ASSUME_NONNULL_END diff --git a/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJBankWebDetailViewController.m b/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJBankWebDetailViewController.m new file mode 100644 index 0000000..634b074 --- /dev/null +++ b/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJBankWebDetailViewController.m @@ -0,0 +1,37 @@ +// +// XJBankWebDetailViewController.m +// XinjiangProject +// +// Created by Apple on 2026/3/11. +// + +#import "XJBankWebDetailViewController.h" + +@interface XJBankWebDetailViewController () + +@end + +@implementation XJBankWebDetailViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.isHidenNaviBar = true; + [self.wkWebView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.left.right.mas_offset(0); + make.bottom.mas_offset(-SafetyAreaHeight); + }]; +} + +// finishActivity 行为与基类一致(pop 返回),无需 override +// 基类 XJBaseWebViewVC 已实现默认 pop 逻辑 + +/* +#pragma mark - Navigation +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/XinjiangProject/XinjiangProject/Project/HomeV2/XJHomePageV2ViewController.h b/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJHomePageV2ViewController.h similarity index 100% rename from XinjiangProject/XinjiangProject/Project/HomeV2/XJHomePageV2ViewController.h rename to XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJHomePageV2ViewController.h diff --git a/XinjiangProject/XinjiangProject/Project/HomeV2/XJHomePageV2ViewController.m b/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJHomePageV2ViewController.m similarity index 89% rename from XinjiangProject/XinjiangProject/Project/HomeV2/XJHomePageV2ViewController.m rename to XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJHomePageV2ViewController.m index 49049a4..9d60a22 100644 --- a/XinjiangProject/XinjiangProject/Project/HomeV2/XJHomePageV2ViewController.m +++ b/XinjiangProject/XinjiangProject/Project/HomeV2/Controllview/XJHomePageV2ViewController.m @@ -4,7 +4,7 @@ // // Created by Apple on 2026/2/9. // - +#import "XJBankWebDetailViewController.h" #import "XJHomePageV2ViewController.h" #import "QuestionViewController.h" #import "HealthyQuestionTable.h" @@ -76,6 +76,9 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 @property (nonatomic, strong) SDCycleScrollView * AIBannerImage; +//加密后的字符串 +@property (nonatomic, copy) NSString * secretString; + @end @@ -123,6 +126,7 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 [self initCompleteBlock]; [self configLocationManager]; [self reGeocodeAction]; + //请求手表数据 // 4. 添加 V2TIMSDKListener 的事件监听器,self 是 id 的实现类,如果您不需要监听 IM SDK 的事件,这个步骤可以忽略。 [[V2TIMManager sharedInstance] addIMSDKListener:self]; @@ -159,23 +163,22 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 } - (void)viewWillAppear:(BOOL)animated { - + [super viewWillAppear:animated]; - + self.polling = YES; //轮询开始 - + //请求token获取数据 [self verifyTokenData]; - + //登录了那就走轮询 if ([HQCommonUtils isLogin]) { //请求消息列表 [self getMessageListData]; [self getUserWatchData]; + [self getWebKeySecret]; + } - - - } @@ -343,6 +346,37 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 [searchApi getHomeWatchData:parmDic]; } +#pragma mark: 请求key的加密 +- (void)getWebKeySecret { + + NSString * scheme = SCHEME; + + NSString * host; + +#if DEBUG + host = @"xj-api.mcrm.vip"; + + +#else + host = @"api-jkglpt.iosp.ydpt.tech"; + +#endif + + NSString * token = User_Token; + + NSString * keyStirng = [NSString stringWithFormat:@"scheme=%@&host=%@&tokenF=%@",scheme,host,token]; + + NSMutableDictionary * parmDic = [[NSMutableDictionary alloc] init]; + + [parmDic setObject:keyStirng forKey:@"str"]; + + XJPNetAPI * searchApi = [[XJPNetAPI alloc] init:self tag:@"SECRET" NeedToken:@""]; + + [searchApi getWebNeedEncryptionKey:parmDic]; + +} + + - (void)Failed:(NSString*)message tag:(NSString*)tag { @@ -411,9 +445,6 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 [self getData]; } - - - } if ([tag isEqualToString:@"IMAPI"]) { @@ -443,9 +474,6 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 [EasyTextView showErrorText:msg]; }]; - - - } if ([tag isEqualToString:@"SMALLHELP"]) { @@ -644,6 +672,17 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 self.topView.watchArray = sortedArray; } + if ([tag isEqualToString:@"SECRET"]) { + DLog(@"%@",response) + NSDictionary * responseDic = response; + + if ([responseDic.allKeys containsObject:@"encryptData"]) { + self.secretString = responseDic[@"encryptData"]; + + } + + + } } //是否需要更新 @@ -722,26 +761,26 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 [self.navigationController pushViewController:foundVC animated:true]; } - -- (void)smallQuestionAction { - - if ([ESCTUIManager TUIUserStatus] == false) { - - - [self loginImAccount]; - return; - } - - NSMutableDictionary * dic = [[NSMutableDictionary alloc] init]; - - [self showMBProgressHUDWithString:@"咨询中,请稍候..." autoHidden:NO]; - XJPNetAPI * searchApi = [[XJPNetAPI alloc] init:self tag:@"SMALLHELP" NeedToken:@""]; - - [searchApi postSmallHelpGroup:dic]; - - - -} +// +//- (void)smallQuestionAction { +// +// if ([ESCTUIManager TUIUserStatus] == false) { +// +// +// [self loginImAccount]; +// return; +// } +// +// NSMutableDictionary * dic = [[NSMutableDictionary alloc] init]; +// +// [self showMBProgressHUDWithString:@"咨询中,请稍候..." autoHidden:NO]; +// XJPNetAPI * searchApi = [[XJPNetAPI alloc] init:self tag:@"SMALLHELP" NeedToken:@""]; +// +// [searchApi postSmallHelpGroup:dic]; +// +// +// +//} - (void)myQuestionAction { @@ -903,14 +942,63 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 }]; //代理 self.homeTable.headDelegate = self; + kWeakSelf(self); + self.homeTable.tableBlock = ^(HomeQusetionRecordsModel * _Nonnull model) { + weakself.recomendModel = model; + + if(![HQCommonUtils isLogin]) { + KPostNotification(KNotificationLoginStateChange, @NO); + return; + } + + //1图文 2视频 + if ([model.contentType intValue] == 2) { + + XJDoctorMainViewController * doctorVC = [[XJDoctorMainViewController alloc] init]; + doctorVC.yuyue_id = model.records_id; + doctorVC.popType = 1; + [weakself.navigationController pushViewController:doctorVC animated:YES]; + } + if ([model.contentType intValue] == 1) { + + if ([TUILogin isUserLogined]) { + ChatViewController * chatVC = [[ChatViewController alloc] init]; + chatVC.isGroupID = YES; + chatVC.chatID = model.imId ; + chatVC.eableSendReport = true; + chatVC.eablehaveHelathData = false; + chatVC.navTitle = @"图文咨询"; + chatVC.isVideo = NO; + chatVC.pictureEnd_id = model.records_id; + chatVC.questionType = 2; + chatVC.medicalRecordsId = model.memberId; + if ([model.contentStatus intValue] == 5) { + chatVC.isEveal = true; + }else + { + chatVC.isEveal = false; + } + if ([model.contentStatus intValue] >=4 ) { + chatVC.endRecordType = 100; + } + [weakself.navigationController pushViewController:chatVC animated:YES]; + }else + { + if ([HQCommonUtils isLogin]) { + [weakself loginImAccountList]; + + } + + } + } + }; //监听 [self.homeTable addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil]; - kWeakSelf(self); - + self.homeTable.lookMoreBlock = ^{ if(![HQCommonUtils isLogin]) { KPostNotification(KNotificationLoginStateChange, @NO); @@ -987,6 +1075,7 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 make.bottom.equalTo(self.contentView.mas_bottom).offset(-18); }]; + } @@ -1084,10 +1173,31 @@ static CGFloat const kEmptyTableMinHeight = 250; // 或屏幕高度的一半 } if (type == 3) { - EmptyFunctionDevelopmentVC * vc = [[EmptyFunctionDevelopmentVC alloc] init]; - vc.navigationItem.title = @"健康银行"; - [self.navigationController pushViewController:vc animated:YES]; +// EmptyFunctionDevelopmentVC * vc = [[EmptyFunctionDevelopmentVC alloc] init]; +// vc.navigationItem.title = @"健康银行"; +// [self.navigationController pushViewController:vc animated:YES]; + if(![HQCommonUtils isLogin]) { + KPostNotification(KNotificationLoginStateChange, @NO); + return; + } + if (ValidStr(self.secretString)) { + [self showMBProgressHUDOnlyWithString:@"网络异常请稍候再试~"]; + [self getWebKeySecret]; + return; + } + XJBankWebDetailViewController * bankVC = [[XJBankWebDetailViewController alloc] init]; + NSString * urlString; +#if DEBUG + urlString = @"https://gstest.superwx.cn/healthbank/index.html?"; + + +#else + urlString = @"https://console-jkglpt.iosp.ydpt.tech/hb/healthweb/index.html"; + +#endif + bankVC.webUrl = [NSString stringWithFormat:@"%@?param=%@",urlString,self.secretString]; + [self.navigationController pushViewController:bankVC animated:YES]; } }