TheoryTrainVC.m 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. //
  2. // TheoryTrainVC.m
  3. // jiaPeiC
  4. //
  5. // Created by apple on 2017/2/6.
  6. // Copyright © 2017年 JCZ. All rights reserved.
  7. //
  8. #define dingColor [UIColor colorWithRed:236/255.0 green:190/255.0 blue:44/255.0 alpha:1]
  9. #import "TheoryTrainVC.h"
  10. #import "STButton.h"
  11. #import "Tools.h"
  12. #import "DES3Util.h"
  13. #import "UIImageView+WebCache.h"
  14. #import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
  15. #import <BaiduMapAPI_Search/BMKSearchComponent.h>//引入检索功能所有的头文件
  16. #import <BMKLocationKit/BMKLocationComponent.h>//引入定位功能所有的头文件
  17. @interface TheoryTrainVC ()<BMKMapViewDelegate,BMKLocationManagerDelegate,BMKGeoCodeSearchDelegate,UITableViewDelegate,UITableViewDataSource,UIAlertViewDelegate,UIActionSheetDelegate>
  18. {
  19. UILabel *addressLabel,*detailAddressLabel;
  20. UIButton *locationBtn;//签到/签退
  21. UITableView *mainTableView;//地点微调tbvc
  22. UIButton *ModeifyAddressbtn;//地点微调
  23. UITableView *studentListTV;//学员信息tbvc
  24. NSMutableArray *_dataurce;//学员信息
  25. UIView *scanView;//二维码视图
  26. UILabel *scanTypeLable;//二维码标题
  27. UILabel *timerLabel;//二维码计时lable
  28. UIImageView *scanImgView;//二维码图片
  29. NSTimer *timer;
  30. //地图定位
  31. BMKLocationManager *_locService;
  32. BMKMapView *_mapView;
  33. BMKGeoCodeSearch *_searcher;
  34. //数据
  35. NSArray *poiInfos;
  36. CLLocationCoordinate2D myLocation;
  37. NSString *scanType;//类型,1签到,2签退,3过程验证
  38. int timeI;//二维码有效时间限制
  39. int timePlayAudio;//通知提醒时间间隔(由教练签到接口返回)
  40. NSInteger currentState;//nil(0)未签到 1实操APP 2模拟 3实操终端 4集中培训 自定义100表示获取失败
  41. }
  42. @property (nonatomic, strong) BMKUserLocation *userLocation;//当前位置对象
  43. @end
  44. @implementation TheoryTrainVC
  45. - (void)viewDidLoad {
  46. [super viewDidLoad];
  47. [self.view setBackgroundColor:backGroundColor];
  48. self.navigationController.navigationBar.translucent = NO;
  49. if (_isNotification == NO)
  50. {
  51. //正常状态
  52. [self configNavBar];
  53. }
  54. else
  55. {
  56. //推送状态 要将根视图变回去
  57. UIBarButtonItem* backBtn = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back.png"] style:UIBarButtonItemStylePlain target:self action:@selector(dismissNavgation)];
  58. [backBtn setTintColor:defGreen];
  59. [self.navigationItem setLeftBarButtonItem:backBtn];
  60. }
  61. _dataurce = [[NSMutableArray alloc]init];
  62. poiInfos = [[NSMutableArray alloc]init];
  63. currentState = 100;//未获取当前状态
  64. scanType = @"";
  65. timeI = 60*60*24;//不可以太小
  66. NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
  67. timePlayAudio = [[ud objectForKey:@"timePlayAudio"] intValue];
  68. [self myInit];
  69. //获取带教/签到状态
  70. [self getCoachSignStatus];
  71. [self getStudentTheoryClassesListWithOver:NO];
  72. }
  73. -(void)dismissNavgation
  74. {
  75. [myDelegate gotoLoad];
  76. }
  77. -(void)viewWillAppear:(BOOL)animated
  78. {
  79. [super viewWillAppear:animated];
  80. [_mapView viewWillAppear];
  81. _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
  82. _searcher.delegate = self;
  83. _locService.delegate = self;
  84. }
  85. -(void)viewWillDisappear:(BOOL)animated
  86. {
  87. [super viewWillDisappear:animated];
  88. [_mapView viewWillDisappear];
  89. _mapView.delegate = nil; // 不用时,置nil
  90. _searcher.delegate = nil;
  91. _locService.delegate = nil;
  92. }
  93. -(void)viewDidDisappear:(BOOL)animated{
  94. [super viewDidDisappear:animated];
  95. if (currentState == 0 && timer) {
  96. [timer invalidate];
  97. timer = nil;
  98. }
  99. }
  100. - (void)didReceiveMemoryWarning {
  101. [super didReceiveMemoryWarning];
  102. }
  103. -(void)myInit
  104. {
  105. UILabel *label;
  106. CGFloat x, y, w, h;
  107. x = 20;
  108. y = 0;
  109. w = (kSize.width - 40)/2.0;
  110. h = 60;
  111. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  112. [formatter setDateFormat:@"yyyy.MM.dd-HH:mm-EEEE"];
  113. NSString *dateString = [formatter stringFromDate:[NSDate date]];
  114. //NSLog(@"dateString---->%@",dateString);
  115. NSArray *dateArray = [NSArray arrayWithObjects:@"暂无",@"暂无",@"暂无", nil];
  116. if (dateString.length > 0) {
  117. if ([dateString containsString:@"-"]) {
  118. dateArray = [dateString componentsSeparatedByString:@"-"];
  119. }
  120. }
  121. label = [[UILabel alloc] setxywh];
  122. [label setText:[NSString stringWithFormat:@"%@ : %@",[dateArray lastObject],[dateArray firstObject]] Font:Font21 TextColor:contentTextColor Alignment:NSTextAlignmentLeft];
  123. [self.view addSubview:label];
  124. x += w;
  125. h = 60;
  126. label = [[UILabel alloc] setxywh];
  127. [label setText:[NSString stringWithFormat:@"上课时间:%@\n下课时间:%@",self.startTime,self.endTime] Font:Font17 TextColor:contentTextColor Alignment:NSTextAlignmentRight];
  128. label.numberOfLines = 0;
  129. [self.view addSubview:label];
  130. // y += h;
  131. // label = [[UILabel alloc] setxywh];
  132. // [label setText:[NSString stringWithFormat:@"下课时间: %@",self.endTime] Font:Font18 TextColor:contentTextColor Alignment:NSTextAlignmentRight];
  133. // [self.view addSubview:label];
  134. x = 20;
  135. y += h;
  136. w = kSize.width - 40;
  137. h = 100;
  138. UIView *mapBar = [[UIView alloc] setxywh];
  139. [mapBar borderColor:lineColor width:2 cornorRadios:0];
  140. mapBar.clipsToBounds = YES;;
  141. [self.view addSubview:mapBar];
  142. x = y = 0;
  143. w = 110;
  144. h = 122;
  145. //创建地图
  146. _mapView = [[BMKMapView alloc]setxywh];
  147. [mapBar addSubview:_mapView];
  148. [_mapView addViewWithRect:CGRectMake(x + w, y, 2, h)];
  149. _mapView.mapType = BMKMapTypeStandard;
  150. //定位功能
  151. _locService = [[BMKLocationManager alloc]init];
  152. _locService.distanceFilter = 10;
  153. [_locService startUpdatingLocation];
  154. //地理位置反编码
  155. _searcher =[[BMKGeoCodeSearch alloc]init];
  156. //这个设置重复是为了消除一个bug 记得
  157. _mapView.showsUserLocation = NO;
  158. _mapView.userTrackingMode = BMKUserTrackingModeNone;
  159. _mapView.zoomLevel = 16;
  160. _mapView.showsUserLocation = YES;
  161. BMKLocationViewDisplayParam *displayParam = [[BMKLocationViewDisplayParam alloc]init];
  162. displayParam.isRotateAngleValid = true;//跟随态旋转角度是否生效
  163. displayParam.isAccuracyCircleShow = false;//精度圈是否显示
  164. displayParam.locationViewOffsetX = 0;//定位偏移量(经度)
  165. displayParam.locationViewOffsetY = 0;//定位偏移量(纬度)
  166. [_mapView updateLocationViewWithParam:displayParam];
  167. x += w + 5;
  168. w = kSize.width - 40 - 115;
  169. h = 25;
  170. label = [[UILabel alloc] setxywh];
  171. [label setText:@"正在定位..." Font:Font18 TextColor:titleColor Alignment:NSTextAlignmentLeft];
  172. [mapBar addSubview:label];
  173. addressLabel = label;
  174. y += h;
  175. h = 50;
  176. label = [[UILabel alloc] setxywh];
  177. [label setText:@"" Font:Font21 TextColor:contentTextColor Alignment:NSTextAlignmentLeft];
  178. label.numberOfLines = 0;
  179. [mapBar addSubview:label];
  180. detailAddressLabel = label;
  181. y += h;
  182. h = 20;
  183. UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
  184. btn.frame = CGRectMake(x, y, w, h);
  185. [btn setTitle:@"地点微调" textColor:[UIColor blueColor] font:Font18 fotState:UIControlStateNormal];
  186. [btn setTitle:@"取消微调" forState:UIControlStateSelected];
  187. btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
  188. [btn.titleLabel setTextAlignment:NSTextAlignmentLeft];
  189. [btn target:self Tag:1];
  190. [mapBar addSubview:btn];
  191. ModeifyAddressbtn = btn;
  192. x = 20;
  193. y = mapBar.y +mapBar.height + 10;
  194. w = kSize.width - 40;
  195. h = 40;
  196. locationBtn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, w, h)];
  197. [locationBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  198. [locationBtn setTitle:@"签到" textColor:dingColor font:20 fotState:UIControlStateNormal];
  199. [locationBtn setTitle:@"签退" textColor:dingColor font:20 fotState:UIControlStateSelected];
  200. [locationBtn borderColor:dingColor width:1 cornorRadios:5];
  201. locationBtn.userInteractionEnabled = NO;
  202. [locationBtn target:self Tag:2];
  203. [self.view addSubview:locationBtn];
  204. y += h+10;
  205. CGFloat bd = 20;
  206. w = (kSize.width-40-bd*2)/3;
  207. NSArray *scanTitles = @[@"学员签到",@"学员签退",@"过程验证"];
  208. for (int i=0; i<3; i++) {
  209. x = 20+i*(w + bd);
  210. btn = [UIButton buttonWithType:UIButtonTypeCustom];
  211. btn.frame = CGRectMake(x, y, w, h);
  212. [btn setTitle:scanTitles[i] textColor:lineColor font:20 fotState:UIControlStateNormal];
  213. [btn borderColor:lineColor width:1 cornorRadios:5];
  214. [btn target:self Tag:100+i];
  215. btn.userInteractionEnabled = NO;
  216. [self.view addSubview:btn];
  217. }
  218. y += h + 10;
  219. h = kSize.height - y - 64;
  220. studentListTV = [[UITableView alloc] initWithFrame:CGRectMake(0, y, kSize.width, h) style:UITableViewStylePlain];
  221. studentListTV.delegate = self;
  222. studentListTV.dataSource = self;
  223. studentListTV.tag = 2;
  224. studentListTV.tableFooterView = [UIView new];
  225. UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kSize.width, 40)];
  226. headerView.backgroundColor = lineColor;
  227. UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, kSize.width - 20, 30)];
  228. [headerLabel setText:@"班级学员列表" Font:Font21 TextColor:[UIColor orangeColor] Alignment:NSTextAlignmentLeft];
  229. [headerView addSubview:headerLabel];
  230. [studentListTV setTableHeaderView:headerView];
  231. [self.view addSubview:studentListTV];
  232. y = mapBar.y +mapBar.height;
  233. h = kSize.height - y - kNavOffSet;
  234. mainTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, y, kSize.width, h) style:UITableViewStylePlain];
  235. mainTableView.delegate = self;
  236. mainTableView.dataSource = self;
  237. mainTableView.tag = 1;
  238. [self.view addSubview:mainTableView];
  239. mainTableView.hidden = YES;
  240. }
  241. -(void)btnClick:(UIButton *)sender
  242. {
  243. if (sender.tag == 1) {
  244. //微调
  245. sender.selected = !sender.selected;
  246. if (sender.selected) {
  247. mainTableView.hidden = NO;
  248. [mainTableView reloadData];
  249. }else{
  250. mainTableView.hidden = YES;
  251. }
  252. return;
  253. }
  254. if (sender.tag == 2) {
  255. if (sender.selected) {
  256. //签退
  257. }else{
  258. //签到
  259. if (currentState == 100) {
  260. //获取带教/签到状态
  261. [self getCoachSignStatus];
  262. return;
  263. }
  264. if (currentState) {
  265. ShowMsg(@"当前正在进行其它(实操/模拟)计时,请结束后再进行理论计时");
  266. return;
  267. }
  268. if (!myLocation.latitude) {
  269. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"未获取到当前位置" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:@"再试一次", nil];
  270. [alert show];
  271. return;
  272. }
  273. }
  274. [self uploadAppSignInfo];
  275. return;
  276. }
  277. //生成二维码
  278. switch (sender.tag) {
  279. case 100:
  280. {
  281. BOOL isNeed = YES;
  282. for (NSDictionary *dic in _dataurce) {
  283. if ([[NSString stringWithFormat:@"%@",dic[@"STATUS"]] integerValue] == 1) {
  284. isNeed = NO;
  285. break;
  286. }
  287. }
  288. if (isNeed) {
  289. [self removeAllTheoryNotify];//先移除已经存在的
  290. [self addLocalNotification];//开启本地通知提醒
  291. }
  292. scanType = @"1";
  293. [self getQrcode];
  294. }
  295. break;
  296. case 101:
  297. {
  298. scanType = @"2";
  299. [self getQrcode];
  300. }
  301. break;
  302. case 102:
  303. {
  304. scanType = @"3";
  305. [self getQrcode];
  306. }
  307. break;
  308. default:
  309. break;
  310. }
  311. }
  312. -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
  313. {
  314. if (buttonIndex == 0) {
  315. }else{
  316. if (_locService) {
  317. //前面定位无数据,定位再试一次
  318. [_locService stopUpdatingLocation];
  319. [_locService startUpdatingLocation];
  320. }
  321. }
  322. }
  323. #pragma mark tableView delegate
  324. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  325. {
  326. if (tableView.tag == 1) {
  327. return poiInfos.count;
  328. }else{
  329. return _dataurce.count;
  330. }
  331. }
  332. -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  333. {
  334. if (tableView.tag == 1) {
  335. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
  336. if (cell == nil)
  337. {
  338. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
  339. }
  340. BMKPoiInfo *poiInfo = poiInfos[indexPath.row];
  341. cell.textLabel.text = poiInfo.name;
  342. cell.textLabel.textColor = titleColor;
  343. cell.textLabel.font = [UIFont scaleSize:Font18];
  344. cell.detailTextLabel.text = poiInfo.address;
  345. cell.detailTextLabel.textColor = contentTextColor;
  346. cell.detailTextLabel.font = [UIFont scaleSize:Font18];
  347. return cell;
  348. }else{
  349. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellid"];
  350. if (!cell) {
  351. cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cellid"];
  352. }
  353. cell.textLabel.text = [NSString stringWithFormat:@"%@",_dataurce[indexPath.row][@"TSC_STUDENT_NAME"]];
  354. NSString *stuStr = @"";
  355. switch ([[NSString stringWithFormat:@"%@",_dataurce[indexPath.row][@"STATUS"]] integerValue]) {
  356. case 0:
  357. stuStr = @"未学习";
  358. cell.detailTextLabel.textColor = contentTextColor;
  359. break;
  360. case 1:
  361. stuStr = @"学习中";
  362. cell.detailTextLabel.textColor = dingColor;
  363. break;
  364. case 2:
  365. stuStr = @"学习结束";
  366. cell.detailTextLabel.textColor = contentTextColor;
  367. break;
  368. default:
  369. break;
  370. }
  371. cell.detailTextLabel.text = stuStr;
  372. return cell;
  373. }
  374. }
  375. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  376. {
  377. if (tableView.tag == 1) {
  378. BMKPoiInfo *info = poiInfos[indexPath.row];
  379. addressLabel.text = info.name;
  380. detailAddressLabel.text = info.address;
  381. _mapView.centerCoordinate = info.pt;
  382. myLocation = info.pt;
  383. //加标注之前要移除之前的
  384. if (_mapView.annotations.count > 0) {
  385. [_mapView removeAnnotations:_mapView.annotations];
  386. }
  387. //选择的位置加上标注
  388. BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];
  389. annotation.coordinate = info.pt;
  390. [_mapView addAnnotation:annotation];
  391. mainTableView.hidden = YES;
  392. ModeifyAddressbtn.selected = NO;
  393. }
  394. }
  395. #pragma mark 地图相关
  396. /**用户拒绝开启定位服务等原因导致的定位失败会调用的方法
  397. */
  398. - (void)didFailToLocateUserWithError:(NSError *)error
  399. {
  400. //[LoadingView showMsg:@"拒绝将无法自动获取当前位置!"];
  401. UIAlertView *alert =[[UIAlertView alloc]initWithTitle:@"温馨提示" message:@"请在iPhone的“设置”-“隐私”-“定位服务”功能中,找到“优易学车”打开位置访问权限" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil];
  402. [alert show];
  403. locationBtn.userInteractionEnabled = YES;
  404. }
  405. //处理位置坐标更新
  406. - (void)BMKLocationManager:(BMKLocationManager *)manager didUpdateLocation:(BMKLocation *)location orError:(NSError *)error {
  407. self.userLocation.location = location.location;
  408. if (self.userLocation.location)
  409. {
  410. [_mapView updateLocationData:self.userLocation];
  411. _mapView.centerCoordinate = self.userLocation.location.coordinate;
  412. myLocation = self.userLocation.location.coordinate;
  413. //发起反向地理编码检索
  414. BMKReverseGeoCodeSearchOption *reverseGeoCodeSearchOption = [[BMKReverseGeoCodeSearchOption alloc]init];
  415. reverseGeoCodeSearchOption.location = location.location.coordinate;
  416. [_searcher reverseGeoCode:reverseGeoCodeSearchOption];
  417. }
  418. }
  419. - (void)onGetGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKGeoCodeSearchResult *)result errorCode:(BMKSearchErrorCode)error {
  420. if (error == BMK_SEARCH_NO_ERROR) {
  421. //在此处理正常结果
  422. BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];
  423. annotation.coordinate = result.location;
  424. [_mapView addAnnotation:annotation];
  425. }
  426. else {
  427. [LoadingView showMsg:@"定位失败!"];
  428. }
  429. }
  430. //反向编码
  431. - (void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeSearchResult *)result errorCode:(BMKSearchErrorCode)error {
  432. searcher.delegate = nil;
  433. locationBtn.userInteractionEnabled = YES;
  434. if (error == BMK_SEARCH_NO_ERROR)
  435. {
  436. // 商业圈 businessCircle
  437. // 街道号码 streetNumber
  438. // 街道名称 streetName
  439. // 区县名称 district
  440. // 城市名称 city
  441. // 省份名称 province;
  442. // 地址全称 address
  443. //地址周边POI信息,成员类型为BMKPoiInfo poiList
  444. /*
  445. NSString* _name; ///<POI名称
  446. NSString* _uid;
  447. NSString* _address; ///<POI地址
  448. NSString* _city; ///<POI所在城市
  449. NSString* _phone; ///<POI电话号码
  450. NSString* _postcode; ///<POI邮编
  451. int _epoitype; ///<POI类型,0:普通点 1:公交站 2:公交线路 3:地铁站 4:地铁线路
  452. CLLocationCoordinate2D _pt; ///<POI坐标
  453. */
  454. //NSLog(@"---->%@---->%@---->%@---->%@---->%@---->%@----->%@",result.addressDetail.streetNumber,result.addressDetail.streetName,result.addressDetail.district,result.addressDetail.city,result.addressDetail.province,result.address,result.poiList);
  455. //在此处理正常结果
  456. addressLabel.text = [NSString stringWithFormat:@"%@%@%@",result.addressDetail.district,result.addressDetail.streetName,result.addressDetail.streetNumber];
  457. //默认这个地址作为签到地址
  458. detailAddressLabel.text = result.address;
  459. //将周边存起来 微调的时候用
  460. poiInfos = result.poiList;
  461. }
  462. else
  463. {
  464. //[LoadingView showMsg:@"编译位置失败!"];
  465. }
  466. }
  467. //标注的代理
  468. -(BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation
  469. {
  470. if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
  471. BMKPinAnnotationView *newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"];
  472. newAnnotationView.pinColor = BMKPinAnnotationColorPurple;
  473. // 设置该标注点动画显示
  474. newAnnotationView.animatesDrop = NO;
  475. return newAnnotationView;
  476. }
  477. return nil;
  478. }
  479. #pragma mark 生成二维码
  480. -(void)makeScanViewWithScanString:(NSString *)qgStr
  481. {
  482. //生成二维码
  483. NSString *typeStr = @"";
  484. NSString *signType = @"";
  485. switch ([scanType integerValue]) {
  486. case 1:
  487. {
  488. typeStr = @"groupSignIn";
  489. signType = @"学员签到二维码";
  490. if (!timer) {
  491. timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeRun) userInfo:nil repeats:YES];
  492. [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
  493. }
  494. }
  495. break;
  496. case 2:
  497. typeStr = @"groupSignOut";
  498. signType = @"学员签退二维码";
  499. break;
  500. case 3:
  501. {
  502. typeStr = @"groupSignProceed";
  503. signType = @"学员过程验证二维码";
  504. }
  505. break;
  506. default:
  507. break;
  508. }
  509. NSString *scanString = [NSString stringWithFormat:@"#LNJP#;%@;%@",typeStr,[DES3Util decrypt:qgStr]];
  510. // NSLog(@"加密前---><>%@",scanString);
  511. scanString = [DES3Util encrypt:scanString];
  512. scanString = [NSString stringWithFormat:@"#DECODE#%@",scanString];
  513. UIImage *qrcode = [self createNonInterpolatedUIImageFormCIImage:[self createQRForString:scanString] withSize:250.0f];
  514. qrcode = [self addIconToQRCodeImage:qrcode withIcon:[UIImage imageNamed:@"loginLogo"] withIconSize:CGSizeMake(40, 40)];
  515. //非第一次,只需更新img
  516. if (scanView) {
  517. if (!scanView.superview) {
  518. [self.view addSubview:scanView];
  519. }
  520. scanTypeLable.text = signType;
  521. timerLabel.text = [NSString stringWithFormat:@"二维码有效时间:%d:%d",timeI/60,timeI%60];
  522. scanImgView.image = qrcode;
  523. return;
  524. }
  525. CGFloat x,y,w,h;
  526. x = 20;
  527. y = 100;
  528. w = kSize.width - 40;
  529. h = kSize.width + 20;
  530. scanView = [[UIView alloc] setxywh];
  531. scanView.backgroundColor = [UIColor whiteColor];
  532. [scanView borderColor:lineColor width:1 cornorRadios:5];
  533. [self.view addSubview:scanView];
  534. x = 0;
  535. y = 0;
  536. h = 30;
  537. UILabel *label = [[UILabel alloc] setxywh];
  538. [label setText:signType Font:Font16 TextColor:[UIColor orangeColor] Alignment:NSTextAlignmentCenter];
  539. [scanView addSubview:label];
  540. scanTypeLable = label;
  541. x = (w - 250)/2.0;
  542. y += h + 10;
  543. w = h = 250;
  544. scanImgView = [[UIImageView alloc] setxywh];
  545. scanImgView.image = qrcode;
  546. [scanView addSubview:scanImgView];
  547. x = 0;
  548. y += h + 10;
  549. w = kSize.width - 40;
  550. h =30;
  551. label = [[UILabel alloc] setxywh];
  552. [label setText:[NSString stringWithFormat:@"二维码有效时间:%d:%d",timeI/60,timeI%60] Font:Font16 TextColor:[UIColor orangeColor] Alignment:NSTextAlignmentCenter];
  553. [scanView addSubview:label];
  554. timerLabel = label;
  555. UIImageView *cancelImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cancel"]];
  556. cancelImg.frame = CGRectMake(w - 25, 5, 20, 20);
  557. [scanView addSubview:cancelImg];
  558. UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
  559. btn.frame = CGRectMake(w - 50, 0, 50, 50);
  560. btn.backgroundColor = [UIColor clearColor];
  561. [btn addTarget:self action:@selector(removeScanView) forControlEvents:UIControlEventTouchUpInside];
  562. [scanView addSubview:btn];
  563. }
  564. -(void)removeScanView
  565. {
  566. [scanView removeFromSuperview];
  567. [self getStudentTheoryClassesListWithOver:YES];
  568. }
  569. //二维码的验证
  570. -(void)timeRun
  571. {
  572. timeI --;
  573. timerLabel.text = [NSString stringWithFormat:@"二维码有效时间:%d:%d",timeI/60,timeI%60];
  574. if (timeI == 0) {
  575. //重新生成二维码
  576. [self getQrcode];
  577. }
  578. }
  579. - (CIImage *)createQRForString:(NSString *)qrString {
  580. NSData *stringData = [qrString dataUsingEncoding:NSUTF8StringEncoding];
  581. // 创建filter
  582. CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
  583. // 设置内容和纠错级别
  584. [qrFilter setValue:stringData forKey:@"inputMessage"];
  585. [qrFilter setValue:@"M" forKey:@"inputCorrectionLevel"];
  586. // 返回CIImage
  587. return qrFilter.outputImage;
  588. }
  589. - (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat) size {
  590. CGRect extent = CGRectIntegral(image.extent);
  591. CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
  592. // 创建bitmap;
  593. size_t width = CGRectGetWidth(extent) * scale;
  594. size_t height = CGRectGetHeight(extent) * scale;
  595. CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
  596. CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
  597. CIContext *context = [CIContext contextWithOptions:nil];
  598. CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
  599. CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
  600. CGContextScaleCTM(bitmapRef, scale, scale);
  601. CGContextDrawImage(bitmapRef, extent, bitmapImage);
  602. // 保存bitmap到图片
  603. CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
  604. CGColorSpaceRelease(cs);
  605. CGContextRelease(bitmapRef);
  606. CGImageRelease(bitmapImage);
  607. UIImage * newImage = (UIImage *)[UIImage imageWithCGImage:scaledImage];
  608. CGImageRelease(scaledImage);
  609. return newImage;
  610. }
  611. -(UIImage *)addIconToQRCodeImage:(UIImage *)image withIcon:(UIImage *)icon withIconSize:(CGSize)iconSize {
  612. UIGraphicsBeginImageContext(image.size);
  613. //通过两张图片进行位置和大小的绘制,实现两张图片的合并;其实此原理做法也可以用于多张图片的合并
  614. CGFloat widthOfImage = image.size.width;
  615. CGFloat heightOfImage = image.size.height;
  616. CGFloat widthOfIcon = iconSize.width;
  617. CGFloat heightOfIcon = iconSize.height;
  618. [image drawInRect:CGRectMake(0, 0, widthOfImage, heightOfImage)];
  619. [icon drawInRect:CGRectMake((widthOfImage-widthOfIcon)/2, (heightOfImage-heightOfIcon)/2,
  620. widthOfIcon, heightOfIcon)];
  621. UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
  622. UIGraphicsEndImageContext();
  623. return img;
  624. }
  625. #pragma mark - 添加本地通知
  626. -(void)addLocalNotification{
  627. //下课时间
  628. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  629. [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  630. NSString *nowStr = [dateFormatter stringFromDate:[NSDate date]];
  631. NSDate *endDate = [dateFormatter dateFromString:[NSString stringWithFormat:@"%@ %@:00",[nowStr substringToIndex:10],self.endTime]];
  632. for (int i=1; i<=60*60*4/timePlayAudio; i++) {
  633. //定义本地通知对象
  634. UILocalNotification *notification=[[UILocalNotification alloc]init];
  635. //设置调用时间
  636. notification.fireDate=[NSDate dateWithTimeIntervalSinceNow:timePlayAudio*i];
  637. NSTimeInterval subT = [endDate timeIntervalSinceDate:notification.fireDate];
  638. if (subT < 0) {
  639. NSLog(@"%@,%@",notification.fireDate,[NSDate dateWithTimeIntervalSinceNow:timePlayAudio*i]);
  640. break;
  641. }
  642. //设置通知属性
  643. notification.alertBody=@"请提醒学员扫描过程验证二维码"; //通知主体
  644. notification.applicationIconBadgeNumber=1;//应用程序图标右上角显示的消息数
  645. notification.alertAction=@"打开应用"; //待机界面的滑动动作提示
  646. notification.soundName=@"TheoryNotify.mp3";//收到通知时播放的声音,默认消息声音
  647. // 通知参数
  648. NSDictionary *userDict = [NSDictionary dictionaryWithObjectsAndKeys:self.classId,@"theoryTrainVC_classId",self.schoolId,@"theoryTrainVC_schoolId", nil];
  649. notification.userInfo = userDict;
  650. //调用通知
  651. [[UIApplication sharedApplication] scheduleLocalNotification:notification];
  652. }
  653. }
  654. -(void)removeAllTheoryNotify{
  655. NSArray *notifiArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
  656. for (UILocalNotification *local in notifiArray) {
  657. if (local.userInfo[@"theoryTrainVC_classId"]) {
  658. //删除单个通知
  659. [[UIApplication sharedApplication]cancelLocalNotification:local];
  660. }
  661. }
  662. }
  663. #pragma mark 数据请求
  664. - (void)getCoachSignStatus
  665. {
  666. [LoadingView showHUD];
  667. if (![Util connectedToNetWork]) {
  668. showMsgUnconnect();
  669. return;
  670. }
  671. NSMutableArray *arr=[NSMutableArray array];
  672. [arr addPro:@"coachOutId" Value:defUser.userDict[@"outId"]];
  673. [arr addPro:@"dqbh" Value:defUser.userDict[@"cityId"]];
  674. NSString* method = @"getCoachSignStatus";
  675. [jiaPeiManager requestAnythingWithURL:method array:arr data:nil completion:^(NSDictionary * root) {
  676. RemoveHUD();
  677. if (!root) {
  678. return;
  679. }
  680. if ([root[@"code"] isEqualToString:@"1"]) {
  681. ShowMsg(root[@"body"]);
  682. return;
  683. }
  684. NSInteger states = [root[@"body"] integerValue];
  685. if (!states) {
  686. states = 0;
  687. }
  688. //0未签到 1实操APP 2模拟 3实操终端 4集中培训
  689. if (states == 2 || states == 3) {
  690. UIAlertController *alertFind = [UIAlertController alertControllerWithTitle:nil message:@"当前正在进行其它(实操/模拟)计时,请结束后再进行理论计时" preferredStyle:UIAlertControllerStyleAlert];
  691. [alertFind addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  692. [self.navigationController popViewControllerAnimated:YES];
  693. }]];
  694. [self presentViewController:alertFind animated:true completion:nil];
  695. }else{
  696. locationBtn.selected = states;
  697. for (int i=100; i<103; i++) {
  698. UIButton *scanBtn = (UIButton *)[self.view viewWithTag:i];
  699. if (locationBtn.selected) {
  700. //签到状态
  701. [scanBtn setTitleColor:dingColor forState:UIControlStateNormal];
  702. scanBtn.layer.borderColor = dingColor.CGColor;
  703. scanBtn.userInteractionEnabled = YES;
  704. }else{
  705. //签退状态
  706. [scanBtn setTitleColor:lineColor forState:UIControlStateNormal];
  707. scanBtn.layer.borderColor = lineColor.CGColor;
  708. scanBtn.userInteractionEnabled = NO;
  709. };
  710. }
  711. }
  712. currentState = states;
  713. if (currentState == 4) {
  714. if (!timer) {
  715. timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeRun) userInfo:nil repeats:YES];
  716. [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
  717. }
  718. }
  719. }];
  720. }
  721. - (void)uploadAppSignInfo
  722. {
  723. [LoadingView showHUD];
  724. if (![Util connectedToNetWork]) {
  725. showMsgUnconnect();
  726. return;
  727. }
  728. NSString *type = locationBtn.selected ? @"2" : @"1";
  729. NSMutableArray *arr = [[NSMutableArray alloc]init];
  730. [arr addPro:@"dqbh" Value:defUser.userDict[@"cityId"]];
  731. [arr addPro:@"classId" Value:self.classId];
  732. [arr addPro:@"coachOutid" Value:defUser.userDict[@"outId"]];
  733. [arr addPro:@"schoolOutid" Value:self.schoolId];
  734. [arr addPro:@"type" Value:type];//类型,1签到,2签退
  735. [arr addPro:@"lng" Value:[NSString stringWithFormat:@"%f",myLocation.longitude]];
  736. [arr addPro:@"lat" Value:[NSString stringWithFormat:@"%f",myLocation.latitude]];
  737. NSString *method = @"coachTheorySign";
  738. [jiaPeiManager requestAnythingWithURL:method array:arr data:nil completion:^(NSDictionary * root) {
  739. RemoveHUD();
  740. if (!root) {
  741. if ([type isEqualToString:@"1"]) {
  742. ShowMsg(@"签到失败,请重试");
  743. [Tools playAudioWithString:@"签到失败,请虫试"];
  744. }else{
  745. ShowMsg(@"签退失败,请重试");
  746. [Tools playAudioWithString:@"签退失败,请虫试"];
  747. }
  748. return;
  749. }
  750. if (![root[@"code"] isEqualToString:@"0"]) {
  751. ShowMsg(root[@"body"]);
  752. return;
  753. }
  754. if ([type isEqualToString:@"1"]) {
  755. [Tools playAudioWithString:@"签到成功"];
  756. timePlayAudio = [root[@"body"] intValue];
  757. NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
  758. [ud setObject:[NSString stringWithFormat:@"%d",timePlayAudio] forKey:@"timePlayAudio"];
  759. [ud synchronize];
  760. }else{
  761. [Tools playAudioWithString:@"签退成功"];
  762. [self removeAllTheoryNotify];
  763. }
  764. locationBtn.selected = !locationBtn.selected;
  765. currentState = locationBtn.selected ? 4 : 0;
  766. for (int i=100; i<103; i++) {
  767. UIButton *scanBtn = (UIButton *)[self.view viewWithTag:i];
  768. if (locationBtn.selected) {
  769. [scanBtn setTitleColor:dingColor forState:UIControlStateNormal];
  770. scanBtn.layer.borderColor = dingColor.CGColor;
  771. scanBtn.userInteractionEnabled = YES;
  772. }else{
  773. [scanBtn setTitleColor:lineColor forState:UIControlStateNormal];
  774. scanBtn.layer.borderColor = lineColor.CGColor;
  775. scanBtn.userInteractionEnabled = NO;
  776. };
  777. }
  778. }];
  779. }
  780. /**
  781. 获取班级学员列表
  782. @param isOver 如果=yes,表示关闭二维码调用,需要判定是否还有学员在学习,如果没有则移除所有通知。=No表示初始化进来获取学员列表信息,无需判断是否需要移除通知,其实判断一下也是可以的,先这样吧
  783. */
  784. -(void)getStudentTheoryClassesListWithOver:(BOOL)isOver{
  785. [LoadingView showHUD];
  786. if (![Util connectedToNetWork]) {
  787. showMsgUnconnect();
  788. return;
  789. }
  790. NSMutableArray *arr = [[NSMutableArray alloc]init];
  791. [arr addPro:@"classId" Value:_classId];
  792. [arr addPro:@"dqbh" Value:defUser.userDict[@"cityId"]];
  793. NSString *method = @"getStudentTheoryClassesList";
  794. [jiaPeiManager requestAnythingWithURL:method array:arr data:nil completion:^(NSDictionary * root) {
  795. RemoveHUD();
  796. if (!root) {
  797. ShowMsg(@"数据请求失败,请重试");
  798. return;
  799. }
  800. if ([root[@"code"] integerValue] == 1) {
  801. ShowMsg(root[@"msg"]);
  802. return;
  803. }
  804. _dataurce = root[@"body"];
  805. [studentListTV reloadData];
  806. //如果二维码关闭,则判断下是否需要移除通知
  807. if (isOver) {
  808. //遍历学员,如果有任何一个学员还在学习中,我们就不移除通知提醒
  809. BOOL isNeed = YES;
  810. for (NSDictionary *dic in _dataurce) {
  811. if ([[NSString stringWithFormat:@"%@",dic[@"STATUS"]] integerValue] == 1) {
  812. isNeed = NO;
  813. break;
  814. }
  815. }
  816. if (isNeed) {
  817. [self removeAllTheoryNotify];//先移除已经存在的
  818. }
  819. }
  820. }];
  821. }
  822. -(void)getQrcode{
  823. [LoadingView showHUD];
  824. if (![Util connectedToNetWork]) {
  825. showMsgUnconnect();
  826. return;
  827. }
  828. if (!myLocation.latitude) {
  829. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"未获取到当前位置" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:@"再试一次", nil];
  830. [alert show];
  831. return;
  832. }
  833. NSMutableArray *arr = [[NSMutableArray alloc]init];
  834. [arr addPro:@"dqbh" Value:defUser.userDict[@"cityId"]];
  835. [arr addPro:@"classId" Value:self.classId];
  836. [arr addPro:@"coachOutid" Value:defUser.userDict[@"outId"]];
  837. [arr addPro:@"type" Value:scanType];//类型,1签到,2签退,3过程验证
  838. [arr addPro:@"lng" Value:[NSString stringWithFormat:@"%f",myLocation.longitude]];
  839. [arr addPro:@"lat" Value:[NSString stringWithFormat:@"%f",myLocation.latitude]];
  840. NSString *method = @"getQrcode";
  841. [jiaPeiManager requestAnythingWithURL:method array:arr data:nil completion:^(NSDictionary * root) {
  842. RemoveHUD();
  843. if (!root) {
  844. ShowMsg(@"数据请求失败,请重试");
  845. if (scanView) {
  846. [self removeScanView];
  847. }
  848. return;
  849. }
  850. if (![root[@"code"] isEqualToString:@"0"]) {
  851. ShowMsg(root[@"body"]);
  852. return;
  853. }
  854. NSArray *arr = [root[@"body"] componentsSeparatedByString:@"@@@"];
  855. timeI = [arr[0] intValue];
  856. [self makeScanViewWithScanString:arr[1]];
  857. // NSLog(@"%@--%@",root[@"body"],[DES3Util decrypt:arr[1]]);
  858. }];
  859. }
  860. #pragma mark - LazyLoad
  861. - (BMKUserLocation *)userLocation {
  862. if (!_userLocation) {
  863. _userLocation = [[BMKUserLocation alloc] init];
  864. }
  865. return _userLocation;
  866. }
  867. @end