RQExerciseSubViewController.m 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  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==0?exerciseModel.idYdt: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. NSLog(@"$$$-下一页:%zd",self.number);
  461. [self.coverVC setController:[self creatSubVC] animated:YES isAbove:NO];
  462. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  463. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  464. [self.view bringSubviewToFront:self.errorExerciseToolBarView];
  465. } else {
  466. [self.view bringSubviewToFront:self.exerciseToolBarView];
  467. }
  468. } else {
  469. [self.view bringSubviewToFront:self.handInThePaperView];
  470. }
  471. }
  472. - (void)jumpLastQuestion{
  473. if (self.number == 0) {
  474. return;
  475. }
  476. self.number -= 1;
  477. NSLog(@"$$$-上一页:%zd",self.number);
  478. [self.coverVC setController:[self creatSubVC] animated:YES isAbove:YES];
  479. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  480. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  481. [self.view bringSubviewToFront:self.errorExerciseToolBarView];
  482. } else {
  483. [self.view bringSubviewToFront:self.exerciseToolBarView];
  484. }
  485. } else {
  486. [self.view bringSubviewToFront:self.handInThePaperView];
  487. }
  488. }
  489. - (void)jumpQuestionWithIndex:(NSUInteger)index {
  490. self.number = (int)index;
  491. [self.coverVC setController:[self creatSubVC] animated:NO isAbove:NO];
  492. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  493. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  494. [self.view bringSubviewToFront:self.errorExerciseToolBarView];
  495. } else {
  496. [self.view bringSubviewToFront:self.exerciseToolBarView];
  497. }
  498. } else {
  499. [self.view bringSubviewToFront:self.handInThePaperView];
  500. }
  501. }
  502. - (void)creatToolsBar {
  503. if (self.viewModel.exerciseType != RQExerciseType_Test && self.viewModel.exerciseType != RQExerciseType_Exam) {
  504. if (self.viewModel.homeSubEditListType == RQHomeSubEditListType_WrongTopic) {
  505. [self.view addSubview:self.errorExerciseToolBarView];
  506. [_errorExerciseToolBarView mas_makeConstraints:^(MASConstraintMaker *make) {
  507. make.centerX.mas_equalTo(self.view);
  508. make.bottom.mas_equalTo(self.view).mas_offset(-(RQ_APPLICATION_SAFEAREA_BOTTOM_HEIGHT + RQ_APPLICATION_NAV_BAR_HEIGHT));
  509. make.size.mas_equalTo(CGSizeMake(RQ_SCREEN_WIDTH, 50));
  510. }];
  511. } else {
  512. [self.view addSubview:self.exerciseToolBarView];
  513. [_exerciseToolBarView mas_makeConstraints:^(MASConstraintMaker *make) {
  514. make.centerX.mas_equalTo(self.view);
  515. make.bottom.mas_equalTo(self.view).mas_offset(-(RQ_APPLICATION_SAFEAREA_BOTTOM_HEIGHT + RQ_APPLICATION_NAV_BAR_HEIGHT));
  516. make.size.mas_equalTo(CGSizeMake(RQ_SCREEN_WIDTH, 50));
  517. }];
  518. }
  519. } else {
  520. [self.view addSubview:self.handInThePaperView];
  521. [_handInThePaperView mas_makeConstraints:^(MASConstraintMaker *make) {
  522. make.centerX.mas_equalTo(self.view);
  523. make.bottom.mas_equalTo(self.view).mas_offset(-(RQ_APPLICATION_SAFEAREA_BOTTOM_HEIGHT + RQ_APPLICATION_NAV_BAR_HEIGHT));
  524. make.size.mas_equalTo(CGSizeMake(RQ_SCREEN_WIDTH, 8.f + RQ_FIT_HORIZONTAL(54.f) + 8.f + 50.f + 8.f));
  525. }];
  526. }
  527. }
  528. - (void)showCatalogue {
  529. @weakify(self)
  530. if (self.questionArr.count == 0) {
  531. return;
  532. }
  533. RQCatalogueViewModel *catalogueViewModel = [[RQCatalogueViewModel alloc] initWithServices:self.viewModel.services params:@{
  534. RQViewModelIDKey : @(self.number),
  535. RQViewModelUtilKey : self.questionArr,
  536. RQViewCommonValueKey : @(self.correctArr.count),
  537. RQViewModelRequestKey : @(self.errorArr.count),
  538. }];
  539. RQCatalogueViewController *catalogueViewController = [[RQCatalogueViewController alloc] initWithViewModel:catalogueViewModel];
  540. [catalogueViewController initCompletionWithSelectIndexBlock:^(NSInteger index) {
  541. @strongify(self)
  542. [self jumpQuestionWithIndex:index];
  543. }];
  544. [self presentPanModal:catalogueViewController];
  545. }
  546. #pragma mark - DZMCoverControllerDelegate
  547. /// 切换结果
  548. - (void)coverController:(DZMCoverController *)coverController currentController:(UIViewController *)currentController finish:(BOOL)isFinish {
  549. if (!isFinish) { // 切换失败
  550. // RQTestQuestionsViewController *vc = (RQTestQuestionsViewController *)currentController;
  551. }
  552. }
  553. /// 上一个控制器
  554. - (UIViewController *)coverController:(DZMCoverController *)coverController getAboveControllerWithCurrentController:(UIViewController *)currentController {
  555. if (self.number == 0) {
  556. return nil;
  557. }
  558. self.number -= 1;
  559. return [self creatSubVC];
  560. }
  561. /// 下一个控制器
  562. - (UIViewController *)coverController:(DZMCoverController *)coverController getBelowControllerWithCurrentController:(UIViewController *)currentController {
  563. if (self.number==self.questionArr.count-1) {
  564. return nil;
  565. }
  566. self.number += 1;
  567. return [self creatSubVC];
  568. }
  569. #pragma mark - UITableViewDataSource, UITableViewDelegate
  570. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  571. !self.scrollCallback ?: self.scrollCallback(scrollView);
  572. }
  573. #pragma mark - JXPagingViewListViewDelegate
  574. - (UIView *)listView {
  575. return self.view;
  576. }
  577. - (UIScrollView *)listScrollView {
  578. return self.tableView;
  579. }
  580. - (void)listViewDidScrollCallback:(void (^)(UIScrollView *))callback {
  581. self.scrollCallback = callback;
  582. }
  583. #pragma mark - LazyLoad
  584. - (NSMutableArray *)questionArr {
  585. if (!_questionArr) {
  586. _questionArr = @[].mutableCopy;
  587. }
  588. return _questionArr;
  589. }
  590. - (RQExerciseToolBarView *)exerciseToolBarView {
  591. if (!_exerciseToolBarView) {
  592. _exerciseToolBarView = [RQExerciseToolBarView exerciseToolBarView];
  593. @weakify(self,_exerciseToolBarView);
  594. // [RACObserve(self, number) subscribeNext:^(id _Nullable x) {
  595. // @strongify(self,_exerciseToolBarView)
  596. // _exerciseToolBarView.totalNumberOfQuestionsLabel.text = [NSString stringWithFormat:@"%ld/%lu",[x integerValue] + 1,(unsigned long)self.questionArr.count];
  597. // }];
  598. RAC(_exerciseToolBarView.totalNumberOfQuestionsLabel, text) = [RACSignal combineLatest:@[RACObserve(self, number), RACObserve(self, questionArr)] reduce:^id (NSNumber *num, NSArray *selectArr){
  599. @strongify(self)
  600. return [NSString stringWithFormat:@"%ld/%lu",(self.questionArr.count == 0)? 0 : [num integerValue] + 1,(unsigned long)self.questionArr.count];
  601. }];
  602. [_exerciseToolBarView.lastQuestionView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  603. @strongify(self)
  604. _exerciseToolBarView.lastQuestionView.userInteractionEnabled = NO;
  605. [self jumpLastQuestion];
  606. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.6f *NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  607. _exerciseToolBarView.lastQuestionView.userInteractionEnabled = YES;
  608. });
  609. }];
  610. [_exerciseToolBarView.nextQuestionView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  611. @strongify(self)
  612. _exerciseToolBarView.nextQuestionView.userInteractionEnabled = NO;
  613. [self jumpNextQuestion];
  614. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.6f *NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  615. _exerciseToolBarView.nextQuestionView.userInteractionEnabled = YES;
  616. });
  617. }];
  618. [_exerciseToolBarView.totalNumberOfQuestionsView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  619. @strongify(self)
  620. [self showCatalogue];
  621. }];
  622. [_exerciseToolBarView.officialInterpretationView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  623. @strongify(self)
  624. if (self.questionArr.count == 0) {
  625. return;
  626. }
  627. RQExerciseModel *exerciseModel = self.questionArr[self.number];
  628. if (RQ_Exercise_Module.isAutoRead) RQ_Exercise_Module.isAutoRead = NO;
  629. [RQ_Exercise_Module rq_showOfficialInterpretationAlertWithMessage:exerciseModel.explain_js mp3Url:exerciseModel.explainjsmp3];
  630. }];
  631. }
  632. return _exerciseToolBarView;
  633. }
  634. - (RQErrorExerciseToolBarView *)errorExerciseToolBarView {
  635. if (!_errorExerciseToolBarView) {
  636. _errorExerciseToolBarView = [RQErrorExerciseToolBarView errorExerciseToolBarView];
  637. @weakify(self);
  638. RAC(_errorExerciseToolBarView.totalNumberOfQuestionsLabel, text) = [RACSignal combineLatest:@[RACObserve(self, number), RACObserve(self, questionArr)] reduce:^id (NSNumber *num, NSArray *selectArr){
  639. @strongify(self)
  640. return [NSString stringWithFormat:@"%ld/%lu",(self.questionArr.count == 0)? 0 : [num integerValue] + 1,(unsigned long)self.questionArr.count];
  641. }];
  642. // [RACObserve(self, number) subscribeNext:^(id _Nullable x) {
  643. // @strongify(self,_errorExerciseToolBarView)
  644. // _errorExerciseToolBarView.totalNumberOfQuestionsLabel.text = [NSString stringWithFormat:@"%ld/%lu",(self.questionArr.count == 0)? 0 : [x integerValue] + 1,(unsigned long)self.questionArr.count];
  645. // }];
  646. [_errorExerciseToolBarView.deleteView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  647. @strongify(self)
  648. if (self.questionArr.count == 0) {
  649. return;
  650. }
  651. RQExerciseModel *exerciseModel = self.questionArr[self.number];
  652. // [[RQ_HTTP_Service queryDeleteWrongRecordWithQuestionId:[NSString qmui_stringWithNSInteger:exerciseModel._id]] subscribeNext:^(id _Nullable x) {
  653. // @strongify(self)
  654. // [RQ_SDJK_DB_MANAGER deleteWrongRecordWithQuestionId:exerciseModel._id];
  655. // [[self mutableArrayValueForKey:@"questionArr"] removeObject:exerciseModel];
  656. // [MBProgressHUD rq_showTips:@"删除成功"];
  657. // [self.coverVC.view removeFromSuperview];
  658. // [RQ_SDJK_DB_MANAGER getAllWrongModelsCount];
  659. // if ([self.errorArr containsObject:exerciseModel]) {
  660. // [self.errorArr removeObject:exerciseModel];
  661. // } else if ([self.correctArr containsObject:exerciseModel]) {
  662. // [self.correctArr removeObject:exerciseModel];
  663. // }
  664. //
  665. // if (self.questionArr.count == 0) {
  666. // self.number = 0;
  667. // _errorExerciseToolBarView.errorOptionNumLabel.text = @"0";
  668. // _errorExerciseToolBarView.correctOptionNumLabel.text = @"0";
  669. // } else {
  670. // self.number = (self.questionArr.count == 1)? 0 : ((self.number == 0)? 0 : self.number - 1);
  671. // [self creatCoverVC];
  672. // [self.view bringSubviewToFront:self.errorExerciseToolBarView];
  673. // _errorExerciseToolBarView.errorOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.errorArr.count];
  674. // _errorExerciseToolBarView.correctOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.correctArr.count];
  675. // }
  676. // } error:^(NSError * _Nullable error) {
  677. // [MBProgressHUD rq_showErrorTips:error];
  678. // }];
  679. BOOL isDelete = [RQ_SDJK_DB_MANAGER deleteWrongRecordWithQuestionId:exerciseModel._id];
  680. if (isDelete) {
  681. [[self mutableArrayValueForKey:@"questionArr"] removeObject:exerciseModel];
  682. [MBProgressHUD rq_showTips:@"删除成功"];
  683. [self.coverVC.view removeFromSuperview];
  684. [RQ_SDJK_DB_MANAGER getAllWrongModelsCount];
  685. if ([self.errorArr containsObject:exerciseModel]) {
  686. [self.errorArr removeObject:exerciseModel];
  687. } else if ([self.correctArr containsObject:exerciseModel]) {
  688. [self.correctArr removeObject:exerciseModel];
  689. }
  690. if (self.questionArr.count == 0) {
  691. self.number = 0;
  692. self.errorExerciseToolBarView.errorOptionNumLabel.text = @"0";
  693. self.errorExerciseToolBarView.correctOptionNumLabel.text = @"0";
  694. } else {
  695. self.number = (self.questionArr.count == 1)? 0 : ((self.number == 0)? 0 : self.number - 1);
  696. [self creatCoverVC];
  697. [self.view bringSubviewToFront:self.errorExerciseToolBarView];
  698. self.errorExerciseToolBarView.errorOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.errorArr.count];
  699. self.errorExerciseToolBarView.correctOptionNumLabel.text = [NSString stringWithFormat:@"%lu",(unsigned long)self.correctArr.count];
  700. }
  701. } else {
  702. [MBProgressHUD rq_showTips:@"删除失败"];
  703. }
  704. }];
  705. [_errorExerciseToolBarView.totalNumberOfQuestionsView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  706. @strongify(self)
  707. [self showCatalogue];
  708. }];
  709. [_errorExerciseToolBarView.officialInterpretationView setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  710. @strongify(self)
  711. if (self.questionArr.count == 0) {
  712. return;
  713. }
  714. RQExerciseModel *exerciseModel = self.questionArr[self.number];
  715. if (RQ_Exercise_Module.isAutoRead) RQ_Exercise_Module.isAutoRead = NO;
  716. [RQ_Exercise_Module rq_showOfficialInterpretationAlertWithMessage:exerciseModel.explain_js mp3Url:exerciseModel.explainjsmp3];
  717. }];
  718. }
  719. return _errorExerciseToolBarView;
  720. }
  721. - (RQHandInThePaperView *)handInThePaperView {
  722. if (!_handInThePaperView) {
  723. @weakify(self)
  724. _handInThePaperView = [RQHandInThePaperView handInThePaperView];
  725. [_handInThePaperView.handInThePaperBtn setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  726. @strongify(self)
  727. 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;
  728. RQTestResultsViewModel *testResultsViewModel = [[RQTestResultsViewModel alloc] initWithServices:self.viewModel.services params:@{
  729. RQHomePageCarTypeKey : @(self.viewModel.homePageCarType),
  730. RQHomePageSubjectTypeKey : @(self.viewModel.homePageSubjectType),
  731. RQHomeSubPageTypeKey : @(self.viewModel.homeSubPageType),
  732. RQExerciseTypeKey : @(self.viewModel.exerciseType),
  733. RQViewModelIDKey : @(score),
  734. RQViewCommonValueKey : @(self.count),
  735. RQViewModelUtilKey : self.questionArr,
  736. }];
  737. [self.viewModel.services pushViewModel:testResultsViewModel animated:YES];
  738. }];
  739. [_handInThePaperView.lastQuestionBtn setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  740. @strongify(self)
  741. _handInThePaperView.lastQuestionBtn.enabled = NO;
  742. [self jumpLastQuestion];
  743. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.6f *NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  744. _handInThePaperView.lastQuestionBtn.enabled = YES;
  745. });
  746. }];
  747. [_handInThePaperView.nextQuestionBtn setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  748. @strongify(self)
  749. _handInThePaperView.nextQuestionBtn.enabled = NO;
  750. [self jumpNextQuestion];
  751. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.6f *NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  752. _handInThePaperView.nextQuestionBtn.enabled = YES;
  753. });
  754. }];
  755. [_handInThePaperView.totalNumberOfQuestionsBtn setTapActionWithBlock:^(UITapGestureRecognizer *tap) {
  756. @strongify(self)
  757. [self showCatalogue];
  758. }];
  759. RAC(_handInThePaperView.totalNumberOfQuestionsBtn.titleLabel, text) = [RACSignal combineLatest:@[RACObserve(self, number), RACObserve(self, questionArr)] reduce:^id (NSNumber *num, NSArray *selectArr){
  760. @strongify(self)
  761. [self.handInThePaperView.totalNumberOfQuestionsBtn setTitleNormal:[NSString stringWithFormat:@"%ld/%lu",(self.questionArr.count == 0)? 0 : [num integerValue] + 1,(unsigned long)self.questionArr.count]];
  762. return [NSString stringWithFormat:@"%ld/%lu",(self.questionArr.count == 0)? 0 : [num integerValue] + 1,(unsigned long)self.questionArr.count];
  763. }];
  764. }
  765. return _handInThePaperView;
  766. }
  767. - (NSMutableArray *)correctArr {
  768. if (!_correctArr) {
  769. _correctArr = @[].mutableCopy;
  770. }
  771. return _correctArr;
  772. }
  773. - (NSMutableArray *)errorArr {
  774. if (!_errorArr) {
  775. _errorArr = @[].mutableCopy;
  776. }
  777. return _errorArr;
  778. }
  779. @end