RQExerciseSubViewController.m 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. //
  2. // RQExerciseSubViewController.m
  3. // SDJK
  4. //
  5. // Created by 张嵘 on 2021/8/12.
  6. //
  7. #import "RQExerciseSubViewController.h"
  8. #import "HWPanModal.h"
  9. @interface RQExerciseSubViewController () <DZMCoverControllerDelegate>
  10. /// viewModel
  11. @property (nonatomic, readonly, strong) RQExerciseSubViewModel *viewModel;
  12. @property (nonatomic, copy) void(^scrollCallback)(UIScrollView *scrollView);
  13. @property (nonatomic, readwrite, weak) DZMCoverController *coverVC;
  14. @property (nonatomic, readwrite, assign) NSInteger firstNum;///再次进来的第一题
  15. @property (nonatomic, readwrite, retain) FMDatabase *db;
  16. @property (nonatomic, readwrite, retain) FMDatabaseQueue *dbQueue;
  17. @property (nonatomic, readwrite, strong) RQExerciseToolBarView *exerciseToolBarView;
  18. @property (nonatomic, readwrite, strong) RQHandInThePaperView *handInThePaperView;
  19. @property (nonatomic, readwrite, strong) NSMutableArray *correctArr;
  20. @property (nonatomic, readwrite, strong) NSMutableArray *errorArr;
  21. @end
  22. @implementation RQExerciseSubViewController
  23. @dynamic viewModel;
  24. #pragma mark - SystemMethod
  25. - (void)viewDidLoad {
  26. [super viewDidLoad];
  27. /// 初始化
  28. [self rq_setup];
  29. }
  30. - (void)viewWillDisappear:(BOOL)animated {
  31. [super viewWillDisappear:animated];
  32. // int popNum = _firstNum<self.questionArr.count-1 ?_firstNum+1:(int)self.questionArr.count-1;
  33. // [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:popNum] forKey:@"QUESTIONNUM"];
  34. // [[NSUserDefaults standardUserDefaults] synchronize];
  35. }
  36. - (void)dealloc {
  37. [RQ_Exercise_Module cancleAutoReadQuestion];
  38. }
  39. #pragma mark - PrivateMethods
  40. /// 初始化
  41. - (void)rq_setup {
  42. if (self.viewModel.homeSubPageType == RQHomeSubPageType_WrongTopicAndCollection) {
  43. self.number = self.viewModel.number;
  44. self.questionArr = [NSMutableArray arrayWithArray:self.viewModel.questionArr];
  45. } else if (self.viewModel.homeSubPageType == RQHomeSubPageType_MockExamination && self.viewModel.questionArr) {
  46. self.questionArr = [NSMutableArray arrayWithArray:self.viewModel.questionArr];
  47. }
  48. ///获取数据
  49. if (self.questionArr.count==0) {
  50. // self.number = [[[NSUserDefaults standardUserDefaults] objectForKey:@"QUESTIONNUM"]intValue];
  51. self.number = 0;
  52. if (self.number!=0){
  53. NSLog(@"已自动回到上次答题位置");
  54. }
  55. [self changeCityQuestion];
  56. } else {
  57. [self creatCoverVC];
  58. [self creatToolsBar];
  59. }
  60. /// 答题结果
  61. [[[RQNotificationCenter rac_addObserverForName:RQAnswerResultsNotification object:nil] deliverOnMainThread] subscribeNext:^(NSNotification * note) {
  62. RQExerciseModel *exerciseModel = note.userInfo[RQAnswerResultsKey];
  63. RQHomePageCarType notifiCarType = [note.userInfo[RQHomePageCarTypeKey] integerValue];
  64. RQHomePageSubjectType notifiSubjectType = [note.userInfo[RQHomePageSubjectTypeKey] integerValue];
  65. RQExerciseDoType exerciseDoType = [note.userInfo[RQExerciseDoTypeKey] integerValue];
  66. if (notifiCarType != self.viewModel.homePageCarType || notifiSubjectType != self.viewModel.homePageSubjectType) {
  67. NSLog(@"重复推送");
  68. return;
  69. }
  70. [self saveTheAnswerRecordActionWithRQExerciseModel:exerciseModel];
  71. switch (exerciseModel.answerResultsType) {
  72. case RQAnswerResultsType_Correct: {
  73. if (![self.correctArr containsObject:exerciseModel]) {
  74. if (self.viewModel.exerciseType != RQExerciseType_Recitation) {
  75. [self.correctArr addObject:exerciseModel];
  76. if (exerciseDoType == RQExerciseDoType_Default && !RQ_Exercise_Module.isAutoRead) {
  77. /// 非自动读题 做对自动跳下一题
  78. [self jumpNextQuestion];
  79. }
  80. }
  81. } else {
  82. }
  83. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  84. _exerciseToolBarView.correctOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.correctArr.count];
  85. }
  86. if (RQ_Exercise_Module.isAutoRead) {
  87. if (!exerciseModel.isAuto) {
  88. ///自动读题模式下: 当前题目结束自动读题 2秒后自动跳到下一题
  89. //延时
  90. [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
  91. [subscriber sendNext:@"延时2秒"];
  92. return nil;
  93. }] delay:2] subscribeNext:^(id x) {
  94. [self jumpNextQuestion];
  95. NSLog(@"-->%@",x);
  96. }];
  97. } else {
  98. /// 自动读题模式下: 当前题目正在自动读题 暂不自动跳到下一题
  99. NSLog(@"自动读题模式下: 当前题目正在自动读题 暂不自动跳到下一题");
  100. }
  101. }
  102. }
  103. break;
  104. case RQAnswerResultsType_Error: {
  105. if ([self.errorArr indexOfObject:exerciseModel] == NSNotFound && ![self.errorArr containsObject:exerciseModel]) {
  106. [_errorArr addObject:exerciseModel];
  107. if (self.viewModel.exerciseType != RQExerciseType_Recitation && self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  108. [RQ_ALERTVIEW_MANAGER rq_showSkillExplanationAlertWithMessage:exerciseModel.explain_jq skillkeyword:exerciseModel.skillkeyword explainGifUrl:exerciseModel.explain_gif mp3Url:exerciseModel.explain_mp3 completeBlock:nil];
  109. }
  110. RQWrongModel *wrongModel = [[RQWrongModel alloc] init];
  111. wrongModel.questionId = exerciseModel._id;
  112. [[RQ_HTTP_Service queryAddWrongRecordWithQuestionId:exerciseModel._id carType:notifiCarType subject:notifiSubjectType] subscribeNext:^(id _Nullable x) {
  113. [RQ_SDJK_DB_MANAGER addWrongRecordWithRQWrongModel:wrongModel];
  114. NSLog(@"%@",x);
  115. }];
  116. }
  117. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  118. _exerciseToolBarView.errorOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.errorArr.count];
  119. }
  120. }
  121. break;
  122. default:
  123. break;
  124. }
  125. switch (exerciseDoType) {
  126. case RQExerciseDoType_Default: {
  127. break;
  128. }
  129. case RQExerciseDoType_Auto: {
  130. break;
  131. }
  132. case RQExerciseDoType_SkillExplanation: {
  133. [RQ_ALERTVIEW_MANAGER rq_showSkillExplanationAlertWithMessage:exerciseModel.explain_jq skillkeyword:exerciseModel.skillkeyword explainGifUrl:exerciseModel.explain_gif mp3Url:exerciseModel.explain_mp3 completeBlock:nil];
  134. break;
  135. }
  136. case RQExerciseDoType_ReadAndAnswer: {
  137. // [RQ_MUSIC_MANAGER rq_resetStreamerWithURLString:exerciseModel.explainjsmp3];
  138. break;
  139. }
  140. default:
  141. break;
  142. }
  143. }];
  144. }
  145. - (void)creatCoverVC {
  146. DZMCoverController *coverVC = [[DZMCoverController alloc] init];
  147. coverVC.delegate = self;
  148. [self.view addSubview:coverVC.view];
  149. [self addChildViewController:coverVC];
  150. self.coverVC = coverVC;
  151. [self.coverVC setController:[self creatSubVC]];
  152. }
  153. - (RQTestQuestionsViewController *)creatSubVC {
  154. RQExerciseModel *exerciseModel = self.questionArr[self.number];
  155. exerciseModel.num = self.number;
  156. exerciseModel.allNum = self.questionArr.count;
  157. exerciseModel.isShowSkillExplanation = NO;
  158. RQTestQuestionsViewModel *testQuestionsViewModel = [[RQTestQuestionsViewModel alloc] initWithServices:self.viewModel.services params:@{
  159. RQViewModelUtilKey : exerciseModel,
  160. RQExerciseTypeKey : @(self.viewModel.exerciseType),
  161. RQHomePageCarTypeKey : @(self.viewModel.homePageCarType),
  162. RQHomePageSubjectTypeKey: @(self.viewModel.homePageSubjectType),
  163. }];
  164. testQuestionsViewModel.lastQuestionCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
  165. [self jumpLastQuestion];
  166. return [RACSignal empty];
  167. }];
  168. testQuestionsViewModel.nextQuestionCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
  169. [self jumpNextQuestion];
  170. return [RACSignal empty];
  171. }];
  172. testQuestionsViewModel.showCatalogueCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
  173. [self showCatalogue];
  174. return [RACSignal empty];
  175. }];
  176. RQTestQuestionsViewController *vc = [[RQTestQuestionsViewController alloc] initWithViewModel:testQuestionsViewModel];
  177. return vc;
  178. }
  179. /// 根据车型取题
  180. - (void)changeCityQuestion {
  181. self.questionArr = [RQ_QUESTION_DB_MANAGER getQuestionWithCarType:self.viewModel.homePageCarType subject:self.viewModel.homePageSubjectType pageType:self.viewModel.homeSubPageType name:self.viewModel.titleStr exerciseType:self.viewModel.exerciseType].mutableCopy;
  182. // [self searchExamRecord]; //顺序练习
  183. if (self.questionArr.count > 0) {
  184. [self creatCoverVC];
  185. [self creatToolsBar];
  186. }
  187. }
  188. /// 查看答题记录
  189. - (void)searchExamRecord {
  190. // FMResultSet *RightresultSet = [_db executeQuery:@"select * from dt_practice_record where course = 1 and mode = 1 and cert_type = 1"];
  191. // // 逐行读取数据
  192. // while ( [ RightresultSet next ] )
  193. // {
  194. // NSInteger ID = [RightresultSet intForColumn:@"_id"];
  195. // for (RQExerciseModel *item in self.questionArr) {
  196. // if (item._id == ID) {
  197. // item.answer = [RightresultSet stringForColumn:@"answer"];
  198. // if ([item.userAnswer isEqualToString:item.answer]) {
  199. // item.answerResultsType=1;//答对
  200. // }else{
  201. // item.answerResultsType=2;//答错
  202. // }
  203. // }
  204. // }
  205. //
  206. // }
  207. }
  208. /// 保存更新答题记录 ,如果没有打完自动跳转到下一题 ,model:1顺序2随机3专项4答对5打错6未答7收藏8模拟9考试纪录10章节 . */
  209. - (void)saveTheAnswerRecordActionWithRQExerciseModel:(RQExerciseModel *_Nullable)exerciseModel {
  210. /*
  211. *自动跳转到下一题
  212. */
  213. _firstNum = self.number;
  214. // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  215. // [self.dbQueue inDatabase:^(FMDatabase *db) {
  216. // BOOL issecect = [db executeUpdate:@"INSERT INTO dt_practice_record (course,mode,cert_type,question_id,user_answer,RIGHT,more_types) VALUES (1,1,1,?,?,?)",
  217. // [NSNumber numberWithInteger:exerciseModel._id],
  218. // exerciseModel.userAnswer,
  219. // exerciseModel.answer];
  220. // if (issecect) {
  221. // NSLog(@"____________插入成功%ld",(long)exerciseModel._id);
  222. // }
  223. // }];
  224. // });
  225. }
  226. - (void)jumpNextQuestion {
  227. if (self.number + 1 >= self.questionArr.count) {
  228. return;
  229. }
  230. self.number += 1;
  231. [self.coverVC setController:[self creatSubVC] animated:YES isAbove:NO];
  232. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  233. [self.view bringSubviewToFront:self.exerciseToolBarView];
  234. } else {
  235. [self.view bringSubviewToFront:self.handInThePaperView];
  236. }
  237. }
  238. - (void)jumpLastQuestion{
  239. if (self.number == 0) {
  240. return;
  241. }
  242. self.number -= 1;
  243. [self.coverVC setController:[self creatSubVC] animated:YES isAbove:YES];
  244. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  245. [self.view bringSubviewToFront:self.exerciseToolBarView];
  246. } else {
  247. [self.view bringSubviewToFront:self.handInThePaperView];
  248. }
  249. }
  250. - (void)jumpQuestionWithIndex:(NSUInteger)index {
  251. self.number = (int)index;
  252. [self.coverVC setController:[self creatSubVC] animated:NO isAbove:NO];
  253. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  254. [self.view bringSubviewToFront:self.exerciseToolBarView];
  255. } else {
  256. [self.view bringSubviewToFront:self.handInThePaperView];
  257. }
  258. }
  259. - (void)creatToolsBar {
  260. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  261. [self.view addSubview:self.exerciseToolBarView];
  262. [_exerciseToolBarView mas_makeConstraints:^(MASConstraintMaker *make) {
  263. make.centerX.mas_equalTo(self.view);
  264. make.bottom.mas_equalTo(self.view).mas_offset(-(RQ_APPLICATION_SAFEAREA_BOTTOM_HEIGHT + RQ_APPLICATION_NAV_BAR_HEIGHT));
  265. make.size.mas_equalTo(CGSizeMake(RQ_SCREEN_WIDTH, 50));
  266. }];
  267. } else {
  268. [self.view addSubview:self.handInThePaperView];
  269. [_handInThePaperView mas_makeConstraints:^(MASConstraintMaker *make) {
  270. make.centerX.mas_equalTo(self.view);
  271. make.bottom.mas_equalTo(self.view).mas_offset(-(RQ_APPLICATION_SAFEAREA_BOTTOM_HEIGHT + RQ_APPLICATION_NAV_BAR_HEIGHT));
  272. make.size.mas_equalTo(CGSizeMake(RQ_SCREEN_WIDTH, 50));
  273. }];
  274. }
  275. }
  276. - (void)showCatalogue {
  277. RQCatalogueViewModel *catalogueViewModel = [[RQCatalogueViewModel alloc] initWithServices:self.viewModel.services params:@{
  278. RQViewModelIDKey : @(self.number),
  279. RQViewModelUtilKey : self.questionArr,
  280. RQViewCommonValueKey : @(self.correctArr.count),
  281. RQViewModelRequestKey : @(self.errorArr.count),
  282. }];
  283. RQCatalogueViewController *catalogueViewController = [[RQCatalogueViewController alloc] initWithViewModel:catalogueViewModel];
  284. [catalogueViewController initCompletionWithSelectIndexBlock:^(NSInteger index) {
  285. [self jumpQuestionWithIndex:index];
  286. }];
  287. [self presentPanModal:catalogueViewController];
  288. }
  289. #pragma mark - DZMCoverControllerDelegate
  290. /// 切换结果
  291. - (void)coverController:(DZMCoverController *)coverController currentController:(UIViewController *)currentController finish:(BOOL)isFinish {
  292. if (!isFinish) { // 切换失败
  293. // RQTestQuestionsViewController *vc = (RQTestQuestionsViewController *)currentController;
  294. }
  295. }
  296. /// 上一个控制器
  297. - (UIViewController *)coverController:(DZMCoverController *)coverController getAboveControllerWithCurrentController:(UIViewController *)currentController {
  298. if (self.number == 0) {
  299. return nil;
  300. }
  301. self.number -= 1;
  302. return [self creatSubVC];
  303. }
  304. /// 下一个控制器
  305. - (UIViewController *)coverController:(DZMCoverController *)coverController getBelowControllerWithCurrentController:(UIViewController *)currentController {
  306. if (self.number==self.questionArr.count-1) {
  307. return nil;
  308. }
  309. self.number += 1;
  310. return [self creatSubVC];
  311. }
  312. #pragma mark - UITableViewDataSource, UITableViewDelegate
  313. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  314. !self.scrollCallback ?: self.scrollCallback(scrollView);
  315. }
  316. #pragma mark - JXPagingViewListViewDelegate
  317. - (UIView *)listView {
  318. return self.view;
  319. }
  320. - (UIScrollView *)listScrollView {
  321. return self.tableView;
  322. }
  323. - (void)listViewDidScrollCallback:(void (^)(UIScrollView *))callback {
  324. self.scrollCallback = callback;
  325. }
  326. #pragma mark - LazyLoad
  327. - (NSMutableArray *)questionArr {
  328. if (!_questionArr) {
  329. _questionArr = @[].mutableCopy;
  330. }
  331. return _questionArr;
  332. }
  333. - (RQExerciseToolBarView *)exerciseToolBarView {
  334. if (!_exerciseToolBarView) {
  335. @weakify(self)
  336. _exerciseToolBarView = [RQExerciseToolBarView exerciseToolBarView];
  337. [RACObserve(self, number) subscribeNext:^(id _Nullable x) {
  338. _exerciseToolBarView.totalNumberOfQuestionsLabel.text = [NSString stringWithFormat:@"%ld/%lu",[x integerValue] + 1,(unsigned long)self.questionArr.count];
  339. }];
  340. [_exerciseToolBarView.lastQuestionView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  341. [self jumpLastQuestion];
  342. }];
  343. [_exerciseToolBarView.nextQuestionView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  344. [self jumpNextQuestion];
  345. }];
  346. [_exerciseToolBarView.totalNumberOfQuestionsView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  347. @strongify(self)
  348. [self showCatalogue];
  349. }];
  350. [_exerciseToolBarView.officialInterpretationView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  351. RQExerciseModel *exerciseModel = self.questionArr[self.number];
  352. if (RQ_Exercise_Module.isAutoRead) RQ_Exercise_Module.isAutoRead = NO;
  353. [RQ_ALERTVIEW_MANAGER rq_showOfficialInterpretationAlertWithMessage:exerciseModel.explain_js mp3Url:exerciseModel.explainjsmp3];
  354. }];
  355. }
  356. return _exerciseToolBarView;
  357. }
  358. - (RQHandInThePaperView *)handInThePaperView {
  359. if (!_handInThePaperView) {
  360. _handInThePaperView = [RQHandInThePaperView handInThePaperView];
  361. [_handInThePaperView.handInThePaperBtn setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  362. NSInteger score = (self.viewModel.homePageSubjectType == RQHomePageSubjectType_SubjectOne && (self.viewModel.homePageCarType == RQHomePageCarType_Car || self.viewModel.homePageCarType == RQHomePageCarType_Bus || self.viewModel.homePageCarType == RQHomePageCarType_Truck))? self.correctArr.count : self.correctArr.count * 2;
  363. RQTestResultsViewModel *testResultsViewModel = [[RQTestResultsViewModel alloc] initWithServices:self.viewModel.services params:@{
  364. RQHomePageCarTypeKey : @(self.viewModel.homePageCarType),
  365. RQHomePageSubjectTypeKey : @(self.viewModel.homePageSubjectType),
  366. RQHomeSubPageTypeKey : @(self.viewModel.homeSubPageType),
  367. RQExerciseTypeKey : @(self.viewModel.exerciseType),
  368. RQViewModelIDKey : @(score),
  369. RQViewCommonValueKey : @(self.count),
  370. RQViewModelUtilKey : self.questionArr,
  371. }];
  372. [self.viewModel.services pushViewModel:testResultsViewModel animated:YES];
  373. }];
  374. }
  375. return _handInThePaperView;
  376. }
  377. - (NSMutableArray *)correctArr {
  378. if (!_correctArr) {
  379. _correctArr = @[].mutableCopy;
  380. }
  381. return _correctArr;
  382. }
  383. - (NSMutableArray *)errorArr {
  384. if (!_errorArr) {
  385. _errorArr = @[].mutableCopy;
  386. }
  387. return _errorArr;
  388. }
  389. @end