HomeViewController.m 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  1. //
  2. // HomeViewController.m
  3. // Apex Mobile
  4. //
  5. // Created by Ray on 25/01/2018.
  6. // Copyright © 2018 United Software Applications, Inc. All rights reserved.
  7. //
  8. #import "HomeViewController.h"
  9. #import "ShipingStatusCell.h"
  10. #import "ShipSearchController.h"
  11. #import "ApexMobileDB.h"
  12. #import "DetailTabBarController.h"
  13. #import "RAUtils.h"
  14. #import "KPICell.h"
  15. #import "KPITableCell.h"
  16. #import "AMResultViewController.h"
  17. #import "AMShipMap.h"
  18. #import "ApexResultViewController.h"
  19. #define SHIP_CELL_IDENTIFIER @"ShippingStatusCell"
  20. #define KPI_CELL_IDENTIFIER @"KPITableCell"
  21. typedef enum {
  22. HomeModeRecent = 0,
  23. HomeModeKPI = 1
  24. } HomeMode;
  25. @interface HomeViewController () <UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,KPIDelegate,ShipCellDelegate,AMShipMapDelegate>
  26. @property (strong, nonatomic) IBOutlet UISegmentedControl *segmentControl;
  27. @property (nonatomic,strong) IBOutlet UIView *ShipContainer;
  28. @property (nonatomic,strong) IBOutlet UIActivityIndicatorView *ShipLoading;
  29. @property (nonatomic,strong) IBOutlet UIButton *ShipNoDataBtn;
  30. @property (strong, nonatomic) IBOutlet UITableView *shipTableView;
  31. @property (strong, nonatomic) IBOutlet UISearchBar *shipSearchBar;
  32. @property (nonatomic,strong) NSMutableArray *shipArray;
  33. @property (nonatomic,strong) UIRefreshControl *refreshControl;
  34. @property (nonatomic,strong) IBOutlet UIView *KPIContainer;
  35. @property (nonatomic,strong) IBOutlet UIActivityIndicatorView *KPILoading;
  36. @property (nonatomic,strong) IBOutlet UIButton *KPINoDataBtn;
  37. @property (nonatomic,strong) IBOutlet UITableView *KPITableView;
  38. @property (nonatomic,strong) UIRefreshControl *KPIRefresh;
  39. @property (nonatomic,strong) NSMutableArray *KPIArray;
  40. @property (nonatomic,strong) NSArray *monthArray;
  41. @property (nonatomic,assign) HomeMode mode;///<
  42. @property (nonatomic,assign) NSInteger currentKPI;
  43. @property (nonatomic,strong) UIAlertController *progressDialog;
  44. @property (nonatomic,assign) BOOL recentRefresh;
  45. @property (nonatomic,assign) BOOL kpiRefresh;
  46. @property (nonatomic,strong) IBOutlet AMShipMap *mapView;
  47. @property (nonatomic,strong) NSIndexPath *iconSelectedIndexPath;
  48. @end
  49. @implementation HomeViewController
  50. - (void)viewDidLoad {
  51. [super viewDidLoad];
  52. // Do any additional setup after loading the view.
  53. if (@available(iOS 11,*)) {
  54. self.shipTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  55. } else {
  56. self.automaticallyAdjustsScrollViewInsets = NO;
  57. }
  58. self.currentKPI = 1;
  59. self.segmentControl.tintColor = APGRAYCOLOR;
  60. self.recentRefresh = NO;
  61. self.kpiRefresh = NO;
  62. [self registNotification];
  63. [self configureTableView];
  64. self.shipSearchBar.delegate =self;
  65. [self configureMap];
  66. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(logout) name:APLogoutNotification object:nil];
  67. // self.loadIndicator.layer.cornerRadius = 5;
  68. // self.loadIndicator.layer.masksToBounds = YES;
  69. // self.loadIndicator.layer.borderColor = [UIColor colorWithRed:169 / 255.0 green:169 / 255.0 blue:169 / 255.0 alpha:1.0].CGColor;
  70. // self.loadIndicator.layer.borderWidth = 0.3f;
  71. // self.loadIndicator.color = [UIColor colorWithRed:43 / 255.0 green:43 / 255.0 blue:43 / 255.0 alpha:1.0];
  72. // self.loadIndicator.backgroundColor = [UIColor colorWithRed:255 / 255.0 green:255 / 255.0 blue:255 / 255.0 alpha:0.9];
  73. }
  74. - (void)didReceiveMemoryWarning {
  75. [super didReceiveMemoryWarning];
  76. // Dispose of any resources that can be recreated.
  77. }
  78. - (void)viewWillAppear:(BOOL)animated {
  79. [super viewWillAppear:animated];
  80. [self clearNavigationbar];
  81. [self configureNavigationBar];
  82. }
  83. - (void)viewDidAppear:(BOOL)animated {
  84. [super viewDidAppear:animated];
  85. if (self.mode == HomeModeRecent) {
  86. if (self.shipArray.count == 0 || self.recentRefresh) {
  87. [self loadData];
  88. }
  89. [self.mapView shipMapWillAppear];
  90. } else if (self.mode == HomeModeKPI) {
  91. if (self.KPIArray.count == 0 || self.kpiRefresh) {
  92. [self loadKPIData];
  93. } else {
  94. NSString *str = [NSString stringWithFormat:@"%ld / %ld",self.currentKPI,self.KPIArray.count];
  95. self.parentViewController.title = str;
  96. }
  97. }
  98. }
  99. - (void)viewWillDisappear:(BOOL)animated {
  100. [super viewWillDisappear:animated];
  101. self.parentViewController.title = nil;
  102. [self.mapView shipMapWillDisappear];
  103. }
  104. - (void)clearNavigationbar {
  105. self.tabBarController.navigationItem.leftBarButtonItem = nil;
  106. self.tabBarController.navigationItem.leftBarButtonItems = nil;
  107. self.tabBarController.navigationItem.titleView = nil;
  108. self.tabBarController.navigationItem.title = nil;
  109. self.tabBarController.navigationItem.rightBarButtonItem = nil;
  110. self.tabBarController.navigationItem.rightBarButtonItems = nil;
  111. }
  112. - (void)configureMap {
  113. self.mapView.showCurrent = YES;
  114. self.mapView.showPoe = YES;
  115. self.mapView.showPol = YES;
  116. self.mapView.showPod = YES;
  117. self.mapView.showPor = YES;
  118. self.mapView.showOrigin = YES;
  119. self.mapView.showDestination = YES;
  120. self.mapView.delegate = self;
  121. }
  122. - (void)configureNavigationBar {
  123. if (self.navigationController && !self.navigationController.isNavigationBarHidden) {
  124. UIImage *logo = [[UIImage imageNamed:@"apexlogo-2"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  125. AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
  126. if (appDelegate.personalmode) {
  127. logo = [[UIImage imageNamed:@"apexlogo-2p"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  128. }
  129. UIBarButtonItem *logoItem = [[UIBarButtonItem alloc] initWithImage:logo landscapeImagePhone:logo style:UIBarButtonItemStylePlain target:self action:@selector(switchMode:)];
  130. logoItem.enabled = true;
  131. self.tabBarController.navigationItem.leftBarButtonItem = logoItem;
  132. UIBarButtonItem *searchItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"bar_search"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(searchItemClick:)];
  133. self.tabBarController.navigationItem.rightBarButtonItem = searchItem;
  134. }
  135. }
  136. - (void)configureTableView {
  137. CGFloat w = CGRectGetWidth(self.shipTableView.bounds);
  138. self.shipTableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, CGFLOAT_MIN)];
  139. self.shipTableView.tableFooterView = [UIView new];
  140. [self.shipTableView registerNib:[UINib nibWithNibName:@"ShippingStatusCell" bundle:nil] forCellReuseIdentifier:SHIP_CELL_IDENTIFIER];
  141. [self.shipTableView registerNib:[UINib nibWithNibName:@"KPITableCell" bundle:nil] forCellReuseIdentifier:KPI_CELL_IDENTIFIER];
  142. UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
  143. refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"loading data..."];
  144. [refresh addTarget:self action:@selector(refreshControlValueChanged:) forControlEvents:UIControlEventValueChanged];
  145. [self.shipTableView addSubview:refresh];
  146. self.refreshControl = refresh;
  147. // KPI
  148. self.KPITableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, CGFLOAT_MIN)];
  149. self.KPITableView.tableFooterView = [UIView new];
  150. [self.KPITableView registerNib:[UINib nibWithNibName:@"KPITableCell" bundle:nil] forCellReuseIdentifier:KPI_CELL_IDENTIFIER];
  151. UIRefreshControl *KPIRefresh = [[UIRefreshControl alloc] init];
  152. KPIRefresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"loading data..."];
  153. [KPIRefresh addTarget:self action:@selector(KPIRefreshControlValueChanged:) forControlEvents:UIControlEventValueChanged];
  154. [self.KPITableView addSubview:KPIRefresh];
  155. self.KPIRefresh = KPIRefresh;
  156. }
  157. - (void)registNotification {
  158. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePersonModeChangeNotification:) name:APPersonModeChangeNotification object:nil];
  159. }
  160. - (void)logout {
  161. [self.shipArray removeAllObjects];
  162. [self.shipTableView reloadData];
  163. self.currentKPI = 1;
  164. self.monthArray = nil;
  165. [self.KPIArray removeAllObjects];
  166. [self.KPITableView reloadData];
  167. }
  168. - (void)handlePersonModeChangeNotification:(NSNotification *)notification {
  169. [self reloadContent];
  170. }
  171. - (void)postPersonModeChangeNotification {
  172. [[NSNotificationCenter defaultCenter] postNotificationName:APPersonModeChangeNotification object:nil];
  173. }
  174. - (void)dealloc {
  175. [[NSNotificationCenter defaultCenter] removeObserver:self];
  176. }
  177. #pragma mark - Private
  178. - (UIAlertController *)progressDialog {
  179. if (!_progressDialog) {
  180. UIAlertController *alertController = [UIAlertController alertControllerWithTitle: nil
  181. message: @"loading..."
  182. preferredStyle: UIAlertControllerStyleAlert];
  183. UIViewController *customVC = [[UIViewController alloc] init];
  184. UIActivityIndicatorView* spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
  185. // spinner.color = [UIColor redColor];
  186. [spinner startAnimating];
  187. [customVC.view addSubview:spinner];
  188. [customVC.view addConstraint:[NSLayoutConstraint
  189. constraintWithItem: spinner
  190. attribute:NSLayoutAttributeCenterX
  191. relatedBy:NSLayoutRelationEqual
  192. toItem:customVC.view
  193. attribute:NSLayoutAttributeCenterX
  194. multiplier:1.0f
  195. constant:0.0f]];
  196. [customVC.view addConstraint:[NSLayoutConstraint
  197. constraintWithItem: spinner
  198. attribute:NSLayoutAttributeCenterY
  199. relatedBy:NSLayoutRelationEqual
  200. toItem:customVC.view
  201. attribute:NSLayoutAttributeCenterY
  202. multiplier:1.0f
  203. constant:0.0f]];
  204. [alertController setValue:customVC forKey:@"contentViewController"];
  205. _progressDialog = alertController;
  206. }
  207. return _progressDialog;
  208. }
  209. - (void)showProgressDialog {
  210. [self presentViewController:self.progressDialog animated:true completion:nil];
  211. NSLog(@"-dialog show %@",self.progressDialog);
  212. }
  213. // 2019.1.4 增加参数completion
  214. // 解决加载完成后在dismiss过程中弹出对话框询问上传Cache时警告:while a presentation is in progress!
  215. - (void)dismissProgressDialog:(void(^)(void))completion {
  216. [self.progressDialog dismissViewControllerAnimated:YES completion:completion];
  217. NSLog(@"-dialog dismiss %@",self.progressDialog);
  218. }
  219. #pragma mark - Check Database
  220. - (void)checkDatabase {
  221. AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
  222. if (appDelegate.shouldCheckCache) {
  223. appDelegate.shouldCheckCache = NO;
  224. if ([ApexMobileDB isCachedDataForUser:appDelegate.user]) {
  225. __weak typeof(self) weakSelf = self;
  226. // alert
  227. UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Warning" message:@"there is some cached data need to upload to service, do you allow us to upload it? if you reject we would clean it" preferredStyle:UIAlertControllerStyleAlert];
  228. UIAlertAction *rejectAction = [UIAlertAction actionWithTitle:@"Reject" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  229. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  230. [ApexMobileDB cleanCacheDataForUser:appDelegate.user];
  231. });
  232. }];
  233. UIAlertAction *allowAction = [UIAlertAction actionWithTitle:@"Allow" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  234. [weakSelf uploadCache];
  235. }];
  236. [alertVC addAction:rejectAction];
  237. [alertVC addAction:allowAction];
  238. [self presentViewController:alertVC animated:YES completion:nil];
  239. }
  240. }
  241. }
  242. - (void)uploadCache {
  243. AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
  244. [self showProgressDialog];
  245. __weak typeof(self) weakSelf = self;
  246. // upload/handle data
  247. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  248. NSString *sql = [ApexMobileDB prepareUploadSQLOfUser:appDelegate.user withDiviceID:RAUtils.deviceID];
  249. // upload
  250. NSDictionary *json = [RANetwork uploadUserSql:sql];
  251. // handle result
  252. int result = [json[@"result"] intValue];
  253. dispatch_async(dispatch_get_main_queue(), ^{
  254. [weakSelf dismissProgressDialog:^{
  255. if (result == RESULT_TRUE) {
  256. [RAUtils message_alert:nil title:@"upload success" controller:self];
  257. } else {
  258. UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Warning" message:@"upload local cached data failed,do you want to rery or cancel? if you choose cancel, then we will clean the cache" preferredStyle:UIAlertControllerStyleAlert];
  259. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  260. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  261. [ApexMobileDB cleanCacheDataForUser:appDelegate.user];
  262. });
  263. }];
  264. UIAlertAction *retryAction = [UIAlertAction actionWithTitle:@"Retry" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  265. [weakSelf uploadCache];
  266. }];
  267. [alertVC addAction:cancelAction];
  268. [alertVC addAction:retryAction];
  269. [self presentViewController:alertVC animated:YES completion:nil];
  270. }
  271. }]; // dismiss
  272. });// main queue
  273. }); // global queue
  274. }
  275. #pragma mark - Load Data
  276. - (NSMutableArray *)shipArray {
  277. if (!_shipArray) {
  278. _shipArray = [NSMutableArray array];
  279. }
  280. return _shipArray;
  281. }
  282. - (NSMutableArray *)KPIArray {
  283. if (!_KPIArray) {
  284. _KPIArray = [NSMutableArray array];
  285. }
  286. return _KPIArray;
  287. }
  288. - (void)reloadContent {
  289. NSLog(@"Home Person Mode Change");
  290. self.recentRefresh = YES;
  291. self.kpiRefresh = YES;
  292. if (((UITabBarController *)self.parentViewController).selectedIndex == 0) {
  293. if (self.mode == HomeModeRecent) {
  294. [self loadData];
  295. } else {
  296. [self loadKPIData];
  297. }
  298. }
  299. }
  300. - (void)loadData {
  301. // NSString *path = [[NSBundle mainBundle] pathForResource:@"fake_container_list.json" ofType:nil];
  302. // NSData *data = [[NSData alloc] initWithContentsOfFile:path];
  303. //
  304. // NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
  305. // 避免重复刷新
  306. if (self.ShipLoading.isAnimating) {
  307. return;
  308. }
  309. [self.ShipLoading startAnimating];
  310. [self showProgressDialog];
  311. __weak typeof(self) weakSelf = self;
  312. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  313. NSDictionary *json = [RANetwork requestHome];
  314. // NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"fake_home.json" ofType:nil]];
  315. // NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
  316. dispatch_async(dispatch_get_main_queue(), ^{
  317. if (self.refreshControl.isRefreshing) {
  318. [self.refreshControl endRefreshing];
  319. }
  320. [self.ShipLoading stopAnimating];
  321. int result = [[json objectForKey:@"result"] intValue];
  322. [weakSelf dismissProgressDialog:^{
  323. if (result == RESULT_TRUE) {
  324. [self.shipArray removeAllObjects];
  325. [self.shipArray addObjectsFromArray:[json objectForKey:@"container_list"]];
  326. self.iconSelectedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
  327. [self showMapAnnotaionWithIndexPath:self.iconSelectedIndexPath];
  328. [self.shipTableView reloadData];
  329. // [self checkDatabase];
  330. } else {
  331. NSString *msg = [json objectForKey:@"err_msg"];
  332. [RAUtils message_alert:msg title:@"Warning" controller:weakSelf];
  333. }
  334. self.ShipNoDataBtn.hidden = self.shipArray.count > 0;
  335. if (self.shipArray.count) {
  336. [self.shipTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
  337. }
  338. weakSelf.recentRefresh = NO;
  339. }];// dismiss
  340. }); // main queue
  341. }); // global queue
  342. }
  343. - (void)loadKPIData {
  344. if (self.KPILoading.isAnimating) {
  345. return;
  346. }
  347. [self.KPILoading startAnimating];
  348. [self showProgressDialog];
  349. __weak typeof(self) weakSelf = self;
  350. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  351. NSDictionary *json = [RANetwork requestKPI];
  352. dispatch_async(dispatch_get_main_queue(), ^{
  353. if (weakSelf.KPIRefresh.isRefreshing) {
  354. [weakSelf.KPIRefresh endRefreshing];
  355. }
  356. [weakSelf.KPILoading stopAnimating];
  357. int result = [[json objectForKey:@"result"] intValue];
  358. [weakSelf dismissProgressDialog:^{
  359. if (result == RESULT_TRUE) {
  360. // self.currentKPI = 1;
  361. weakSelf.monthArray = [json objectForKey:@"month"];
  362. [weakSelf.KPIArray removeAllObjects];
  363. NSArray *kpiArr = [json objectForKey:@"KPI"];
  364. // [self.KPIArray addObject:[[kpiArr firstObject] mutableCopy]];
  365. for (int i = 0; i < kpiArr.count; i++) {
  366. NSMutableDictionary *kpiModel = [[kpiArr objectAtIndex:i] mutableCopy];
  367. NSMutableArray *itemMutArr = [NSMutableArray array];
  368. NSArray *itemArr = [kpiModel objectForKey:@"arr_val"];
  369. for (int j = 0; j < itemArr.count; j++) {
  370. NSMutableDictionary *item = [[itemArr objectAtIndex:j] mutableCopy];
  371. [itemMutArr addObject:item];
  372. }
  373. [kpiModel setObject:itemMutArr forKey:@"arr_val"];
  374. // [self.KPIArray addObjectsFromArray:kpiArr];
  375. [weakSelf.KPIArray addObject:kpiModel];
  376. }
  377. // [self.KPIArray addObject:[[kpiArr lastObject] mutableCopy]];
  378. [weakSelf.KPITableView reloadData];
  379. if (((UITabBarController *)weakSelf.parentViewController).selectedIndex == 0) {
  380. NSString *str = [NSString stringWithFormat:@"%ld / %ld",self.currentKPI,self.KPIArray.count];
  381. weakSelf.parentViewController.title = str;
  382. }
  383. } else {
  384. NSString *msg = [json objectForKey:@"err_msg"];
  385. [RAUtils message_alert:msg title:@"Warning" controller:weakSelf];
  386. }
  387. weakSelf.KPINoDataBtn.hidden = self.KPIArray.count > 0;
  388. weakSelf.kpiRefresh = NO;
  389. }];
  390. });
  391. });
  392. }
  393. #pragma mark - Actinon
  394. - (void)refreshControlValueChanged:(UIRefreshControl *)refresh {
  395. [self loadData];
  396. }
  397. - (void)KPIRefreshControlValueChanged:(UIRefreshControl *)refresh {
  398. [self loadKPIData];
  399. }
  400. - (void)searchItemClick:(id)sender {
  401. ShipSearchController *searchVC = [ShipSearchController build];
  402. [self.navigationController pushViewController:searchVC animated:YES];
  403. }
  404. - (IBAction)modeSegmentClick:(UISegmentedControl *)sender {
  405. if (sender.selectedSegmentIndex == 1) {
  406. self.mode = HomeModeKPI;
  407. self.ShipContainer.hidden = YES;
  408. self.KPIContainer.hidden = NO;
  409. if (self.KPIArray.count == 0 || self.kpiRefresh) {
  410. [self loadKPIData];
  411. } else {
  412. NSString *str = [NSString stringWithFormat:@"%ld / %ld",self.currentKPI,self.KPIArray.count];
  413. self.parentViewController.title = str;
  414. }
  415. [self.mapView shipMapWillDisappear];
  416. } else {
  417. self.mode = HomeModeRecent;
  418. self.KPIContainer.hidden = YES;
  419. self.ShipContainer.hidden = NO;
  420. self.parentViewController.title = nil;
  421. if (self.shipArray.count == 0 || self.recentRefresh) {
  422. [self loadData];
  423. }
  424. [self.mapView shipMapWillAppear];
  425. }
  426. [self.shipTableView reloadData];
  427. }
  428. - (void)switchMode:(id)sender {
  429. AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
  430. appDelegate.personalmode = ! appDelegate.personalmode;
  431. NSString* msg = @"";
  432. if(appDelegate.personalmode)
  433. {
  434. msg=@"Personal Mode On.";
  435. self.tabBarController.navigationItem.leftBarButtonItem.image = [[UIImage imageNamed:@"apexlogo-2p"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  436. }
  437. else
  438. {
  439. msg=@"Personal Mode Off.";
  440. self.tabBarController.navigationItem.leftBarButtonItem.image = [[UIImage imageNamed:@"apexlogo-2"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  441. }
  442. [self postPersonModeChangeNotification];
  443. // [RAUtils alert_view:msg title:@"Personal Mode"];
  444. }
  445. - (IBAction)ShipNoDataBtnClick:(UIButton *)sender {
  446. [self loadData];
  447. }
  448. - (IBAction)KPINoDataBtnClick:(UIButton *)sender {
  449. [self loadKPIData];
  450. }
  451. #pragma mark - TableView DataSource && Delegate
  452. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  453. if (self.shipTableView == tableView) {
  454. return self.shipArray.count;
  455. } else {
  456. return 1;
  457. }
  458. }
  459. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  460. return 1;
  461. }
  462. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  463. if (self.shipTableView == tableView) {
  464. ShipingStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:SHIP_CELL_IDENTIFIER forIndexPath:indexPath];
  465. NSDictionary *item = [self.shipArray objectAtIndex:indexPath.section];
  466. NSString *title = [item objectForKey:@"title"];
  467. NSString *icon = [item objectForKey:@"icon"];
  468. NSString *desc = [item objectForKey:@"description"];
  469. NSString *detail = [item objectForKey:@"detail"];
  470. NSString *date = [item objectForKey:@"date"];
  471. NSString *port = [item objectForKey:@"port"];
  472. NSInteger stage = [[item objectForKey:@"transport_stage"] integerValue];
  473. [[[[[[[[cell setTitle:title] setDescription:desc] setDetail:detail] setPort:port] setTime:date] setIcon:icon] setTransportStage:stage] setDelegate:self];
  474. if (self.iconSelectedIndexPath && self.iconSelectedIndexPath.section == indexPath.section) {
  475. [self setSelectedIndexPath:self.iconSelectedIndexPath shipCell:cell];
  476. }
  477. return cell;
  478. } else {
  479. KPITableCell *kpiCell = [tableView dequeueReusableCellWithIdentifier:KPI_CELL_IDENTIFIER forIndexPath:indexPath];
  480. kpiCell.KPICollectionView.dataSource = self;
  481. kpiCell.KPICollectionView.delegate = self;
  482. [kpiCell.KPICollectionView reloadData];
  483. if (self.KPIArray.count) {
  484. [kpiCell.KPICollectionView setContentOffset:CGPointMake(self.currentKPI * kpiCell.KPICollectionView.bounds.size.width, 0) animated:NO];
  485. }
  486. return kpiCell;
  487. }
  488. }
  489. //- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  490. // CGFloat w = CGRectGetWidth(tableView.bounds);
  491. //
  492. // UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, 30)];
  493. // header.backgroundColor = [UIColor lightGrayColor];
  494. //
  495. // UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, w - 10 * 2, 20)];
  496. // label.textColor = [UIColor whiteColor];
  497. // label.text = @"Recently";
  498. //
  499. // [header addSubview:label];
  500. // return header;
  501. //}
  502. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  503. if (self.shipTableView != tableView) {
  504. return 0.f;
  505. }
  506. return 10;
  507. }
  508. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  509. return 0.001;
  510. }
  511. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
  512. if (self.shipTableView != tableView) {
  513. return tableView.bounds.size.height;
  514. }
  515. return 110;
  516. }
  517. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  518. if (self.shipTableView != tableView) {
  519. return;
  520. }
  521. [self setSelectedIndexPath:indexPath shipCell:nil];
  522. [self showMapAnnotaionWithIndexPath:indexPath];
  523. NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
  524. // [params setObject:@"dumb" forKey:@"id"];
  525. NSString* h_field;
  526. //if(self.radioContainer.selected==true)
  527. //{
  528. // [params setObject:@"1" forKey:@"criterion_type"];
  529. // h_field = @"ctnr";
  530. //}
  531. //else
  532. {
  533. [params setObject:@"0" forKey:@"criterion_type"];
  534. h_field = @"h_bol";
  535. }
  536. NSDictionary *item = [self.shipArray objectAtIndex:indexPath.section];
  537. NSString * cargo_criterion = item[@"hbol"];
  538. NSString *serial_no = item[@"serial_no"];
  539. if(cargo_criterion==nil)
  540. cargo_criterion=@"";
  541. [params setObject:cargo_criterion forKey:@"cargo_criterion"];
  542. if (serial_no != nil) {
  543. [params setObject:serial_no forKey:@"serial_no"];
  544. [params setObject:serial_no forKey:@"id"];
  545. }
  546. [ApexMobileDB savehistory:h_field value:cargo_criterion];
  547. DetailTabBarController *detailViewController=[[DetailTabBarController alloc] init:@"Cargo Tracking" actions:[NSArray arrayWithObjects:@"Tracking",nil] params:params];
  548. [self.navigationController pushViewController:detailViewController animated:YES];
  549. }
  550. //#pragma mark - SearchBar Delegate
  551. //
  552. //- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
  553. //
  554. // ShipSearchController *searchVC = [ShipSearchController build];
  555. //
  556. // UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:searchVC];
  557. //
  558. // [self presentViewController:nav animated:YES completion:nil];
  559. //
  560. // return NO;
  561. //}
  562. #pragma mark - CollectionView DataSource & Delegate
  563. - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
  564. return 1;
  565. }
  566. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  567. if (self.KPIArray && self.KPIArray.count > 0) {
  568. return self.KPIArray.count + 2;
  569. }
  570. return 0;
  571. }
  572. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  573. KPICell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"KPICell" forIndexPath:indexPath];
  574. NSInteger index = indexPath.item;
  575. if (indexPath.item == 0) {
  576. index = self.KPIArray.count - 1;
  577. } else if (indexPath.item == self.KPIArray.count + 1) {
  578. index = 0;
  579. } else {
  580. index = indexPath.item - 1;
  581. }
  582. NSMutableDictionary *item = [self.KPIArray objectAtIndex:index];
  583. [item setObject:self.monthArray forKey:@"month"];
  584. [cell setInfoDic:item];
  585. cell.delegate = self;
  586. return cell;
  587. }
  588. #pragma mark - KPICell Delegate
  589. - (void)KPICell:(KPICell *)cell repeatClickLegendAtIndex:(NSInteger)index withItem:(NSDictionary *)item {
  590. NSLog(@"double clicked %ld",index);
  591. /**
  592. s_kpi = true;
  593. name = kpi name
  594. sector = sector title
  595. module_name = module_name
  596. */
  597. NSArray * itemsArr = item[@"arr_val"];
  598. NSMutableDictionary* legend = [itemsArr objectAtIndex:index];
  599. NSString *kpi_name = [item objectForKey:@"name"];
  600. NSString *sector = [legend objectForKey:@"full_title"];
  601. NSString *module_name = [item objectForKey:@"module_name"];
  602. if (kpi_name == nil) {
  603. kpi_name = @"";
  604. }
  605. if (sector == nil) {
  606. sector = @"";
  607. }
  608. if (module_name == nil) {
  609. module_name = @"";
  610. }
  611. NSMutableDictionary *params = [@{
  612. @"is_kpi" : @(YES),
  613. @"name" : kpi_name,
  614. @"sector": sector,
  615. @"module_name" : module_name
  616. } mutableCopy];
  617. // AMResultViewController *resultVC = [[AMResultViewController alloc] initWithNibName:@"Result" bundle:nil];
  618. // resultVC.params = params;
  619. // [self.navigationController pushViewController:resultVC animated:YES];
  620. ApexResultViewController *vc = [ApexResultViewController resultViewController:params];
  621. [self.navigationController pushViewController:vc animated:YES];
  622. }
  623. #pragma mark - FlowLayout Delegate
  624. - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  625. return collectionView.bounds.size;
  626. }
  627. - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
  628. return 0.0f;
  629. }
  630. - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
  631. return 0.0f;
  632. }
  633. #pragma mark - ScrollViewDelegate
  634. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  635. if (scrollView != self.shipTableView && [scrollView isKindOfClass:[UICollectionView class]]) {
  636. UICollectionView *collectionView = (UICollectionView *)scrollView;
  637. CGFloat w = scrollView.bounds.size.width;
  638. CGFloat offsetX = scrollView.contentOffset.x;
  639. float f = floorf(offsetX / w);
  640. NSInteger index = floorf(f + 0.5);
  641. NSInteger cur = index;
  642. if (index == 0) {
  643. cur = self.KPIArray.count;
  644. [collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:cur inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
  645. } else if (index == self.KPIArray.count + 1) {
  646. cur = 1;
  647. [collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:cur inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
  648. } else {
  649. cur = index;
  650. }
  651. }
  652. }
  653. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  654. if (scrollView != self.shipTableView && [scrollView isKindOfClass:[UICollectionView class]]) {
  655. // UICollectionView *collectionView = (UICollectionView *)scrollView;
  656. CGFloat w = scrollView.bounds.size.width;
  657. CGFloat offsetX = scrollView.contentOffset.x;
  658. float f = floorf(offsetX / w);
  659. NSInteger index = floorf(f + 0.5);
  660. NSInteger cur = index;
  661. if (index == 0) {
  662. cur = self.KPIArray.count;
  663. } else if (index == self.KPIArray.count + 1) {
  664. cur = 1;
  665. } else {
  666. cur = index;
  667. }
  668. self.currentKPI = cur;
  669. if (self.currentKPI > 0) {
  670. NSString *str = [NSString stringWithFormat:@"%ld / %ld",self.currentKPI,self.KPIArray.count];
  671. self.parentViewController.title = str;
  672. } else {
  673. self.currentKPI = 1;
  674. }
  675. }
  676. }
  677. #pragma mark - Map
  678. - (NSDictionary *)fakeLoaction {
  679. NSArray *arr = [ApexMobileDB get_Location];
  680. NSMutableDictionary *returnDic = [NSMutableDictionary dictionary];
  681. for (int i = 0; i < arr.count ; i ++) {
  682. NSDictionary* location = arr[i];
  683. NSString* area = [location valueForKey:@"area"];
  684. NSString* company = [location valueForKey:@"company"];
  685. // NSString* city = [location valueForKey:@"city"];
  686. NSString *longitude = [location valueForKey:@"longitude"];
  687. NSString *latitude = [location valueForKey:@"latitude"];
  688. NSDictionary *dic = @{
  689. @"addr" : area,
  690. @"name" : company,
  691. @"lon" : longitude,
  692. @"lat" : latitude
  693. };
  694. if (i == 0) {
  695. [returnDic setObject:dic forKey:@"pol"];
  696. } else if (i == 1) {
  697. [returnDic setObject:dic forKey:@"pod"];
  698. } else if (i == 2) {
  699. [returnDic setObject:dic forKey:@"poe"];
  700. } else if (i == 3) {
  701. [returnDic setObject:dic forKey:@"por"];
  702. } else if (i == 4) {
  703. [returnDic setObject:dic forKey:@"origin"];
  704. } else if (i == 5) {
  705. [returnDic setObject:dic forKey:@"destination"];
  706. } else if (i == 6) {
  707. [returnDic setObject:dic forKey:@"current"];
  708. } else {
  709. break;
  710. }
  711. }
  712. return returnDic;
  713. }
  714. - (void)setSelectedIndexPath:(NSIndexPath *)indexPath shipCell:(ShipingStatusCell *)shipCell {
  715. if (indexPath == nil) {
  716. return;
  717. }
  718. if (self.iconSelectedIndexPath) {
  719. ShipingStatusCell *cell = [self.shipTableView cellForRowAtIndexPath:self.iconSelectedIndexPath];
  720. [cell setIconSelect:NO];
  721. }
  722. self.iconSelectedIndexPath = indexPath;
  723. ShipingStatusCell *cell = [self.shipTableView cellForRowAtIndexPath:indexPath];
  724. if (cell == nil) { // 滑动过程中,dequeue方法中设置选中
  725. cell = shipCell;
  726. }
  727. [self.shipTableView selectRowAtIndexPath:self.iconSelectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
  728. [cell setIconSelect:YES];
  729. }
  730. - (void)showMapAnnotaionWithIndexPath:(NSIndexPath *)indexPath {
  731. if(self.shipArray.count==0)
  732. return;
  733. NSDictionary *item = [self.shipArray objectAtIndex:indexPath.section];
  734. NSDictionary *locationInfo = [item objectForKey:@"locations"];
  735. NSString* port = @"";
  736. if([item[@"location_eta"] boolValue])
  737. port=@"pod";
  738. else
  739. if([item[@"location_etd"] boolValue])
  740. port=@"pol";
  741. [self.mapView showShipAnnotaion:locationInfo backupLocation:port];
  742. }
  743. #pragma mark - ShipCell Delegate
  744. - (void)shipCellDidTapIcon:(ShipingStatusCell *)cell {
  745. NSIndexPath *indexPath = [self.shipTableView indexPathForCell:cell];
  746. [self setSelectedIndexPath:indexPath shipCell:cell];
  747. [self showMapAnnotaionWithIndexPath:indexPath];
  748. }
  749. #pragma mark - ShipMap Delegate
  750. - (void)shipMap:(AMShipMap *)shipMap tryToZoomIn:(BOOL)zoomIn {
  751. if (zoomIn) {
  752. NSArray *constraints = self.ShipContainer.constraints;
  753. NSLayoutConstraint *h_ratio_constraint = nil;
  754. for (NSLayoutConstraint *constraint in constraints) {
  755. if (constraint.identifier && [constraint.identifier isEqualToString:@"map_height_ratio"]) {
  756. h_ratio_constraint = constraint;
  757. }
  758. }
  759. if (h_ratio_constraint) {
  760. [self.ShipContainer removeConstraint:h_ratio_constraint];
  761. }
  762. NSLayoutConstraint *table_h_constraint = [NSLayoutConstraint constraintWithItem:self.shipTableView
  763. attribute:NSLayoutAttributeHeight
  764. relatedBy:NSLayoutRelationEqual
  765. toItem:nil
  766. attribute:NSLayoutAttributeNotAnAttribute
  767. multiplier:0
  768. constant:120.0f];
  769. table_h_constraint.identifier = @"ship_table_height";
  770. [self.ShipContainer addConstraint:table_h_constraint];
  771. } else {
  772. NSArray *constraints = self.ShipContainer.constraints;
  773. NSLayoutConstraint *h_constraint = nil;
  774. for (NSLayoutConstraint *constraint in constraints) {
  775. if (constraint.identifier && [constraint.identifier isEqualToString:@"ship_table_height"]) {
  776. h_constraint = constraint;
  777. }
  778. }
  779. if (h_constraint) {
  780. [self.ShipContainer removeConstraint:h_constraint];
  781. }
  782. float h_ratio = 0.5;
  783. NSLayoutConstraint *h_ratio_constraint = [NSLayoutConstraint constraintWithItem:shipMap
  784. attribute:NSLayoutAttributeHeight
  785. relatedBy:NSLayoutRelationEqual
  786. toItem:self.shipTableView
  787. attribute:NSLayoutAttributeHeight
  788. multiplier:h_ratio
  789. constant:0];
  790. h_ratio_constraint.identifier = @"map_height_ratio";
  791. [self.ShipContainer addConstraint:h_ratio_constraint];
  792. }
  793. [self.ShipContainer layoutIfNeeded];
  794. }
  795. @end