HomeViewController.m 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044
  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. NSString *po_no = [item objectForKey:@"po_no"];
  474. NSString * po_text = @"PO#: ";
  475. if(po_no.length>0)
  476. po_text=[po_text stringByAppendingString:po_no];
  477. [cell setPoNO:po_text];
  478. [[[[[[[[cell setTitle:title] setDescription:desc] setDetail:detail] setPort:port] setTime:date] setIcon:icon] setTransportStage:stage] setDelegate:self];
  479. if (self.iconSelectedIndexPath && self.iconSelectedIndexPath.section == indexPath.section) {
  480. [self setSelectedIndexPath:self.iconSelectedIndexPath shipCell:cell];
  481. }
  482. return cell;
  483. } else {
  484. KPITableCell *kpiCell = [tableView dequeueReusableCellWithIdentifier:KPI_CELL_IDENTIFIER forIndexPath:indexPath];
  485. kpiCell.KPICollectionView.dataSource = self;
  486. kpiCell.KPICollectionView.delegate = self;
  487. [kpiCell.KPICollectionView reloadData];
  488. if (self.KPIArray.count) {
  489. [kpiCell.KPICollectionView setContentOffset:CGPointMake(self.currentKPI * kpiCell.KPICollectionView.bounds.size.width, 0) animated:NO];
  490. }
  491. return kpiCell;
  492. }
  493. }
  494. //- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  495. // CGFloat w = CGRectGetWidth(tableView.bounds);
  496. //
  497. // UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, 30)];
  498. // header.backgroundColor = [UIColor lightGrayColor];
  499. //
  500. // UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, w - 10 * 2, 20)];
  501. // label.textColor = [UIColor whiteColor];
  502. // label.text = @"Recently";
  503. //
  504. // [header addSubview:label];
  505. // return header;
  506. //}
  507. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  508. if (self.shipTableView != tableView) {
  509. return 0.f;
  510. }
  511. return 10;
  512. }
  513. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  514. return 0.001;
  515. }
  516. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
  517. if (self.shipTableView != tableView) {
  518. return tableView.bounds.size.height;
  519. }
  520. return 128;
  521. }
  522. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  523. if (self.shipTableView != tableView) {
  524. return;
  525. }
  526. [self setSelectedIndexPath:indexPath shipCell:nil];
  527. [self showMapAnnotaionWithIndexPath:indexPath];
  528. NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
  529. // [params setObject:@"dumb" forKey:@"id"];
  530. NSString* h_field;
  531. //if(self.radioContainer.selected==true)
  532. //{
  533. // [params setObject:@"1" forKey:@"criterion_type"];
  534. // h_field = @"ctnr";
  535. //}
  536. //else
  537. {
  538. [params setObject:@"0" forKey:@"criterion_type"];
  539. h_field = @"h_bol";
  540. }
  541. NSDictionary *item = [self.shipArray objectAtIndex:indexPath.section];
  542. NSString * cargo_criterion = item[@"hbol"];
  543. NSString *serial_no = item[@"serial_no"];
  544. if(cargo_criterion==nil)
  545. cargo_criterion=@"";
  546. [params setObject:cargo_criterion forKey:@"cargo_criterion"];
  547. if (serial_no != nil) {
  548. [params setObject:serial_no forKey:@"serial_no"];
  549. [params setObject:serial_no forKey:@"id"];
  550. }
  551. [ApexMobileDB savehistory:h_field value:cargo_criterion];
  552. DetailTabBarController *detailViewController=[[DetailTabBarController alloc] init:@"Cargo Tracking" actions:[NSArray arrayWithObjects:@"Tracking",nil] params:params];
  553. [self.navigationController pushViewController:detailViewController animated:YES];
  554. }
  555. //#pragma mark - SearchBar Delegate
  556. //
  557. //- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
  558. //
  559. // ShipSearchController *searchVC = [ShipSearchController build];
  560. //
  561. // UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:searchVC];
  562. //
  563. // [self presentViewController:nav animated:YES completion:nil];
  564. //
  565. // return NO;
  566. //}
  567. #pragma mark - CollectionView DataSource & Delegate
  568. - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
  569. return 1;
  570. }
  571. - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
  572. if (self.KPIArray && self.KPIArray.count > 0) {
  573. return self.KPIArray.count + 2;
  574. }
  575. return 0;
  576. }
  577. - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  578. KPICell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"KPICell" forIndexPath:indexPath];
  579. NSInteger index = indexPath.item;
  580. if (indexPath.item == 0) {
  581. index = self.KPIArray.count - 1;
  582. } else if (indexPath.item == self.KPIArray.count + 1) {
  583. index = 0;
  584. } else {
  585. index = indexPath.item - 1;
  586. }
  587. NSMutableDictionary *item = [self.KPIArray objectAtIndex:index];
  588. [item setObject:self.monthArray forKey:@"month"];
  589. [cell setInfoDic:item];
  590. cell.delegate = self;
  591. return cell;
  592. }
  593. #pragma mark - KPICell Delegate
  594. - (void)KPICell:(KPICell *)cell repeatClickLegendAtIndex:(NSInteger)index withItem:(NSDictionary *)item {
  595. NSLog(@"double clicked %ld",index);
  596. /**
  597. s_kpi = true;
  598. name = kpi name
  599. sector = sector title
  600. module_name = module_name
  601. */
  602. NSArray * itemsArr = item[@"arr_val"];
  603. NSMutableDictionary* legend = [itemsArr objectAtIndex:index];
  604. NSString *kpi_name = [item objectForKey:@"name"];
  605. NSString *sector = [legend objectForKey:@"full_title"];
  606. NSString *module_name = [item objectForKey:@"module_name"];
  607. if (kpi_name == nil) {
  608. kpi_name = @"";
  609. }
  610. if (sector == nil) {
  611. sector = @"";
  612. }
  613. if (module_name == nil) {
  614. module_name = @"";
  615. }
  616. NSMutableDictionary *params = [@{
  617. @"is_kpi" : @(YES),
  618. @"name" : kpi_name,
  619. @"sector": sector,
  620. @"module_name" : module_name
  621. } mutableCopy];
  622. // AMResultViewController *resultVC = [[AMResultViewController alloc] initWithNibName:@"Result" bundle:nil];
  623. // resultVC.params = params;
  624. // [self.navigationController pushViewController:resultVC animated:YES];
  625. ApexResultViewController *vc = [ApexResultViewController resultViewController:params];
  626. [self.navigationController pushViewController:vc animated:YES];
  627. }
  628. #pragma mark - FlowLayout Delegate
  629. - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  630. return collectionView.bounds.size;
  631. }
  632. - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
  633. return 0.0f;
  634. }
  635. - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
  636. return 0.0f;
  637. }
  638. #pragma mark - ScrollViewDelegate
  639. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  640. if (scrollView != self.shipTableView && [scrollView isKindOfClass:[UICollectionView class]]) {
  641. UICollectionView *collectionView = (UICollectionView *)scrollView;
  642. CGFloat w = scrollView.bounds.size.width;
  643. CGFloat offsetX = scrollView.contentOffset.x;
  644. float f = floorf(offsetX / w);
  645. NSInteger index = floorf(f + 0.5);
  646. NSInteger cur = index;
  647. if (index == 0) {
  648. cur = self.KPIArray.count;
  649. [collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:cur inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
  650. } else if (index == self.KPIArray.count + 1) {
  651. cur = 1;
  652. [collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:cur inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
  653. } else {
  654. cur = index;
  655. }
  656. }
  657. }
  658. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  659. if (scrollView != self.shipTableView && [scrollView isKindOfClass:[UICollectionView class]]) {
  660. // UICollectionView *collectionView = (UICollectionView *)scrollView;
  661. CGFloat w = scrollView.bounds.size.width;
  662. CGFloat offsetX = scrollView.contentOffset.x;
  663. float f = floorf(offsetX / w);
  664. NSInteger index = floorf(f + 0.5);
  665. NSInteger cur = index;
  666. if (index == 0) {
  667. cur = self.KPIArray.count;
  668. } else if (index == self.KPIArray.count + 1) {
  669. cur = 1;
  670. } else {
  671. cur = index;
  672. }
  673. self.currentKPI = cur;
  674. if (self.currentKPI > 0) {
  675. NSString *str = [NSString stringWithFormat:@"%ld / %ld",self.currentKPI,self.KPIArray.count];
  676. self.parentViewController.title = str;
  677. } else {
  678. self.currentKPI = 1;
  679. }
  680. }
  681. }
  682. #pragma mark - Map
  683. - (NSDictionary *)fakeLoaction {
  684. NSArray *arr = [ApexMobileDB get_Location];
  685. NSMutableDictionary *returnDic = [NSMutableDictionary dictionary];
  686. for (int i = 0; i < arr.count ; i ++) {
  687. NSDictionary* location = arr[i];
  688. NSString* area = [location valueForKey:@"area"];
  689. NSString* company = [location valueForKey:@"company"];
  690. // NSString* city = [location valueForKey:@"city"];
  691. NSString *longitude = [location valueForKey:@"longitude"];
  692. NSString *latitude = [location valueForKey:@"latitude"];
  693. NSDictionary *dic = @{
  694. @"addr" : area,
  695. @"name" : company,
  696. @"lon" : longitude,
  697. @"lat" : latitude
  698. };
  699. if (i == 0) {
  700. [returnDic setObject:dic forKey:@"pol"];
  701. } else if (i == 1) {
  702. [returnDic setObject:dic forKey:@"pod"];
  703. } else if (i == 2) {
  704. [returnDic setObject:dic forKey:@"poe"];
  705. } else if (i == 3) {
  706. [returnDic setObject:dic forKey:@"por"];
  707. } else if (i == 4) {
  708. [returnDic setObject:dic forKey:@"origin"];
  709. } else if (i == 5) {
  710. [returnDic setObject:dic forKey:@"destination"];
  711. } else if (i == 6) {
  712. [returnDic setObject:dic forKey:@"current"];
  713. } else {
  714. break;
  715. }
  716. }
  717. return returnDic;
  718. }
  719. - (void)setSelectedIndexPath:(NSIndexPath *)indexPath shipCell:(ShipingStatusCell *)shipCell {
  720. if (indexPath == nil) {
  721. return;
  722. }
  723. if (self.iconSelectedIndexPath) {
  724. ShipingStatusCell *cell = [self.shipTableView cellForRowAtIndexPath:self.iconSelectedIndexPath];
  725. [cell setIconSelect:NO];
  726. }
  727. self.iconSelectedIndexPath = indexPath;
  728. ShipingStatusCell *cell = [self.shipTableView cellForRowAtIndexPath:indexPath];
  729. if (cell == nil) { // 滑动过程中,dequeue方法中设置选中
  730. cell = shipCell;
  731. }
  732. [self.shipTableView selectRowAtIndexPath:self.iconSelectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
  733. [cell setIconSelect:YES];
  734. }
  735. - (void)showMapAnnotaionWithIndexPath:(NSIndexPath *)indexPath {
  736. if(self.shipArray.count==0)
  737. return;
  738. NSDictionary *item = [self.shipArray objectAtIndex:indexPath.section];
  739. NSDictionary *locationInfo = [item objectForKey:@"locations"];
  740. NSString* port = @"";
  741. if([item[@"location_eta"] boolValue])
  742. port=@"pod";
  743. else
  744. if([item[@"location_etd"] boolValue])
  745. port=@"pol";
  746. [self.mapView showShipAnnotaion:locationInfo backupLocation:port];
  747. }
  748. #pragma mark - ShipCell Delegate
  749. - (void)shipCellDidTapIcon:(ShipingStatusCell *)cell {
  750. NSIndexPath *indexPath = [self.shipTableView indexPathForCell:cell];
  751. [self setSelectedIndexPath:indexPath shipCell:cell];
  752. [self showMapAnnotaionWithIndexPath:indexPath];
  753. }
  754. #pragma mark - ShipMap Delegate
  755. - (void)shipMap:(AMShipMap *)shipMap tryToZoomIn:(BOOL)zoomIn {
  756. if (zoomIn) {
  757. NSArray *constraints = self.ShipContainer.constraints;
  758. NSLayoutConstraint *h_ratio_constraint = nil;
  759. for (NSLayoutConstraint *constraint in constraints) {
  760. if (constraint.identifier && [constraint.identifier isEqualToString:@"map_height_ratio"]) {
  761. h_ratio_constraint = constraint;
  762. }
  763. }
  764. if (h_ratio_constraint) {
  765. [self.ShipContainer removeConstraint:h_ratio_constraint];
  766. }
  767. NSLayoutConstraint *table_h_constraint = [NSLayoutConstraint constraintWithItem:self.shipTableView
  768. attribute:NSLayoutAttributeHeight
  769. relatedBy:NSLayoutRelationEqual
  770. toItem:nil
  771. attribute:NSLayoutAttributeNotAnAttribute
  772. multiplier:0
  773. constant:120.0f];
  774. table_h_constraint.identifier = @"ship_table_height";
  775. [self.ShipContainer addConstraint:table_h_constraint];
  776. } else {
  777. NSArray *constraints = self.ShipContainer.constraints;
  778. NSLayoutConstraint *h_constraint = nil;
  779. for (NSLayoutConstraint *constraint in constraints) {
  780. if (constraint.identifier && [constraint.identifier isEqualToString:@"ship_table_height"]) {
  781. h_constraint = constraint;
  782. }
  783. }
  784. if (h_constraint) {
  785. [self.ShipContainer removeConstraint:h_constraint];
  786. }
  787. float h_ratio = 0.5;
  788. NSLayoutConstraint *h_ratio_constraint = [NSLayoutConstraint constraintWithItem:shipMap
  789. attribute:NSLayoutAttributeHeight
  790. relatedBy:NSLayoutRelationEqual
  791. toItem:self.shipTableView
  792. attribute:NSLayoutAttributeHeight
  793. multiplier:h_ratio
  794. constant:0];
  795. h_ratio_constraint.identifier = @"map_height_ratio";
  796. [self.ShipContainer addConstraint:h_ratio_constraint];
  797. }
  798. [self.ShipContainer layoutIfNeeded];
  799. }
  800. @end