CourseViewController.m 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. //
  2. // CourseViewController.m
  3. // KulexiuForTeacher
  4. //
  5. // Created by Kyle on 2022/3/17.
  6. //
  7. #import "CourseViewController.h"
  8. #import "FSCalendar.h"
  9. #import "CourseNavView.h"
  10. #import "LTSCalendarBottomView.h"
  11. #import <KSFullDatePicker.h>
  12. #import "AccompanyCourseCell.h"
  13. #import "CourseForLiveCell.h"
  14. #import "TableCourseModel.h"
  15. #import "KSChatConversationViewController.h"
  16. #import "KSGroupConversationController.h"
  17. #import "KSEnterLiveroomManager.h"
  18. #import "KSBaseWKWebViewController.h"
  19. #import "AccompanyDetailViewController.h"
  20. #import "VipCouseDetailViewController.h"
  21. #import <NSDate+Transform.h>
  22. #import "MusicRoomCourseCell.h"
  23. #import "MusicRoomViewController.h"
  24. #import "VIPCourseCell.h"
  25. @interface CourseViewController ()<UITableViewDataSource,UITableViewDelegate,FSCalendarDataSource,FSCalendarDelegate,UIGestureRecognizerDelegate>
  26. {
  27. void * _KVOContext;
  28. }
  29. @property (nonatomic, strong) CourseNavView *navHeadView;
  30. @property (nonatomic, strong) NSString *chooseMonth;
  31. @property (nonatomic, strong) NSString *chooseDay;
  32. @property (nonatomic,strong) FSCalendar *calendar;
  33. @property (strong, nonatomic) NSCalendar *gregorian;
  34. @property (nonatomic, strong) UITableView *tableView;
  35. @property (strong, nonatomic) UIPanGestureRecognizer *scopeGesture;
  36. @property (strong, nonatomic) NSDateFormatter *dateFormatter;
  37. @property (nonatomic, strong) LTSCalendarBottomView *calendarBottom;
  38. @property (nonatomic, assign) BOOL cancleRequest;
  39. @property (nonatomic, strong) KSFullDatePicker *datePicker;
  40. @property (nonatomic, assign) BOOL isPickerChoose; // 是否选择的月份
  41. @property (nonatomic, assign) NSInteger vipStartTime; // VIP课开课前可进入时间配置(分钟)
  42. @property (nonatomic, assign) NSInteger vipEndTime; // VIP课结束后退出时间配置(分钟)
  43. @property (nonatomic, assign) NSInteger practiceStartTime; // 趣纠课开课前可进入时间配置(分钟)
  44. @property (nonatomic, assign) NSInteger practiceEndTime; // 趣纠课结束后退出时间配置(分钟)
  45. @property (nonatomic, assign) NSInteger liveStartTime; // 直播课开课前可进入时间配置(分钟)
  46. @property (nonatomic, assign) NSInteger liveEndTime; // 直播课结束后退出时间配置(分钟)
  47. @property (nonatomic, assign) NSInteger pianoStartTime; // 琴房课开课前可进入时间配置(分钟)
  48. @property (nonatomic, assign) NSInteger pianoEndTime; // 琴房课结束后退出时间配置(分钟)
  49. @property (nonatomic, strong) NSString *adjustBeginTime; // 可调整开始时间
  50. @property (nonatomic, strong) NSString *adjustEndTime; // 可调整结束时间
  51. @end
  52. @implementation CourseViewController
  53. - (void)viewDidLoad {
  54. [super viewDidLoad];
  55. // Do any additional setup after loading the view.
  56. self.ks_prefersNavigationBarHidden = YES;
  57. [self configUI];
  58. [self loadCalendarInfo];
  59. }
  60. - (void)loadCalendarInfo {
  61. NSDateFormatter *formatter = [NSObject getDateformatter];
  62. [formatter setDateFormat:@"yyyy-MM"];
  63. NSDate *date = [NSDate date];
  64. self.chooseMonth = [formatter stringFromDate:date];
  65. [formatter setDateFormat:@"yyyy-MM-dd"];
  66. self.chooseDay = [NSString stringWithFormat:@"%@ 00:00:00", [formatter stringFromDate:date]];
  67. [self.calendar selectDate:date];
  68. // title 显示
  69. [formatter setDateFormat:@"yyyy年MM月"];
  70. [self.navHeadView.navTitle setText:[formatter stringFromDate:date]];
  71. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  72. }
  73. - (void)viewWillAppear:(BOOL)animated {
  74. [super viewWillAppear:animated];
  75. [self loadMonthCourse:self.chooseMonth];
  76. if (![NSString isEmptyString:self.chooseDay]) {
  77. [self getCourseByDate:self.chooseDay];
  78. }
  79. [self requestAdjustConfig];
  80. }
  81. - (void)requestAdjustConfig {
  82. [KSNetworkingManager queryCourseAdjustTimeLimit:KS_GET success:^(NSDictionary * _Nonnull dic) {
  83. if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
  84. NSArray *result = [dic ks_arrayValueForKey:@"data"];
  85. for (NSDictionary *parm in result) {
  86. if ([[parm ks_stringValueForKey:@"paramName"] isEqualToString:@"course_start_setting"]) { // 开始时间
  87. NSString *begTime = [parm ks_stringValueForKey:@"paramValue"];
  88. if (![NSString isEmptyString:begTime]) {
  89. self.adjustBeginTime = [NSString stringWithFormat:@"%@",begTime];
  90. }
  91. }
  92. else if ([[parm ks_stringValueForKey:@"paramName"] isEqualToString:@"course_end_setting"]) { // 结束时间
  93. NSString *endTime = [parm ks_stringValueForKey:@"paramValue"];
  94. if (![NSString isEmptyString:endTime]) {
  95. self.adjustEndTime = [NSString stringWithFormat:@"%@",endTime];
  96. }
  97. }
  98. }
  99. }
  100. else {
  101. }
  102. } faliure:^(NSError * _Nonnull error) {
  103. }];
  104. }
  105. - (void)configEmptyView {
  106. [self setPromptString:@"暂无课程" imageName:@"empty_course" inView:self.tableView];
  107. }
  108. - (void)configUI {
  109. [self.view addSubview:self.navHeadView];
  110. [self.navHeadView mas_makeConstraints:^(MASConstraintMaker *make) {
  111. make.left.right.top.mas_equalTo(self.view);
  112. make.height.mas_equalTo(kNaviBarHeight);
  113. }];
  114. [self.scrollView mas_remakeConstraints:^(MASConstraintMaker *make) {
  115. make.left.right.mas_equalTo(self.view);
  116. make.top.mas_equalTo(self.navHeadView.mas_bottom);
  117. make.bottom.mas_equalTo(self.view.mas_bottom);
  118. }];
  119. UIView *containerView = [[UIView alloc] initWithFrame:CGRectZero];
  120. containerView.backgroundColor = [UIColor clearColor];
  121. [self.scrollView addSubview:containerView];
  122. [containerView mas_makeConstraints:^(MASConstraintMaker *make) {
  123. make.edges.mas_equalTo(self.scrollView);
  124. make.width.mas_equalTo(self.scrollView);
  125. }];
  126. self.calendar = [[FSCalendar alloc] init];
  127. [self configCalendar];
  128. [containerView addSubview:self.calendar];
  129. [self.calendar mas_makeConstraints:^(MASConstraintMaker *make) {
  130. make.left.right.mas_equalTo(containerView);
  131. make.top.mas_equalTo(containerView.mas_top);
  132. make.height.mas_equalTo(300);
  133. }];
  134. self.calendarBottom = [LTSCalendarBottomView shareInstance];
  135. MJWeakSelf;
  136. [self.calendarBottom changeDisplay:^{
  137. [weakSelf changeDisplay];
  138. }];
  139. [containerView addSubview:self.calendarBottom];
  140. [self.calendarBottom mas_makeConstraints:^(MASConstraintMaker *make) {
  141. make.left.right.mas_equalTo(containerView);
  142. make.top.mas_equalTo(self.calendar.mas_bottom);
  143. make.height.mas_equalTo(40);
  144. }];
  145. [containerView addSubview:self.tableView];
  146. CGFloat tableHeight = kScreenHeight - kNaviBarHeight - kTabBarHeight - 300 - 40;
  147. [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
  148. make.left.right.mas_equalTo(self.view);
  149. make.top.mas_equalTo(self.calendarBottom.mas_bottom);
  150. make.height.mas_equalTo(tableHeight);
  151. }];
  152. [containerView mas_makeConstraints:^(MASConstraintMaker *make) {
  153. make.bottom.mas_equalTo(self.tableView.mas_bottom);
  154. }];
  155. UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self.calendar action:@selector(handleScopeGesture:)];
  156. panGesture.delegate = self;
  157. panGesture.minimumNumberOfTouches = 1;
  158. panGesture.maximumNumberOfTouches = 2;
  159. [self.scrollView addGestureRecognizer:panGesture];
  160. self.scopeGesture = panGesture;
  161. [self.tableView.panGestureRecognizer requireGestureRecognizerToFail:panGesture];
  162. self.scrollView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
  163. [weakSelf.calendar setToday:[NSDate date]];
  164. [weakSelf loadMonthCourse:weakSelf.chooseMonth];
  165. if (![NSString isEmptyString:weakSelf.chooseDay]) {
  166. [weakSelf getCourseByDate:weakSelf.chooseDay];
  167. }
  168. }];
  169. self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  170. [self configEmptyView];
  171. }
  172. - (void)endRefresh {
  173. @weakObj(self);
  174. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  175. @strongObj(self);
  176. [self.scrollView.mj_header endRefreshing];
  177. });
  178. }
  179. #pragma mark ---- calender action
  180. // 收起或展开日历
  181. - (void)changeDisplay {
  182. FSCalendarScope selectedScope = self.calendar.scope == FSCalendarScopeMonth ? FSCalendarScopeWeek : FSCalendarScopeMonth;
  183. [self.calendar setScope:selectedScope animated:YES];
  184. NSString *imgName = selectedScope == FSCalendarScopeWeek ? @"arrow_down" : @"arrow_up";
  185. [self.calendarBottom.arrowImage setImage:[UIImage imageNamed:imgName]];
  186. [self.calendar reloadData];
  187. }
  188. - (void)configCalendar {
  189. self.calendar.backgroundColor = [UIColor whiteColor];
  190. self.calendar.appearance.titleFont = [UIFont systemFontOfSize:14.0f weight:UIFontWeightMedium];
  191. self.calendar.appearance.titleDefaultColor = HexRGB(0x444444);
  192. self.calendar.appearance.titleTodayColor = HexRGB(0x444444);
  193. self.calendar.appearance.titleSelectionColor = [UIColor whiteColor];
  194. self.calendar.appearance.selectionColor = THEMECOLOR;
  195. self.calendar.appearance.weekdayFont = [UIFont systemFontOfSize:14.0f];
  196. self.calendar.appearance.weekdayTextColor = HexRGB(0x777777);
  197. self.calendar.appearance.titleWeekendColor = THEMECOLOR;
  198. self.calendar.appearance.todaySelectionColor = THEMECOLOR;
  199. self.calendar.appearance.todayColor = [UIColor whiteColor];
  200. self.calendar.appearance.todayBorderColor = [UIColor whiteColor];
  201. self.calendar.appearance.borderRadius = 0.2f;
  202. self.calendar.appearance.borderDefaultColor = [UIColor whiteColor];
  203. self.calendar.appearance.titleHightlightColor = HexRGB(0x444444);
  204. self.calendar.appearance.backgoundHightlightColor = HexRGBAlpha(0xffd7a6, 0.21);
  205. self.calendar.appearance.subtitleFont = [UIFont systemFontOfSize:10.0f];
  206. self.calendar.appearance.subtitleOffset = CGPointMake(0, 3);
  207. self.calendar.appearance.subtitleTodayColor = HexRGB(0xff6363);
  208. self.calendar.appearance.subtitleDefaultColor = HexRGB(0xff6363);
  209. self.calendar.appearance.subtitleSelectionColor = [UIColor whiteColor];
  210. self.calendar.appearance.titleTodayColor = THEMECOLOR;
  211. self.calendar.dataSource = self;
  212. self.calendar.delegate = self;
  213. // self.calendar.firstWeekday = 2;
  214. self.calendar.appearance.caseOptions = FSCalendarCaseOptionsWeekdayUsesSingleUpperCase|FSCalendarCaseOptionsHeaderUsesUpperCase;
  215. self.calendar.calendarHeaderView.hidden = YES;
  216. self.calendar.locale = [NSLocale localeWithLocaleIdentifier:@"zh_CN"];
  217. [self.calendar addObserver:self forKeyPath:@"scope" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:_KVOContext];
  218. self.calendar.placeholderType = FSCalendarPlaceholderTypeNone;
  219. self.calendar.scope = FSCalendarScopeMonth;
  220. [self.calendar selectDate:[NSDate date] scrollToDate:YES];
  221. }
  222. #pragma mark - FSCalendarDataSource
  223. - (NSString *)calendar:(FSCalendar *)calendar subtitleForDate:(NSDate *)date {
  224. // 判断有课的日期显示subtitle
  225. if ([calendar.highlightDates containsObject:date]) {
  226. return @"有课";
  227. }
  228. return nil;
  229. }
  230. #pragma mark - FSCalendarDelegate
  231. - (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated
  232. {
  233. [calendar mas_updateConstraints:^(MASConstraintMaker *make) {
  234. make.height.mas_equalTo(bounds.size.height);
  235. // Do other updates
  236. }];
  237. [self.tableView mas_updateConstraints:^(MASConstraintMaker *make) {
  238. make.height.mas_equalTo(kScreenHeight - kTabBarHeight - bounds.size.height - kNaviBarHeight - 40);
  239. }];
  240. [self.view layoutIfNeeded];
  241. }
  242. - (void)calendar:(FSCalendar *)calendar didSelectDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)monthPosition
  243. {
  244. NSLog(@"did select date %@",[self.dateFormatter stringFromDate:date]);
  245. NSMutableArray *selectedDates = [NSMutableArray arrayWithCapacity:calendar.selectedDates.count];
  246. [calendar.selectedDates enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  247. [selectedDates addObject:[self.dateFormatter stringFromDate:obj]];
  248. }];
  249. self.navHeadView.navTitle.text = [self.dateFormatter stringFromDate:date];
  250. NSLog(@"selected dates is %@",selectedDates);
  251. if (monthPosition == FSCalendarMonthPositionNext || monthPosition == FSCalendarMonthPositionPrevious) {
  252. [calendar setCurrentPage:date animated:YES];
  253. }
  254. NSDateFormatter *formatter = [NSObject getDateformatter];
  255. [formatter setDateFormat:@"yyyy-MM-dd"];
  256. NSString *dateStr = [formatter stringFromDate:date];
  257. dateStr = [NSString stringWithFormat:@"%@ 00:00:00", dateStr];
  258. self.chooseDay = dateStr;
  259. [self getCourseByDate:dateStr];
  260. }
  261. - (void)calendarCurrentPageDidChange:(FSCalendar *)calendar {
  262. if (_isPickerChoose) {
  263. _isPickerChoose = NO;
  264. return;
  265. }
  266. self.navHeadView.navTitle.text = [self.dateFormatter stringFromDate:calendar.currentPage];
  267. NSLog(@"%s %@", __FUNCTION__, [self.dateFormatter stringFromDate:calendar.currentPage]);
  268. // 获取当前月份信息
  269. NSDateFormatter *formatter = [NSObject getDateformatter];
  270. [formatter setDateFormat:@"yyyy-MM"];
  271. NSString *month = [formatter stringFromDate:calendar.currentPage];
  272. if (![_chooseMonth isEqualToString:month]) {
  273. _chooseMonth = month;
  274. [self loadMonthCourse:month];
  275. }
  276. [formatter setDateFormat:@"yyyy-MM-dd"];
  277. NSString *chooseDay = [formatter stringFromDate:calendar.currentPage];
  278. self.chooseDay = chooseDay;
  279. [self.calendar selectDate:calendar.currentPage];
  280. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  281. NSString *currentDate = [formatter stringFromDate:calendar.currentPage];
  282. [self getCourseByDate:currentDate];
  283. }
  284. #pragma mark --- 获取当前月份有课日期
  285. - (void)loadMonthCourse:(NSString *)month {
  286. [KSNetworkingManager queryCourseSchedule:KS_POST classMonth:month success:^(NSDictionary * _Nonnull dic) {
  287. [self endRefresh];
  288. if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
  289. NSArray *courseArray = [dic ks_arrayValueForKey:@"data"];
  290. NSMutableArray *courseDateArray = [NSMutableArray array];
  291. for (NSString *dateString in courseArray) {
  292. NSString *dateStr = [NSString stringWithFormat:@"%@ %@", dateString, @"00:00:00"];
  293. [courseDateArray addObject:dateStr];
  294. }
  295. self.calendar.highlightDates = courseDateArray;
  296. [self.calendar reloadData];
  297. }
  298. else {
  299. [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
  300. }
  301. } faliure:^(NSError * _Nonnull error) {
  302. [self endRefresh];
  303. }];
  304. }
  305. #pragma mark --- 获取当日课程
  306. - (void)getCourseByDate:(NSString *)date {
  307. [KSNetworkingManager queryCourseForDay:KS_POST classDate:date success:^(NSDictionary * _Nonnull dic) {
  308. if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
  309. // 配置信息
  310. NSDictionary *config = [[dic ks_dictionaryValueForKey:@"data"] ks_dictionaryValueForKey:@"sysConfig"];
  311. self.vipStartTime = [config ks_integerValueForKey:@"vipStartTime"];
  312. self.vipEndTime = [config ks_integerValueForKey:@"vipEndTime"];
  313. self.practiceStartTime = [config ks_integerValueForKey:@"practiceStartTime"];
  314. self.practiceEndTime = [config ks_integerValueForKey:@"practiceEndTime"];
  315. self.liveStartTime = [config ks_integerValueForKey:@"liveStartTime"];
  316. self.liveEndTime = [config ks_integerValueForKey:@"liveEndTime"];
  317. self.pianoStartTime = [config ks_integerValueForKey:@"pianoStartTime"];
  318. self.pianoEndTime = [config ks_integerValueForKey:@"pianoEndTime"];
  319. NSArray *courseArray = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"studentList"];
  320. NSMutableArray *lessonArray = [NSMutableArray array];
  321. for (NSDictionary *parm in courseArray) {
  322. TableCourseModel *model = [[TableCourseModel alloc] initWithDictionary:parm];
  323. [lessonArray addObject:model];
  324. }
  325. self.dataArray = [lessonArray mutableCopy];
  326. }
  327. else {
  328. [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
  329. }
  330. [self.tableView reloadData];
  331. [self changePromptLabelState];
  332. } faliure:^(NSError * _Nonnull error) {
  333. }];
  334. }
  335. #pragma mark - <UIGestureRecognizerDelegate>
  336. // Whether scope gesture should begin
  337. - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
  338. {
  339. BOOL shouldBegin = self.tableView.contentOffset.y <= -self.tableView.contentInset.top;
  340. if (shouldBegin) {
  341. CGPoint velocity = [self.scopeGesture velocityInView:self.view];
  342. switch (self.calendar.scope) {
  343. case FSCalendarScopeMonth:
  344. return velocity.y < 0;
  345. case FSCalendarScopeWeek:
  346. return velocity.y > 0;
  347. }
  348. }
  349. return shouldBegin;
  350. }
  351. #pragma mark - KVO
  352. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
  353. {
  354. if (context == _KVOContext) {
  355. FSCalendarScope oldScope = [change[NSKeyValueChangeOldKey] unsignedIntegerValue];
  356. FSCalendarScope newScope = [change[NSKeyValueChangeNewKey] unsignedIntegerValue];
  357. NSLog(@"From %@ to %@",(oldScope==FSCalendarScopeWeek?@"week":@"month"),(newScope==FSCalendarScopeWeek?@"week":@"month"));
  358. NSString *imgName = newScope == FSCalendarScopeWeek ? @"arrow_down" : @"arrow_up";
  359. [self.calendarBottom.arrowImage setImage:[UIImage imageNamed:imgName]];
  360. } else {
  361. [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  362. }
  363. }
  364. #pragma mark --- table data source
  365. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
  366. return 1;
  367. }
  368. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
  369. return self.dataArray.count;
  370. }
  371. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  372. return 137.0f;
  373. }
  374. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  375. TableCourseModel *model = self.dataArray[indexPath.row];
  376. if ([model.courseType isEqualToString:@"PRACTICE"]) { // 趣纠课
  377. AccompanyCourseCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AccompanyCourseCell"];
  378. MJWeakSelf;
  379. [cell configWithCourseMessage:model beforeTime:self.practiceStartTime actionCallback:^(ACCOMPANY_TYPE type, TableCourseModel * _Nonnull courseModel) {
  380. [weakSelf accompanyLessonAction:type source:courseModel];
  381. }];
  382. return cell;
  383. }
  384. else if ([model.courseType isEqualToString:@"LIVE"]) { // 直播课
  385. CourseForLiveCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CourseForLiveCell"];
  386. MJWeakSelf;
  387. [cell configWithSource:model beforeTime:self.liveStartTime callback:^(LIVECOURSEACTION action, TableCourseModel *sourceModel) {
  388. [weakSelf liveCourseAction:action source:sourceModel];
  389. }];
  390. return cell;
  391. }
  392. else if ([model.courseType isEqualToString:@"VIP"]) { // 定制课
  393. VIPCourseCell *cell = [tableView dequeueReusableCellWithIdentifier:@"VIPCourseCell"];
  394. MJWeakSelf;
  395. [cell configWithCourseMessage:model beforeTime:self.vipStartTime actionCallback:^(ACCOMPANY_TYPE type, TableCourseModel * _Nonnull courseModel) {
  396. [weakSelf vipLessionAction:type source:courseModel];
  397. }];
  398. return cell;
  399. }
  400. else { // 琴房课 PIANO_ROOM_CLASS
  401. BOOL isGroup = [model.courseType isEqualToString:@"GROUP"] ? YES : NO;
  402. MusicRoomCourseCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MusicRoomCourseCell"];
  403. MJWeakSelf;
  404. [cell configWithSource:model isGroup:isGroup beforeTime:self.pianoStartTime callback:^(NSString * _Nonnull targetId) {
  405. [weakSelf chatAction:targetId groupName:@"" isGroup:YES];
  406. }];
  407. return cell;
  408. }
  409. }
  410. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  411. TableCourseModel *model = self.dataArray[indexPath.row];
  412. if ([model.courseType isEqualToString:@"PRACTICE"]) { // 趣纠课
  413. [self showAccompanyDetailAction:model];
  414. }
  415. else if ([model.courseType isEqualToString:@"VIP"]) {
  416. [self showVipDetailAction:model];
  417. }
  418. else if ([model.courseType isEqualToString:@"LIVE"]) { // 直播课详情
  419. [self liveCourseDetail:model.courseId courseGroupId:model.courseGoupId];
  420. }
  421. else if ([model.courseType isEqualToString:@"GROUP"]) {
  422. MusicRoomViewController *ctrl = [[MusicRoomViewController alloc] init];
  423. ctrl.courseType = MUTIL_COURSE_TYPE_GROUP;
  424. ctrl.courseId = model.courseId;
  425. ctrl.courseGroupId = model.courseGoupId;
  426. [self.navigationController pushViewController:ctrl animated:YES];
  427. }
  428. else {
  429. MusicRoomViewController *ctrl = [[MusicRoomViewController alloc] init];
  430. ctrl.courseType = MUTIL_COURSE_TYPE_MUSIC;
  431. ctrl.courseId = model.courseId;
  432. ctrl.courseGroupId = model.courseGoupId;
  433. [self.navigationController pushViewController:ctrl animated:YES];
  434. }
  435. }
  436. - (void)accompanyLessonAction:(ACCOMPANY_TYPE)action source:(TableCourseModel *)source {
  437. switch (action) {
  438. case ACCOMPANY_TYPE_CHAT:
  439. {
  440. [self chatAction:source.imUserId groupName:source.name isGroup:NO];
  441. }
  442. break;
  443. case ACCOMPANY_TYPE_ADJUST:
  444. {
  445. [self adjustCourseAction:source];
  446. }
  447. break;
  448. case ACCOMPANY_DETAIL:
  449. {
  450. [self showAccompanyDetailAction:source];
  451. }
  452. break;
  453. default:
  454. break;
  455. }
  456. }
  457. - (void)vipLessionAction:(ACCOMPANY_TYPE)action source:(TableCourseModel *)source {
  458. switch (action) {
  459. case ACCOMPANY_TYPE_CHAT:
  460. {
  461. [self chatAction:source.imUserId groupName:source.name isGroup:NO];
  462. }
  463. break;
  464. case ACCOMPANY_TYPE_ADJUST:
  465. {
  466. [self adjustCourseAction:source];
  467. }
  468. break;
  469. case ACCOMPANY_DETAIL:
  470. {
  471. [self showVipDetailAction:source];
  472. }
  473. break;
  474. default:
  475. break;
  476. }
  477. }
  478. - (void)adjustCourseAction:(TableCourseModel *)source {
  479. // 获取当前课程的时间
  480. NSString *formatString = @"yyyy-MM-dd HH:mm:ss";
  481. NSDateFormatter *dateFormat = [NSObject getDateformatter];
  482. dateFormat.dateFormat = @"yyyy年MM月";
  483. [dateFormat setDateFormat:formatString];
  484. NSDate *courseBeginDate = [dateFormat dateFromString:source.startTime];
  485. if (courseBeginDate == nil) {
  486. courseBeginDate = [NSDate date];
  487. }
  488. KSFullDatePicker *adjustPicker = [[KSFullDatePicker alloc] initWithTitle:@"课程调整" date:courseBeginDate pickMode:KSDATEPICKER_MODE_DAY_TIME sureButtonColor:THEMECOLOR selectDateBlock:^(NSString *date) {
  489. NSString *timeString = [NSString stringWithFormat:@"%@:00", date];
  490. [self adjustCourseWithSource:source time:timeString];
  491. } cancleBlock:^{
  492. }];
  493. [adjustPicker show];
  494. }
  495. - (void)adjustCourseWithSource:(TableCourseModel *)model time:(NSString *)chooseTime {
  496. NSString *formatString = @"yyyy-MM-dd HH:mm:ss";
  497. NSTimeInterval courseDuration = [NSDate countTimesTampWithBeginTime:model.startTime endTime:model.endTime format:formatString];
  498. NSDate *endDate = [NSDate dateWithTimeInterval:courseDuration sinceDate:[NSDate dateFromString:chooseTime format:formatString]];
  499. NSString *endTime = [endDate stringDateWithFormat:formatString];
  500. NSString *classDay = [[chooseTime componentsSeparatedByString:@" "] firstObject];
  501. NSString *classDate = [NSString stringWithFormat:@"%@ 00:00:00", classDay];
  502. // 判断是否能在规定的时间内
  503. if (![NSString isEmptyString:self.adjustBeginTime] && ![NSString isEmptyString:self.adjustEndTime]) {
  504. NSString *limitBegin = [NSString stringWithFormat:@"%@ %@:00",classDay,self.adjustBeginTime];
  505. NSString *limitEnd = [NSString stringWithFormat:@"%@ %@:00",classDay,self.adjustEndTime];
  506. NSTimeInterval beginDuration = [NSDate countTimesTampWithBeginTime:limitBegin endTime:chooseTime format:formatString];
  507. NSTimeInterval endDuration = [NSDate countTimesTampWithBeginTime:endTime endTime:limitEnd format:formatString];
  508. if (beginDuration < 0) {
  509. [LOADING_MANAGER MBShowAUTOHidingInWindow:[NSString stringWithFormat:@"课程开始时间不可早于%@",self.adjustBeginTime]];
  510. return;
  511. }
  512. else if (endDuration < 0) {
  513. [LOADING_MANAGER MBShowAUTOHidingInWindow:[NSString stringWithFormat:@"课程结束时间不可晚于%@",self.adjustEndTime]];
  514. return;
  515. }
  516. }
  517. [LOADING_MANAGER showCustomLoading:@"加载中..."];
  518. [KSNetworkingManager courseAdjustRequst:KS_POST courseId:model.courseId classDate:classDate startTime:chooseTime endTime:endTime success:^(NSDictionary * _Nonnull dic) {
  519. [LOADING_MANAGER removeCustomLoading];
  520. if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
  521. [LOADING_MANAGER KSShowMsg:@"调整成功" promptCompletion:^{
  522. [self loadMonthCourse:self.chooseMonth];
  523. if (![NSString isEmptyString:self.chooseDay]) {
  524. [self getCourseByDate:self.chooseDay];
  525. }
  526. }];
  527. }
  528. else {
  529. [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
  530. }
  531. } faliure:^(NSError * _Nonnull error) {
  532. [LOADING_MANAGER removeCustomLoading];
  533. }];
  534. }
  535. - (void)showAccompanyDetailAction:(TableCourseModel *)source {
  536. AccompanyDetailViewController *detailVC = [[AccompanyDetailViewController alloc] init];
  537. detailVC.courseId = source.courseId;
  538. detailVC.courseGroupId = source.courseGoupId;
  539. detailVC.studentId = source.userId;
  540. [self.navigationController pushViewController:detailVC animated:YES];
  541. }
  542. - (void)showVipDetailAction:(TableCourseModel *)source {
  543. VipCouseDetailViewController *detailVC = [[VipCouseDetailViewController alloc] init];
  544. detailVC.courseId = source.courseId;
  545. detailVC.courseGroupId = source.courseGoupId;
  546. detailVC.studentId = source.userId;
  547. [self.navigationController pushViewController:detailVC animated:YES];
  548. }
  549. - (void)liveCourseAction:(LIVECOURSEACTION)action source:(TableCourseModel *)source {
  550. switch (action) {
  551. case LIVECOURSEACTION_CHAT: // 聊天
  552. {
  553. [self chatAction:source.imGroupId groupName:@"" isGroup:YES];
  554. }
  555. break;
  556. case LIVECOURSEACTION_LIVEROOM: // 直播课上课
  557. {
  558. [self liveCourseDetail:source.courseId courseGroupId:source.courseGoupId];
  559. }
  560. break;
  561. default:
  562. break;
  563. }
  564. }
  565. - (void)chatAction:(NSString *)targetId groupName:(NSString *)targetName isGroup:(BOOL)isGroup {
  566. if ([NSString isEmptyString:targetId] && isGroup) {
  567. [LOADING_MANAGER MBShowAUTOHidingInWindow:@"报名未结束,暂无群组"];
  568. return;
  569. }
  570. if (isGroup) {
  571. TUIChatConversationModel *model = [[TUIChatConversationModel alloc] init];
  572. model.groupID = targetId;
  573. KSGroupConversationController *ctrl = [[KSGroupConversationController alloc] init];
  574. ctrl.conversation = model;
  575. [self.navigationController pushViewController:ctrl animated:YES];
  576. }
  577. else {
  578. TUIChatConversationModel *model = [[TUIChatConversationModel alloc] init];
  579. model.userID = targetId;
  580. KSChatConversationViewController *ctrl = [[KSChatConversationViewController alloc] init];
  581. ctrl.conversation = model;
  582. [self.navigationController pushViewController:ctrl animated:YES];
  583. }
  584. }
  585. - (void)liveCourseDetail:(NSString *)courseId courseGroupId:(NSString *)courseGroupId {
  586. KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
  587. ctrl.url = [NSString stringWithFormat:@"%@/#/liveDetail?joinRoom=1&groupId=%@&classId=%@", WEBHOST, courseGroupId,courseId];
  588. [self.navigationController pushViewController:ctrl animated:YES];
  589. }
  590. #pragma mark --- lazying
  591. - (CourseNavView *)navHeadView {
  592. if (!_navHeadView) {
  593. _navHeadView = [CourseNavView shareInstance];
  594. MJWeakSelf;
  595. [_navHeadView chooseNavCallback:^{
  596. [weakSelf displayMounthPicker];
  597. }];
  598. }
  599. return _navHeadView;
  600. }
  601. - (KSFullDatePicker *)datePicker {
  602. if (!_datePicker) {
  603. _datePicker = [[KSFullDatePicker alloc] initWithTitle:@"" date:[NSDate date] pickMode:KSDATEPICKER_MODE_YEAR_MONTH sureButtonColor:THEMECOLOR selectDateBlock:^(NSString *date) {
  604. self.navHeadView.navTitle.text = [self getTimeDisplay:date];
  605. self.chooseMonth = date;
  606. [self resetPickerStatus];
  607. [self scrollCalendarToChooseMonth];
  608. } cancleBlock:^{
  609. [self resetPickerStatus];
  610. }];
  611. }
  612. return _datePicker;
  613. }
  614. - (void)scrollCalendarToChooseMonth {
  615. self.isPickerChoose = YES;
  616. NSDateFormatter *formatter = [NSObject getDateformatter];
  617. [formatter setDateFormat:@"yyyy-MM"];
  618. NSDate *chooseDate = [formatter dateFromString:self.chooseMonth];
  619. [formatter setDateFormat:@"yyyy-MM-dd"];
  620. self.chooseDay = [NSString stringWithFormat:@"%@ 00:00:00", [formatter stringFromDate:chooseDate]];
  621. [self.calendar setCurrentPage:chooseDate animated:YES];
  622. [self loadMonthCourse:self.chooseMonth];
  623. if (![NSString isEmptyString:self.chooseDay]) {
  624. [self.calendar selectDate:chooseDate];
  625. [self getCourseByDate:self.chooseDay];
  626. }
  627. }
  628. - (NSString *)getTimeDisplay:(NSString *)chooseMonth {
  629. [self.dateFormatter setDateFormat:@"yyyy-MM"];
  630. NSDate *chooseDate = [self.dateFormatter dateFromString:chooseMonth];
  631. [self.dateFormatter setDateFormat:@"yyyy年MM月"];
  632. NSString *displayTime = [self.dateFormatter stringFromDate:chooseDate];
  633. return displayTime;
  634. }
  635. - (void)resetPickerStatus {
  636. self.navHeadView.arrowUp = NO;
  637. }
  638. - (void)displayMounthPicker {
  639. [self.datePicker show];
  640. }
  641. - (NSDateFormatter *)dateFormatter {
  642. if (!_dateFormatter) {
  643. _dateFormatter = [NSObject getDateformatter];
  644. _dateFormatter.dateFormat = @"yyyy年MM月";
  645. }
  646. return _dateFormatter;
  647. }
  648. - (UITableView *)tableView {
  649. if (!_tableView) {
  650. _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
  651. _tableView.delegate = self;
  652. _tableView.dataSource = self;
  653. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  654. _tableView.backgroundColor = [UIColor clearColor];
  655. _tableView.showsVerticalScrollIndicator = NO;
  656. _tableView.showsHorizontalScrollIndicator = NO;
  657. [_tableView registerNib:[UINib nibWithNibName:@"AccompanyCourseCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"AccompanyCourseCell"];
  658. [_tableView registerNib:[UINib nibWithNibName:@"CourseForLiveCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"CourseForLiveCell"];
  659. [_tableView registerNib:[UINib nibWithNibName:@"MusicRoomCourseCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"MusicRoomCourseCell"];
  660. [_tableView registerNib:[UINib nibWithNibName:@"VIPCourseCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"VIPCourseCell"];
  661. UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 15)];
  662. bottomView.backgroundColor = [UIColor clearColor];
  663. _tableView.tableFooterView = bottomView;
  664. }
  665. return _tableView;
  666. }
  667. /*
  668. #pragma mark - Navigation
  669. // In a storyboard-based application, you will often want to do a little preparation before navigation
  670. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  671. // Get the new view controller using [segue destinationViewController].
  672. // Pass the selected object to the new view controller.
  673. }
  674. */
  675. @end