RQExerciseSubViewController.m 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  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) RQErrorExerciseToolBarView *errorExerciseToolBarView;
  19. @property (nonatomic, readwrite, strong) RQHandInThePaperView *handInThePaperView;
  20. @property (nonatomic, readwrite, strong) NSMutableArray *correctArr;
  21. @property (nonatomic, readwrite, strong) NSMutableArray *errorArr;
  22. @end
  23. @implementation RQExerciseSubViewController
  24. @dynamic viewModel;
  25. #pragma mark - SystemMethod
  26. - (void)viewDidLoad {
  27. [super viewDidLoad];
  28. /// 初始化
  29. [self rq_setup];
  30. }
  31. - (void)viewWillDisappear:(BOOL)animated {
  32. [super viewWillDisappear:animated];
  33. // int popNum = _firstNum<self.questionArr.count-1 ?_firstNum+1:(int)self.questionArr.count-1;
  34. // [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:popNum] forKey:@"QUESTIONNUM"];
  35. // [[NSUserDefaults standardUserDefaults] synchronize];
  36. }
  37. - (void)dealloc {
  38. [RQ_Exercise_Module cancleAutoReadQuestion];
  39. [RQNotificationCenter removeObserver:self name:RQAnswerResultsNotification object:nil];
  40. }
  41. - (void)updateQuestionArr {
  42. [self.view removeAllSubviews];
  43. [self rq_setup];
  44. }
  45. #pragma mark - PrivateMethods
  46. /// 初始化
  47. - (void)rq_setup {
  48. @weakify(self)
  49. if (self.viewModel.homeSubPageType == RQHomeSubPageType_WrongTopicAndCollection) {
  50. [self getQuestionArrayWithComplete:^(NSArray *getQuestionArr) {
  51. self.questionArr = getQuestionArr.mutableCopy;
  52. dispatch_async(dispatch_get_main_queue(), ^{
  53. [self creatCoverVC];
  54. [self creatToolsBar];
  55. });
  56. }];
  57. /// 错题·收藏题的随机练习和背题模式得单独对数组进行处理
  58. self.number = self.viewModel.number;
  59. [[[RQNotificationCenter rac_addObserverForName:RQCancelCollectNotification object:nil] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSNotification * note) {
  60. @strongify(self);
  61. RQExerciseModel *exerciseModel = note.userInfo[RQCancelCollectExerciseModelKey];
  62. [[self mutableArrayValueForKey:@"questionArr"] removeObject:exerciseModel];
  63. [self.coverVC.view removeFromSuperview];
  64. if ([self.errorArr containsObject:exerciseModel]) {
  65. [self.errorArr removeObject:exerciseModel];
  66. } else if ([self.correctArr containsObject:exerciseModel]) {
  67. [self.correctArr removeObject:exerciseModel];
  68. }
  69. if (self.questionArr.count == 0) {
  70. self.number = 0;
  71. _exerciseToolBarView.errorOptionNumLabel.text = @"0";
  72. _exerciseToolBarView.correctOptionNumLabel.text = @"0";
  73. } else {
  74. self.number = (self.questionArr.count == 1)? 0 : ((self.number == 0)? 0 : self.number - 1);
  75. [self creatCoverVC];
  76. [self.view bringSubviewToFront:self.exerciseToolBarView];
  77. _exerciseToolBarView.errorOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.errorArr.count];
  78. _exerciseToolBarView.correctOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.correctArr.count];
  79. }
  80. }];
  81. } /*else if (self.viewModel.homeSubPageType == RQHomeSubPageType_MockExamination && self.viewModel.questionArr) {
  82. self.questionArr = [NSMutableArray arrayWithArray:self.viewModel.questionArr];
  83. [self creatCoverVC];
  84. [self creatToolsBar];
  85. }*/ else {
  86. if (RQObjectIsNil(self.viewModel.questionArr)) {
  87. ///获取数据
  88. if (self.questionArr.count==0) {
  89. self.number = 0;
  90. [self changeCityQuestion];
  91. } else {
  92. self.number = 0;
  93. [self creatCoverVC];
  94. [self creatToolsBar];
  95. }
  96. } else {
  97. if (self.viewModel.questionArr.count > 0) {
  98. self.questionArr = [NSMutableArray arrayWithArray:self.viewModel.questionArr];
  99. self.number = 0;
  100. [self creatCoverVC];
  101. [self creatToolsBar];
  102. } else {
  103. ///获取数据
  104. if (self.questionArr.count==0) {
  105. self.number = 0;
  106. [self changeCityQuestion];
  107. } else {
  108. self.number = 0;
  109. [self creatCoverVC];
  110. [self creatToolsBar];
  111. }
  112. }
  113. }
  114. }
  115. /// 答题结果
  116. [RQNotificationCenter addObserver:self selector:@selector(dealWithAnswerResults:) name:RQAnswerResultsNotification object:nil];
  117. }
  118. - (void)getQuestionArrayWithComplete:(VoidBlock_id)complete {
  119. @weakify(self)
  120. switch (self.viewModel.homeSubPageType) {
  121. case RQHomeSubPageType_WrongTopicAndCollection: {
  122. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  123. NSArray *questionIdArr = [RQ_SDJK_DB_MANAGER queryWrongModelQuestionIdArrWithSubjectType:self.viewModel.homePageSubjectType];
  124. [RQ_QUESTION_DB_MANAGER getQuestionsWithQuestionIdArr:questionIdArr complete:^(NSArray *modelArray) {
  125. @strongify(self)
  126. if (self.viewModel.exerciseType == RQExerciseType_Random) {
  127. complete([NSMutableArray arrayWithArray:[modelArray rq_randomArray]]);
  128. } else if (self.viewModel.exerciseType == RQExerciseType_Recitation) {
  129. complete([modelArray.rac_sequence.signal map:^id _Nullable(RQExerciseModel *exerciseModel) {
  130. exerciseModel.userAnswer = exerciseModel.answer;
  131. return exerciseModel;
  132. }].toArray.mutableCopy);
  133. } else {
  134. complete(modelArray.mutableCopy);
  135. }
  136. }];
  137. } else if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_Collection) {
  138. NSArray *questionIdArr = [RQ_SDJK_DB_MANAGER queryCollectionModelQuestionIdArrWithSubjectType:self.viewModel.homePageSubjectType];
  139. [RQ_QUESTION_DB_MANAGER getQuestionsWithQuestionIdArr:questionIdArr complete:^(NSArray *modelArray) {
  140. @strongify(self)
  141. if (self.viewModel.exerciseType == RQExerciseType_Random) {
  142. complete([NSMutableArray arrayWithArray:[modelArray rq_randomArray]]);
  143. } else if (self.viewModel.exerciseType == RQExerciseType_Recitation) {
  144. complete([modelArray.rac_sequence.signal map:^id _Nullable(RQExerciseModel *exerciseModel) {
  145. exerciseModel.userAnswer = exerciseModel.answer;
  146. return exerciseModel;
  147. }].toArray.mutableCopy);
  148. } else {
  149. complete(modelArray.mutableCopy);
  150. }
  151. }];
  152. }
  153. break;
  154. }
  155. default:
  156. break;
  157. }
  158. }
  159. - (void)dealWithAnswerResults:(NSNotification *)note {
  160. RQExerciseModel *exerciseModel = note.userInfo[RQAnswerResultsKey];
  161. RQHomePageCarType notifiCarType = [note.userInfo[RQHomePageCarTypeKey] integerValue];
  162. RQHomePageSubjectType notifiSubjectType = [note.userInfo[RQHomePageSubjectTypeKey] integerValue];
  163. RQExerciseDoType exerciseDoType = [note.userInfo[RQExerciseDoTypeKey] integerValue];
  164. if (notifiCarType != self.viewModel.homePageCarType || notifiSubjectType != self.viewModel.homePageSubjectType) {
  165. NSLog(@"重复推送");
  166. return;
  167. }
  168. [self saveTheAnswerRecordActionWithRQExerciseModel:exerciseModel];
  169. switch (exerciseModel.answerResultsType) {
  170. case RQAnswerResultsType_Correct: {
  171. if (![self.correctArr containsObject:exerciseModel]) {
  172. if (self.viewModel.exerciseType != RQExerciseType_Recitation) {
  173. [self.correctArr addObject:exerciseModel];
  174. if (exerciseDoType == RQExerciseDoType_Default && !RQ_Exercise_Module.isAutoRead) {
  175. /// 非自动读题 做对自动跳下一题
  176. /// 延时
  177. if (RQ_Exercise_Module.isRightAutoJumpToNext) {
  178. [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
  179. [subscriber sendNext:@"延时0.5秒"];
  180. return nil;
  181. }] delay:.5f] subscribeNext:^(id x) {
  182. [self jumpNextQuestion];
  183. NSLog(@"-->%@",x);
  184. }];
  185. }
  186. }
  187. }
  188. } else {
  189. }
  190. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  191. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  192. _errorExerciseToolBarView.correctOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.correctArr.count];
  193. } else {
  194. _exerciseToolBarView.correctOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.correctArr.count];
  195. }
  196. }
  197. if (RQ_Exercise_Module.isAutoRead) {
  198. if (!exerciseModel.isAuto) {
  199. ///自动读题模式下: 当前题目结束自动读题 2秒后自动跳到下一题
  200. //延时
  201. [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
  202. [subscriber sendNext:@"延时2秒"];
  203. return nil;
  204. }] delay:2] subscribeNext:^(id x) {
  205. [self jumpNextQuestion];
  206. NSLog(@"-->%@",x);
  207. }];
  208. } else {
  209. /// 自动读题模式下: 当前题目正在自动读题 暂不自动跳到下一题
  210. NSLog(@"自动读题模式下: 当前题目正在自动读题 暂不自动跳到下一题");
  211. }
  212. }
  213. }
  214. break;
  215. case RQAnswerResultsType_Error: {
  216. if ([self.errorArr indexOfObject:exerciseModel] == NSNotFound && ![self.errorArr containsObject:exerciseModel]) {
  217. [_errorArr addObject:exerciseModel];
  218. if (self.viewModel.exerciseType != RQExerciseType_Recitation && self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  219. [RQ_Exercise_Module rq_showSkillExplanationAlertWithMessage:exerciseModel.explain_jq skillkeyword:exerciseModel.skillkeyword explainGifUrl:exerciseModel.explain_gif mp3Url:exerciseModel.explain_mp3 completeBlock:nil];
  220. }
  221. RQWrongModel *wrongModel = [[RQWrongModel alloc] init];
  222. wrongModel.questionId = exerciseModel._id;
  223. wrongModel.km = RQ_COMMON_MANAGER.subjectStr;
  224. wrongModel.createTime = [NSDate rq_currentTimeSSSInterval];
  225. wrongModel.userId = RQ_USER_MANAGER.currentUserId;
  226. // [[RQ_HTTP_Service queryAddWrongRecordWithQuestionId:exerciseModel._id carType:notifiCarType subject:notifiSubjectType] subscribeNext:^(id _Nullable x) {
  227. // [RQ_SDJK_DB_MANAGER addWrongRecordWithRQWrongModel:wrongModel];
  228. // [RQ_SDJK_DB_MANAGER getAllWrongModelsCount];
  229. // NSLog(@"%@",x);
  230. // }];
  231. [RQ_SDJK_DB_MANAGER addWrongRecordWithRQWrongModel:wrongModel];
  232. [RQ_SDJK_DB_MANAGER getAllWrongModelsCount];
  233. }
  234. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  235. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  236. _errorExerciseToolBarView.errorOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.errorArr.count];
  237. } else {
  238. _exerciseToolBarView.errorOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.errorArr.count];
  239. }
  240. }
  241. }
  242. break;
  243. default:
  244. break;
  245. }
  246. switch (exerciseDoType) {
  247. case RQExerciseDoType_Default: {
  248. break;
  249. }
  250. case RQExerciseDoType_Auto: {
  251. break;
  252. }
  253. case RQExerciseDoType_SkillExplanation: {
  254. [RQ_Exercise_Module rq_showSkillExplanationAlertWithMessage:exerciseModel.explain_jq skillkeyword:exerciseModel.skillkeyword explainGifUrl:exerciseModel.explain_gif mp3Url:exerciseModel.explain_mp3 completeBlock:nil];
  255. break;
  256. }
  257. case RQExerciseDoType_ReadAndAnswer: {
  258. // [RQ_MUSIC_MANAGER rq_resetStreamerWithURLString:exerciseModel.explainjsmp3];
  259. break;
  260. }
  261. default:
  262. break;
  263. }
  264. }
  265. - (void)creatCoverVC {
  266. if (self.questionArr.count <= 0) {
  267. return;
  268. }
  269. if (self.number > self.questionArr.count) {
  270. return;
  271. }
  272. DZMCoverController *coverVC = [[DZMCoverController alloc] init];
  273. coverVC.delegate = self;
  274. [self.view addSubview:coverVC.view];
  275. [self addChildViewController:coverVC];
  276. self.coverVC = coverVC;
  277. [self.coverVC setController:[self creatSubVC]];
  278. }
  279. - (RQTestQuestionsViewController *)creatSubVC {
  280. @weakify(self)
  281. RQExerciseModel *exerciseModel = self.questionArr[self.number];
  282. exerciseModel.num = self.number;
  283. exerciseModel.allNum = self.questionArr.count;
  284. exerciseModel.isShowSkillExplanation = NO;
  285. RQTestQuestionsViewModel *testQuestionsViewModel = [[RQTestQuestionsViewModel alloc] initWithServices:self.viewModel.services params:@{
  286. RQViewModelUtilKey : exerciseModel,
  287. RQExerciseTypeKey : @(self.viewModel.exerciseType),
  288. RQHomePageCarTypeKey : @(self.viewModel.homePageCarType),
  289. RQHomePageSubjectTypeKey: @(self.viewModel.homePageSubjectType),
  290. }];
  291. testQuestionsViewModel.lastQuestionCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
  292. @strongify(self)
  293. [self jumpLastQuestion];
  294. return [RACSignal empty];
  295. }];
  296. testQuestionsViewModel.nextQuestionCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
  297. @strongify(self)
  298. [self jumpNextQuestion];
  299. return [RACSignal empty];
  300. }];
  301. testQuestionsViewModel.showCatalogueCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
  302. @strongify(self)
  303. [self showCatalogue];
  304. return [RACSignal empty];
  305. }];
  306. RQTestQuestionsViewController *vc = [[RQTestQuestionsViewController alloc] initWithViewModel:testQuestionsViewModel];
  307. __weak typeof(vc) weakController = vc;
  308. return weakController;
  309. }
  310. /// 根据车型取题
  311. - (void)changeCityQuestion {
  312. if (self.viewModel.homeSubPageType == RQHomeSubPageType_MockExamination &&
  313. self.viewModel.exerciseType == RQExerciseType_Exam) { //模拟考从网络获取考题
  314. @weakify(self)
  315. /// 默认为轿车 cart,bus,truck
  316. NSString *carTypeStr = @"cart";
  317. switch (self.viewModel.homePageCarType) {
  318. case RQHomePageCarType_Car:
  319. carTypeStr = @"cart";
  320. break;
  321. case RQHomePageCarType_Bus:
  322. carTypeStr = @"bus";
  323. break;
  324. case RQHomePageCarType_Truck:
  325. carTypeStr = @"truck";
  326. break;
  327. case RQHomePageCarType_Motorcycle:
  328. carTypeStr = @"mtc";
  329. break;
  330. default:
  331. break;
  332. }
  333. /// 默认科目一
  334. NSString *subjectTypeStr = @"1";
  335. switch (self.viewModel.homePageSubjectType) {
  336. case RQHomePageSubjectType_SubjectOne:
  337. subjectTypeStr = @"1";
  338. break;
  339. case RQHomePageSubjectType_SubjectTwo:
  340. subjectTypeStr = @"2";
  341. break;
  342. case RQHomePageSubjectType_SubjectThree:
  343. subjectTypeStr = @"3";
  344. break;
  345. case RQHomePageSubjectType_SubjectFour:
  346. subjectTypeStr = @"4";
  347. break;
  348. default:
  349. break;
  350. }
  351. [[[RQ_HTTP_Service getSelectTestK14QuestionInfoList:carTypeStr subject:subjectTypeStr] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSArray *array) {
  352. //获取考题
  353. @strongify(self)
  354. self.questionArr = array.mutableCopy;
  355. [self setup_dataarray];
  356. } error:^(NSError * _Nullable error) {
  357. }];
  358. return;
  359. }
  360. 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;
  361. [self setup_dataarray];
  362. }
  363. - (void)setup_dataarray{
  364. NSString *titleStr = [self.viewModel.title componentsSeparatedByString:@"/"].lastObject;
  365. RQHistoryModel *history = [RQ_SDJK_DB_MANAGER queryHistoryModelWithCarType:self.viewModel.homePageCarType subjectType:self.viewModel.homePageSubjectType homeSubPageTyp:self.viewModel.homeSubPageType titleStr:titleStr];
  366. if (!RQObjectIsNil(history)) {
  367. NSInteger historyIndex = [[self.viewModel.questionArr.rac_sequence.signal map:^id _Nullable(RQExerciseModel *exerciseModel) {
  368. return @(exerciseModel._id);
  369. }].toArray indexOfObject:@(history.questionId)] + 1;
  370. if (historyIndex > 1) {
  371. self.number = historyIndex;
  372. }
  373. }
  374. // if (arr && arr.count > 0) {
  375. // NSInteger questionId = [arr.firstObject intValue];
  376. // NSArray *arr1 = [self.questionArr.rac_sequence filter:^BOOL(RQExerciseModel *exerciseModel) {
  377. // return exerciseModel._id == questionId;
  378. // }].array;
  379. // if (arr1 && arr1.count > 0) {
  380. // RQExerciseModel *exerciseModel = (RQExerciseModel *)arr1.firstObject;
  381. // NSInteger historyNum = [self.questionArr indexOfObject:exerciseModel];
  382. // self.number = historyNum;
  383. // }
  384. // }
  385. // [self searchExamRecord]; //顺序练习
  386. // if (self.number > 0) {
  387. // [NSObject rq_showAlertViewWithTitle:@"温馨提示" message:[NSString stringWithFormat:@"检测到您上次做到第%ld题,是否跳转?",self.number] confirmTitle:@"确定" cancelTitle:@"取消" confirmAction:^{
  388. // @strongify(self)
  389. // [self jumpQuestionWithIndex:self.number];
  390. // } cancelAction:nil];
  391. // }
  392. if (self.questionArr.count > 0) {
  393. [self creatCoverVC];
  394. [self creatToolsBar];
  395. }
  396. }
  397. /// 查看答题记录
  398. - (void)searchExamRecord {
  399. // FMResultSet *RightresultSet = [_db executeQuery:@"select * from dt_practice_record where course = 1 and mode = 1 and cert_type = 1"];
  400. // // 逐行读取数据
  401. // while ( [ RightresultSet next ] )
  402. // {
  403. // NSInteger ID = [RightresultSet intForColumn:@"_id"];
  404. // for (RQExerciseModel *item in self.questionArr) {
  405. // if (item._id == ID) {
  406. // item.answer = [RightresultSet stringForColumn:@"answer"];
  407. // if ([item.userAnswer isEqualToString:item.answer]) {
  408. // item.answerResultsType=1;//答对
  409. // }else{
  410. // item.answerResultsType=2;//答错
  411. // }
  412. // }
  413. // }
  414. //
  415. // }
  416. }
  417. /// 保存更新答题记录 ,如果没有打完自动跳转到下一题 ,model:1顺序2随机3专项4答对5打错6未答7收藏8模拟9考试纪录10章节 . */
  418. - (void)saveTheAnswerRecordActionWithRQExerciseModel:(RQExerciseModel *_Nullable)exerciseModel {
  419. /*
  420. *自动跳转到下一题
  421. */
  422. _firstNum = self.number;
  423. NSString *seque_issue_name = @"";
  424. NSString *class_issue_name = @"";
  425. NSString *place_issue_name = @"";
  426. NSString *excell_issue_name = @"";
  427. NSString *titleStr = [self.viewModel.title componentsSeparatedByString:@"/"].lastObject;
  428. switch (self.viewModel.homeSubPageType) {
  429. case RQHomeSubPageType_SequentialPractice:
  430. seque_issue_name = titleStr;
  431. break;
  432. case RQHomeSubPageType_LocalTopics:
  433. place_issue_name = titleStr;
  434. break;
  435. case RQHomeSubPageType_ClassificationExercise:
  436. class_issue_name = titleStr;
  437. break;
  438. case RQHomeSubPageType_SelectedTestQuestions:
  439. excell_issue_name = titleStr;
  440. break;
  441. default:
  442. break;
  443. }
  444. RQHistoryModel *historyModel = [[RQHistoryModel alloc] init];
  445. historyModel.questionId = exerciseModel._id;
  446. historyModel.userId = RQ_USER_MANAGER.currentUserId;
  447. historyModel.km = [RQ_COMMON_MANAGER getSubjectTypeStrWithSubjectType:self.viewModel.homePageSubjectType];
  448. historyModel.carType = [RQ_COMMON_MANAGER getCarTypeStrWithCarType:self.viewModel.homePageCarType];
  449. historyModel.seque_issue_name = seque_issue_name;
  450. historyModel.place_issue_name = place_issue_name;
  451. historyModel.class_issue_name = class_issue_name;
  452. historyModel.excell_issue_name = excell_issue_name;
  453. [RQ_SDJK_DB_MANAGER addHistoryRecordWithRQHistoryModel:historyModel];
  454. }
  455. - (void)jumpNextQuestion {
  456. if (self.number + 1 >= self.questionArr.count) {
  457. return;
  458. }
  459. self.number += 1;
  460. [self.coverVC setController:[self creatSubVC] animated:YES isAbove:NO];
  461. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  462. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  463. [self.view bringSubviewToFront:self.errorExerciseToolBarView];
  464. } else {
  465. [self.view bringSubviewToFront:self.exerciseToolBarView];
  466. }
  467. } else {
  468. [self.view bringSubviewToFront:self.handInThePaperView];
  469. }
  470. }
  471. - (void)jumpLastQuestion{
  472. if (self.number == 0) {
  473. return;
  474. }
  475. self.number -= 1;
  476. [self.coverVC setController:[self creatSubVC] animated:YES isAbove:YES];
  477. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  478. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  479. [self.view bringSubviewToFront:self.errorExerciseToolBarView];
  480. } else {
  481. [self.view bringSubviewToFront:self.exerciseToolBarView];
  482. }
  483. } else {
  484. [self.view bringSubviewToFront:self.handInThePaperView];
  485. }
  486. }
  487. - (void)jumpQuestionWithIndex:(NSUInteger)index {
  488. self.number = (int)index;
  489. [self.coverVC setController:[self creatSubVC] animated:NO isAbove:NO];
  490. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  491. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  492. [self.view bringSubviewToFront:self.errorExerciseToolBarView];
  493. } else {
  494. [self.view bringSubviewToFront:self.exerciseToolBarView];
  495. }
  496. } else {
  497. [self.view bringSubviewToFront:self.handInThePaperView];
  498. }
  499. }
  500. - (void)creatToolsBar {
  501. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  502. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  503. [self.view addSubview:self.errorExerciseToolBarView];
  504. [_errorExerciseToolBarView mas_makeConstraints:^(MASConstraintMaker *make) {
  505. make.centerX.mas_equalTo(self.view);
  506. make.bottom.mas_equalTo(self.view).mas_offset(-(RQ_APPLICATION_SAFEAREA_BOTTOM_HEIGHT + RQ_APPLICATION_NAV_BAR_HEIGHT));
  507. make.size.mas_equalTo(CGSizeMake(RQ_SCREEN_WIDTH, 50));
  508. }];
  509. } else {
  510. [self.view addSubview:self.exerciseToolBarView];
  511. [_exerciseToolBarView mas_makeConstraints:^(MASConstraintMaker *make) {
  512. make.centerX.mas_equalTo(self.view);
  513. make.bottom.mas_equalTo(self.view).mas_offset(-(RQ_APPLICATION_SAFEAREA_BOTTOM_HEIGHT + RQ_APPLICATION_NAV_BAR_HEIGHT));
  514. make.size.mas_equalTo(CGSizeMake(RQ_SCREEN_WIDTH, 50));
  515. }];
  516. }
  517. } else {
  518. [self.view addSubview:self.handInThePaperView];
  519. [_handInThePaperView mas_makeConstraints:^(MASConstraintMaker *make) {
  520. make.centerX.mas_equalTo(self.view);
  521. make.bottom.mas_equalTo(self.view).mas_offset(-(RQ_APPLICATION_SAFEAREA_BOTTOM_HEIGHT + RQ_APPLICATION_NAV_BAR_HEIGHT));
  522. make.size.mas_equalTo(CGSizeMake(RQ_SCREEN_WIDTH, 8.f + RQ_FIT_HORIZONTAL(54.f) + 8.f + 50.f + 8.f));
  523. }];
  524. }
  525. }
  526. - (void)showCatalogue {
  527. @weakify(self)
  528. if (self.questionArr.count == 0) {
  529. return;
  530. }
  531. RQCatalogueViewModel *catalogueViewModel = [[RQCatalogueViewModel alloc] initWithServices:self.viewModel.services params:@{
  532. RQViewModelIDKey : @(self.number),
  533. RQViewModelUtilKey : self.questionArr,
  534. RQViewCommonValueKey : @(self.correctArr.count),
  535. RQViewModelRequestKey : @(self.errorArr.count),
  536. }];
  537. RQCatalogueViewController *catalogueViewController = [[RQCatalogueViewController alloc] initWithViewModel:catalogueViewModel];
  538. [catalogueViewController initCompletionWithSelectIndexBlock:^(NSInteger index) {
  539. @strongify(self)
  540. [self jumpQuestionWithIndex:index];
  541. }];
  542. [self presentPanModal:catalogueViewController];
  543. }
  544. #pragma mark - DZMCoverControllerDelegate
  545. /// 切换结果
  546. - (void)coverController:(DZMCoverController *)coverController currentController:(UIViewController *)currentController finish:(BOOL)isFinish {
  547. if (!isFinish) { // 切换失败
  548. // RQTestQuestionsViewController *vc = (RQTestQuestionsViewController *)currentController;
  549. }
  550. }
  551. /// 上一个控制器
  552. - (UIViewController *)coverController:(DZMCoverController *)coverController getAboveControllerWithCurrentController:(UIViewController *)currentController {
  553. if (self.number == 0) {
  554. return nil;
  555. }
  556. self.number -= 1;
  557. return [self creatSubVC];
  558. }
  559. /// 下一个控制器
  560. - (UIViewController *)coverController:(DZMCoverController *)coverController getBelowControllerWithCurrentController:(UIViewController *)currentController {
  561. if (self.number==self.questionArr.count-1) {
  562. return nil;
  563. }
  564. self.number += 1;
  565. return [self creatSubVC];
  566. }
  567. #pragma mark - UITableViewDataSource, UITableViewDelegate
  568. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  569. !self.scrollCallback ?: self.scrollCallback(scrollView);
  570. }
  571. #pragma mark - JXPagingViewListViewDelegate
  572. - (UIView *)listView {
  573. return self.view;
  574. }
  575. - (UIScrollView *)listScrollView {
  576. return self.tableView;
  577. }
  578. - (void)listViewDidScrollCallback:(void (^)(UIScrollView *))callback {
  579. self.scrollCallback = callback;
  580. }
  581. #pragma mark - LazyLoad
  582. - (NSMutableArray *)questionArr {
  583. if (!_questionArr) {
  584. _questionArr = @[].mutableCopy;
  585. }
  586. return _questionArr;
  587. }
  588. - (RQExerciseToolBarView *)exerciseToolBarView {
  589. if (!_exerciseToolBarView) {
  590. _exerciseToolBarView = [RQExerciseToolBarView exerciseToolBarView];
  591. @weakify(self,_exerciseToolBarView);
  592. // [RACObserve(self, number) subscribeNext:^(id _Nullable x) {
  593. // @strongify(self,_exerciseToolBarView)
  594. // _exerciseToolBarView.totalNumberOfQuestionsLabel.text = [NSString stringWithFormat:@"%ld/%lu",[x integerValue] + 1,(unsigned long)self.questionArr.count];
  595. // }];
  596. RAC(_exerciseToolBarView.totalNumberOfQuestionsLabel, text) = [RACSignal combineLatest:@[RACObserve(self, number), RACObserve(self, questionArr)] reduce:^id (NSNumber *num, NSArray *selectArr){
  597. @strongify(self)
  598. return [NSString stringWithFormat:@"%ld/%lu",(self.questionArr.count == 0)? 0 : [num integerValue] + 1,(unsigned long)self.questionArr.count];
  599. }];
  600. [_exerciseToolBarView.lastQuestionView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  601. @strongify(self)
  602. [self jumpLastQuestion];
  603. }];
  604. [_exerciseToolBarView.nextQuestionView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  605. @strongify(self)
  606. [self jumpNextQuestion];
  607. }];
  608. [_exerciseToolBarView.totalNumberOfQuestionsView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  609. @strongify(self)
  610. [self showCatalogue];
  611. }];
  612. [_exerciseToolBarView.officialInterpretationView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  613. @strongify(self)
  614. if (self.questionArr.count == 0) {
  615. return;
  616. }
  617. RQExerciseModel *exerciseModel = self.questionArr[self.number];
  618. if (RQ_Exercise_Module.isAutoRead) RQ_Exercise_Module.isAutoRead = NO;
  619. [RQ_Exercise_Module rq_showOfficialInterpretationAlertWithMessage:exerciseModel.explain_js mp3Url:exerciseModel.explainjsmp3];
  620. }];
  621. }
  622. return _exerciseToolBarView;
  623. }
  624. - (RQErrorExerciseToolBarView *)errorExerciseToolBarView {
  625. if (!_errorExerciseToolBarView) {
  626. _errorExerciseToolBarView = [RQErrorExerciseToolBarView errorExerciseToolBarView];
  627. @weakify(self);
  628. RAC(_errorExerciseToolBarView.totalNumberOfQuestionsLabel, text) = [RACSignal combineLatest:@[RACObserve(self, number), RACObserve(self, questionArr)] reduce:^id (NSNumber *num, NSArray *selectArr){
  629. @strongify(self)
  630. return [NSString stringWithFormat:@"%ld/%lu",(self.questionArr.count == 0)? 0 : [num integerValue] + 1,(unsigned long)self.questionArr.count];
  631. }];
  632. // [RACObserve(self, number) subscribeNext:^(id _Nullable x) {
  633. // @strongify(self,_errorExerciseToolBarView)
  634. // _errorExerciseToolBarView.totalNumberOfQuestionsLabel.text = [NSString stringWithFormat:@"%ld/%lu",(self.questionArr.count == 0)? 0 : [x integerValue] + 1,(unsigned long)self.questionArr.count];
  635. // }];
  636. [_errorExerciseToolBarView.deleteView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  637. @strongify(self)
  638. if (self.questionArr.count == 0) {
  639. return;
  640. }
  641. RQExerciseModel *exerciseModel = self.questionArr[self.number];
  642. // [[RQ_HTTP_Service queryDeleteWrongRecordWithQuestionId:[NSString qmui_stringWithNSInteger:exerciseModel._id]] subscribeNext:^(id _Nullable x) {
  643. // @strongify(self)
  644. // [RQ_SDJK_DB_MANAGER deleteWrongRecordWithQuestionId:exerciseModel._id];
  645. // [[self mutableArrayValueForKey:@"questionArr"] removeObject:exerciseModel];
  646. // [MBProgressHUD rq_showTips:@"删除成功"];
  647. // [self.coverVC.view removeFromSuperview];
  648. // [RQ_SDJK_DB_MANAGER getAllWrongModelsCount];
  649. // if ([self.errorArr containsObject:exerciseModel]) {
  650. // [self.errorArr removeObject:exerciseModel];
  651. // } else if ([self.correctArr containsObject:exerciseModel]) {
  652. // [self.correctArr removeObject:exerciseModel];
  653. // }
  654. //
  655. // if (self.questionArr.count == 0) {
  656. // self.number = 0;
  657. // _errorExerciseToolBarView.errorOptionNumLabel.text = @"0";
  658. // _errorExerciseToolBarView.correctOptionNumLabel.text = @"0";
  659. // } else {
  660. // self.number = (self.questionArr.count == 1)? 0 : ((self.number == 0)? 0 : self.number - 1);
  661. // [self creatCoverVC];
  662. // [self.view bringSubviewToFront:self.errorExerciseToolBarView];
  663. // _errorExerciseToolBarView.errorOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.errorArr.count];
  664. // _errorExerciseToolBarView.correctOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.correctArr.count];
  665. // }
  666. // } error:^(NSError * _Nullable error) {
  667. // [MBProgressHUD rq_showErrorTips:error];
  668. // }];
  669. BOOL isDelete = [RQ_SDJK_DB_MANAGER deleteWrongRecordWithQuestionId:exerciseModel._id];
  670. if (isDelete) {
  671. [[self mutableArrayValueForKey:@"questionArr"] removeObject:exerciseModel];
  672. [MBProgressHUD rq_showTips:@"删除成功"];
  673. [self.coverVC.view removeFromSuperview];
  674. [RQ_SDJK_DB_MANAGER getAllWrongModelsCount];
  675. if ([self.errorArr containsObject:exerciseModel]) {
  676. [self.errorArr removeObject:exerciseModel];
  677. } else if ([self.correctArr containsObject:exerciseModel]) {
  678. [self.correctArr removeObject:exerciseModel];
  679. }
  680. if (self.questionArr.count == 0) {
  681. self.number = 0;
  682. self.errorExerciseToolBarView.errorOptionNumLabel.text = @"0";
  683. self.errorExerciseToolBarView.correctOptionNumLabel.text = @"0";
  684. } else {
  685. self.number = (self.questionArr.count == 1)? 0 : ((self.number == 0)? 0 : self.number - 1);
  686. [self creatCoverVC];
  687. [self.view bringSubviewToFront:self.errorExerciseToolBarView];
  688. self.errorExerciseToolBarView.errorOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.errorArr.count];
  689. self.errorExerciseToolBarView.correctOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.correctArr.count];
  690. }
  691. } else {
  692. [MBProgressHUD rq_showTips:@"删除失败"];
  693. }
  694. }];
  695. [_errorExerciseToolBarView.totalNumberOfQuestionsView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  696. @strongify(self)
  697. [self showCatalogue];
  698. }];
  699. [_errorExerciseToolBarView.officialInterpretationView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  700. @strongify(self)
  701. if (self.questionArr.count == 0) {
  702. return;
  703. }
  704. RQExerciseModel *exerciseModel = self.questionArr[self.number];
  705. if (RQ_Exercise_Module.isAutoRead) RQ_Exercise_Module.isAutoRead = NO;
  706. [RQ_Exercise_Module rq_showOfficialInterpretationAlertWithMessage:exerciseModel.explain_js mp3Url:exerciseModel.explainjsmp3];
  707. }];
  708. }
  709. return _errorExerciseToolBarView;
  710. }
  711. - (RQHandInThePaperView *)handInThePaperView {
  712. if (!_handInThePaperView) {
  713. @weakify(self)
  714. _handInThePaperView = [RQHandInThePaperView handInThePaperView];
  715. [_handInThePaperView.handInThePaperBtn setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  716. @strongify(self)
  717. 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;
  718. RQTestResultsViewModel *testResultsViewModel = [[RQTestResultsViewModel alloc] initWithServices:self.viewModel.services params:@{
  719. RQHomePageCarTypeKey : @(self.viewModel.homePageCarType),
  720. RQHomePageSubjectTypeKey : @(self.viewModel.homePageSubjectType),
  721. RQHomeSubPageTypeKey : @(self.viewModel.homeSubPageType),
  722. RQExerciseTypeKey : @(self.viewModel.exerciseType),
  723. RQViewModelIDKey : @(score),
  724. RQViewCommonValueKey : @(self.count),
  725. RQViewModelUtilKey : self.questionArr,
  726. }];
  727. [self.viewModel.services pushViewModel:testResultsViewModel animated:YES];
  728. }];
  729. [_handInThePaperView.lastQuestionBtn setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  730. @strongify(self)
  731. [self jumpLastQuestion];
  732. }];
  733. [_handInThePaperView.nextQuestionBtn setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  734. @strongify(self)
  735. [self jumpNextQuestion];
  736. }];
  737. [_handInThePaperView.totalNumberOfQuestionsBtn setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  738. @strongify(self)
  739. [self showCatalogue];
  740. }];
  741. RAC(_handInThePaperView.totalNumberOfQuestionsBtn.titleLabel, text) = [RACSignal combineLatest:@[RACObserve(self, number), RACObserve(self, questionArr)] reduce:^id (NSNumber *num, NSArray *selectArr){
  742. @strongify(self)
  743. [self.handInThePaperView.totalNumberOfQuestionsBtn setTitleNormal:[NSString stringWithFormat:@"%ld/%lu",(self.questionArr.count == 0)? 0 : [num integerValue] + 1,(unsigned long)self.questionArr.count]];
  744. return [NSString stringWithFormat:@"%ld/%lu",(self.questionArr.count == 0)? 0 : [num integerValue] + 1,(unsigned long)self.questionArr.count];
  745. }];
  746. }
  747. return _handInThePaperView;
  748. }
  749. - (NSMutableArray *)correctArr {
  750. if (!_correctArr) {
  751. _correctArr = @[].mutableCopy;
  752. }
  753. return _correctArr;
  754. }
  755. - (NSMutableArray *)errorArr {
  756. if (!_errorArr) {
  757. _errorArr = @[].mutableCopy;
  758. }
  759. return _errorArr;
  760. }
  761. @end