IncomeCountViewController.m 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. //
  2. // IncomeCountViewController.m
  3. // KulexiuForTeacher
  4. //
  5. // Created by 王智 on 2022/4/26.
  6. //
  7. #import "IncomeCountViewController.h"
  8. #import "IncomeCountTopView.h"
  9. #import <WebKit/WebKit.h>
  10. #import "KSMutilDatePicker.h"
  11. #import "IncomeCountBottomView.h"
  12. #import <AuthChallengeManager.h>
  13. // WKWebView 内存不释放的问题解决
  14. @interface KSWeakWebViewScriptMessageDelegate : NSObject<WKScriptMessageHandler>
  15. //WKScriptMessageHandler 这个协议类专门用来处理JavaScript调用原生OC的方法
  16. @property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;
  17. - (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;
  18. @end
  19. @implementation KSWeakWebViewScriptMessageDelegate
  20. - (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate {
  21. self = [super init];
  22. if (self) {
  23. _scriptDelegate = scriptDelegate;
  24. }
  25. return self;
  26. }
  27. #pragma mark - WKScriptMessageHandler
  28. //遵循WKScriptMessageHandler协议,必须实现如下方法,然后把方法向外传递
  29. //通过接收JS传出消息的name进行捕捉的回调方法
  30. - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
  31. if ([self.scriptDelegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {
  32. [self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
  33. }
  34. }
  35. @end
  36. @interface IncomeCountViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>
  37. @property (nonatomic, strong) IncomeCountTopView *topView;
  38. @property (nonatomic, strong) UIView *bottomView;
  39. @property (nonatomic, strong) WKWebView *myWebView;
  40. @property (nonatomic, strong) IncomeCountBottomView *roundView;
  41. @property (nonatomic, strong) WKWebView *bottomWebView;;
  42. @property (nonatomic, strong) NSURL *fileUrl;
  43. @property (nonatomic, strong) KSMutilDatePicker *datePicker;
  44. @property (nonatomic, strong) NSString *chooseDate;
  45. @property (nonatomic, strong) NSString *salary;
  46. @property (nonatomic, strong) NSString *total;
  47. @property (nonatomic, assign) BOOL isYear;
  48. @property (nonatomic, strong) NSArray *sourceArray;
  49. @property (nonatomic, assign) BOOL hasLoad;
  50. @property (nonatomic, strong) UIView *emptyView;
  51. @property (nonatomic, assign) CGFloat totalAmount;
  52. @property (nonatomic, strong) NSDictionary *parmDic;
  53. @end
  54. @implementation IncomeCountViewController
  55. - (void)viewDidLoad {
  56. [super viewDidLoad];
  57. // Do any additional setup after loading the view.
  58. [self allocTitle:@"收入统计"];
  59. [self configUI];
  60. [self requestData];
  61. }
  62. - (void)configUI {
  63. self.scrollView.backgroundColor = [UIColor clearColor];
  64. self.scrollView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight - kNaviBarHeight- iPhoneXSafeBottomMargin);
  65. [self.scrollView addSubview:self.topView];
  66. [self.scrollView addSubview:self.myWebView];
  67. [self.scrollView addSubview:self.roundView];
  68. [self.roundView.bgView addSubview:self.bottomWebView];
  69. [self.bottomWebView mas_makeConstraints:^(MASConstraintMaker *make) {
  70. make.right.top.bottom.left.mas_equalTo(self.roundView.bgView);
  71. }];
  72. [self.scrollView addSubview:self.bottomView];
  73. NSDate *currentDate = [NSDate date];
  74. NSDateFormatter *dateFormatter = [NSObject getDateformatter];
  75. [dateFormatter setDateFormat:@"yyyy"];
  76. NSString *dateStr = [dateFormatter stringFromDate:currentDate];
  77. self.chooseDate = dateStr;
  78. self.topView.dateLabel.text = [NSString stringWithFormat:@"%@年", dateStr];
  79. self.isYear = YES;
  80. CGFloat height = CGRectGetMaxY(self.bottomView.frame) + 20;
  81. self.scrollView.contentSize = CGSizeMake(kScreenWidth, height);
  82. }
  83. - (void)showEmptyView:(BOOL)isShow {
  84. if (isShow) {
  85. if (![self.view.subviews containsObject:self.emptyView]) {
  86. [self.view addSubview:self.emptyView];
  87. }
  88. self.roundView.hidden = YES;
  89. }
  90. else {
  91. if ([self.view.subviews containsObject:self.emptyView]) {
  92. [self.emptyView removeFromSuperview];
  93. }
  94. self.roundView.hidden = NO;
  95. }
  96. }
  97. - (void)requestData {
  98. NSString *timeType = self.isYear ? @"YEAR" : @"MONTH";
  99. [LOADING_MANAGER showHUD];
  100. [KSNetworkingManager accountTotalRequest:KS_POST dateTime:self.chooseDate timeType:timeType success:^(NSDictionary * _Nonnull dic) {
  101. [LOADING_MANAGER removeHUD];
  102. if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
  103. NSDictionary *returnValue = [dic ks_dictionaryValueForKey:@"data"];
  104. self.topView.totalSalary.text = [NSString formatMoneyDoubleNum:[returnValue ks_floatValueForKey:@"totalInAmount"]];
  105. NSArray *sourceArray = [returnValue ks_arrayValueForKey:@"infoList"];
  106. if (sourceArray != nil && sourceArray.count > 0) {
  107. [self showEmptyView:NO];
  108. if (self.hasLoad) {
  109. [self configMessage:sourceArray headSource:returnValue];
  110. }
  111. else {
  112. self.sourceArray = sourceArray;
  113. self.parmDic = returnValue;
  114. }
  115. }
  116. else {
  117. [self showEmptyView:YES];
  118. }
  119. }
  120. else {
  121. [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
  122. }
  123. } faliure:^(NSError * _Nonnull error) {
  124. [LOADING_MANAGER removeHUD];
  125. }];
  126. }
  127. - (void)configMessage:(NSArray *)source headSource:(NSDictionary *)parmDic {
  128. // 顶部数据
  129. NSMutableArray *descArray = [NSMutableArray array];
  130. NSMutableArray *amountArray = [NSMutableArray array];
  131. NSMutableArray *rateArray = [NSMutableArray array];
  132. float practiceAmount = [parmDic ks_floatValueForKey:@"practiceAmount"];
  133. NSString *practiceDescString = @"陪练课";
  134. [descArray addObject:practiceDescString];
  135. [amountArray addObject:[NSString stringWithFormat:@"%.2f",practiceAmount]];
  136. float liveAmount = [parmDic ks_floatValueForKey:@"liveAmount"];
  137. NSString *liveDesc = @"直播课";
  138. [descArray addObject:liveDesc];
  139. [amountArray addObject:[NSString stringWithFormat:@"%.2f",liveAmount]];
  140. float videoAmount = [parmDic ks_floatValueForKey:@"videoAmount"];
  141. NSString *videoDesc = @"视频课";
  142. [descArray addObject:videoDesc];
  143. [amountArray addObject:[NSString stringWithFormat:@"%.2f",videoAmount]];
  144. float musicAmount = [parmDic ks_floatValueForKey:@"musicAmount"];
  145. NSString *musicDesc = @"乐谱";
  146. [descArray addObject:musicDesc];
  147. [amountArray addObject:[NSString stringWithFormat:@"%.2f",musicAmount]];
  148. [self.topView configSource:descArray amountArray:amountArray];
  149. float practiceRate = [parmDic ks_floatValueForKey:@"practiceRate"];
  150. [rateArray addObject:[NSString stringWithFormat:@"%.2f",practiceRate]];
  151. float liveRate = [parmDic ks_floatValueForKey:@"liveRate"];
  152. [rateArray addObject:[NSString stringWithFormat:@"%.2f",liveRate]];
  153. float videoRate = [parmDic ks_floatValueForKey:@"videoRate"];
  154. [rateArray addObject:[NSString stringWithFormat:@"%.2f",videoRate]];
  155. float musicRate = [parmDic ks_floatValueForKey:@"musicRate"];
  156. [rateArray addObject:[NSString stringWithFormat:@"%.2f",musicRate]];
  157. NSArray *colorArray = @[@"#5B8FF9",
  158. @"#2DC7AA",
  159. @"#91DD1C",
  160. @"#FFA92C"];
  161. // configSource:
  162. NSMutableArray *keyArray = [NSMutableArray array];
  163. NSMutableArray *valueArray = [NSMutableArray array];
  164. NSMutableArray *practiceArray = [NSMutableArray array];
  165. NSMutableArray *practiceAmountArray = [NSMutableArray array];
  166. NSMutableArray *liveArray = [NSMutableArray array];
  167. NSMutableArray *liveAmountArray = [NSMutableArray array];
  168. NSMutableArray *videoArray = [NSMutableArray array];
  169. NSMutableArray *videoAmountArray = [NSMutableArray array];
  170. NSMutableArray *musicArray = [NSMutableArray array];
  171. NSMutableArray *musicAmountArray = [NSMutableArray array];
  172. for (NSDictionary *dic in source) {
  173. float practiceAmount = [dic ks_floatValueForKey:@"practiceAmount"];
  174. NSString *practiceDescString = @"陪练课";
  175. [practiceAmountArray addObject:[NSString stringWithFormat:@"%.2f",practiceAmount]];
  176. [practiceArray addObject:practiceDescString];
  177. float liveAmount = [dic ks_floatValueForKey:@"liveAmount"];
  178. NSString *liveDesc = @"直播课";
  179. [liveAmountArray addObject:[NSString stringWithFormat:@"%.2f",liveAmount]];
  180. [liveArray addObject:liveDesc];
  181. float videoAmount = [dic ks_floatValueForKey:@"videoAmount"];
  182. NSString *videoDesc = @"视频课";
  183. [videoAmountArray addObject:[NSString stringWithFormat:@"%.2f",videoAmount]];
  184. [videoArray addObject:videoDesc];
  185. float musicAmount = [dic ks_floatValueForKey:@"musicAmount"];
  186. NSString *musicDesc = @"乐谱";
  187. [musicAmountArray addObject:[NSString stringWithFormat:@"%.2f",musicAmount]];
  188. [musicArray addObject:musicDesc];
  189. }
  190. [valueArray addObject:practiceAmountArray];
  191. [valueArray addObject:liveAmountArray];
  192. [valueArray addObject:videoAmountArray];
  193. [valueArray addObject:musicAmountArray];
  194. for (NSDictionary *dic in source) {
  195. NSString *bottomValue = @"";
  196. if (_isYear) {
  197. bottomValue = [NSString stringWithFormat:@"%@月",[[[dic ks_stringValueForKey:@"timeStr"] componentsSeparatedByString:@"-"] lastObject]];
  198. }
  199. else {
  200. bottomValue = [NSString stringWithFormat:@"%@日",[[[dic ks_stringValueForKey:@"timeStr"] componentsSeparatedByString:@"-"] lastObject]];
  201. }
  202. [keyArray addObject:bottomValue];
  203. }
  204. NSMutableDictionary *parm = [NSMutableDictionary dictionary];
  205. [parm setValue:@{@"show":@(NO)} forKey:@"title"];
  206. [parm setValue:@{@"trigger": @"axis"} forKey:@"tooltip"];
  207. [parm setValue:@{@"show": @(NO)} forKey:@"legend"];
  208. [parm setValue:@{
  209. @"left": @"3%",
  210. @"right": @"5%",
  211. @"bottom": @"3%",
  212. @"containLabel": @(YES)
  213. } forKey:@"grid"];
  214. [parm setValue:@{
  215. @"type": @"category",
  216. @"boundaryGap": @(NO),
  217. @"data":keyArray,
  218. @"axisLine" : @{@"lineStyle":@{@"color": @"#8C8C8C",}},
  219. } forKey:@"xAxis"];
  220. [parm setValue:@{@"feature": @{@"saveAsImage": @{@"show":@(NO)}}} forKey:@"toolbox"];
  221. [parm setValue:@{@"type": @"value",
  222. @"splitLine":@{
  223. @"lineStyle":@{@"color": @[@"#E2E2E2"]},
  224. @"axisLine":@{@"lineStyle":@{@"color": @"#8C8C8C"}}
  225. },
  226. } forKey:@"yAxis"];
  227. [parm setValue:@{@"lineStyle":@{ @"width": @2}} forKey:@"emphasis"];
  228. [parm setValue:@[@{@"type" : @"inside",
  229. @"throttle" : keyArray.count > 15 ? @(50) : @(100),
  230. }] forKey:@"dataZoom"];
  231. NSMutableArray *fillColorArray = [NSMutableArray array];
  232. NSMutableArray *seriesArray = [NSMutableArray array];
  233. for (int i = 0; i < descArray.count && i < colorArray.count; i++) {
  234. NSString *fillColor = colorArray[i];
  235. [fillColorArray addObject:fillColor];
  236. NSArray *amountDetailArray = valueArray[i];
  237. NSString *desc = descArray[i];
  238. NSDictionary *serier = @{@"symbol":@"circle",
  239. @"name": desc,
  240. @"type": @"line",
  241. @"data": amountDetailArray,
  242. @"emphasis":@{@"lineStyle" : @{@"width": @1}},
  243. @"lineStyle":@{ @"width": @1},
  244. };
  245. [seriesArray addObject:serier];
  246. }
  247. // 根据返回数据生成颜色和显示数据
  248. [parm setValue:fillColorArray forKey:@"color"];
  249. [parm setValue:seriesArray forKey:@"series"];
  250. [self postMessage:parm inWebView:self.myWebView];
  251. NSMutableDictionary *secondParm = [NSMutableDictionary dictionary];
  252. [secondParm setValue:@{@"feature":@{@"saveAsImage":@{@"show":@(NO)}}}
  253. forKey:@"toolbox"];
  254. [secondParm setValue:@{@"borderWidth" : @0,
  255. @"formatter":@"{b} : {c} ({d}%)",
  256. @"padding":@3,
  257. @"position":@[@"30%",@"30%"],
  258. @"textStyle": @{@"fontSize": @12},
  259. @"trigger":@"item",
  260. }
  261. forKey:@"tooltip"];
  262. NSMutableArray *bottomFillColorArray = [NSMutableArray array];
  263. NSMutableArray *dataArray = [NSMutableArray array];
  264. for (int i = 0; i < descArray.count && i < colorArray.count; i++) {
  265. NSString *fillColor = colorArray[i];
  266. [bottomFillColorArray addObject:fillColor];
  267. NSString *desc = descArray[i];
  268. NSNumber *amount = amountArray[i];
  269. NSDictionary *data = @{@"name":desc,
  270. @"value":amount,
  271. };
  272. [dataArray addObject:data];
  273. }
  274. [secondParm setValue:fillColorArray forKey:@"color"];
  275. [secondParm setValue:@[@{@"type":@"pie",
  276. @"radius":@[@"50%",@"80%"],
  277. @"avoidLabelOverlap" : @(NO),
  278. @"label" : @{@"show": @(NO)},
  279. @"data" :dataArray}]
  280. forKey:@"series"];
  281. [self postMessage:secondParm inWebView:self.bottomWebView];
  282. [self.roundView configSource:descArray amountArray:rateArray];
  283. }
  284. - (void)postMessage:(NSDictionary *)parm inWebView:(WKWebView *)webView {
  285. NSString *jsString = [parm mj_JSONString];
  286. [webView evaluateJavaScript:[NSString stringWithFormat:@"loadEcharts('%@')", jsString] completionHandler:nil];
  287. }
  288. // 5 页面加载完成之后调用
  289. - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
  290. NSLog(@"5-------页面加载完成之后调用");
  291. if (_hasLoad == NO) {
  292. _hasLoad = YES;
  293. if (self.sourceArray != nil) {
  294. [self configMessage:self.sourceArray headSource:self.parmDic];
  295. }
  296. }
  297. }
  298. #pragma mark - WKScriptMessageHandler
  299. - (void)userContentController:(WKUserContentController *)userContentController
  300. didReceiveScriptMessage:(WKScriptMessage *)message {
  301. }
  302. - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *_Nullable))completionHandler
  303. {
  304. dispatch_queue_t queue = dispatch_queue_create("webViewChallengeQueue", NULL);
  305. dispatch_async(queue, ^{
  306. if (SSL_AUTH) {
  307. NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
  308. NSURLCredential *customCredential = nil;
  309. if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
  310. // 默认信任
  311. customCredential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
  312. disposition = NSURLSessionAuthChallengeUseCredential;
  313. }
  314. else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate]) {
  315. // client authentication
  316. SecIdentityRef identity = NULL;
  317. SecTrustRef trust = NULL;
  318. if ([AuthChallengeManager extractIdentity:&identity andTrust:&trust filePath:CERT_PATH]) {
  319. SecCertificateRef certificate = NULL;
  320. SecIdentityCopyCertificate(identity, &certificate);
  321. const void*certs[] = {certificate};
  322. CFArrayRef certArray =CFArrayCreate(kCFAllocatorDefault, certs,1,NULL);
  323. customCredential =[NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)certArray persistence:NSURLCredentialPersistencePermanent];
  324. disposition = NSURLSessionAuthChallengeUseCredential;
  325. // 释放 CFArrayRef 和 SecCertificateRef
  326. CFRelease(certArray);
  327. CFRelease(certificate);
  328. }
  329. }
  330. if (completionHandler) {
  331. completionHandler(disposition, customCredential);
  332. }
  333. }
  334. else {
  335. if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
  336. if (challenge.previousFailureCount == 0) {
  337. NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
  338. completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
  339. } else {
  340. completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
  341. }
  342. }
  343. else {
  344. completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
  345. }
  346. }
  347. });
  348. }
  349. #pragma mark ---- lazying
  350. - (WKWebView *)myWebView {
  351. if (!_myWebView) {
  352. WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
  353. config.selectionGranularity = WKSelectionGranularityDynamic;
  354. config.processPool = [IncomeCountViewController singleWkProcessPool];
  355. config.websiteDataStore = [WKWebsiteDataStore defaultDataStore];
  356. //自定义的WKScriptMessageHandler 是为了解决内存不释放的问题
  357. KSWeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[KSWeakWebViewScriptMessageDelegate alloc] initWithDelegate:self];
  358. //这个类主要用来做native与JavaScript的交互管理
  359. WKUserContentController * wkUController = [[WKUserContentController alloc] init];
  360. [wkUController addScriptMessageHandler:weakScriptMessageDelegate name:@"DAYA"];
  361. config.userContentController = wkUController;
  362. WKPreferences *preferences = [WKPreferences new];
  363. // 是否支出javaScript
  364. preferences.javaScriptEnabled = YES;
  365. //不通过用户交互,是否可以打开窗口
  366. preferences.javaScriptCanOpenWindowsAutomatically = YES;
  367. config.preferences = preferences;
  368. _myWebView = [[WKWebView alloc] initWithFrame:CGRectMake(12, 190, kScreenWidth - 24, 240) configuration:config];
  369. _myWebView.UIDelegate = self;
  370. _myWebView.navigationDelegate = self;
  371. _myWebView.scrollView.bounces = NO;
  372. [self loadSource];
  373. }
  374. return _myWebView;
  375. }
  376. - (WKWebView *)bottomWebView {
  377. if (!_bottomWebView) {
  378. WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
  379. config.selectionGranularity = WKSelectionGranularityDynamic;
  380. config.processPool = [IncomeCountViewController singleWkProcessPool];
  381. config.websiteDataStore = [WKWebsiteDataStore defaultDataStore];
  382. //自定义的WKScriptMessageHandler 是为了解决内存不释放的问题
  383. KSWeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[KSWeakWebViewScriptMessageDelegate alloc] initWithDelegate:self];
  384. //这个类主要用来做native与JavaScript的交互管理
  385. WKUserContentController * wkUController = [[WKUserContentController alloc] init];
  386. [wkUController addScriptMessageHandler:weakScriptMessageDelegate name:@"DAYA"];
  387. config.userContentController = wkUController;
  388. WKPreferences *preferences = [WKPreferences new];
  389. // 是否支出javaScript
  390. preferences.javaScriptEnabled = YES;
  391. //不通过用户交互,是否可以打开窗口
  392. preferences.javaScriptCanOpenWindowsAutomatically = YES;
  393. config.preferences = preferences;
  394. _bottomWebView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
  395. _bottomWebView.UIDelegate = self;
  396. _bottomWebView.navigationDelegate = self;
  397. _bottomWebView.scrollView.bounces = NO;
  398. [self loadBottomWebSource];
  399. }
  400. return _bottomWebView;
  401. }
  402. - (UIView *)emptyView {
  403. if (!_emptyView) {
  404. CGFloat width = kScreenWidth - 24;
  405. _emptyView = [[UIView alloc] initWithFrame:CGRectMake(12, 190, width, 240)];
  406. _emptyView.backgroundColor = [UIColor whiteColor];
  407. UIImageView *emptyImage = [[UIImageView alloc] initWithFrame:CGRectMake((width - 140) / 2.0f, 30, 140, 140)];
  408. [emptyImage setImage:[UIImage imageNamed:@"wd_img_zwsj"]];
  409. [_emptyView addSubview:emptyImage];
  410. UILabel *label = [[UILabel alloc] init];
  411. label.frame = CGRectMake(0, CGRectGetMaxY(emptyImage.frame)+10, width, 20);
  412. label.font = [UIFont systemFontOfSize:14.0f];
  413. label.textColor = HexRGB(0x999999);
  414. label.textAlignment = NSTextAlignmentCenter;
  415. label.numberOfLines = 1;
  416. label.text = @"暂无数据";
  417. [_emptyView addSubview:label];
  418. }
  419. return _emptyView;
  420. }
  421. - (void)loadSource {
  422. NSString *filePath = [[NSBundle mainBundle] pathForResource:@"stacked_line_chart" ofType:@"html"];
  423. [_myWebView loadFileURL:[NSURL fileURLWithPath:filePath] allowingReadAccessToURL:[NSURL fileURLWithPath:[NSBundle mainBundle].bundlePath]];
  424. }
  425. - (void)loadBottomWebSource {
  426. NSString *filePath = [[NSBundle mainBundle] pathForResource:@"stacked_line_chart" ofType:@"html"];
  427. [_bottomWebView loadFileURL:[NSURL fileURLWithPath:filePath] allowingReadAccessToURL:[NSURL fileURLWithPath:[NSBundle mainBundle].bundlePath]];
  428. }
  429. - (IncomeCountTopView *)topView {
  430. if (!_topView) {
  431. _topView = [IncomeCountTopView shareInstance];
  432. _topView.frame = CGRectMake(0, 0, kScreenWidth, 220);
  433. MJWeakSelf;
  434. [_topView chooseDateCallback:^{
  435. [weakSelf showPickerView];
  436. }];
  437. }
  438. return _topView;
  439. }
  440. - (IncomeCountBottomView *)roundView {
  441. if (!_roundView) {
  442. _roundView = [IncomeCountBottomView shareInstance];
  443. _roundView.frame = CGRectMake(12, CGRectGetMaxY(self.myWebView.frame), kScreenWidth - 24, 250);
  444. }
  445. return _roundView;
  446. }
  447. - (UIView *)bottomView {
  448. if (!_bottomView) {
  449. CGFloat width = kScreenWidth - 24;
  450. _bottomView = [[UIView alloc] init];
  451. _bottomView.frame = CGRectMake(12, CGRectGetMaxY(self.roundView.frame), width, 20);
  452. _bottomView.backgroundColor = [UIColor whiteColor];
  453. UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, width, 20) byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(10, 10)];
  454. CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
  455. maskLayer.frame = CGRectMake(0, 0, width, 20);
  456. maskLayer.path = path.CGPath;
  457. _bottomView.layer.mask = maskLayer;
  458. }
  459. return _bottomView;
  460. }
  461. - (KSMutilDatePicker *)datePicker {
  462. if (!_datePicker) {
  463. MJWeakSelf;
  464. // 最大时间 now
  465. // 最小时间 2021-03
  466. NSString *minLimitStr = @"2021-03";
  467. NSDateFormatter *outputFormatter = [NSObject getDateformatter];
  468. [outputFormatter setDateFormat:@"yyyy-MM"];
  469. NSDate *minDate = [outputFormatter dateFromString:minLimitStr];
  470. _datePicker = [[KSMutilDatePicker alloc] initWithTitle:@"选择时间" date:[NSDate date] maxLimitDate:[NSDate date] minLimitDate:minDate selectDateBlock:^(NSString * _Nonnull date, NSString * _Nonnull descDate) {
  471. [weakSelf.topView changeArrowStatus:NO];
  472. [weakSelf finishChooseDate:date disc:descDate];
  473. } cancleBolck:^{
  474. [weakSelf.topView changeArrowStatus:NO];
  475. }];
  476. }
  477. return _datePicker;
  478. }
  479. - (void)finishChooseDate:(NSString *)dateStr disc:(NSString *)descStr {
  480. self.topView.dateLabel.text = descStr;
  481. if ([dateStr containsString:@"-"]) {
  482. self.isYear = NO;
  483. self.chooseDate = dateStr;
  484. }
  485. else {
  486. self.isYear = YES;
  487. self.chooseDate = dateStr;
  488. }
  489. [self requestData];
  490. }
  491. - (void)showPickerView {
  492. [self.datePicker show];
  493. }
  494. + (WKProcessPool*)singleWkProcessPool {
  495. static WKProcessPool *sharedPool;
  496. static dispatch_once_t onceToken;
  497. dispatch_once(&onceToken, ^{
  498. sharedPool = [[WKProcessPool alloc] init];
  499. });
  500. return sharedPool;
  501. }
  502. - (NSDictionary *)convertJsonStringToNSDictionary:(NSString *)jsonString {
  503. if (jsonString == nil) {
  504. return nil;
  505. }
  506. NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
  507. NSError *error;
  508. NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
  509. if (error) {
  510. NSLog(@"jsonString解析失败:%@", error);
  511. return nil;
  512. }
  513. return json;
  514. }
  515. - (void)dealloc {
  516. [[_myWebView configuration].userContentController removeScriptMessageHandlerForName:@"DAYA"];
  517. [_myWebView loadHTMLString:@"" baseURL:nil];
  518. [_myWebView removeFromSuperview];
  519. _myWebView = nil;
  520. [[NSURLCache sharedURLCache] removeAllCachedResponses];
  521. [[NSURLCache sharedURLCache] setDiskCapacity:0];
  522. [[NSURLCache sharedURLCache] setMemoryCapacity:0];
  523. }
  524. /*
  525. #pragma mark - Navigation
  526. // In a storyboard-based application, you will often want to do a little preparation before navigation
  527. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  528. // Get the new view controller using [segue destinationViewController].
  529. // Pass the selected object to the new view controller.
  530. }
  531. */
  532. @end