Steven 8 mesi fa
parent
commit
f4e75af4ff
76 ha cambiato i file con 4443 aggiunte e 147 eliminazioni
  1. 182 0
      KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj
  2. 1 1
      KulexiuForTeacher/KulexiuForTeacher.xcodeproj/xcshareddata/xcschemes/KulexiuForTeacher.xcscheme
  3. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/search_green.imageset/search_green@2x.png
  4. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/search_green.imageset/search_green@3x.png
  5. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Course/course_musicRoom.imageset/course_musicRoom@2x.png
  6. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Course/course_musicRoom.imageset/course_musicRoom@3x.png
  7. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/fansGroup_alert_top.imageset/fansGroup_alert_top@2x.png
  8. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/fansGroup_alert_top.imageset/fansGroup_alert_top@3x.png
  9. 6 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/Contents.json
  10. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/arrange_course_icon.imageset/Contents.json
  11. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/arrange_course_icon.imageset/arrange_course_icon@2x.png
  12. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/arrange_course_icon.imageset/arrange_course_icon@3x.png
  13. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/course_desc_top.imageset/Contents.json
  14. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/course_desc_top.imageset/course_desc_top@2x.png
  15. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/course_desc_top.imageset/course_desc_top@3x.png
  16. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/live_courseGroup_icon.imageset/Contents.json
  17. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/live_courseGroup_icon.imageset/live_courseGroup_icon@2x.png
  18. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/live_courseGroup_icon.imageset/live_courseGroup_icon@3x.png
  19. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/myCourse_bg.imageset/Contents.json
  20. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/myCourse_bg.imageset/myCourse_bg@2x.png
  21. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/myCourse_bg.imageset/myCourse_bg@3x.png
  22. 50 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h
  23. 82 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m
  24. 6 6
      KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/KSChatListSearchView.xib
  25. 6 6
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MusicRoom/View/MusicRoomCourseInfoCell.xib
  26. 0 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Controller/HomeViewController.m
  27. 9 9
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/View/MusicRoomHomeworkCell.xib
  28. 128 100
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Controller/MyCourseViewController.m
  29. 3 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/LiveLessonModel.h
  30. 22 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/LiveLessonModel.m
  31. 28 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/ProgramCourseGroupModel.h
  32. 155 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/ProgramCourseGroupModel.m
  33. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/AccompanyCourseGroup/MyAccompanyCourseGroupView.h
  34. 299 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/AccompanyCourseGroup/MyAccompanyCourseGroupView.m
  35. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertCell.h
  36. 48 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertCell.m
  37. 67 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertCell.xib
  38. 31 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertView.h
  39. 140 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertView.m
  40. 117 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertView.xib
  41. 19 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/LiveCourseGroup/MyLiveCourseGroupListCell.h
  42. 74 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/LiveCourseGroup/MyLiveCourseGroupListCell.m
  43. 191 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/LiveCourseGroup/MyLiveCourseGroupListCell.xib
  44. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/LiveCourseGroup/MyLiveCourseGroupView.h
  45. 311 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/LiveCourseGroup/MyLiveCourseGroupView.m
  46. 11 11
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseCell.xib
  47. 19 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseGroup/MyMusicGroupListCell.h
  48. 80 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseGroup/MyMusicGroupListCell.m
  49. 141 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseGroup/MyMusicGroupListCell.xib
  50. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseGroup/MyMusicRoomCourseGroupView.h
  51. 296 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseGroup/MyMusicRoomCourseGroupView.m
  52. 24 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseGroupNavView.h
  53. 54 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseGroupNavView.m
  54. 86 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseGroupNavView.xib
  55. 31 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseSortView/MyCourseSearchView.h
  56. 65 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseSortView/MyCourseSearchView.m
  57. 129 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseSortView/MyCourseSearchView.xib
  58. 19 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VIPCourseGroup/MyProgramCourseGroupCell.h
  59. 93 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VIPCourseGroup/MyProgramCourseGroupCell.m
  60. 147 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VIPCourseGroup/MyProgramCourseGroupCell.xib
  61. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VIPCourseGroup/MyVipCourseGroupView.h
  62. 298 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VIPCourseGroup/MyVipCourseGroupView.m
  63. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VideoCourseGroup/MyVideoCourseGroupView.h
  64. 304 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VideoCourseGroup/MyVideoCourseGroupView.m
  65. 19 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VideoCourseGroup/MyVideoGroupListCell.h
  66. 71 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VideoCourseGroup/MyVideoGroupListCell.m
  67. 196 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VideoCourseGroup/MyVideoGroupListCell.xib
  68. 16 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertCell.h
  69. 26 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertCell.m
  70. 25 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertCell.xib
  71. 8 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertView.h
  72. 40 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertView.m
  73. 37 2
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertView.xib
  74. 9 8
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/MinePageLiveCourse/MineLiveCourseGroupCell.xib
  75. 27 2
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/VipCourse/MinePageVIPCourseView.m
  76. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Widget/View/toneTuning/TunerSettingView.m

+ 182 - 0
KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj

@@ -879,6 +879,15 @@
 		BCA724052806AFF100DA0D0D /* AccompanyCourseInfoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCA724032806AFF100DA0D0D /* AccompanyCourseInfoCell.xib */; };
 		BCA7C34328476533009D20EC /* KSBoardAddStaffView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA7C34028476532009D20EC /* KSBoardAddStaffView.m */; };
 		BCA7C34428476533009D20EC /* KSBoardAddStaffView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCA7C34228476532009D20EC /* KSBoardAddStaffView.xib */; };
+		BCA9AC442CED91F200047BFA /* MyLiveCourseGroupListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA9AC422CED91F200047BFA /* MyLiveCourseGroupListCell.m */; };
+		BCA9AC452CED91F200047BFA /* MyLiveCourseGroupListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCA9AC432CED91F200047BFA /* MyLiveCourseGroupListCell.xib */; };
+		BCA9AC492CED921100047BFA /* MyVideoGroupListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCA9AC482CED921100047BFA /* MyVideoGroupListCell.xib */; };
+		BCA9AC4A2CED921100047BFA /* MyVideoGroupListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA9AC472CED921100047BFA /* MyVideoGroupListCell.m */; };
+		BCA9AC4E2CED921E00047BFA /* MyMusicGroupListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA9AC4C2CED921E00047BFA /* MyMusicGroupListCell.m */; };
+		BCA9AC4F2CED921E00047BFA /* MyMusicGroupListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCA9AC4D2CED921E00047BFA /* MyMusicGroupListCell.xib */; };
+		BCA9AC522CEDB57500047BFA /* ProgramCourseGroupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA9AC512CEDB57500047BFA /* ProgramCourseGroupModel.m */; };
+		BCA9AC582CEDDDEE00047BFA /* FansGroupAlertCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA9AC562CEDDDEE00047BFA /* FansGroupAlertCell.m */; };
+		BCA9AC592CEDDDEE00047BFA /* FansGroupAlertCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCA9AC572CEDDDEE00047BFA /* FansGroupAlertCell.xib */; };
 		BCA9CE1527FD339400D558C6 /* AuthDisplayView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA9CE1427FD339400D558C6 /* AuthDisplayView.m */; };
 		BCA9CE1727FD339D00D558C6 /* AuthDisplayView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCA9CE1627FD339D00D558C6 /* AuthDisplayView.xib */; };
 		BCA9CE1E27FD5F9D00D558C6 /* MyLiveCourseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA9CE1D27FD5F9D00D558C6 /* MyLiveCourseViewController.m */; };
@@ -1022,6 +1031,21 @@
 		BCC9F44727F69BD200647449 /* ClassSongMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC9F3F927F69BD200647449 /* ClassSongMessage.m */; };
 		BCC9F44827F69BD200647449 /* Classroom.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC9F3FA27F69BD200647449 /* Classroom.m */; };
 		BCC9F44927F69BD200647449 /* ClassroomService.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC9F40027F69BD200647449 /* ClassroomService.m */; };
+		BCD1604C2CED7F2E00A78B43 /* MyCourseSearchView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD1604B2CED7F2E00A78B43 /* MyCourseSearchView.m */; };
+		BCD1604E2CED7F3600A78B43 /* MyCourseSearchView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD1604D2CED7F3600A78B43 /* MyCourseSearchView.xib */; };
+		BCD160572CED845A00A78B43 /* MyVipCourseGroupView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD160562CED845A00A78B43 /* MyVipCourseGroupView.m */; };
+		BCD1605A2CED846A00A78B43 /* MyAccompanyCourseGroupView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD160592CED846A00A78B43 /* MyAccompanyCourseGroupView.m */; };
+		BCD160602CED849300A78B43 /* MyLiveCourseGroupView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD1605F2CED849300A78B43 /* MyLiveCourseGroupView.m */; };
+		BCD160632CED84A300A78B43 /* MyVideoCourseGroupView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD160622CED84A300A78B43 /* MyVideoCourseGroupView.m */; };
+		BCD160662CED84B000A78B43 /* MyMusicRoomCourseGroupView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD160652CED84B000A78B43 /* MyMusicRoomCourseGroupView.m */; };
+		BCD160692CED86FB00A78B43 /* MyCourseGroupNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD160682CED86FB00A78B43 /* MyCourseGroupNavView.m */; };
+		BCD1606B2CED870700A78B43 /* MyCourseGroupNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD1606A2CED870700A78B43 /* MyCourseGroupNavView.xib */; };
+		BCD160732CED8DF600A78B43 /* CourseDescAlertCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD1606F2CED8DF600A78B43 /* CourseDescAlertCell.xib */; };
+		BCD160742CED8DF600A78B43 /* CourseDescAlertView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD160722CED8DF600A78B43 /* CourseDescAlertView.xib */; };
+		BCD160752CED8DF600A78B43 /* CourseDescAlertCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD1606E2CED8DF600A78B43 /* CourseDescAlertCell.m */; };
+		BCD160762CED8DF600A78B43 /* CourseDescAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD160712CED8DF600A78B43 /* CourseDescAlertView.m */; };
+		BCD1607A2CED8EA700A78B43 /* MyProgramCourseGroupCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD160792CED8EA700A78B43 /* MyProgramCourseGroupCell.xib */; };
+		BCD1607B2CED8EA700A78B43 /* MyProgramCourseGroupCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD160782CED8EA700A78B43 /* MyProgramCourseGroupCell.m */; };
 		BCD457A5286319660010B493 /* CourseTimeSegView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD457A4286319660010B493 /* CourseTimeSegView.m */; };
 		BCD457A72863196F0010B493 /* CourseTimeSegView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD457A62863196E0010B493 /* CourseTimeSegView.xib */; };
 		BCD457B2286564DB0010B493 /* LiveRoomAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD457B1286564DB0010B493 /* LiveRoomAlertView.m */; };
@@ -2623,6 +2647,20 @@
 		BCA7C34028476532009D20EC /* KSBoardAddStaffView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSBoardAddStaffView.m; sourceTree = "<group>"; };
 		BCA7C34128476532009D20EC /* KSBoardAddStaffView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSBoardAddStaffView.h; sourceTree = "<group>"; };
 		BCA7C34228476532009D20EC /* KSBoardAddStaffView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSBoardAddStaffView.xib; sourceTree = "<group>"; };
+		BCA9AC412CED91F200047BFA /* MyLiveCourseGroupListCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyLiveCourseGroupListCell.h; sourceTree = "<group>"; };
+		BCA9AC422CED91F200047BFA /* MyLiveCourseGroupListCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyLiveCourseGroupListCell.m; sourceTree = "<group>"; };
+		BCA9AC432CED91F200047BFA /* MyLiveCourseGroupListCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyLiveCourseGroupListCell.xib; sourceTree = "<group>"; };
+		BCA9AC462CED921100047BFA /* MyVideoGroupListCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyVideoGroupListCell.h; sourceTree = "<group>"; };
+		BCA9AC472CED921100047BFA /* MyVideoGroupListCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyVideoGroupListCell.m; sourceTree = "<group>"; };
+		BCA9AC482CED921100047BFA /* MyVideoGroupListCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyVideoGroupListCell.xib; sourceTree = "<group>"; };
+		BCA9AC4B2CED921E00047BFA /* MyMusicGroupListCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyMusicGroupListCell.h; sourceTree = "<group>"; };
+		BCA9AC4C2CED921E00047BFA /* MyMusicGroupListCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyMusicGroupListCell.m; sourceTree = "<group>"; };
+		BCA9AC4D2CED921E00047BFA /* MyMusicGroupListCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyMusicGroupListCell.xib; sourceTree = "<group>"; };
+		BCA9AC502CEDB57500047BFA /* ProgramCourseGroupModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProgramCourseGroupModel.h; sourceTree = "<group>"; };
+		BCA9AC512CEDB57500047BFA /* ProgramCourseGroupModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ProgramCourseGroupModel.m; sourceTree = "<group>"; };
+		BCA9AC552CEDDDEE00047BFA /* FansGroupAlertCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FansGroupAlertCell.h; sourceTree = "<group>"; };
+		BCA9AC562CEDDDEE00047BFA /* FansGroupAlertCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FansGroupAlertCell.m; sourceTree = "<group>"; };
+		BCA9AC572CEDDDEE00047BFA /* FansGroupAlertCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FansGroupAlertCell.xib; sourceTree = "<group>"; };
 		BCA9CE1327FD339400D558C6 /* AuthDisplayView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AuthDisplayView.h; sourceTree = "<group>"; };
 		BCA9CE1427FD339400D558C6 /* AuthDisplayView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AuthDisplayView.m; sourceTree = "<group>"; };
 		BCA9CE1627FD339D00D558C6 /* AuthDisplayView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AuthDisplayView.xib; sourceTree = "<group>"; };
@@ -2849,6 +2887,31 @@
 		BCC9F3FE27F69BD200647449 /* RoomMember.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomMember.h; sourceTree = "<group>"; };
 		BCC9F3FF27F69BD200647449 /* ClassroomDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassroomDefine.h; sourceTree = "<group>"; };
 		BCC9F40027F69BD200647449 /* ClassroomService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ClassroomService.m; sourceTree = "<group>"; };
+		BCD1604A2CED7F2E00A78B43 /* MyCourseSearchView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyCourseSearchView.h; sourceTree = "<group>"; };
+		BCD1604B2CED7F2E00A78B43 /* MyCourseSearchView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyCourseSearchView.m; sourceTree = "<group>"; };
+		BCD1604D2CED7F3600A78B43 /* MyCourseSearchView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyCourseSearchView.xib; sourceTree = "<group>"; };
+		BCD160552CED845A00A78B43 /* MyVipCourseGroupView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyVipCourseGroupView.h; sourceTree = "<group>"; };
+		BCD160562CED845A00A78B43 /* MyVipCourseGroupView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyVipCourseGroupView.m; sourceTree = "<group>"; };
+		BCD160582CED846A00A78B43 /* MyAccompanyCourseGroupView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyAccompanyCourseGroupView.h; sourceTree = "<group>"; };
+		BCD160592CED846A00A78B43 /* MyAccompanyCourseGroupView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyAccompanyCourseGroupView.m; sourceTree = "<group>"; };
+		BCD1605E2CED849300A78B43 /* MyLiveCourseGroupView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyLiveCourseGroupView.h; sourceTree = "<group>"; };
+		BCD1605F2CED849300A78B43 /* MyLiveCourseGroupView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyLiveCourseGroupView.m; sourceTree = "<group>"; };
+		BCD160612CED84A300A78B43 /* MyVideoCourseGroupView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyVideoCourseGroupView.h; sourceTree = "<group>"; };
+		BCD160622CED84A300A78B43 /* MyVideoCourseGroupView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyVideoCourseGroupView.m; sourceTree = "<group>"; };
+		BCD160642CED84B000A78B43 /* MyMusicRoomCourseGroupView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyMusicRoomCourseGroupView.h; sourceTree = "<group>"; };
+		BCD160652CED84B000A78B43 /* MyMusicRoomCourseGroupView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyMusicRoomCourseGroupView.m; sourceTree = "<group>"; };
+		BCD160672CED86FB00A78B43 /* MyCourseGroupNavView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyCourseGroupNavView.h; sourceTree = "<group>"; };
+		BCD160682CED86FB00A78B43 /* MyCourseGroupNavView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyCourseGroupNavView.m; sourceTree = "<group>"; };
+		BCD1606A2CED870700A78B43 /* MyCourseGroupNavView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyCourseGroupNavView.xib; sourceTree = "<group>"; };
+		BCD1606D2CED8DF600A78B43 /* CourseDescAlertCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CourseDescAlertCell.h; sourceTree = "<group>"; };
+		BCD1606E2CED8DF600A78B43 /* CourseDescAlertCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CourseDescAlertCell.m; sourceTree = "<group>"; };
+		BCD1606F2CED8DF600A78B43 /* CourseDescAlertCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CourseDescAlertCell.xib; sourceTree = "<group>"; };
+		BCD160702CED8DF600A78B43 /* CourseDescAlertView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CourseDescAlertView.h; sourceTree = "<group>"; };
+		BCD160712CED8DF600A78B43 /* CourseDescAlertView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CourseDescAlertView.m; sourceTree = "<group>"; };
+		BCD160722CED8DF600A78B43 /* CourseDescAlertView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CourseDescAlertView.xib; sourceTree = "<group>"; };
+		BCD160772CED8EA700A78B43 /* MyProgramCourseGroupCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyProgramCourseGroupCell.h; sourceTree = "<group>"; };
+		BCD160782CED8EA700A78B43 /* MyProgramCourseGroupCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MyProgramCourseGroupCell.m; sourceTree = "<group>"; };
+		BCD160792CED8EA700A78B43 /* MyProgramCourseGroupCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyProgramCourseGroupCell.xib; sourceTree = "<group>"; };
 		BCD457A3286319660010B493 /* CourseTimeSegView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CourseTimeSegView.h; sourceTree = "<group>"; };
 		BCD457A4286319660010B493 /* CourseTimeSegView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CourseTimeSegView.m; sourceTree = "<group>"; };
 		BCD457A62863196E0010B493 /* CourseTimeSegView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CourseTimeSegView.xib; sourceTree = "<group>"; };
@@ -4500,6 +4563,8 @@
 		BC0167A227FC06C300AE66A1 /* Model */ = {
 			isa = PBXGroup;
 			children = (
+				BCA9AC502CEDB57500047BFA /* ProgramCourseGroupModel.h */,
+				BCA9AC512CEDB57500047BFA /* ProgramCourseGroupModel.m */,
 				BCDB093328058A8700D0BDAD /* LiveLessonModel.h */,
 				BCDB093228058A8700D0BDAD /* LiveLessonModel.m */,
 				BCA353D92858D97B00377661 /* MusicRoomListModel.h */,
@@ -4513,6 +4578,13 @@
 		BC0167A327FC06C300AE66A1 /* View */ = {
 			isa = PBXGroup;
 			children = (
+				BCD1606C2CED8DF000A78B43 /* CourseGroupAlertView */,
+				BCD160492CED7F1A00A78B43 /* MyCourseSortView */,
+				BCD1604F2CED83D400A78B43 /* VIPCourseGroup */,
+				BCD160502CED83EB00A78B43 /* AccompanyCourseGroup */,
+				BCD160512CED83FD00A78B43 /* LiveCourseGroup */,
+				BCD160522CED841000A78B43 /* VideoCourseGroup */,
+				BCD160542CED844000A78B43 /* MusicRoomCourseGroup */,
 				BCDB09382805C0DD00D0BDAD /* PopView */,
 				BCC03F93280562F700461B7C /* MyLessonBodyView.h */,
 				BCC03F94280562F700461B7C /* MyLessonBodyView.m */,
@@ -4532,6 +4604,9 @@
 				BCA353CB2858A86200377661 /* MusicRoomCourseCell.h */,
 				BCA353CC2858A86200377661 /* MusicRoomCourseCell.m */,
 				BCA353CD2858A86200377661 /* MusicRoomCourseCell.xib */,
+				BCD160672CED86FB00A78B43 /* MyCourseGroupNavView.h */,
+				BCD160682CED86FB00A78B43 /* MyCourseGroupNavView.m */,
+				BCD1606A2CED870700A78B43 /* MyCourseGroupNavView.xib */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -6847,6 +6922,9 @@
 				BCAF36EC2CEAE3E8009434AD /* FansGroupAlertView.h */,
 				BCAF36ED2CEAE3E8009434AD /* FansGroupAlertView.m */,
 				BCAF36EF2CEAE3EF009434AD /* FansGroupAlertView.xib */,
+				BCA9AC552CEDDDEE00047BFA /* FansGroupAlertCell.h */,
+				BCA9AC562CEDDDEE00047BFA /* FansGroupAlertCell.m */,
+				BCA9AC572CEDDDEE00047BFA /* FansGroupAlertCell.xib */,
 			);
 			path = FansGroupAlert;
 			sourceTree = "<group>";
@@ -7247,6 +7325,86 @@
 			path = Model;
 			sourceTree = "<group>";
 		};
+		BCD160492CED7F1A00A78B43 /* MyCourseSortView */ = {
+			isa = PBXGroup;
+			children = (
+				BCD1604A2CED7F2E00A78B43 /* MyCourseSearchView.h */,
+				BCD1604B2CED7F2E00A78B43 /* MyCourseSearchView.m */,
+				BCD1604D2CED7F3600A78B43 /* MyCourseSearchView.xib */,
+			);
+			path = MyCourseSortView;
+			sourceTree = "<group>";
+		};
+		BCD1604F2CED83D400A78B43 /* VIPCourseGroup */ = {
+			isa = PBXGroup;
+			children = (
+				BCD160552CED845A00A78B43 /* MyVipCourseGroupView.h */,
+				BCD160562CED845A00A78B43 /* MyVipCourseGroupView.m */,
+				BCD160772CED8EA700A78B43 /* MyProgramCourseGroupCell.h */,
+				BCD160782CED8EA700A78B43 /* MyProgramCourseGroupCell.m */,
+				BCD160792CED8EA700A78B43 /* MyProgramCourseGroupCell.xib */,
+			);
+			path = VIPCourseGroup;
+			sourceTree = "<group>";
+		};
+		BCD160502CED83EB00A78B43 /* AccompanyCourseGroup */ = {
+			isa = PBXGroup;
+			children = (
+				BCD160582CED846A00A78B43 /* MyAccompanyCourseGroupView.h */,
+				BCD160592CED846A00A78B43 /* MyAccompanyCourseGroupView.m */,
+			);
+			path = AccompanyCourseGroup;
+			sourceTree = "<group>";
+		};
+		BCD160512CED83FD00A78B43 /* LiveCourseGroup */ = {
+			isa = PBXGroup;
+			children = (
+				BCD1605E2CED849300A78B43 /* MyLiveCourseGroupView.h */,
+				BCD1605F2CED849300A78B43 /* MyLiveCourseGroupView.m */,
+				BCA9AC412CED91F200047BFA /* MyLiveCourseGroupListCell.h */,
+				BCA9AC422CED91F200047BFA /* MyLiveCourseGroupListCell.m */,
+				BCA9AC432CED91F200047BFA /* MyLiveCourseGroupListCell.xib */,
+			);
+			path = LiveCourseGroup;
+			sourceTree = "<group>";
+		};
+		BCD160522CED841000A78B43 /* VideoCourseGroup */ = {
+			isa = PBXGroup;
+			children = (
+				BCD160612CED84A300A78B43 /* MyVideoCourseGroupView.h */,
+				BCD160622CED84A300A78B43 /* MyVideoCourseGroupView.m */,
+				BCA9AC462CED921100047BFA /* MyVideoGroupListCell.h */,
+				BCA9AC472CED921100047BFA /* MyVideoGroupListCell.m */,
+				BCA9AC482CED921100047BFA /* MyVideoGroupListCell.xib */,
+			);
+			path = VideoCourseGroup;
+			sourceTree = "<group>";
+		};
+		BCD160542CED844000A78B43 /* MusicRoomCourseGroup */ = {
+			isa = PBXGroup;
+			children = (
+				BCD160642CED84B000A78B43 /* MyMusicRoomCourseGroupView.h */,
+				BCD160652CED84B000A78B43 /* MyMusicRoomCourseGroupView.m */,
+				BCA9AC4B2CED921E00047BFA /* MyMusicGroupListCell.h */,
+				BCA9AC4C2CED921E00047BFA /* MyMusicGroupListCell.m */,
+				BCA9AC4D2CED921E00047BFA /* MyMusicGroupListCell.xib */,
+			);
+			path = MusicRoomCourseGroup;
+			sourceTree = "<group>";
+		};
+		BCD1606C2CED8DF000A78B43 /* CourseGroupAlertView */ = {
+			isa = PBXGroup;
+			children = (
+				BCD1606D2CED8DF600A78B43 /* CourseDescAlertCell.h */,
+				BCD1606E2CED8DF600A78B43 /* CourseDescAlertCell.m */,
+				BCD1606F2CED8DF600A78B43 /* CourseDescAlertCell.xib */,
+				BCD160702CED8DF600A78B43 /* CourseDescAlertView.h */,
+				BCD160712CED8DF600A78B43 /* CourseDescAlertView.m */,
+				BCD160722CED8DF600A78B43 /* CourseDescAlertView.xib */,
+			);
+			path = CourseGroupAlertView;
+			sourceTree = "<group>";
+		};
 		BCD457B82865652C0010B493 /* AnimationView */ = {
 			isa = PBXGroup;
 			children = (
@@ -7715,6 +7873,7 @@
 				BC2820E52C9182D9008BD2CC /* GroupNoticeDetailBodyView.xib in Resources */,
 				BC71D1EF2887FDD40010F14B /* img_2.png in Resources */,
 				BC8B641D28F3E8D800A08D16 /* KSAwardAlertView.xib in Resources */,
+				BCD1606B2CED870700A78B43 /* MyCourseGroupNavView.xib in Resources */,
 				BC48C3B028292FBE00EE65C5 /* ReceiveHeaderView.xib in Resources */,
 				BC8B6DBA285327EE00866917 /* MusicShareDisplayView.xib in Resources */,
 				BC58E7D5281B9637004B0893 /* PublicNoticeView.xib in Resources */,
@@ -7863,6 +8022,9 @@
 				BC15535C2AB33B0300C1C347 /* TenantCreateStuView.xib in Resources */,
 				BC8B6E562856ED0600866917 /* iOS集成升级必读.pdf in Resources */,
 				BC8B6E6A28575DEE00866917 /* MusicDisplayView.xib in Resources */,
+				BCD160732CED8DF600A78B43 /* CourseDescAlertCell.xib in Resources */,
+				BCA9AC492CED921100047BFA /* MyVideoGroupListCell.xib in Resources */,
+				BCD160742CED8DF600A78B43 /* CourseDescAlertView.xib in Resources */,
 				BC9EFEB12C0480A500CFA7B1 /* BanStudentListCell.xib in Resources */,
 				BCB9FA21286D53A1005D766B /* ScanNavView.xib in Resources */,
 				BC7B0F5229271B650044CF61 /* CourseWarePreviewView.xib in Resources */,
@@ -7877,6 +8039,7 @@
 				BCB9FA4F28717BBD005D766B /* MyMusicSearchView.xib in Resources */,
 				BCC5840A28A9FA8100BAB4CF /* cloud_animation_6.png in Resources */,
 				BC483233282A6473005F534C /* HomeRecentCourseView.xib in Resources */,
+				BCA9AC452CED91F200047BFA /* MyLiveCourseGroupListCell.xib in Resources */,
 				2708565927ED961900EC8E72 /* ApplyBottomView.xib in Resources */,
 				BCB399AE27F946AA00AFF376 /* CourseNavView.xib in Resources */,
 				BC38C42B2AF900E100ABFCC2 /* KSMergeAudioControlView.xib in Resources */,
@@ -7890,6 +8053,7 @@
 				BCC5840E28A9FA8100BAB4CF /* cloud_animation_0.png in Resources */,
 				275B170D27EB14AC0081FDEF /* KSChatListSearchView.xib in Resources */,
 				BC71D1332887ADDA0010F14B /* teacher_refresh.json in Resources */,
+				BCD1604E2CED7F3600A78B43 /* MyCourseSearchView.xib in Resources */,
 				BC7CFFCA2817F2FF00CAEB21 /* CashRecordListCell.xib in Resources */,
 				BC1E284F2C77218A0063E0A1 /* KSDeleteFailedAlertView.xib in Resources */,
 				BCB9FA41286DA337005D766B /* GuideListView.xib in Resources */,
@@ -7948,6 +8112,7 @@
 				BC221FB628C82F0C00F99802 /* MinePageSortView.xib in Resources */,
 				BCA1135228A242FD007FAFB9 /* HomeBannerView.xib in Resources */,
 				BC3673D628A606A500059721 /* live_animation_0.png in Resources */,
+				BCA9AC592CEDDDEE00047BFA /* FansGroupAlertCell.xib in Resources */,
 				BC71D1FB2887FDD40010F14B /* img_28.png in Resources */,
 				BCA1135828A2439D007FAFB9 /* HomeBannerCell.xib in Resources */,
 				BC38C4292AF900E100ABFCC2 /* KSAudioAnimationView.xib in Resources */,
@@ -7975,6 +8140,7 @@
 				BC9EFE972C04804200CFA7B1 /* KSMuteTipsView.xib in Resources */,
 				BC31BFA02B219C5700F7D538 /* WidgetDotView.xib in Resources */,
 				BCC5841028A9FA8100BAB4CF /* cloud_animation_3.png in Resources */,
+				BCA9AC4F2CED921E00047BFA /* MyMusicGroupListCell.xib in Resources */,
 				BC32E10E286AB326001434DD /* KSPublicAlertView.xib in Resources */,
 				BC71D296288811BF0010F14B /* tabbar3.json in Resources */,
 				BC71D2022887FDD40010F14B /* img_30.png in Resources */,
@@ -8068,6 +8234,7 @@
 				BCD6D16728195A98009A773E /* WithdrawApplyBodyView.xib in Resources */,
 				BC5EB5BC2804083800B4A3B0 /* MyStyleIntroduceCell.xib in Resources */,
 				BC71D1FC2887FDD40010F14B /* img_25.png in Resources */,
+				BCD1607A2CED8EA700A78B43 /* MyProgramCourseGroupCell.xib in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -8157,6 +8324,8 @@
 				275E3DF727F467ED0010EC30 /* LiveRoomLikeLayer.m in Sources */,
 				BC7003232CE74F52008D041E /* ProgramAddButton.m in Sources */,
 				BC3A557F2BAA8F26002E1616 /* KSCloudWebManager.m in Sources */,
+				BCD160752CED8DF600A78B43 /* CourseDescAlertCell.m in Sources */,
+				BCD160762CED8DF600A78B43 /* CourseDescAlertView.m in Sources */,
 				BC38C42D2AF900E100ABFCC2 /* KSPlayerSliderView.m in Sources */,
 				BC71DE922A89C937003F165E /* TXClassroomTextMsg.m in Sources */,
 				BC38C4232AF900E100ABFCC2 /* UIView+KSCovertImage.m in Sources */,
@@ -8242,6 +8411,7 @@
 				BC41104228066E5500800BD9 /* EvaluateCourseListViewController.m in Sources */,
 				BC106B8E2A8F4586000759A9 /* TXMicStatusSync.m in Sources */,
 				BC41103B28066D2E00800BD9 /* HomeworkBodyView.m in Sources */,
+				BCD1604C2CED7F2E00A78B43 /* MyCourseSearchView.m in Sources */,
 				BC9070A228C7159800237958 /* MyStyleNavView.m in Sources */,
 				BC81F0E929232D01004106AF /* CoursewareListCell.m in Sources */,
 				275E8A6F27E18F2300DD3F6E /* ViewController.m in Sources */,
@@ -8255,6 +8425,7 @@
 				BCA9CE4327FD947C00D558C6 /* AccompanyArrangeCell.m in Sources */,
 				2779360F27E32BF20010E277 /* HomeViewController.m in Sources */,
 				27A2F62927E6C996009E2380 /* KSImageAlert.m in Sources */,
+				BCD160632CED84A300A78B43 /* MyVideoCourseGroupView.m in Sources */,
 				BC9473FD282A5E71004B3B27 /* NoticeSourceModel.m in Sources */,
 				BC8B6E6828575DD200866917 /* MusicDisplayView.m in Sources */,
 				BC31BF802B219C5700F7D538 /* ToneTuningViewController.m in Sources */,
@@ -8319,6 +8490,7 @@
 				BC12638C28FEB5E600509E90 /* ChatUserInfo.m in Sources */,
 				BC2888642A8100EA0064B773 /* KSGroupConversationController.m in Sources */,
 				BCF1BA5A27F5CF3C00FA36C4 /* LiveSeatApplyCell.m in Sources */,
+				BCD1605A2CED846A00A78B43 /* MyAccompanyCourseGroupView.m in Sources */,
 				BC14E4732AB2DAFD000C4983 /* StyleVideo.m in Sources */,
 				BC7CFFAF2817E6C900CAEB21 /* IncomeCountBottomView.m in Sources */,
 				BCE6A0A927F852CD00C97704 /* MineFansGroupCell.m in Sources */,
@@ -8344,6 +8516,7 @@
 				BC31BF8E2B219C5700F7D538 /* TuningNavView.m in Sources */,
 				BC71D293288811BF0010F14B /* AnimationHelper.m in Sources */,
 				BC60E3C0287D447F00B05441 /* DeleteAccountBodyView.m in Sources */,
+				BCD160662CED84B000A78B43 /* MyMusicRoomCourseGroupView.m in Sources */,
 				BC31BF9D2B219C5700F7D538 /* WidgetDotView.m in Sources */,
 				BC38C4272AF900E100ABFCC2 /* KSVideoPlayerView.m in Sources */,
 				2779326827E30FD80010E277 /* FSCalendar.m in Sources */,
@@ -8406,6 +8579,7 @@
 				BC8B6DBF28532DB800866917 /* MusicSheetVoList.m in Sources */,
 				2755C08D27ED5DB2007D9070 /* GroupApplyChooseCell.m in Sources */,
 				BCC0F7042A8CF13D00C4EFA4 /* TXDanChatCell.m in Sources */,
+				BCA9AC4E2CED921E00047BFA /* MyMusicGroupListCell.m in Sources */,
 				BCC5841A28AA36CF00BAB4CF /* BadgeIntroduceView.m in Sources */,
 				27D83F5727F4224F00062476 /* LivePreviewBodyView.m in Sources */,
 				BC1191F6280EBC7D00A716F7 /* AccompanyDetailBottomView.m in Sources */,
@@ -8479,6 +8653,7 @@
 				BC221FB928C8687300F99802 /* MusicSortView.m in Sources */,
 				BC4BCE7D2823B66000522C8B /* AddressDetailBodyView.m in Sources */,
 				BC38C4222AF900E100ABFCC2 /* KSPlayerView.m in Sources */,
+				BCA9AC442CED91F200047BFA /* MyLiveCourseGroupListCell.m in Sources */,
 				BC42CAAE2BEC9CDA001F076E /* RhythmChooseView.m in Sources */,
 				BCF425ED2AB975D200BCD942 /* TenantMineHeadView.m in Sources */,
 				27FC2F6D27F1BE4800FCC239 /* VideoCourseViewController.m in Sources */,
@@ -8503,6 +8678,7 @@
 				BCEA752028190CEB00886A86 /* CardBandResultViewController.m in Sources */,
 				BC106BA92A8F45AA000759A9 /* TXLiveDownSeatView.m in Sources */,
 				BCECE21C2B3D5F0800C0D555 /* FeedbackListCell.m in Sources */,
+				BCA9AC582CEDDDEE00047BFA /* FansGroupAlertCell.m in Sources */,
 				BCB9FA4D28717BB2005D766B /* MyMusicSearchView.m in Sources */,
 				275B170527EB13420081FDEF /* KSChatListViewController.m in Sources */,
 				BC106B7C2A8F4586000759A9 /* TXLiveMessageSeatControl.m in Sources */,
@@ -8600,6 +8776,7 @@
 				BC14A60D28A0AAE00086395C /* MineFunctionView.m in Sources */,
 				275E3DE727F4677F0010EC30 /* LiveRoomHeadView.m in Sources */,
 				BC106B882A8F4586000759A9 /* TXLiveMessageBlockUser.m in Sources */,
+				BCD160602CED849300A78B43 /* MyLiveCourseGroupView.m in Sources */,
 				BC106B7E2A8F4586000759A9 /* TXLiveMessageDownSeatAll.m in Sources */,
 				BC9EFEB32C0480A500CFA7B1 /* GroupBanBottomView.m in Sources */,
 				2779320427E30FC30010E277 /* KSHoldButton.m in Sources */,
@@ -8634,6 +8811,7 @@
 				BC33000F2BBAB5ED003D4921 /* KnowledgePointListModel.m in Sources */,
 				BCC0F7032A8CF13D00C4EFA4 /* TXDanBottomView.m in Sources */,
 				BC71DE932A89C937003F165E /* TXClassroomDeviceMsg.m in Sources */,
+				BCA9AC522CEDB57500047BFA /* ProgramCourseGroupModel.m in Sources */,
 				BCB908FB2850C9C300F5FF69 /* MusicChooseSearchView.m in Sources */,
 				BC2456EE286BEFC600D1F7C0 /* MineEmptyIntroduceCell.m in Sources */,
 				BCC0F7092A8CF13D00C4EFA4 /* TXDanMuView.m in Sources */,
@@ -8670,6 +8848,7 @@
 				BC106B772A8F4586000759A9 /* TXLiveMessageDownSeat.m in Sources */,
 				BC85A9ED2C6B59CC003C1ABE /* KSTargetWebSocketManager.m in Sources */,
 				BC31BF7F2B219C5700F7D538 /* WidgetViewController.m in Sources */,
+				BCA9AC4A2CED921100047BFA /* MyVideoGroupListCell.m in Sources */,
 				27F902F427E863B600C08A19 /* NetworkingCheckController.m in Sources */,
 				BCD457A5286319660010B493 /* CourseTimeSegView.m in Sources */,
 				2779362327E334470010E277 /* KSUpdateAlert.m in Sources */,
@@ -8691,6 +8870,7 @@
 				BC02BCE428B324C9005CB483 /* LiveApplyControlView.m in Sources */,
 				BC433E542CE6E4F3002870EC /* JXCategoryIndicatorGradientLineView.m in Sources */,
 				BC56C96A2923736200AF301F /* KSHudLoagingManager.m in Sources */,
+				BCD160692CED86FB00A78B43 /* MyCourseGroupNavView.m in Sources */,
 				BC8A2CF828476C3000122BBE /* MusicScoreViewController.m in Sources */,
 				BC71DEF72A89F470003F165E /* TXChatAreaView.m in Sources */,
 				BCB9FA1F286D539A005D766B /* ScanNavView.m in Sources */,
@@ -8724,6 +8904,7 @@
 				BC1365CF280D48B800EB03E2 /* HomeworkListModel.m in Sources */,
 				BCFC09DD2C48E4A0009A727F /* UserVip.m in Sources */,
 				BCECE2142B3D5F0800C0D555 /* FeedbackListModel.m in Sources */,
+				BCD1607B2CED8EA700A78B43 /* MyProgramCourseGroupCell.m in Sources */,
 				BC38C42A2AF900E100ABFCC2 /* KSAudioPlayAnimationView.m in Sources */,
 				BC71DF0E2A89F470003F165E /* KSRateSliderView.m in Sources */,
 				BC7DEC9D2C2D555800154524 /* AudioEnginePlayer.m in Sources */,
@@ -8843,6 +9024,7 @@
 				BCB9FA622872C8D2005D766B /* UnderwayLiveCell.m in Sources */,
 				BC71DEF42A89F470003F165E /* TXChatAreaTopView.m in Sources */,
 				BCB399B227F94B5A00AFF376 /* LTSCalendarBottomView.m in Sources */,
+				BCD160572CED845A00A78B43 /* MyVipCourseGroupView.m in Sources */,
 				BC8B6E84285887A400866917 /* MusicRoomViewController.m in Sources */,
 				BC71DE962A89C937003F165E /* TXNodePlayMessage.m in Sources */,
 				275E3DA327F441EC0010EC30 /* KSEnterLiveroomManager.m in Sources */,

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher.xcodeproj/xcshareddata/xcschemes/KulexiuForTeacher.xcscheme

@@ -52,7 +52,7 @@
       </Testables>
    </TestAction>
    <LaunchAction
-      buildConfiguration = "TEST"
+      buildConfiguration = "DEV"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/search_green.imageset/search_green@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Chat/search_green.imageset/search_green@3x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Course/course_musicRoom.imageset/course_musicRoom@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Course/course_musicRoom.imageset/course_musicRoom@3x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/fansGroup_alert_top.imageset/fansGroup_alert_top@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Mine/fansGroup_alert_top.imageset/fansGroup_alert_top@3x.png


+ 6 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/arrange_course_icon.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "arrange_course_icon@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "arrange_course_icon@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/arrange_course_icon.imageset/arrange_course_icon@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/arrange_course_icon.imageset/arrange_course_icon@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/course_desc_top.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "course_desc_top@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "course_desc_top@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/course_desc_top.imageset/course_desc_top@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/course_desc_top.imageset/course_desc_top@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/live_courseGroup_icon.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "live_courseGroup_icon@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "live_courseGroup_icon@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/live_courseGroup_icon.imageset/live_courseGroup_icon@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/live_courseGroup_icon.imageset/live_courseGroup_icon@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/myCourse_bg.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "myCourse_bg@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "myCourse_bg@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/myCourse_bg.imageset/myCourse_bg@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/MyCourse/myCourse_bg.imageset/myCourse_bg@3x.png


+ 50 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h

@@ -1575,5 +1575,55 @@ NS_ASSUME_NONNULL_BEGIN
 /// @param faliure 失败
 + (void)verifyQrcode:(NSString *)post uuid:(NSString *)uuid success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
 
+
+#pragma mark ------- 课程方案
+// teacherSubjectPrice/list
+
+/// 获取老师课程方案列表
+/// @param post post
+/// @param courseType 课程类型 VIP、PRACTICE
+/// @param page 分页
+/// @param rows 条数
+/// @param success 成功
+/// @param faliure 失败
++ (void)teacherSubjectPriceRequest:(NSString *)post courseType:(NSString *)courseType page:(NSInteger)page rows:(NSInteger)rows success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// teacherSubjectPrice/delete
+
+/// 删除课程方案
+/// @param post post
+/// @param programId 方案ID
+/// @param success 成功
+/// @param faliure 失败
++ (void)teacherSubjectPriceDeleteRequest:(NSString *)post programId:(NSString *)programId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// teacherSubjectPrice/saveOrUpdate
+
+/// 保存课程方案
+/// @param post post
+/// @param courseType 课程类型
+/// @param subjectName 声部名称
+/// @param subjectId 声部ID
+/// @param subjectPrice 单课程价格
+/// @param courseMinutes 课程时长
+/// @param success 成功
+/// @param faliure 失败
++ (void)teacherSubjectPriceSaveRequest:(NSString *)post courseType:(NSString *)courseType subjectName:(NSString *)subjectName subjectId:(NSString *)subjectId subjectPrice:(NSString *)subjectPrice courseMinutes:(NSString *)courseMinutes success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+#pragma mark ---- 我的课程组
+
+// courseGroup/myCourseGroup
+
+/// 我的课程组
+/// @param post post
+/// @param courseType 课程类型 VIP、PRACTICE
+/// @param search 搜索关键字
+/// @param subjectId 声部ID
+/// @param status 课程组状态
+/// @param success 成功
+/// @param faliure 失败
++ (void)myCourseGroupRequest:(NSString *)post courseType:(NSString *)courseType search:(NSString *)search subjectId:(NSString *)subjectId status:(NSString *)status success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+
 @end
 NS_ASSUME_NONNULL_END

+ 82 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m

@@ -2911,4 +2911,86 @@
 
     [self request:post andWithUrl:url and:parm success:success faliure:faliure];
 }
+
+#pragma mark ------- 课程方案
+// teacherSubjectPrice/list
+
+/// 获取老师课程方案列表
+/// @param post post
+/// @param courseType 课程类型 VIP、
+/// @param page 分页
+/// @param rows 条数
+/// @param success 成功
+/// @param faliure 失败
++ (void)teacherSubjectPriceRequest:(NSString *)post courseType:(NSString *)courseType page:(NSInteger)page rows:(NSInteger)rows success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    [self configRequestMethodJSON];
+    NSString *url = [NSString stringWithFormat:@"%@%@",hostURL, @"/api-teacher/teacherSubjectPrice/list"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:courseType forKey:@"courseType"];
+    [parm setValue:@(page) forKey:@"page"];
+    [parm setValue:@(rows) forKey:@"rows"];
+    
+    [self request:post andWithUrl:url and:parm success:success faliure:faliure];
+}
+
+// teacherSubjectPrice/delete
+
+/// 删除课程方案
+/// @param post post
+/// @param programId 方案ID
+/// @param success 成功
+/// @param faliure 失败
++ (void)teacherSubjectPriceDeleteRequest:(NSString *)post programId:(NSString *)programId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    [self configRequestMethodJSON];
+    NSString *url = [NSString stringWithFormat:@"%@%@",hostURL, @"/api-teacher/teacherSubjectPrice/delete"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:programId forKey:@"id"];
+    [self request:post andWithUrl:url and:parm success:success faliure:faliure];
+}
+
+// teacherSubjectPrice/saveOrUpdate
+
+/// 保存课程方案
+/// @param post post
+/// @param courseType 课程类型
+/// @param subjectName 声部名称
+/// @param subjectId 声部ID
+/// @param subjectPrice 单课程价格
+/// @param courseMinutes 课程时长
+/// @param success 成功
+/// @param faliure 失败
++ (void)teacherSubjectPriceSaveRequest:(NSString *)post courseType:(NSString *)courseType subjectName:(NSString *)subjectName subjectId:(NSString *)subjectId subjectPrice:(NSString *)subjectPrice courseMinutes:(NSString *)courseMinutes success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    [self configRequestMethodJSON];
+    NSString *url = [NSString stringWithFormat:@"%@%@",hostURL, @"/api-teacher/teacherSubjectPrice/saveOrUpdate"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:courseType forKey:@"courseType"];
+    [parm setValue:subjectName forKey:@"subjectName"];
+    [parm setValue:subjectId forKey:@"subjectId"];
+    [parm setValue:subjectPrice forKey:@"subjectPrice"];
+    [parm setValue:courseMinutes forKey:@"courseMinutes"];
+    [self request:post andWithUrl:url and:parm success:success faliure:faliure];
+}
+
+#pragma mark ---- 我的课程组
+
+// courseGroup/myCourseGroup
+
+/// 我的课程组
+/// @param post post
+/// @param courseType 课程类型 VIP、PRACTICE
+/// @param search 搜索关键字
+/// @param subjectId 声部ID
+/// @param status 课程组状态
+/// @param success 成功
+/// @param faliure 失败
++ (void)myCourseGroupRequest:(NSString *)post courseType:(NSString *)courseType search:(NSString *)search subjectId:(NSString *)subjectId status:(NSString *)status success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    [self configRequestMethodJSON];
+    NSString *url = [NSString stringWithFormat:@"%@%@",hostURL, @"/api-teacher/courseGroup/myCourseGroup"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:courseType forKey:@"courseType"];
+    [parm setValue:search forKey:@"search"];
+    [parm setValue:subjectId forKey:@"subjectId"];
+    [parm setValue:status forKey:@"status"];
+    [self request:post andWithUrl:url and:parm success:success faliure:faliure];
+}
 @end

+ 6 - 6
KulexiuForTeacher/KulexiuForTeacher/Module/Chat/View/KSChatListSearchView.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -24,13 +24,13 @@
                             </constraints>
                         </imageView>
                         <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="查找聊天记录" adjustsFontSizeToFit="NO" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="s9n-ZY-b4Y">
-                            <rect key="frame" x="38" y="0.0" width="271" height="35"/>
+                            <rect key="frame" x="38" y="0.0" width="278" height="35"/>
                             <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
                             <fontDescription key="fontDescription" type="system" pointSize="13"/>
                             <textInputTraits key="textInputTraits" returnKeyType="done" enablesReturnKeyAutomatically="YES"/>
                         </textField>
                         <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="va7-49-aYd">
-                            <rect key="frame" x="319" y="4" width="56" height="27"/>
+                            <rect key="frame" x="326" y="4" width="56" height="27"/>
                             <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
                             <constraints>
                                 <constraint firstAttribute="height" constant="27" id="RD8-Dh-zm8"/>
@@ -59,7 +59,7 @@
                         <constraint firstItem="BoO-sd-jlY" firstAttribute="leading" secondItem="Kx9-xj-kfl" secondAttribute="leading" constant="12" id="jlr-KB-WGx"/>
                         <constraint firstAttribute="bottom" secondItem="s9n-ZY-b4Y" secondAttribute="bottom" id="nE7-ME-kcc"/>
                         <constraint firstItem="BoO-sd-jlY" firstAttribute="centerY" secondItem="Kx9-xj-kfl" secondAttribute="centerY" id="ttB-3o-wap"/>
-                        <constraint firstAttribute="trailing" secondItem="va7-49-aYd" secondAttribute="trailing" constant="11" id="zow-Ud-FXd"/>
+                        <constraint firstAttribute="trailing" secondItem="va7-49-aYd" secondAttribute="trailing" constant="4" id="zow-Ud-FXd"/>
                     </constraints>
                     <userDefinedRuntimeAttributes>
                         <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
@@ -84,6 +84,6 @@
         </view>
     </objects>
     <resources>
-        <image name="search_green" width="15" height="16"/>
+        <image name="search_green" width="16" height="16"/>
     </resources>
 </document>

+ 6 - 6
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MusicRoom/View/MusicRoomCourseInfoCell.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -78,10 +78,10 @@
                                 </userDefinedRuntimeAttributes>
                             </view>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="course_musicRoom" translatesAutoresizingMaskIntoConstraints="NO" id="MPJ-dm-TQx">
-                                <rect key="frame" x="11" y="53" width="47" height="51"/>
+                                <rect key="frame" x="11" y="53" width="47" height="47"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="47" id="YIK-Oi-iUK"/>
-                                    <constraint firstAttribute="height" constant="51" id="yLf-ul-Qz1"/>
+                                    <constraint firstAttribute="height" constant="47" id="yLf-ul-Qz1"/>
                                 </constraints>
                             </imageView>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="beA-D7-Fro">
@@ -143,7 +143,7 @@
                             <constraint firstItem="xGN-fD-6g8" firstAttribute="centerY" secondItem="CSZ-cc-B2S" secondAttribute="centerY" id="iEe-aS-tcZ"/>
                             <constraint firstItem="1JB-RE-CPf" firstAttribute="centerY" secondItem="xGN-fD-6g8" secondAttribute="centerY" id="jrf-db-QbH"/>
                             <constraint firstItem="xGN-fD-6g8" firstAttribute="leading" secondItem="CSZ-cc-B2S" secondAttribute="trailing" constant="6" id="lD3-wz-hkl"/>
-                            <constraint firstAttribute="bottom" secondItem="MPJ-dm-TQx" secondAttribute="bottom" constant="22" id="myg-9t-fsJ"/>
+                            <constraint firstAttribute="bottom" secondItem="MPJ-dm-TQx" secondAttribute="bottom" constant="26" id="myg-9t-fsJ"/>
                             <constraint firstItem="k2L-h9-9b3" firstAttribute="top" secondItem="CSZ-cc-B2S" secondAttribute="bottom" constant="10" id="nrg-zV-2Wy"/>
                             <constraint firstItem="1JB-RE-CPf" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="xGN-fD-6g8" secondAttribute="trailing" constant="10" id="vRh-MH-6qJ"/>
                             <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="H2e-81-i3m" secondAttribute="trailing" constant="5" id="wXu-kG-UZC"/>
@@ -176,7 +176,7 @@
     </objects>
     <resources>
         <image name="course_chat" width="19" height="18"/>
-        <image name="course_musicRoom" width="47" height="51"/>
+        <image name="course_musicRoom" width="40" height="40"/>
         <image name="course_time" width="16" height="16"/>
         <systemColor name="systemBackgroundColor">
             <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>

+ 0 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Controller/HomeViewController.m

@@ -9,7 +9,6 @@
 #import "HomeNavView.h"
 #import "KSBaseWKWebViewController.h"
 #import "MyMusicViewController.h"
-#import "MyCourseViewController.h"
 #import "HomeworkListViewController.h"
 #import "EvaluateCourseListViewController.h"
 #import "NotiferMessageViewController.h"

+ 9 - 9
KulexiuForTeacher/KulexiuForTeacher/Module/Home/Homework/View/MusicRoomHomeworkCell.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -51,14 +51,14 @@
                                 <nil key="highlightedColor"/>
                             </label>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="course_musicRoom" translatesAutoresizingMaskIntoConstraints="NO" id="vbJ-lB-Z7m">
-                                <rect key="frame" x="11" y="56" width="47" height="51"/>
+                                <rect key="frame" x="11" y="56" width="47" height="47"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="47" id="GJE-kv-Q75"/>
-                                    <constraint firstAttribute="height" constant="51" id="zsp-wi-eXy"/>
+                                    <constraint firstAttribute="height" constant="47" id="zsp-wi-eXy"/>
                                 </constraints>
                             </imageView>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="张豆豆" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="INl-R7-pRX">
-                                <rect key="frame" x="68" y="56" width="49" height="24"/>
+                                <rect key="frame" x="68" y="56" width="48" height="24"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="24" id="Sgg-XH-ZuZ"/>
                                 </constraints>
@@ -67,10 +67,10 @@
                                 <nil key="highlightedColor"/>
                             </label>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2XU-rf-TDq">
-                                <rect key="frame" x="68" y="87" width="44" height="20"/>
+                                <rect key="frame" x="68" y="83" width="43" height="20"/>
                                 <subviews>
                                     <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="单簧管" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sRr-14-Xr7">
-                                        <rect key="frame" x="5" y="0.0" width="34" height="20"/>
+                                        <rect key="frame" x="5" y="0.0" width="33" height="20"/>
                                         <fontDescription key="fontDescription" type="system" pointSize="11"/>
                                         <color key="textColor" red="1" green="0.54901960780000003" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
                                         <nil key="highlightedColor"/>
@@ -91,7 +91,7 @@
                                 </userDefinedRuntimeAttributes>
                             </view>
                             <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="C9U-yd-Bp1">
-                                <rect key="frame" x="117" y="48" width="40" height="40"/>
+                                <rect key="frame" x="116" y="48" width="40" height="40"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="40" id="GAR-wZ-GHE"/>
                                     <constraint firstAttribute="width" constant="40" id="ob0-NF-cC9"/>
@@ -152,7 +152,7 @@
     </objects>
     <resources>
         <image name="course_chat" width="19" height="18"/>
-        <image name="course_musicRoom" width="47" height="51"/>
+        <image name="course_musicRoom" width="40" height="40"/>
         <image name="course_time" width="16" height="16"/>
         <systemColor name="systemBackgroundColor">
             <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>

+ 128 - 100
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Controller/MyCourseViewController.m

@@ -6,29 +6,38 @@
 //
 
 #import "MyCourseViewController.h"
-#import "KSBaseWKWebViewController.h"
 #import "JXCategoryView.h"
 #import "JXPagerListRefreshView.h"
-#import "MyVideoCourseBodyView.h"
-#import "MyLessonBodyView.h"
-#import "TeacherInfo.h"
+
 #import "UserInfoManager.h"
-#import "MyMusicRoomBodyView.h"
 
-#define HEADER_HEIGHT (50)
+#import "MyCourseGroupNavView.h"
+
+#import "MyVipCourseGroupView.h"
+#import "MyAccompanyCourseGroupView.h"
+#import "MyLiveCourseGroupView.h"
+#import "MyVideoCourseGroupView.h"
+#import "MyMusicRoomCourseGroupView.h"
+
+#import "CourseDescAlertView.h"
+
+#define HEADER_HEIGHT (44)
 
 @interface MyCourseViewController ()<JXPagerViewDelegate, JXPagerMainTableViewGestureDelegate,JXCategoryViewDelegate>
 
+@property (nonatomic, strong) MyCourseGroupNavView *navView;
+
 @property (nonatomic, assign) NSInteger selectedIndex;
 
 @property (nonatomic, strong) NSMutableArray *listViewArray;
 
-@property (nonatomic, strong) TeacherInfo *teacherInfo;
-
 @property (nonatomic, strong) NSMutableArray *subjectList;
 
 @property (nonatomic, assign) DISPLAY_INDEX displayIndex;
 
+@property (nonatomic, strong) CourseDescAlertView *tipsAlert;
+
+
 @end
 
 @implementation MyCourseViewController
@@ -36,8 +45,9 @@
 - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
-    [self allocTitle:@"我的课程"];
-    self.titles = @[@"陪练课",@"直播课",@"视频课",@"琴房课"];
+    self.ks_prefersNavigationBarHidden = YES;
+    
+    
     [self configUI];
     [self countUMEvent];
 }
@@ -46,48 +56,33 @@
     [USER_MANAGER sendUMEvent:@"klx_myCourse"];
 }
 
-- (void)requestTeachMessage {
-    [KSNetworkingManager queryTeacherInfoRequest:KS_GET success:^(NSDictionary * _Nonnull dic) {
-        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
-            self.teacherInfo = [[TeacherInfo alloc] initWithDictionary:[dic ks_dictionaryValueForKey:@"data"]];
-            [self refreshAuthStatus];
-        }
-        else {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
-        }
-    } faliure:^(NSError * _Nonnull error) {
-        
+- (void)configUI {
+    [self.scrollView removeFromSuperview];
+    UIImage *bgImage = [UIImage imageNamed:@"myCourse_bg"];
+    NSInteger height = (NSInteger)(bgImage.size.height / bgImage.size.width * KPortraitWidth);
+    UIImageView *imageView = [[UIImageView alloc] initWithImage:bgImage];
+    imageView.frame = CGRectMake(0, 0, KPortraitWidth, height);
+    [self.view addSubview:imageView];
+    
+    [self.view addSubview:self.navView];
+    CGFloat navHeight = [MyCourseGroupNavView getViewHeight];
+    [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.mas_equalTo(self.view);
+        make.height.mas_equalTo(navHeight);
     }];
+    
+    self.titles = @[@"VIP定制课", @"趣纠课", @"直播课",@"视频课",@"琴房课"];
+    [self configCategoryView:navHeight];
 }
 
-- (void)refreshAuthStatus {
-    for (NSInteger index = 0; index < self.listViewArray.count; index++) {
-        id view = self.listViewArray[index];
-        if ([view isKindOfClass:[MyLessonBodyView class]]) {
-            MyLessonBodyView *courseView = (MyLessonBodyView *)view;
-            courseView.liveFlag = [self.teacherInfo.liveFlag isEqualToString:@"1"] ? YES : NO;
-            courseView.teaherStatus = self.teacherInfo.entryStatus;
-        }
-        else if ([view isKindOfClass:[MyVideoCourseBodyView class]]) {
-            MyVideoCourseBodyView *videoCourseView = (MyVideoCourseBodyView *)view;
-            videoCourseView.teaherStatus = self.teacherInfo.entryStatus;
-        }
-        else if ([view isKindOfClass:[MyMusicRoomBodyView class]]) {
-            MyMusicRoomBodyView *musicCourse = (MyMusicRoomBodyView *)view;
-            musicCourse.teaherStatus = self.teacherInfo.entryStatus;
-        }
-    }
-}
-
-- (void)configUI {
-    [self.scrollView removeFromSuperview];
-    self.view.backgroundColor = HexRGB(0xf8f9fc);
+- (void)configCategoryView:(NSInteger)topHeight {
     
-    _categoryView = [[JXCategoryTitleView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, HEADER_HEIGHT)];
+    
+    _categoryView = [[JXCategoryTitleView alloc] initWithFrame:CGRectMake(0, topHeight, KPortraitWidth, HEADER_HEIGHT)];
     self.categoryView.titles = self.titles;
     self.categoryView.delegate = self;
-    self.categoryView.titleFont = [UIFont systemFontOfSize:17.0f];
-    self.categoryView.titleSelectedFont = [UIFont systemFontOfSize:17.0f weight:UIFontWeightMedium];
+    self.categoryView.titleFont = [UIFont systemFontOfSize:16.0f];
+    self.categoryView.titleSelectedFont = [UIFont systemFontOfSize:16.0f weight:UIFontWeightSemibold];
     self.categoryView.titleSelectedColor = HexRGB(0x333333);
     self.categoryView.titleColor = HexRGB(0x666666);
     self.categoryView.titleColorGradientEnabled = YES;
@@ -99,7 +94,7 @@
     self.categoryView.indicators = @[lineView];
     
     _pagerView = [self preferredPagingView];
-    self.pagerView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight - kNaviBarHeight - iPhoneXSafeBottomMargin);
+    self.pagerView.frame = CGRectMake(0, topHeight, KPortraitWidth, KPortraitHeight - topHeight);
     self.pagerView.backgroundColor = [UIColor clearColor];
     self.pagerView.mainTableView.backgroundColor = [UIColor clearColor];
     self.pagerView.listContainerView.backgroundColor = [UIColor clearColor];
@@ -120,23 +115,7 @@
 - (void)viewWillAppear:(BOOL)animated {
     [super viewWillAppear:animated];
     self.navigationController.interactivePopGestureRecognizer.enabled = YES;
-//    [self requestTeachMessage];
     [self requestSubjectList];
-    if (self.listViewArray.count > self.categoryView.selectedIndex) {
-        id value = self.listViewArray[self.categoryView.selectedIndex];
-        if ([value isKindOfClass:[MyVideoCourseBodyView class]]) {
-            MyVideoCourseBodyView *listView = (MyVideoCourseBodyView *)value;
-            [listView beginFirstRefresh];
-        }
-        else if ([value isKindOfClass:[MyLessonBodyView class]]) {
-            MyLessonBodyView *listView = (MyLessonBodyView *)value;
-            [listView beginFirstRefresh];
-        }
-        else if ([value isKindOfClass:[MyMusicRoomBodyView class]]) {
-            MyMusicRoomBodyView *listView = (MyMusicRoomBodyView *)value;
-            [listView beginFirstRefresh];
-        }
-    }
 }
 
 - (void)requestSubjectList {
@@ -165,17 +144,25 @@
 - (void)refreshSubjectMessage {
     for (NSInteger index = 0; index < self.listViewArray.count; index++) {
         id view = self.listViewArray[index];
-        if ([view isKindOfClass:[MyLessonBodyView class]]) {
-            MyLessonBodyView *courseView = (MyLessonBodyView *)view;
-            courseView.subjectList = [self.subjectList mutableCopy];
+        if ([view isKindOfClass:[MyVipCourseGroupView class]]) {
+            MyVipCourseGroupView *pageView = (MyVipCourseGroupView *)view;
+            pageView.subjectList = [self.subjectList mutableCopy];
+        }
+        else if ([view isKindOfClass:[MyAccompanyCourseGroupView class]]) {
+            MyAccompanyCourseGroupView *pageView = (MyAccompanyCourseGroupView *)view;
+            pageView.subjectList = [self.subjectList mutableCopy];
         }
-        else if ([view isKindOfClass:[MyVideoCourseBodyView class]]) {
-            MyVideoCourseBodyView *videoCourseView = (MyVideoCourseBodyView *)view;
-            videoCourseView.subjectList = [self.subjectList mutableCopy];
+        else if ([view isKindOfClass:[MyLiveCourseGroupView class]]) {
+            MyLiveCourseGroupView *pageView = (MyLiveCourseGroupView *)view;
+            pageView.subjectList = [self.subjectList mutableCopy];
         }
-        else if ([view isKindOfClass:[MyMusicRoomBodyView class]]) {
-            MyMusicRoomBodyView *musicView = (MyMusicRoomBodyView *)view;
-            musicView.subjectList = [self.subjectList mutableCopy];
+        else if ([view isKindOfClass:[MyVideoCourseGroupView class]]) {
+            MyVideoCourseGroupView *pageView = (MyVideoCourseGroupView *)view;
+            pageView.subjectList = [self.subjectList mutableCopy];
+        }
+        else if ([view isKindOfClass:[MyMusicRoomCourseGroupView class]]) {
+            MyMusicRoomCourseGroupView *pageView = (MyMusicRoomCourseGroupView *)view;
+            pageView.subjectList = [self.subjectList mutableCopy];
         }
     }
 }
@@ -212,26 +199,20 @@
 }
 
 - (id<JXPagerViewListViewDelegate>)pagerView:(JXPagerView *)pagerView initListAtIndex:(NSInteger)index {
-    if (index == 2) {
-        MyVideoCourseBodyView *listView = [[MyVideoCourseBodyView alloc] init];
+    if (index == 0) {
+        MyVipCourseGroupView *listView = [[MyVipCourseGroupView alloc] init];
         listView.naviController = self.navigationController;
         [self.listViewArray replaceObjectAtIndex:index withObject:listView];
         self.listViewArray[index] = listView;
         listView.selectIndex = index;
-//        if (self.teacherInfo) {
-//            listView.teaherStatus = self.teacherInfo.entryStatus;
-//        }
-//        else {
-            listView.teaherStatus = @"PASS";
-//        }
         if (self.subjectList) {
             listView.subjectList = [self.subjectList mutableCopy];
         }
         [listView beginFirstRefresh];
         return listView;
     }
-    else if (index == 3) { // 琴房课
-        MyMusicRoomBodyView *listView = [[MyMusicRoomBodyView alloc] init];
+    else if (index == 1) {
+        MyAccompanyCourseGroupView *listView = [[MyAccompanyCourseGroupView alloc] init];
         listView.naviController = self.navigationController;
         [self.listViewArray replaceObjectAtIndex:index withObject:listView];
         self.listViewArray[index] = listView;
@@ -239,36 +220,45 @@
         if (self.subjectList) {
             listView.subjectList = [self.subjectList mutableCopy];
         }
-//        if (self.teacherInfo) {
-//            listView.teaherStatus = self.teacherInfo.entryStatus;
-//        }
-//        else {
-            listView.teaherStatus = @"PASS";
-//        }
         [listView beginFirstRefresh];
         return listView;
     }
-    else {
-        MyLessonBodyView *listView = [[MyLessonBodyView alloc] init];
+    else if (index == 2) {
+        MyLiveCourseGroupView *listView = [[MyLiveCourseGroupView alloc] init];
+        listView.naviController = self.navigationController;
+        [self.listViewArray replaceObjectAtIndex:index withObject:listView];
+        self.listViewArray[index] = listView;
+        listView.selectIndex = index;
+        if (self.subjectList) {
+            listView.subjectList = [self.subjectList mutableCopy];
+        }
+        [listView beginFirstRefresh];
+        return listView;
+    }
+    else if (index == 3) {
+        MyVideoCourseGroupView *listView = [[MyVideoCourseGroupView alloc] init];
+        listView.naviController = self.navigationController;
+        [self.listViewArray replaceObjectAtIndex:index withObject:listView];
+        self.listViewArray[index] = listView;
+        listView.selectIndex = index;
+        if (self.subjectList) {
+            listView.subjectList = [self.subjectList mutableCopy];
+        }
+        [listView beginFirstRefresh];
+        return listView;
+    }
+    else { // 琴房课
+        MyMusicRoomCourseGroupView *listView = [[MyMusicRoomCourseGroupView alloc] init];
         listView.naviController = self.navigationController;
         [self.listViewArray replaceObjectAtIndex:index withObject:listView];
         self.listViewArray[index] = listView;
         listView.selectIndex = index;
-//        if (self.teacherInfo) {
-//            listView.liveFlag = [self.teacherInfo.liveFlag isEqualToString:@"1"] ? YES : NO;
-//            listView.teaherStatus = self.teacherInfo.entryStatus;
-//        }
-//        else {
-            listView.liveFlag = YES;
-            listView.teaherStatus = @"PASS";
-//        }
         if (self.subjectList) {
             listView.subjectList = [self.subjectList mutableCopy];
         }
         [listView beginFirstRefresh];
         return listView;
     }
-    
 }
 
 #pragma mark - JXCategoryViewDelegate
@@ -280,6 +270,10 @@
             KSJXBodyView *listView = (KSJXBodyView *)value;
             [listView beginFirstRefresh];
         }
+        else if ([value isKindOfClass:[kSJXCollectionView class]]) {
+            kSJXCollectionView *listView = (kSJXCollectionView *)value;
+            [listView beginFirstRefresh];
+        }
     }
 }
 
@@ -294,10 +288,44 @@
     return [gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]];
 }
 
+#pragma mark ----- lazying
+- (MyCourseGroupNavView *)navView {
+    if (!_navView) {
+        _navView = [MyCourseGroupNavView sharedInstance];
+        MJWeakSelf;
+        [_navView navAction:^(BOOL isBack) {
+            [weakSelf myNavAction:isBack];
+        }];
+
+    }
+    return _navView;
+}
+
+- (void)myNavAction:(BOOL)isBack {
+    if (isBack) {
+        [self backAction];
+    }
+    else {
+        [self showTipsAlert:self.categoryView.selectedIndex];
+    }
+}
+
+- (void)showTipsAlert:(NSInteger)displayIndex {
+    [self.tipsAlert displayCourseTypeIndex:displayIndex];
+    [self.tipsAlert showInView:[NSObject getKeyWindow]];
+}
+
+- (CourseDescAlertView *)tipsAlert {
+    if (!_tipsAlert) {
+        _tipsAlert = [CourseDescAlertView sharedInstance];
+        [_tipsAlert refreshView];
+    }
+    return _tipsAlert;
+}
 
 - (NSMutableArray *)listViewArray {
     if (!_listViewArray) {
-        _listViewArray = [NSMutableArray arrayWithArray:@[@"",@"",@"",@""]];
+        _listViewArray = [NSMutableArray arrayWithArray:@[@"",@"",@"",@"",@""]];
     }
     return _listViewArray;
 }

+ 3 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/LiveLessonModel.h

@@ -25,6 +25,9 @@
 @property (nonatomic, strong) NSString *avatar;
 @property (nonatomic, strong) NSString *username;
 @property (nonatomic, strong) NSString *userId;
+@property (nonatomic, strong) NSString *courseIntroduce;
+@property (nonatomic, assign) NSInteger courseNum;
+@property (nonatomic, assign) NSInteger completeCourseNum;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
 - (instancetype)initWithDictionary:(NSDictionary *)dict;

+ 22 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/LiveLessonModel.m

@@ -21,6 +21,10 @@ NSString *const kLiveLessonModelCourseId = @"courseId";
 NSString *const kLiveLessonModelAvatar = @"avatar";
 NSString *const kLiveLessonModelUsername = @"username";
 NSString *const kLiveLessonModelUserId = @"userId";
+NSString *const kLiveLessonModelCourseIntroduce = @"courseIntroduce";
+NSString *const kLiveLessonModelCourseNum = @"courseNum";
+NSString *const kLiveLessonModelCompleteCourseNum = @"completeCourseNum";
+
 
 @interface LiveLessonModel ()
 
@@ -43,6 +47,9 @@ NSString *const kLiveLessonModelUserId = @"userId";
 @synthesize avatar = _avatar;
 @synthesize username = _username;
 @synthesize userId = _userId;
+@synthesize courseIntroduce = _courseIntroduce;
+@synthesize courseNum = _courseNum;
+@synthesize completeCourseNum = _completeCourseNum;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
 {
@@ -69,6 +76,9 @@ NSString *const kLiveLessonModelUserId = @"userId";
         self.avatar = [self objectOrNilForKey:kLiveLessonModelAvatar fromDictionary:dict];
         self.username = [self objectOrNilForKey:kLiveLessonModelUsername fromDictionary:dict];
         self.userId = [self objectOrNilForKey:kLiveLessonModelUserId fromDictionary:dict];
+        self.courseIntroduce = [self objectOrNilForKey:kLiveLessonModelCourseIntroduce fromDictionary:dict];
+        self.courseNum = [[self objectOrNilForKey:kLiveLessonModelCourseNum fromDictionary:dict] integerValue];
+        self.completeCourseNum = [[self objectOrNilForKey:kLiveLessonModelCompleteCourseNum fromDictionary:dict] integerValue];
     }
     
     return self;
@@ -91,7 +101,9 @@ NSString *const kLiveLessonModelUserId = @"userId";
     [mutableDict setValue:self.avatar forKey:kLiveLessonModelAvatar];
     [mutableDict setValue:self.username forKey:kLiveLessonModelUsername];
     [mutableDict setValue:self.userId forKey:kLiveLessonModelUserId];
-    
+    [mutableDict setValue:self.courseIntroduce forKey:kLiveLessonModelCourseIntroduce];
+    [mutableDict setValue:[NSNumber numberWithInteger:self.courseNum] forKey:kLiveLessonModelCourseNum];
+    [mutableDict setValue:[NSNumber numberWithInteger:self.completeCourseNum] forKey:kLiveLessonModelCompleteCourseNum];
     return [NSDictionary dictionaryWithDictionary:mutableDict];
 }
 
@@ -131,6 +143,9 @@ NSString *const kLiveLessonModelUserId = @"userId";
     self.avatar = [aDecoder decodeObjectForKey:kLiveLessonModelAvatar];
     self.username = [aDecoder decodeObjectForKey:kLiveLessonModelUsername];
     self.userId = [aDecoder decodeObjectForKey:kLiveLessonModelUserId];
+    self.courseIntroduce = [aDecoder decodeObjectForKey:kLiveLessonModelCourseIntroduce];
+    self.courseNum = [aDecoder decodeIntegerForKey:kLiveLessonModelCourseNum];
+    self.completeCourseNum = [aDecoder decodeIntegerForKey:kLiveLessonModelCompleteCourseNum];
     
     return self;
 }
@@ -151,6 +166,9 @@ NSString *const kLiveLessonModelUserId = @"userId";
     [aCoder encodeObject:_avatar forKey:kLiveLessonModelAvatar];
     [aCoder encodeObject:_username forKey:kLiveLessonModelUsername];
     [aCoder encodeObject:_userId forKey:kLiveLessonModelUserId];
+    [aCoder encodeObject:_courseIntroduce forKey:kLiveLessonModelCourseIntroduce];
+    [aCoder encodeInteger:_courseNum forKey:kLiveLessonModelCourseNum];
+    [aCoder encodeInteger:_completeCourseNum forKey:kLiveLessonModelCompleteCourseNum];
     
 }
 
@@ -173,6 +191,9 @@ NSString *const kLiveLessonModelUserId = @"userId";
         copy.avatar = [self.avatar copyWithZone:zone];
         copy.username = [self.username copyWithZone:zone];
         copy.userId = [self.userId copyWithZone:zone];
+        copy.courseIntroduce = [self.courseIntroduce copyWithZone:zone];
+        copy.courseNum = self.courseNum;
+        copy.completeCourseNum = self.completeCourseNum;
     }
     
     return copy;

+ 28 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/ProgramCourseGroupModel.h

@@ -0,0 +1,28 @@
+//
+//  ProgramCourseGroupModel.h
+//
+//  Created by Steven  on 2024/11/20
+//  Copyright (c) 2024 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+
+@interface ProgramCourseGroupModel : NSObject <NSCoding, NSCopying>
+
+@property (nonatomic, strong) NSString *status;
+@property (nonatomic, assign) double courseGroupId;
+@property (nonatomic, assign) double completeCourseNum;
+@property (nonatomic, strong) NSString *subjectId;
+@property (nonatomic, strong) NSString *studentName;
+@property (nonatomic, strong) NSString *studentAvatar;
+@property (nonatomic, strong) NSString *subjectName;
+@property (nonatomic, strong) NSString *courseGroupName;
+@property (nonatomic, assign) double courseNum;
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+- (NSDictionary *)dictionaryRepresentation;
+
+@end

+ 155 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Model/ProgramCourseGroupModel.m

@@ -0,0 +1,155 @@
+//
+//  ProgramCourseGroupModel.m
+//
+//  Created by Steven  on 2024/11/20
+//  Copyright (c) 2024 __MyCompanyName__. All rights reserved.
+//
+
+#import "ProgramCourseGroupModel.h"
+
+
+NSString *const kProgramCourseGroupModelStatus = @"status";
+NSString *const kProgramCourseGroupModelCourseGroupId = @"courseGroupId";
+NSString *const kProgramCourseGroupModelCompleteCourseNum = @"completeCourseNum";
+NSString *const kProgramCourseGroupModelSubjectId = @"subjectId";
+NSString *const kProgramCourseGroupModelStudentName = @"studentName";
+NSString *const kProgramCourseGroupModelStudentAvatar = @"studentAvatar";
+NSString *const kProgramCourseGroupModelSubjectName = @"subjectName";
+NSString *const kProgramCourseGroupModelCourseGroupName = @"courseGroupName";
+NSString *const kProgramCourseGroupModelCourseNum = @"courseNum";
+
+
+@interface ProgramCourseGroupModel ()
+
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
+
+@end
+
+@implementation ProgramCourseGroupModel
+
+@synthesize status = _status;
+@synthesize courseGroupId = _courseGroupId;
+@synthesize completeCourseNum = _completeCourseNum;
+@synthesize subjectId = _subjectId;
+@synthesize studentName = _studentName;
+@synthesize studentAvatar = _studentAvatar;
+@synthesize subjectName = _subjectName;
+@synthesize courseGroupName = _courseGroupName;
+@synthesize courseNum = _courseNum;
+
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
+{
+    return [[self alloc] initWithDictionary:dict];
+}
+
+- (instancetype)initWithDictionary:(NSDictionary *)dict
+{
+    self = [super init];
+    
+    // This check serves to make sure that a non-NSDictionary object
+    // passed into the model class doesn't break the parsing.
+    if(self && [dict isKindOfClass:[NSDictionary class]]) {
+            self.status = [self objectOrNilForKey:kProgramCourseGroupModelStatus fromDictionary:dict];
+            self.courseGroupId = [[self objectOrNilForKey:kProgramCourseGroupModelCourseGroupId fromDictionary:dict] doubleValue];
+            self.completeCourseNum = [[self objectOrNilForKey:kProgramCourseGroupModelCompleteCourseNum fromDictionary:dict] doubleValue];
+            self.subjectId = [self objectOrNilForKey:kProgramCourseGroupModelSubjectId fromDictionary:dict];
+            self.studentName = [self objectOrNilForKey:kProgramCourseGroupModelStudentName fromDictionary:dict];
+            self.studentAvatar = [self objectOrNilForKey:kProgramCourseGroupModelStudentAvatar fromDictionary:dict];
+            self.subjectName = [self objectOrNilForKey:kProgramCourseGroupModelSubjectName fromDictionary:dict];
+            self.courseGroupName = [self objectOrNilForKey:kProgramCourseGroupModelCourseGroupName fromDictionary:dict];
+            self.courseNum = [[self objectOrNilForKey:kProgramCourseGroupModelCourseNum fromDictionary:dict] doubleValue];
+
+    }
+    
+    return self;
+    
+}
+
+- (NSDictionary *)dictionaryRepresentation
+{
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    [mutableDict setValue:self.status forKey:kProgramCourseGroupModelStatus];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.courseGroupId] forKey:kProgramCourseGroupModelCourseGroupId];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.completeCourseNum] forKey:kProgramCourseGroupModelCompleteCourseNum];
+    [mutableDict setValue:self.subjectId forKey:kProgramCourseGroupModelSubjectId];
+    [mutableDict setValue:self.studentName forKey:kProgramCourseGroupModelStudentName];
+    [mutableDict setValue:self.studentAvatar forKey:kProgramCourseGroupModelStudentAvatar];
+    [mutableDict setValue:self.subjectName forKey:kProgramCourseGroupModelSubjectName];
+    [mutableDict setValue:self.courseGroupName forKey:kProgramCourseGroupModelCourseGroupName];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.courseNum] forKey:kProgramCourseGroupModelCourseNum];
+
+    return [NSDictionary dictionaryWithDictionary:mutableDict];
+}
+
+- (NSString *)description 
+{
+    return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
+}
+
+#pragma mark - Helper Method
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
+{
+    id object = [dict objectForKey:aKey];
+    if ([object isKindOfClass:[NSNumber class]]) {
+        NSNumber *number = object;
+        object = [number stringValue];
+    }
+    return [object isEqual:[NSNull null]] ? nil : object;
+}
+
+
+#pragma mark - NSCoding Methods
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+    self = [super init];
+
+    self.status = [aDecoder decodeObjectForKey:kProgramCourseGroupModelStatus];
+    self.courseGroupId = [aDecoder decodeDoubleForKey:kProgramCourseGroupModelCourseGroupId];
+    self.completeCourseNum = [aDecoder decodeDoubleForKey:kProgramCourseGroupModelCompleteCourseNum];
+    self.subjectId = [aDecoder decodeObjectForKey:kProgramCourseGroupModelSubjectId];
+    self.studentName = [aDecoder decodeObjectForKey:kProgramCourseGroupModelStudentName];
+    self.studentAvatar = [aDecoder decodeObjectForKey:kProgramCourseGroupModelStudentAvatar];
+    self.subjectName = [aDecoder decodeObjectForKey:kProgramCourseGroupModelSubjectName];
+    self.courseGroupName = [aDecoder decodeObjectForKey:kProgramCourseGroupModelCourseGroupName];
+    self.courseNum = [aDecoder decodeDoubleForKey:kProgramCourseGroupModelCourseNum];
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+
+    [aCoder encodeObject:_status forKey:kProgramCourseGroupModelStatus];
+    [aCoder encodeDouble:_courseGroupId forKey:kProgramCourseGroupModelCourseGroupId];
+    [aCoder encodeDouble:_completeCourseNum forKey:kProgramCourseGroupModelCompleteCourseNum];
+    [aCoder encodeObject:_subjectId forKey:kProgramCourseGroupModelSubjectId];
+    [aCoder encodeObject:_studentName forKey:kProgramCourseGroupModelStudentName];
+    [aCoder encodeObject:_studentAvatar forKey:kProgramCourseGroupModelStudentAvatar];
+    [aCoder encodeObject:_subjectName forKey:kProgramCourseGroupModelSubjectName];
+    [aCoder encodeObject:_courseGroupName forKey:kProgramCourseGroupModelCourseGroupName];
+    [aCoder encodeDouble:_courseNum forKey:kProgramCourseGroupModelCourseNum];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    ProgramCourseGroupModel *copy = [[ProgramCourseGroupModel alloc] init];
+    
+    if (copy) {
+
+        copy.status = [self.status copyWithZone:zone];
+        copy.courseGroupId = self.courseGroupId;
+        copy.completeCourseNum = self.completeCourseNum;
+        copy.subjectId = [self.subjectId copyWithZone:zone];
+        copy.studentName = [self.studentName copyWithZone:zone];
+        copy.studentAvatar = [self.studentAvatar copyWithZone:zone];
+        copy.subjectName = [self.subjectName copyWithZone:zone];
+        copy.courseGroupName = [self.courseGroupName copyWithZone:zone];
+        copy.courseNum = self.courseNum;
+    }
+    
+    return copy;
+}
+
+
+@end

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/AccompanyCourseGroup/MyAccompanyCourseGroupView.h

@@ -0,0 +1,18 @@
+//
+//  MyAccompanyCourseGroupView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "KSJXBodyView.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyAccompanyCourseGroupView : KSJXBodyView
+
+@property (nonatomic, strong) NSMutableArray *subjectList;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 299 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/AccompanyCourseGroup/MyAccompanyCourseGroupView.m

@@ -0,0 +1,299 @@
+//
+//  MyAccompanyCourseGroupView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyAccompanyCourseGroupView.h"
+#import "MyProgramCourseGroupCell.h"
+#import "MyCourseSearchView.h"
+#import "StateView.h"
+#import "Reachability.h"
+#import "ProgramCourseGroupModel.h"
+
+@interface MyAccompanyCourseGroupView ()<UITableViewDelegate,UITableViewDataSource>
+
+@property (nonatomic, assign) BOOL isLoadMore;
+@property (nonatomic, assign) NSInteger rows;
+@property (nonatomic, assign) NSInteger pages;
+
+@property (nonatomic, strong) NSMutableArray *dataArray;
+
+@property (nonatomic, strong) StateView *promptView;
+@property (nonatomic, strong) UIView *promptPlaceView;
+
+@property (nonatomic, assign) BOOL networkAvaiable; // 网络是否可用
+
+@property (nonatomic, strong) MyCourseSearchView *searchView;
+
+@property (nonatomic, strong) NSString *searchKey;
+
+@property (nonatomic, strong) NSString *subjectId;
+
+@property (nonatomic, strong) NSString *status;
+
+@end
+
+
+
+@implementation MyAccompanyCourseGroupView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+        self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height) style:UITableViewStylePlain];
+        self.tableView.backgroundColor = [UIColor clearColor];
+        self.tableView.showsVerticalScrollIndicator = NO;
+        
+        self.tableView.dataSource = self;
+        self.tableView.delegate = self;
+        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+        [self addSubview:self.tableView];
+        self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
+        [self.tableView registerNib:[UINib nibWithNibName:@"MyProgramCourseGroupCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"MyProgramCourseGroupCell"];
+
+        UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, iPhoneXSafeBottomMargin)];
+        bottomView.backgroundColor = [UIColor clearColor];
+        self.tableView.tableFooterView = bottomView;
+        
+        MJWeakSelf;
+        self.tableView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
+            [weakSelf resetParamenter];
+            [weakSelf requestData];
+        }];
+        self.tableView.mj_footer = [KSGifRefreshFooter footerWithRefreshingBlock:^{
+            if (weakSelf.isLoadMore) {
+                weakSelf.pages += 1;
+                [weakSelf requestData];
+            }
+            else {
+                [weakSelf.tableView.mj_footer endRefreshingWithNoMoreData];
+            }
+        }];
+    }
+    return self;
+}
+
+- (void)refreshAndRequestData {
+    [self resetParamenter];
+    [self requestData];
+}
+
+- (void)resetParamenter {
+    self.isLoadMore = YES;
+    self.pages = 1;
+    self.rows = 10;
+    
+    self.dataArray = [NSMutableArray array];
+    [self.tableView.mj_footer resetNoMoreData];
+    [self setPromptString:@"暂无内容" imageName:@"empty_course" inView:self.tableView];
+    [self.tableView reloadData];
+}
+
+- (void)endRefresh {
+    @weakObj(self);
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        @strongObj(self);
+        [self.tableView.mj_header endRefreshing];
+        [self.tableView.mj_footer endRefreshing];
+    });
+}
+
+
+- (void)requestData {
+    [KSNetworkingManager myCourseGroupRequest:KS_POST courseType:@"PRACTICE" search:self.searchKey subjectId:self.subjectId status:self.status success:^(NSDictionary * _Nonnull dic) {
+        [self endRefresh];
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            NSArray *sourceArray = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"rows"];
+            for (NSDictionary *parm in sourceArray) {
+                ProgramCourseGroupModel *model = [[ProgramCourseGroupModel alloc] initWithDictionary:parm];
+                [self.dataArray addObject:model];
+            }
+            if (sourceArray.count < self.rows) {
+                self.isLoadMore = NO;
+            }
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+        [self.tableView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    } faliure:^(NSError * _Nonnull error) {
+        [self endRefresh];
+        if (self.networkAvaiable == NO) {
+            [self setPromptString:@"暂无网络" imageName:@"no_networking" inView:self.tableView];
+        }
+        [self.dataArray removeAllObjects];
+        [self.tableView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    }];
+}
+
+- (void)beginRefreshImmediately {
+    [self.tableView.mj_header beginRefreshing];
+}
+
+- (void)beginFirstRefresh {
+    if (!self.isHeaderRefreshed) {
+        [self beginRefreshImmediately];
+    }
+}
+- (void)selectCellAtIndexPath:(NSIndexPath *)indexPath {
+    
+    if (self.lastSelectedIndexPath == indexPath) {
+        return;
+    }
+    if (self.lastSelectedIndexPath != nil) {
+        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.lastSelectedIndexPath];
+        [cell setSelected:NO animated:NO];
+    }
+    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
+    [cell setSelected:YES animated:NO];
+    self.lastSelectedIndexPath = indexPath;
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    CGFloat searchViewHeight = [MyCourseSearchView getViewHeight];
+
+    if (![self.subviews containsObject:self.searchView]) {
+        [self addSubview:self.searchView];
+        [self.searchView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.mas_equalTo(self);
+            make.height.mas_equalTo(searchViewHeight);
+        }];
+    }
+
+    [self.tableView mas_remakeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.bottom.mas_equalTo(self);
+        make.top.mas_equalTo(self.searchView.mas_bottom);
+    }];
+}
+
+#pragma mark - UITableViewDataSource
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return self.dataArray.count;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
+    return 106.0f;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    ProgramCourseGroupModel *model = self.dataArray[indexPath.row];
+    MyProgramCourseGroupCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyProgramCourseGroupCell"];
+    [cell configWithSource:model isVipCourse:NO];
+    return cell;
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    // 课程详情
+    
+}
+
+#pragma mark ------ lazying
+- (MyCourseSearchView *)searchView {
+    if (!_searchView) {
+        _searchView = [MyCourseSearchView sharedInstance];
+        MJWeakSelf;
+        [_searchView searchActionCallback:^(MY_COURSE_SORT type, NSString * _Nullable searchKey) {
+            [weakSelf searchAction:type searchKey:searchKey];
+        }];
+    }
+    return _searchView;
+}
+
+- (void)searchAction:(MY_COURSE_SORT)type searchKey:(NSString *)searchKey {
+    switch (type) {
+        case MY_COURSE_SORT_RANK:
+        {
+            
+        }
+            break;
+        case MY_COURSE_SORT_SEARCH:
+        {
+            [self evaluateSource:searchKey];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)evaluateSource:(NSString *)searchKey {
+    self.searchKey = searchKey;
+    [self refreshAndRequestData];
+}
+
+/**
+ 设置没有数据时的显示
+ 
+ @param promptString 提示语
+ @param imgName 图片名称
+ @param view 显示在什么地方
+ */
+- (void)setPromptString:(NSString *)promptString imageName:(NSString *)imgName inView:(UIView *)view {
+    if (self.promptView != nil) {
+        [self.promptView removeFromSuperview];
+    }
+    else {
+        self.promptView = [[StateView alloc]init];
+        self.promptView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight - 300);
+    }
+    _promptPlaceView = view;
+    //当请求不到数据时 ,自定义提示view 将会出现;
+    self.promptView.imageName = imgName;
+    self.promptView.alpha = 0.0f;
+    [self.promptView setText:promptString];
+    [view addSubview:self.promptView];
+}
+
+// 结束刷新后调用方法
+- (void)changePromptLabelStateWithArray:(NSMutableArray *)array {
+    NSInteger count;
+    if (array.count) {
+        count = array.count;
+    } else {
+        count = 0;
+    }
+    
+    [UIView animateWithDuration:0.1 animations:^{
+        [[self promptView] setAlpha:count ? 0.0f :1.0f ] ;
+    }] ;
+    
+}
+
+- (BOOL)networkAvaiable {
+    return [self checkNetworkAvaiable];
+}
+
+- (BOOL)checkNetworkAvaiable {
+    BOOL isExistenceNetwork = YES;
+    Reachability *reach = [Reachability reachabilityWithHostName:@"www.apple.com"];
+    switch ([reach currentReachabilityStatus]) {
+        case NotReachable:
+            isExistenceNetwork = NO;
+            //NSLog(@"notReachable");
+            break;
+        case ReachableViaWiFi:
+            isExistenceNetwork = YES;
+            //NSLog(@"WIFI");
+            break;
+        case ReachableViaWWAN:
+            isExistenceNetwork = YES;
+            //NSLog(@"3G");
+            break;
+    }
+    return isExistenceNetwork;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertCell.h

@@ -0,0 +1,18 @@
+//
+//  CourseDescAlertCell.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2024/11/19.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CourseDescAlertCell : UICollectionViewCell
+
+- (void)configWithTitle:(NSString *)title desc:(NSString *)desc;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 48 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertCell.m

@@ -0,0 +1,48 @@
+//
+//  CourseDescAlertCell.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2024/11/19.
+//
+
+#import "CourseDescAlertCell.h"
+
+@interface CourseDescAlertCell ()
+
+@property (weak, nonatomic) IBOutlet UILabel *tipsTitle;
+
+@property (weak, nonatomic) IBOutlet UILabel *tipsDesc;
+
+
+@end
+
+@implementation CourseDescAlertCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+}
+
+- (void)configWithTitle:(NSString *)title desc:(NSString *)desc {
+    self.tipsTitle.text = [NSString returnNoNullStringWithString:title];
+    
+    NSMutableParagraphStyle *paragraphStyle = [self getParagraphStyleWithFont:[UIFont systemFontOfSize:13.0f] lineHeight:22.0f];
+    CGFloat baselineOffset = [self getBaseOffline:[UIFont systemFontOfSize:13.0f] lineHeight:22.0f];
+    NSMutableAttributedString *attrs = [[NSMutableAttributedString alloc] initWithString:desc attributes:@{NSParagraphStyleAttributeName:paragraphStyle, NSBaselineOffsetAttributeName:@(baselineOffset),NSFontAttributeName:[UIFont systemFontOfSize:13.0f]}];
+    self.tipsDesc.attributedText = attrs;
+}
+
+- (CGFloat)getBaseOffline:(UIFont *)font lineHeight:(CGFloat)lineHeight {
+    CGFloat baselineOffset = (lineHeight - font.lineHeight) / 4;
+    return baselineOffset;
+}
+
+- (NSMutableParagraphStyle *)getParagraphStyleWithFont:(UIFont *)font lineHeight:(CGFloat)lineHeigh {
+    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
+    paragraphStyle.maximumLineHeight = lineHeigh;
+    paragraphStyle.minimumLineHeight = lineHeigh;
+    return paragraphStyle;
+}
+
+
+@end

+ 67 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertCell.xib

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="CourseDescAlertCell">
+            <rect key="frame" x="0.0" y="0.0" width="324" height="248"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                <rect key="frame" x="0.0" y="0.0" width="324" height="248"/>
+                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZxP-yq-fSD">
+                        <rect key="frame" x="0.0" y="0.0" width="324" height="248"/>
+                        <subviews>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="什么是VIP定制课程?" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="H1O-RV-1Sz">
+                                <rect key="frame" x="20" y="16" width="139.33333333333334" height="18"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="18" id="EFZ-kx-sVa"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/>
+                                <color key="textColor" red="0.074509803921568626" green="0.078431372549019607" blue="0.082352941176470587" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="69V-S9-pbv">
+                                <rect key="frame" x="20" y="44" width="284" height="155.33333333333334"/>
+                                <string key="text">VIP定制课程采用一对一专属授课模式,每节课时长为45分钟。课程内容根据学生的具体需求量身打造,旨在全面提升学生的个人技能与表现。不论是希望在乐器演奏技巧上取得突破,如提高指法精准度、气息控制能力或节奏掌握等;还是为即将到来的重要活动、比赛或考级做充分准备,我们都能提供高度匹配的教学方案。此外,教学进度将根据每位学员的学习吸收情况灵活调整,确保每个人都能在最适合自己的节奏中稳步前进,扎实提升个人能力。</string>
+                                <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                                <color key="textColor" red="0.46666666666666667" green="0.46666666666666667" blue="0.46666666666666667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        <constraints>
+                            <constraint firstItem="H1O-RV-1Sz" firstAttribute="top" secondItem="ZxP-yq-fSD" secondAttribute="top" constant="16" id="2kY-FE-cfT"/>
+                            <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="69V-S9-pbv" secondAttribute="bottom" id="4dK-Lv-hAR"/>
+                            <constraint firstAttribute="trailing" secondItem="69V-S9-pbv" secondAttribute="trailing" constant="20" id="5nO-kp-aDg"/>
+                            <constraint firstItem="69V-S9-pbv" firstAttribute="leading" secondItem="ZxP-yq-fSD" secondAttribute="leading" constant="20" id="Cs4-Jp-vgs"/>
+                            <constraint firstItem="69V-S9-pbv" firstAttribute="top" secondItem="H1O-RV-1Sz" secondAttribute="bottom" constant="10" id="hVr-dq-nEI"/>
+                            <constraint firstItem="H1O-RV-1Sz" firstAttribute="leading" secondItem="ZxP-yq-fSD" secondAttribute="leading" constant="20" id="tkT-hc-iKz"/>
+                        </constraints>
+                    </view>
+                </subviews>
+            </view>
+            <viewLayoutGuide key="safeArea" id="SEy-5g-ep8"/>
+            <constraints>
+                <constraint firstItem="ZxP-yq-fSD" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="BM5-4d-8VT"/>
+                <constraint firstItem="ZxP-yq-fSD" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="ZUE-0w-3Jx"/>
+                <constraint firstAttribute="bottom" secondItem="ZxP-yq-fSD" secondAttribute="bottom" id="v2a-iv-dYy"/>
+                <constraint firstAttribute="trailing" secondItem="ZxP-yq-fSD" secondAttribute="trailing" id="zJl-Sd-ASu"/>
+            </constraints>
+            <size key="customSize" width="324" height="248"/>
+            <connections>
+                <outlet property="tipsDesc" destination="69V-S9-pbv" id="gx1-jx-BTf"/>
+                <outlet property="tipsTitle" destination="H1O-RV-1Sz" id="OYV-hh-vlL"/>
+            </connections>
+            <point key="canvasLocation" x="74.809160305343511" y="89.436619718309871"/>
+        </collectionViewCell>
+    </objects>
+</document>

+ 31 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertView.h

@@ -0,0 +1,31 @@
+//
+//  CourseDescAlertView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2024/11/19.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, COURSE_DISPLAY_INDEX) {
+    COURSE_DISPLAY_INDEX_VIP = 0,
+    COURSE_DISPLAY_INDEX_ACCOMPANY,
+    COURSE_DISPLAY_INDEX_LIVE,
+    COURSE_DISPLAY_INDEX_VIDEO,
+};
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface CourseDescAlertView : UIView
+
++ (instancetype)sharedInstance;
+
+- (void)refreshView;
+
+- (void)displayCourseTypeIndex:(NSInteger)index;
+
+- (void)showInView:(UIView *)displayView;
+
+@end
+
+NS_ASSUME_NONNULL_END

File diff suppressed because it is too large
+ 140 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertView.m


+ 117 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/CourseGroupAlertView/CourseDescAlertView.xib

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="CourseDescAlertView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="azl-Ae-oTb">
+                    <rect key="frame" x="46.666666666666657" y="174" width="300" height="504"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="course_desc_top" translatesAutoresizingMaskIntoConstraints="NO" id="krG-Dg-aen">
+                            <rect key="frame" x="0.0" y="0.0" width="300" height="113"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="113" id="Fae-UT-5W4"/>
+                                <constraint firstAttribute="width" constant="300" id="fb4-7b-21v"/>
+                            </constraints>
+                        </imageView>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cqL-gu-egq">
+                            <rect key="frame" x="0.0" y="113" width="300" height="332"/>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        </view>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rwW-L4-iiZ">
+                            <rect key="frame" x="20" y="445" width="260" height="39"/>
+                            <color key="backgroundColor" red="0.1764705882352941" green="0.7803921568627451" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="39" id="0Hx-gk-O27"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" title="我知道了"/>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="8"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <connections>
+                                <action selector="removeView:" destination="iN0-l3-epB" eventType="touchUpInside" id="RYg-4T-Fqi"/>
+                            </connections>
+                        </button>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cancle_button" translatesAutoresizingMaskIntoConstraints="NO" id="b4p-H9-rif">
+                            <rect key="frame" x="274" y="13" width="13" height="13"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="13" id="AKb-6s-PJJ"/>
+                                <constraint firstAttribute="height" constant="13" id="AQX-Ra-dN9"/>
+                            </constraints>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jF1-Hx-NNv">
+                            <rect key="frame" x="260" y="0.0" width="40" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="40" id="4BV-48-Byj"/>
+                                <constraint firstAttribute="height" constant="40" id="gXB-Au-TeE"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="removeView:" destination="iN0-l3-epB" eventType="touchUpInside" id="MKw-fa-cG2"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="trailing" secondItem="krG-Dg-aen" secondAttribute="trailing" id="0vW-OY-vVD"/>
+                        <constraint firstAttribute="bottom" secondItem="rwW-L4-iiZ" secondAttribute="bottom" constant="20" id="2Jr-b3-yKl"/>
+                        <constraint firstItem="rwW-L4-iiZ" firstAttribute="top" secondItem="cqL-gu-egq" secondAttribute="bottom" id="81x-OM-IH9"/>
+                        <constraint firstItem="jF1-Hx-NNv" firstAttribute="top" secondItem="azl-Ae-oTb" secondAttribute="top" id="8Vq-FJ-nec"/>
+                        <constraint firstItem="b4p-H9-rif" firstAttribute="top" secondItem="azl-Ae-oTb" secondAttribute="top" constant="13" id="A75-Tq-Bfv"/>
+                        <constraint firstAttribute="trailing" secondItem="b4p-H9-rif" secondAttribute="trailing" constant="13" id="HCe-RP-H8c"/>
+                        <constraint firstAttribute="width" constant="300" id="OoO-5l-wQW"/>
+                        <constraint firstAttribute="trailing" secondItem="cqL-gu-egq" secondAttribute="trailing" id="PaH-lu-eAA"/>
+                        <constraint firstItem="krG-Dg-aen" firstAttribute="top" secondItem="azl-Ae-oTb" secondAttribute="top" id="alz-DX-sff"/>
+                        <constraint firstItem="krG-Dg-aen" firstAttribute="leading" secondItem="azl-Ae-oTb" secondAttribute="leading" id="ge7-9X-Ybd"/>
+                        <constraint firstAttribute="trailing" secondItem="jF1-Hx-NNv" secondAttribute="trailing" id="j0S-er-iZ6"/>
+                        <constraint firstItem="rwW-L4-iiZ" firstAttribute="leading" secondItem="azl-Ae-oTb" secondAttribute="leading" constant="20" id="sFL-jx-daD"/>
+                        <constraint firstItem="cqL-gu-egq" firstAttribute="top" secondItem="krG-Dg-aen" secondAttribute="bottom" id="sLL-Qb-6jt"/>
+                        <constraint firstAttribute="height" constant="504" id="u4m-cZ-5ct"/>
+                        <constraint firstAttribute="trailing" secondItem="rwW-L4-iiZ" secondAttribute="trailing" constant="20" id="yaY-8f-z2q"/>
+                        <constraint firstItem="cqL-gu-egq" firstAttribute="leading" secondItem="azl-Ae-oTb" secondAttribute="leading" id="ycI-2K-a4K"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="10"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
+            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
+            <constraints>
+                <constraint firstItem="azl-Ae-oTb" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="QUM-nk-6Do"/>
+                <constraint firstItem="azl-Ae-oTb" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="wfu-Jg-UTT"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="containerView" destination="cqL-gu-egq" id="CoO-5Y-KgI"/>
+            </connections>
+            <point key="canvasLocation" x="23.664122137404579" y="19.718309859154932"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="cancle_button" width="20" height="20"/>
+        <image name="course_desc_top" width="300" height="113"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 19 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/LiveCourseGroup/MyLiveCourseGroupListCell.h

@@ -0,0 +1,19 @@
+//
+//  MyLiveCourseGroupListCell.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import <UIKit/UIKit.h>
+#import "LiveLessonModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyLiveCourseGroupListCell : UICollectionViewCell
+
+- (void)configWithSource:(LiveLessonModel *)model;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 74 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/LiveCourseGroup/MyLiveCourseGroupListCell.m

@@ -0,0 +1,74 @@
+//
+//  MyLiveCourseGroupListCell.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyLiveCourseGroupListCell.h"
+
+
+@interface MyLiveCourseGroupListCell ()
+
+@property (weak, nonatomic) IBOutlet UILabel *courseStatus;
+
+@property (weak, nonatomic) IBOutlet UIImageView *courseCover;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseSubject;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseTitle;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseDesc;
+
+@property (weak, nonatomic) IBOutlet UILabel *bookDesc;
+
+@property (weak, nonatomic) IBOutlet UILabel *finishDesc;
+
+@end
+
+@implementation MyLiveCourseGroupListCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+}
+
+- (void)configWithSource:(LiveLessonModel *)model {
+    [self evaluateGroupStatus:model.status];
+    [self.courseCover sd_setImageWithURL:[NSURL URLWithString:[model.backgroundPic getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"video_placeholder"]];
+    self.courseSubject.text = [NSString returnNoNullStringWithString:model.subjectName];
+    self.courseTitle.text = [NSString returnNoNullStringWithString:model.courseGroupName];
+    self.courseDesc.text = [NSString returnNoNullStringWithString:model.courseIntroduce];
+    self.bookDesc.text = [NSString stringWithFormat:@"%.0f人已学习", model.studentCount];
+    
+    NSMutableAttributedString *attrs = [[NSMutableAttributedString alloc] initWithString:@"已上课时 " attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightRegular],NSForegroundColorAttributeName:HexRGB(0x999999)}];
+    NSAttributedString *finishNumAttr = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%zd", model.completeCourseNum] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightSemibold],NSForegroundColorAttributeName:THEMECOLOR}];
+    [attrs appendAttributedString:finishNumAttr];
+    
+    NSAttributedString *totalDescAttr = [[NSAttributedString alloc] initWithString:@" /总课时 " attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightRegular],NSForegroundColorAttributeName:HexRGB(0x999999)}];
+    [attrs appendAttributedString:totalDescAttr];
+    NSAttributedString *totalNumAttr = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%zd", model.courseNum] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightSemibold],NSForegroundColorAttributeName:THEMECOLOR}];
+    [attrs appendAttributedString:totalNumAttr];
+    self.finishDesc.attributedText = attrs;
+}
+
+
+- (void)evaluateGroupStatus:(NSString *)status {
+    if ([status isEqualToString:@"ING"]) {
+        self.courseStatus.text = @"已开课";
+        self.courseStatus.textColor = THEMECOLOR;
+    }
+    else if ([status isEqualToString:@"NOT_START"]) {
+        self.courseStatus.text = @"未开课";
+        self.courseStatus.textColor = HexRGB(0xFF802C);
+    }
+    else if ([status isEqualToString:@"COMPLETE"]) {
+        self.courseStatus.text = @"已结课";
+        self.courseStatus.textColor = HexRGB(0x999999);
+    }
+    else if ([status isEqualToString:@"CANCEL"]) {
+        self.courseStatus.text = @"已取消";
+        self.courseStatus.textColor = HexRGB(0x999999);
+    }
+}
+@end

+ 191 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/LiveCourseGroup/MyLiveCourseGroupListCell.xib

@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="MyLiveCourseGroupListCell">
+            <rect key="frame" x="0.0" y="0.0" width="291" height="298"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                <rect key="frame" x="0.0" y="0.0" width="291" height="298"/>
+                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xJj-eX-YDa">
+                        <rect key="frame" x="0.0" y="0.0" width="291" height="298"/>
+                        <subviews>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="live_courseGroup_icon" translatesAutoresizingMaskIntoConstraints="NO" id="AUA-6F-MXS">
+                                <rect key="frame" x="12" y="16" width="16" height="14"/>
+                            </imageView>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="课程状态" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HT9-iE-aoN">
+                                <rect key="frame" x="36" y="13" width="55.666666666666657" height="20"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="20" id="X1q-B1-232"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="已开课" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8nr-OW-hsO">
+                                <rect key="frame" x="237" y="13" width="42" height="20"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="20" id="pzy-qh-z2B"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                                <color key="textColor" red="0.1764705882352941" green="0.7803921568627451" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="video_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="gJz-ge-yei">
+                                <rect key="frame" x="12" y="45" width="267" height="150.33333333333334"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" secondItem="gJz-ge-yei" secondAttribute="height" multiplier="16:9" id="LzS-SI-uJM"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="6"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </imageView>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7YS-Lc-hvS">
+                                <rect key="frame" x="20" y="53" width="36" height="19"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="长笛" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="K2S-UG-2xD">
+                                        <rect key="frame" x="6" y="3.0000000000000009" width="24" height="13.333333333333336"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                        <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.40000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="trailing" secondItem="K2S-UG-2xD" secondAttribute="trailing" constant="6" id="Hic-K1-lqh"/>
+                                    <constraint firstAttribute="height" constant="19" id="hWL-ge-oF0"/>
+                                    <constraint firstItem="K2S-UG-2xD" firstAttribute="centerY" secondItem="7YS-Lc-hvS" secondAttribute="centerY" id="iPi-1x-OB8"/>
+                                    <constraint firstItem="K2S-UG-2xD" firstAttribute="leading" secondItem="7YS-Lc-hvS" secondAttribute="leading" constant="6" id="uer-1m-fKJ"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="3"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="从零开始学竖笛直播课" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UwF-HP-7VM">
+                                <rect key="frame" x="12" y="203.33333333333334" width="267" height="22"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="22" id="mec-OG-ov4"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                                <color key="textColor" red="0.074509803920000006" green="0.078431372550000003" blue="0.08235294118" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="国际著名长笛演奏家、教育家张子珊女士为您讲…" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2hL-aY-XV2">
+                                <rect key="frame" x="12" y="229.33333333333334" width="267" height="20"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="20" id="1yp-t1-vx3"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                <color key="textColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0ga-Xp-k5f">
+                                <rect key="frame" x="12" y="265" width="65" height="19"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="6人已购买" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7Tu-az-bug">
+                                        <rect key="frame" x="4" y="2.3333333333333153" width="57" height="14.333333333333336"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                        <color key="textColor" red="1" green="0.40784313729999999" blue="0.1529411765" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="1" green="0.50196078430000002" blue="0.17254901959999999" alpha="0.070000000000000007" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstItem="7Tu-az-bug" firstAttribute="centerY" secondItem="0ga-Xp-k5f" secondAttribute="centerY" id="YvE-ce-Wx8"/>
+                                    <constraint firstAttribute="height" constant="19" id="fZS-nb-Dxp"/>
+                                    <constraint firstItem="7Tu-az-bug" firstAttribute="leading" secondItem="0ga-Xp-k5f" secondAttribute="leading" constant="4" id="oFq-T3-fus"/>
+                                    <constraint firstAttribute="trailing" secondItem="7Tu-az-bug" secondAttribute="trailing" constant="4" id="wJO-px-dxC"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="2"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="已上课时 4 /总课时 6" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9sU-yS-7be">
+                                <rect key="frame" x="146.66666666666663" y="265" width="132.33333333333337" height="19"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrange_course_icon" translatesAutoresizingMaskIntoConstraints="NO" id="iiI-K9-fO1">
+                                <rect key="frame" x="132.66666666666666" y="267.66666666666669" width="12" height="14"/>
+                            </imageView>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        <constraints>
+                            <constraint firstItem="2hL-aY-XV2" firstAttribute="leading" secondItem="xJj-eX-YDa" secondAttribute="leading" constant="12" id="2cb-S7-ZtC"/>
+                            <constraint firstAttribute="trailing" secondItem="8nr-OW-hsO" secondAttribute="trailing" constant="12" id="8TP-Md-KQH"/>
+                            <constraint firstItem="2hL-aY-XV2" firstAttribute="top" secondItem="UwF-HP-7VM" secondAttribute="bottom" constant="4" id="A21-Y9-bAb"/>
+                            <constraint firstItem="9sU-yS-7be" firstAttribute="leading" secondItem="iiI-K9-fO1" secondAttribute="trailing" constant="2" id="ARq-CK-t43"/>
+                            <constraint firstItem="HT9-iE-aoN" firstAttribute="leading" secondItem="AUA-6F-MXS" secondAttribute="trailing" constant="8" id="AoK-S7-ldP"/>
+                            <constraint firstItem="HT9-iE-aoN" firstAttribute="centerY" secondItem="AUA-6F-MXS" secondAttribute="centerY" id="BXT-gy-mMP"/>
+                            <constraint firstItem="9sU-yS-7be" firstAttribute="centerY" secondItem="0ga-Xp-k5f" secondAttribute="centerY" id="EU1-Ph-UVy"/>
+                            <constraint firstItem="UwF-HP-7VM" firstAttribute="leading" secondItem="xJj-eX-YDa" secondAttribute="leading" constant="12" id="Jxb-8y-cp8"/>
+                            <constraint firstAttribute="trailing" secondItem="9sU-yS-7be" secondAttribute="trailing" constant="12" id="L4i-wF-Re6"/>
+                            <constraint firstItem="gJz-ge-yei" firstAttribute="top" secondItem="AUA-6F-MXS" secondAttribute="bottom" constant="15" id="LSH-OU-dCc"/>
+                            <constraint firstAttribute="trailing" secondItem="2hL-aY-XV2" secondAttribute="trailing" constant="12" id="TPk-MW-c6u"/>
+                            <constraint firstItem="gJz-ge-yei" firstAttribute="leading" secondItem="xJj-eX-YDa" secondAttribute="leading" constant="12" id="Tab-w6-EMA"/>
+                            <constraint firstAttribute="bottom" secondItem="9sU-yS-7be" secondAttribute="bottom" constant="14" id="XcT-n7-xFg"/>
+                            <constraint firstItem="8nr-OW-hsO" firstAttribute="centerY" secondItem="HT9-iE-aoN" secondAttribute="centerY" id="Xv7-n8-APu"/>
+                            <constraint firstItem="7YS-Lc-hvS" firstAttribute="top" secondItem="gJz-ge-yei" secondAttribute="top" constant="8" id="ZJz-b9-4Z5"/>
+                            <constraint firstItem="8nr-OW-hsO" firstAttribute="centerY" secondItem="HT9-iE-aoN" secondAttribute="centerY" id="ZfT-Al-5ON"/>
+                            <constraint firstItem="7YS-Lc-hvS" firstAttribute="leading" secondItem="gJz-ge-yei" secondAttribute="leading" constant="8" id="Zms-fW-utt"/>
+                            <constraint firstAttribute="trailing" secondItem="gJz-ge-yei" secondAttribute="trailing" constant="12" id="bx1-H0-mEf"/>
+                            <constraint firstAttribute="bottom" secondItem="0ga-Xp-k5f" secondAttribute="bottom" constant="14" id="d2m-Jn-vFG"/>
+                            <constraint firstItem="0ga-Xp-k5f" firstAttribute="top" relation="greaterThanOrEqual" secondItem="2hL-aY-XV2" secondAttribute="bottom" constant="8" id="gWa-yc-b28"/>
+                            <constraint firstItem="UwF-HP-7VM" firstAttribute="top" secondItem="gJz-ge-yei" secondAttribute="bottom" constant="8" id="ign-tx-78w"/>
+                            <constraint firstItem="0ga-Xp-k5f" firstAttribute="leading" secondItem="xJj-eX-YDa" secondAttribute="leading" constant="12" id="oTi-kR-hiS"/>
+                            <constraint firstItem="AUA-6F-MXS" firstAttribute="leading" secondItem="xJj-eX-YDa" secondAttribute="leading" constant="12" id="tiQ-ev-GVh"/>
+                            <constraint firstItem="AUA-6F-MXS" firstAttribute="top" secondItem="xJj-eX-YDa" secondAttribute="top" constant="16" id="uyB-TJ-90N"/>
+                            <constraint firstAttribute="trailing" secondItem="UwF-HP-7VM" secondAttribute="trailing" constant="12" id="vcj-Ub-YSw"/>
+                            <constraint firstItem="iiI-K9-fO1" firstAttribute="centerY" secondItem="0ga-Xp-k5f" secondAttribute="centerY" id="yEh-Jh-3xh"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="6"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+            </view>
+            <viewLayoutGuide key="safeArea" id="SEy-5g-ep8"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="xJj-eX-YDa" secondAttribute="trailing" id="aOq-qQ-0hO"/>
+                <constraint firstItem="xJj-eX-YDa" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="d22-hH-C7Q"/>
+                <constraint firstItem="xJj-eX-YDa" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="tYg-hx-rEf"/>
+                <constraint firstAttribute="bottom" secondItem="xJj-eX-YDa" secondAttribute="bottom" id="xP1-4D-31W"/>
+            </constraints>
+            <size key="customSize" width="291" height="298"/>
+            <connections>
+                <outlet property="bookDesc" destination="7Tu-az-bug" id="YQC-wH-7UJ"/>
+                <outlet property="courseCover" destination="gJz-ge-yei" id="Z0x-gZ-31s"/>
+                <outlet property="courseDesc" destination="2hL-aY-XV2" id="XSy-3v-1GF"/>
+                <outlet property="courseStatus" destination="8nr-OW-hsO" id="FD1-lo-pGc"/>
+                <outlet property="courseSubject" destination="K2S-UG-2xD" id="wQv-N0-1Gn"/>
+                <outlet property="courseTitle" destination="UwF-HP-7VM" id="w83-3a-9Ke"/>
+                <outlet property="finishDesc" destination="9sU-yS-7be" id="7Ee-v0-TRQ"/>
+            </connections>
+            <point key="canvasLocation" x="214.50381679389312" y="80.281690140845072"/>
+        </collectionViewCell>
+    </objects>
+    <resources>
+        <image name="arrange_course_icon" width="12" height="14"/>
+        <image name="live_courseGroup_icon" width="16" height="14"/>
+        <image name="video_placeholder" width="103" height="72"/>
+    </resources>
+</document>

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/LiveCourseGroup/MyLiveCourseGroupView.h

@@ -0,0 +1,18 @@
+//
+//  MyLiveCourseGroupView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "kSJXCollectionView.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyLiveCourseGroupView : kSJXCollectionView
+
+@property (nonatomic, strong) NSMutableArray *subjectList;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 311 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/LiveCourseGroup/MyLiveCourseGroupView.m

@@ -0,0 +1,311 @@
+//
+//  MyLiveCourseGroupView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyLiveCourseGroupView.h"
+#import "MyCourseSearchView.h"
+#import "MyLiveCourseGroupListCell.h"
+#import "StateView.h"
+#import "Reachability.h"
+#import "LiveLessonModel.h"
+#import "KSBaseWKWebViewController.h"
+
+@interface MyLiveCourseGroupView ()<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
+
+@property (nonatomic, strong) NSMutableArray *dataArray;
+
+@property (nonatomic, strong) StateView *promptView;
+@property (nonatomic, strong) UIView *promptPlaceView;
+
+@property (nonatomic, assign) BOOL networkAvaiable; // 网络是否可用
+
+@property (nonatomic, assign) BOOL isLoadMore;
+@property (nonatomic, assign) NSInteger rows;
+@property (nonatomic, assign) NSInteger pages;
+
+@property (nonatomic, strong) MyCourseSearchView *searchView;
+
+@property (nonatomic, strong) NSString *searchKey;
+
+@property (nonatomic, strong) NSString *subjectId;
+
+@property (nonatomic, strong) NSString *status;
+
+@property (nonatomic, strong) NSString *classDate;
+@end
+
+
+@implementation MyLiveCourseGroupView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
+        layout.sectionInset = UIEdgeInsetsMake(12, 14, 12, 14);
+        
+        self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height) collectionViewLayout:layout];
+        self.collectionView.backgroundColor = [UIColor clearColor];
+        self.collectionView.delegate = self;
+        self.collectionView.dataSource = self;
+        self.collectionView.showsVerticalScrollIndicator = NO;
+        self.collectionView.showsHorizontalScrollIndicator = NO;
+        [self.collectionView registerNib:[UINib nibWithNibName:@"MyLiveCourseGroupListCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:@"MyLiveCourseGroupListCell"];
+        [self addSubview:self.collectionView];
+        self.collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
+        MJWeakSelf;
+        self.collectionView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
+            [weakSelf resetParamenter];
+            [weakSelf requestData];
+        }];
+        self.collectionView.mj_footer = [KSGifRefreshFooter footerWithRefreshingBlock:^{
+            if (weakSelf.isLoadMore) {
+                weakSelf.pages += 1;
+                [weakSelf requestData];
+            }
+            else {
+                [weakSelf.collectionView.mj_footer endRefreshingWithNoMoreData];
+            }
+        }];
+    }
+    return self;
+}
+
+- (void)endRefresh {
+    @weakObj(self);
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        @strongObj(self);
+        [self.collectionView.mj_header endRefreshing];
+        [self.collectionView.mj_footer endRefreshing];
+    });
+}
+
+- (void)refreshAndRequestData {
+    [self resetParamenter];
+    [self requestData];
+}
+
+- (void)resetParamenter {
+    self.isLoadMore = YES;
+    self.pages = 1;
+    self.rows = 10;
+    self.dataArray = [NSMutableArray array];
+    [self.collectionView.mj_footer resetNoMoreData];
+    [self setPromptString:@"暂无内容" imageName:@"empty_course" inView:self.collectionView];
+    [self.collectionView reloadData];
+}
+
+- (void)requestData {
+    [KSNetworkingManager queryTeacherLiveCourse:KS_POST classDate:self.classDate status:self.status subjectId:self.subjectId page:self.pages rows:self.rows success:^(NSDictionary * _Nonnull dic) {
+        [self endRefresh];
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            NSArray *sourceArray = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"rows"];
+            for (NSDictionary *parm in sourceArray) {
+                LiveLessonModel *model = [[LiveLessonModel alloc] initWithDictionary:parm];
+                [self.dataArray addObject:model];
+            }
+            
+            if (sourceArray.count < self.rows) {
+                self.isLoadMore = NO;
+            }
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+        [self.collectionView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    } faliure:^(NSError * _Nonnull error) {
+        [self endRefresh];
+        if (self.networkAvaiable == NO) {
+            [self setPromptString:@"暂无网络" imageName:@"no_networking" inView:self.collectionView];
+        }
+        [self.dataArray removeAllObjects];
+        [self.collectionView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    }];
+}
+
+- (void)beginRefreshImmediately {
+    [self.collectionView.mj_header beginRefreshing];
+}
+
+- (void)selectCellAtIndexPath:(NSIndexPath *)indexPath {
+    
+    if (self.lastSelectedIndexPath == indexPath) {
+        return;
+    }
+    if (self.lastSelectedIndexPath != nil) {
+        UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:self.lastSelectedIndexPath];
+        [cell setSelected:NO];
+    }
+    UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
+    [cell setSelected:YES];
+    self.lastSelectedIndexPath = indexPath;
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    CGFloat searchViewHeight = [MyCourseSearchView getViewHeight];
+
+    if (![self.subviews containsObject:self.searchView]) {
+        [self addSubview:self.searchView];
+        [self.searchView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.mas_equalTo(self);
+            make.height.mas_equalTo(searchViewHeight);
+        }];
+    }
+
+    [self.collectionView mas_remakeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.bottom.mas_equalTo(self);
+        make.top.mas_equalTo(self.searchView.mas_bottom);
+    }];
+}
+
+
+- (void)beginFirstRefresh {
+    if (!self.isHeaderRefreshed) {
+        [self beginRefreshImmediately];
+    }
+}
+
+#pragma mark ----- collection view
+- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
+    return 1;
+}
+
+- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
+    return self.dataArray.count;
+}
+
+- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
+    MyLiveCourseGroupListCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyLiveCourseGroupListCell" forIndexPath:indexPath];
+    
+    LiveLessonModel *model = [self.dataArray objectAtIndex:indexPath.row];
+    [cell configWithSource:model];
+    return cell;
+}
+
+- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
+    LiveLessonModel *model = self.dataArray[indexPath.row];
+    KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+    NSString *url = [NSString stringWithFormat:@"%@/#/liveDetail?joinRoom=1&groupId=%@&classId=%@", WEBHOST, model.courseGroupId,model.courseId];
+    ctrl.url = url;
+    [self.naviController pushViewController:ctrl animated:YES];
+}
+
+- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
+    CGFloat width = KPortraitWidth - 28;
+    if (IS_IPAD) {
+        width = (KPortraitWidth - 28 - 12 * 2 - 12) / 2.0f;
+    }
+    CGFloat height = (width - 12 * 2) / 16 * 9 + 143;
+    return CGSizeMake(width, height);
+}
+
+#pragma mark ------ lazying
+- (MyCourseSearchView *)searchView {
+    if (!_searchView) {
+        _searchView = [MyCourseSearchView sharedInstance];
+        MJWeakSelf;
+        [_searchView searchActionCallback:^(MY_COURSE_SORT type, NSString * _Nullable searchKey) {
+            [weakSelf searchAction:type searchKey:searchKey];
+        }];
+    }
+    return _searchView;
+}
+
+- (void)searchAction:(MY_COURSE_SORT)type searchKey:(NSString *)searchKey {
+    switch (type) {
+        case MY_COURSE_SORT_RANK:
+        {
+            
+        }
+            break;
+        case MY_COURSE_SORT_SEARCH:
+        {
+            [self evaluateSource:searchKey];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)evaluateSource:(NSString *)searchKey {
+    self.searchKey = searchKey;
+    [self refreshAndRequestData];
+}
+
+/**
+ 设置没有数据时的显示
+ 
+ @param promptString 提示语
+ @param imgName 图片名称
+ @param view 显示在什么地方
+ */
+- (void)setPromptString:(NSString *)promptString imageName:(NSString *)imgName inView:(UIView *)view {
+    if (self.promptView != nil) {
+        [self.promptView removeFromSuperview];
+    }
+    else {
+        self.promptView = [[StateView alloc]init];
+        self.promptView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight - 300);
+    }
+    _promptPlaceView = view;
+    //当请求不到数据时 ,自定义提示view 将会出现;
+    self.promptView.imageName = imgName;
+    self.promptView.alpha = 0.0f;
+    [self.promptView setText:promptString];
+    [view addSubview:self.promptView];
+}
+
+// 结束刷新后调用方法
+- (void)changePromptLabelStateWithArray:(NSMutableArray *)array {
+    NSInteger count;
+    if (array.count) {
+        count = array.count;
+    } else {
+        count = 0;
+    }
+    
+    [UIView animateWithDuration:0.1 animations:^{
+        [[self promptView] setAlpha:count ? 0.0f :1.0f ] ;
+    }] ;
+    
+}
+
+- (BOOL)networkAvaiable {
+    return [self checkNetworkAvaiable];
+}
+
+- (BOOL)checkNetworkAvaiable {
+    BOOL isExistenceNetwork = YES;
+    Reachability *reach = [Reachability reachabilityWithHostName:@"www.apple.com"];
+    switch ([reach currentReachabilityStatus]) {
+        case NotReachable:
+            isExistenceNetwork = NO;
+            //NSLog(@"notReachable");
+            break;
+        case ReachableViaWiFi:
+            isExistenceNetwork = YES;
+            //NSLog(@"WIFI");
+            break;
+        case ReachableViaWWAN:
+            isExistenceNetwork = YES;
+            //NSLog(@"3G");
+            break;
+    }
+    return isExistenceNetwork;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 11 - 11
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseCell.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -45,7 +45,7 @@
                                 </constraints>
                             </view>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="单簧管第一期" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l2B-EY-GWY">
-                                <rect key="frame" x="68" y="53" width="98" height="28"/>
+                                <rect key="frame" x="68" y="53" width="95.5" height="28"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="28" id="kAd-0f-k5x"/>
                                 </constraints>
@@ -54,10 +54,10 @@
                                 <nil key="highlightedColor"/>
                             </label>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Dys-CR-rsC">
-                                <rect key="frame" x="68" y="81" width="44" height="20"/>
+                                <rect key="frame" x="68" y="81" width="43" height="20"/>
                                 <subviews>
                                     <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="单簧管" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TPd-JA-v98">
-                                        <rect key="frame" x="5" y="0.0" width="34" height="20"/>
+                                        <rect key="frame" x="5" y="0.0" width="33" height="20"/>
                                         <fontDescription key="fontDescription" type="system" pointSize="11"/>
                                         <color key="textColor" red="1" green="0.54901960780000003" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
                                         <nil key="highlightedColor"/>
@@ -78,20 +78,20 @@
                                 </userDefinedRuntimeAttributes>
                             </view>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="course_musicRoom" translatesAutoresizingMaskIntoConstraints="NO" id="SU2-Qb-iP7">
-                                <rect key="frame" x="11" y="55" width="47" height="51"/>
+                                <rect key="frame" x="11" y="55" width="47" height="47"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="47" id="7XX-Pp-wuW"/>
-                                    <constraint firstAttribute="height" constant="51" id="m1c-NL-CHV"/>
+                                    <constraint firstAttribute="height" constant="47" id="m1c-NL-CHV"/>
                                 </constraints>
                             </imageView>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="6人" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IdU-Te-VFw">
-                                <rect key="frame" x="129" y="82.5" width="23.5" height="17"/>
+                                <rect key="frame" x="128" y="82.5" width="24.5" height="17"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
                                 <nil key="highlightedColor"/>
                             </label>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XK0-9s-28t">
-                                <rect key="frame" x="120" y="85" width="1" height="12"/>
+                                <rect key="frame" x="119" y="85" width="1" height="12"/>
                                 <color key="backgroundColor" red="0.87058823529999996" green="0.87058823529999996" blue="0.87058823529999996" alpha="1" colorSpace="calibratedRGB"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="1" id="3H3-aX-PD8"/>
@@ -99,7 +99,7 @@
                                 </constraints>
                             </view>
                             <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="t3h-kH-4md">
-                                <rect key="frame" x="166" y="47" width="40" height="40"/>
+                                <rect key="frame" x="163.5" y="47" width="40" height="40"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="40" id="e1k-NM-T9g"/>
                                     <constraint firstAttribute="height" constant="40" id="yHT-o3-kyh"/>
@@ -195,7 +195,7 @@
     </objects>
     <resources>
         <image name="course_chat" width="19" height="18"/>
-        <image name="course_musicRoom" width="47" height="51"/>
+        <image name="course_musicRoom" width="40" height="40"/>
         <image name="course_time" width="16" height="16"/>
         <systemColor name="systemBackgroundColor">
             <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>

+ 19 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseGroup/MyMusicGroupListCell.h

@@ -0,0 +1,19 @@
+//
+//  MyMusicGroupListCell.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import <UIKit/UIKit.h>
+#import "ProgramCourseGroupModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyMusicGroupListCell : UITableViewCell
+
+- (void)configWithSource:(ProgramCourseGroupModel *)model;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 80 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseGroup/MyMusicGroupListCell.m

@@ -0,0 +1,80 @@
+//
+//  MyMusicGroupListCell.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyMusicGroupListCell.h"
+
+@interface MyMusicGroupListCell ()
+
+@property (weak, nonatomic) IBOutlet UILabel *courseGroupName;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseStudents;
+
+@property (weak, nonatomic) IBOutlet UILabel *subjectLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseDesc;
+
+@end
+
+@implementation MyMusicGroupListCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+- (void)configWithSource:(ProgramCourseGroupModel *)model {
+    
+    self.courseGroupName.text = [NSString returnNoNullStringWithString:model.courseGroupName];
+    /// 状态
+    [self evaluateGroupStatus:model.status];
+        
+    self.courseStudents.text = [NSString returnNoNullStringWithString:model.studentName];
+    
+    self.subjectLabel.text = [NSString returnNoNullStringWithString:model.subjectName];
+    
+    // 课程描述
+    NSMutableAttributedString *attrs = [[NSMutableAttributedString alloc] initWithString:@"已上课时 " attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightRegular],NSForegroundColorAttributeName:HexRGB(0x999999)}];
+    NSAttributedString *finishNumAttr = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%.0f", model.completeCourseNum] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightSemibold],NSForegroundColorAttributeName:THEMECOLOR}];
+    [attrs appendAttributedString:finishNumAttr];
+    
+    NSAttributedString *totalDescAttr = [[NSAttributedString alloc] initWithString:@" /总课时 " attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightRegular],NSForegroundColorAttributeName:HexRGB(0x999999)}];
+    [attrs appendAttributedString:totalDescAttr];
+    NSAttributedString *totalNumAttr = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%.0f", model.courseNum] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightSemibold],NSForegroundColorAttributeName:THEMECOLOR}];
+    [attrs appendAttributedString:totalNumAttr];
+    self.courseDesc.attributedText = attrs;
+}
+
+
+- (void)evaluateGroupStatus:(NSString *)status {
+    if ([status isEqualToString:@"ING"]) {
+        self.statusLabel.text = @"已开课";
+        self.statusLabel.textColor = THEMECOLOR;
+    }
+    else if ([status isEqualToString:@"NOT_START"]) {
+        self.statusLabel.text = @"未开课";
+        self.statusLabel.textColor = HexRGB(0xFF802C);
+    }
+    else if ([status isEqualToString:@"COMPLETE"]) {
+        self.statusLabel.text = @"已结课";
+        self.statusLabel.textColor = HexRGB(0x999999);
+    }
+    else if ([status isEqualToString:@"CANCEL"]) {
+        self.statusLabel.text = @"已取消";
+        self.statusLabel.textColor = HexRGB(0x999999);
+    }
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end

+ 141 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseGroup/MyMusicGroupListCell.xib

@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="105" id="KGk-i7-Jjw" customClass="MyMusicGroupListCell">
+            <rect key="frame" x="0.0" y="0.0" width="320" height="106"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="320" height="106"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wVO-PU-gXJ">
+                        <rect key="frame" x="14" y="0.0" width="292" height="94"/>
+                        <subviews>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="张老师琴房课" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dy9-VA-eiu">
+                                <rect key="frame" x="12" y="12" width="95.333333333333329" height="22"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="22" id="p5C-Kg-rww"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                                <color key="textColor" red="0.074509803920000006" green="0.078431372550000003" blue="0.08235294118" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="未开课" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1Ol-S1-0uy">
+                                <rect key="frame" x="238" y="12" width="42" height="17"/>
+                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                                <color key="textColor" red="1" green="0.50196078430000002" blue="0.17254901959999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="course_musicRoom" translatesAutoresizingMaskIntoConstraints="NO" id="H34-rn-KTf">
+                                <rect key="frame" x="12" y="42" width="40" height="40"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="40" id="Kbe-83-N14"/>
+                                    <constraint firstAttribute="width" constant="40" id="McX-ua-4GD"/>
+                                </constraints>
+                            </imageView>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="张涵宇、向冰冰等5人" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hQh-fY-QGG">
+                                <rect key="frame" x="60" y="42" width="128" height="17"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="17" id="cta-ti-zwQ"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <view contentMode="scaleToFill" horizontalCompressionResistancePriority="752" translatesAutoresizingMaskIntoConstraints="NO" id="vge-mo-L76">
+                                <rect key="frame" x="193" y="42" width="38" height="17"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="单簧管" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HuW-TI-Qg2">
+                                        <rect key="frame" x="4" y="2.6666666666666643" width="30" height="12"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="10"/>
+                                        <color key="textColor" red="1" green="0.54901960780000003" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="1" green="0.94509803920000002" blue="0.87058823529999996" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="17" id="EKs-GN-PrW"/>
+                                    <constraint firstItem="HuW-TI-Qg2" firstAttribute="leading" secondItem="vge-mo-L76" secondAttribute="leading" constant="4" id="PXG-Ga-ZuL"/>
+                                    <constraint firstAttribute="trailing" secondItem="HuW-TI-Qg2" secondAttribute="trailing" constant="4" id="hfg-wn-1T6"/>
+                                    <constraint firstItem="HuW-TI-Qg2" firstAttribute="centerY" secondItem="vge-mo-L76" secondAttribute="centerY" id="tIg-gR-Rs4"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="4"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="已上课时 4 /总课时 6" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pMp-Fa-WxS">
+                                <rect key="frame" x="77.000000000000014" y="64.666666666666671" width="132.33333333333337" height="17"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrange_course_icon" translatesAutoresizingMaskIntoConstraints="NO" id="UMu-rh-fKg">
+                                <rect key="frame" x="63" y="66" width="12" height="14"/>
+                            </imageView>
+                        </subviews>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <constraints>
+                            <constraint firstItem="hQh-fY-QGG" firstAttribute="leading" secondItem="H34-rn-KTf" secondAttribute="trailing" constant="8" id="5VJ-nV-V4r"/>
+                            <constraint firstItem="H34-rn-KTf" firstAttribute="leading" secondItem="wVO-PU-gXJ" secondAttribute="leading" constant="12" id="7oN-IZ-bHp"/>
+                            <constraint firstItem="dy9-VA-eiu" firstAttribute="top" secondItem="wVO-PU-gXJ" secondAttribute="top" constant="12" id="9xd-i0-ns0"/>
+                            <constraint firstItem="pMp-Fa-WxS" firstAttribute="centerY" secondItem="UMu-rh-fKg" secondAttribute="centerY" id="Aco-Kv-llh"/>
+                            <constraint firstItem="pMp-Fa-WxS" firstAttribute="leading" secondItem="UMu-rh-fKg" secondAttribute="trailing" constant="2" id="D7D-IT-PsW"/>
+                            <constraint firstItem="hQh-fY-QGG" firstAttribute="top" secondItem="H34-rn-KTf" secondAttribute="top" id="JCY-y9-xpg"/>
+                            <constraint firstAttribute="trailing" secondItem="1Ol-S1-0uy" secondAttribute="trailing" constant="12" id="QHO-GJ-PWT"/>
+                            <constraint firstItem="UMu-rh-fKg" firstAttribute="leading" secondItem="H34-rn-KTf" secondAttribute="trailing" constant="11" id="Qmv-DU-ZYM"/>
+                            <constraint firstItem="1Ol-S1-0uy" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="dy9-VA-eiu" secondAttribute="trailing" constant="10" id="UFV-EE-oA1"/>
+                            <constraint firstItem="dy9-VA-eiu" firstAttribute="leading" secondItem="wVO-PU-gXJ" secondAttribute="leading" constant="12" id="VEF-5y-R1e"/>
+                            <constraint firstItem="1Ol-S1-0uy" firstAttribute="top" secondItem="wVO-PU-gXJ" secondAttribute="top" constant="12" id="WKU-QV-WGl"/>
+                            <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="pMp-Fa-WxS" secondAttribute="trailing" constant="12" id="bQe-YL-cUT"/>
+                            <constraint firstItem="vge-mo-L76" firstAttribute="centerY" secondItem="hQh-fY-QGG" secondAttribute="centerY" id="caQ-vi-RYp"/>
+                            <constraint firstItem="H34-rn-KTf" firstAttribute="top" secondItem="dy9-VA-eiu" secondAttribute="bottom" constant="8" id="eAK-e9-KFp"/>
+                            <constraint firstItem="vge-mo-L76" firstAttribute="leading" secondItem="hQh-fY-QGG" secondAttribute="trailing" constant="5" id="hnf-Ts-Avn"/>
+                            <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="vge-mo-L76" secondAttribute="trailing" constant="12" id="uuM-Oj-f5J"/>
+                            <constraint firstItem="UMu-rh-fKg" firstAttribute="bottom" secondItem="H34-rn-KTf" secondAttribute="bottom" constant="-2" id="wLG-6O-Nv3"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="10"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+                <constraints>
+                    <constraint firstAttribute="trailing" secondItem="wVO-PU-gXJ" secondAttribute="trailing" constant="14" id="1ii-QB-Vkc"/>
+                    <constraint firstItem="wVO-PU-gXJ" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="JO7-me-hyT"/>
+                    <constraint firstItem="wVO-PU-gXJ" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="sNQ-Ok-pa8"/>
+                    <constraint firstAttribute="bottom" secondItem="wVO-PU-gXJ" secondAttribute="bottom" constant="12" id="tIB-nf-OP6"/>
+                </constraints>
+            </tableViewCellContentView>
+            <viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <connections>
+                <outlet property="courseDesc" destination="pMp-Fa-WxS" id="4fb-Q2-fAR"/>
+                <outlet property="courseGroupName" destination="dy9-VA-eiu" id="FHM-97-lzy"/>
+                <outlet property="courseStudents" destination="hQh-fY-QGG" id="Epo-eU-D0S"/>
+                <outlet property="statusLabel" destination="1Ol-S1-0uy" id="snf-BD-ZBZ"/>
+                <outlet property="subjectLabel" destination="HuW-TI-Qg2" id="W8c-3O-Eva"/>
+            </connections>
+            <point key="canvasLocation" x="33.587786259541986" y="57.74647887323944"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="arrange_course_icon" width="12" height="14"/>
+        <image name="course_musicRoom" width="40" height="40"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseGroup/MyMusicRoomCourseGroupView.h

@@ -0,0 +1,18 @@
+//
+//  MyMusicRoomCourseGroupView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "KSJXBodyView.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyMusicRoomCourseGroupView : KSJXBodyView
+
+@property (nonatomic, strong) NSMutableArray *subjectList;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 296 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MusicRoomCourseGroup/MyMusicRoomCourseGroupView.m

@@ -0,0 +1,296 @@
+//
+//  MyMusicRoomCourseGroupView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyMusicRoomCourseGroupView.h"
+#import "MyCourseSearchView.h"
+#import "MyMusicGroupListCell.h"
+#import "StateView.h"
+#import "Reachability.h"
+#import "ProgramCourseGroupModel.h"
+
+@interface MyMusicRoomCourseGroupView ()<UITableViewDelegate,UITableViewDataSource>
+
+@property (nonatomic, assign) BOOL isLoadMore;
+@property (nonatomic, assign) NSInteger rows;
+@property (nonatomic, assign) NSInteger pages;
+
+@property (nonatomic, strong) NSMutableArray *dataArray;
+
+@property (nonatomic, strong) StateView *promptView;
+@property (nonatomic, strong) UIView *promptPlaceView;
+
+@property (nonatomic, assign) BOOL networkAvaiable; // 网络是否可用
+
+@property (nonatomic, strong) MyCourseSearchView *searchView;
+
+@property (nonatomic, strong) NSString *searchKey;
+
+@property (nonatomic, strong) NSString *subjectId;
+
+@property (nonatomic, strong) NSString *status;
+
+@end
+
+@implementation MyMusicRoomCourseGroupView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+        self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height) style:UITableViewStylePlain];
+        self.tableView.backgroundColor = [UIColor clearColor];
+        self.tableView.showsVerticalScrollIndicator = NO;
+        
+        self.tableView.dataSource = self;
+        self.tableView.delegate = self;
+        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+        [self addSubview:self.tableView];
+        self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
+        [self.tableView registerNib:[UINib nibWithNibName:@"MyMusicGroupListCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"MyMusicGroupListCell"];
+
+        UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, iPhoneXSafeBottomMargin)];
+        bottomView.backgroundColor = [UIColor clearColor];
+        self.tableView.tableFooterView = bottomView;
+        
+        MJWeakSelf;
+        self.tableView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
+            [weakSelf resetParamenter];
+            [weakSelf requestData];
+        }];
+        self.tableView.mj_footer = [KSGifRefreshFooter footerWithRefreshingBlock:^{
+            if (weakSelf.isLoadMore) {
+                weakSelf.pages += 1;
+                [weakSelf requestData];
+            }
+            else {
+                [weakSelf.tableView.mj_footer endRefreshingWithNoMoreData];
+            }
+        }];
+    }
+    return self;
+}
+
+- (void)refreshAndRequestData {
+    [self resetParamenter];
+    [self requestData];
+}
+
+- (void)resetParamenter {
+    self.isLoadMore = YES;
+    self.pages = 1;
+    self.rows = 10;
+    self.dataArray = [NSMutableArray array];
+    [self.tableView.mj_footer resetNoMoreData];
+    [self setPromptString:@"暂无内容" imageName:@"empty_course" inView:self.tableView];
+    [self.tableView reloadData];
+}
+
+- (void)endRefresh {
+    @weakObj(self);
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        @strongObj(self);
+        [self.tableView.mj_header endRefreshing];
+        [self.tableView.mj_footer endRefreshing];
+    });
+}
+
+
+- (void)requestData {
+    [KSNetworkingManager myCourseGroupRequest:KS_POST courseType:@"PIANO_ROOM_CLASS" search:self.searchKey subjectId:self.subjectId status:self.status success:^(NSDictionary * _Nonnull dic) {
+        [self endRefresh];
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            NSArray *sourceArray = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"rows"];
+            for (NSDictionary *parm in sourceArray) {
+                ProgramCourseGroupModel *model = [[ProgramCourseGroupModel alloc] initWithDictionary:parm];
+                [self.dataArray addObject:model];
+            }
+            if (sourceArray.count < self.rows) {
+                self.isLoadMore = NO;
+            }
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+        [self.tableView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    } faliure:^(NSError * _Nonnull error) {
+        [self endRefresh];
+        if (self.networkAvaiable == NO) {
+            [self setPromptString:@"暂无网络" imageName:@"no_networking" inView:self.tableView];
+        }
+        [self.dataArray removeAllObjects];
+        [self.tableView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    }];
+}
+
+- (void)beginRefreshImmediately {
+    [self.tableView.mj_header beginRefreshing];
+}
+
+- (void)beginFirstRefresh {
+    if (!self.isHeaderRefreshed) {
+        [self beginRefreshImmediately];
+    }
+}
+- (void)selectCellAtIndexPath:(NSIndexPath *)indexPath {
+    
+    if (self.lastSelectedIndexPath == indexPath) {
+        return;
+    }
+    if (self.lastSelectedIndexPath != nil) {
+        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.lastSelectedIndexPath];
+        [cell setSelected:NO animated:NO];
+    }
+    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
+    [cell setSelected:YES animated:NO];
+    self.lastSelectedIndexPath = indexPath;
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    CGFloat searchViewHeight = [MyCourseSearchView getViewHeight];
+
+    if (![self.subviews containsObject:self.searchView]) {
+        [self addSubview:self.searchView];
+        [self.searchView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.mas_equalTo(self);
+            make.height.mas_equalTo(searchViewHeight);
+        }];
+    }
+
+    [self.tableView mas_remakeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.bottom.mas_equalTo(self);
+        make.top.mas_equalTo(self.searchView.mas_bottom);
+    }];
+}
+
+#pragma mark - UITableViewDataSource
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return self.dataArray.count;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
+    return 106.0f;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    ProgramCourseGroupModel *model = self.dataArray[indexPath.row];
+    MyMusicGroupListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyMusicGroupListCell"];
+    [cell configWithSource:model];
+    return cell;
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    // 课程组详情
+    
+}
+
+#pragma mark ------ lazying
+- (MyCourseSearchView *)searchView {
+    if (!_searchView) {
+        _searchView = [MyCourseSearchView sharedInstance];
+        MJWeakSelf;
+        [_searchView searchActionCallback:^(MY_COURSE_SORT type, NSString * _Nullable searchKey) {
+            [weakSelf searchAction:type searchKey:searchKey];
+        }];
+    }
+    return _searchView;
+}
+
+- (void)searchAction:(MY_COURSE_SORT)type searchKey:(NSString *)searchKey {
+    switch (type) {
+        case MY_COURSE_SORT_RANK:
+        {
+            
+        }
+            break;
+        case MY_COURSE_SORT_SEARCH:
+        {
+            [self evaluateSource:searchKey];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)evaluateSource:(NSString *)searchKey {
+    self.searchKey = searchKey;
+    [self refreshAndRequestData];
+}
+
+/**
+ 设置没有数据时的显示
+ 
+ @param promptString 提示语
+ @param imgName 图片名称
+ @param view 显示在什么地方
+ */
+- (void)setPromptString:(NSString *)promptString imageName:(NSString *)imgName inView:(UIView *)view {
+    if (self.promptView != nil) {
+        [self.promptView removeFromSuperview];
+    }
+    else {
+        self.promptView = [[StateView alloc]init];
+        self.promptView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight - 300);
+    }
+    _promptPlaceView = view;
+    //当请求不到数据时 ,自定义提示view 将会出现;
+    self.promptView.imageName = imgName;
+    self.promptView.alpha = 0.0f;
+    [self.promptView setText:promptString];
+    [view addSubview:self.promptView];
+}
+
+// 结束刷新后调用方法
+- (void)changePromptLabelStateWithArray:(NSMutableArray *)array {
+    NSInteger count;
+    if (array.count) {
+        count = array.count;
+    } else {
+        count = 0;
+    }
+    
+    [UIView animateWithDuration:0.1 animations:^{
+        [[self promptView] setAlpha:count ? 0.0f :1.0f ] ;
+    }] ;
+    
+}
+
+- (BOOL)networkAvaiable {
+    return [self checkNetworkAvaiable];
+}
+
+- (BOOL)checkNetworkAvaiable {
+    BOOL isExistenceNetwork = YES;
+    Reachability *reach = [Reachability reachabilityWithHostName:@"www.apple.com"];
+    switch ([reach currentReachabilityStatus]) {
+        case NotReachable:
+            isExistenceNetwork = NO;
+            //NSLog(@"notReachable");
+            break;
+        case ReachableViaWiFi:
+            isExistenceNetwork = YES;
+            //NSLog(@"WIFI");
+            break;
+        case ReachableViaWWAN:
+            isExistenceNetwork = YES;
+            //NSLog(@"3G");
+            break;
+    }
+    return isExistenceNetwork;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 24 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseGroupNavView.h

@@ -0,0 +1,24 @@
+//
+//  MyCourseGroupNavView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^MyCourseNavCallback)(BOOL isBack);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyCourseGroupNavView : UIView
+
++ (instancetype)sharedInstance;
+
+- (void)navAction:(MyCourseNavCallback)callback;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 54 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseGroupNavView.m

@@ -0,0 +1,54 @@
+//
+//  MyCourseGroupNavView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyCourseGroupNavView.h"
+
+@interface MyCourseGroupNavView ()
+
+@property (nonatomic, copy) MyCourseNavCallback callback;
+
+@end
+
+@implementation MyCourseGroupNavView
+
++ (instancetype)sharedInstance {
+    MyCourseGroupNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"MyCourseGroupNavView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)navAction:(MyCourseNavCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)backAction:(id)sender {
+    if (self.callback) {
+        self.callback(YES);
+    }
+}
+
+- (IBAction)showTips:(id)sender {
+    if (self.callback) {
+        self.callback(NO);
+    }
+}
+
+
+
++ (CGFloat)getViewHeight {
+    return kNaviBarHeight;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 86 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseGroupNavView.xib

@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MyCourseGroupNavView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="85"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="boo-Uv-klO">
+                    <rect key="frame" x="0.0" y="41" width="393" height="44"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="back_black" translatesAutoresizingMaskIntoConstraints="NO" id="lME-kR-y32">
+                            <rect key="frame" x="15" y="12" width="12" height="20"/>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZQy-2D-h6w">
+                            <rect key="frame" x="0.0" y="0.0" width="44" height="44"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="44" id="w9i-XK-uls"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="backAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="KYl-xW-s4f"/>
+                            </connections>
+                        </button>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我的课程" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="98I-jh-ZtZ">
+                            <rect key="frame" x="160.66666666666666" y="11" width="71.666666666666657" height="22"/>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/>
+                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="program_tips" translatesAutoresizingMaskIntoConstraints="NO" id="cd4-ry-QF5">
+                            <rect key="frame" x="359" y="12" width="20" height="20"/>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2NZ-5x-aXa">
+                            <rect key="frame" x="349" y="0.0" width="44" height="44"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="44" id="PzE-Li-O3n"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="showTips:" destination="iN0-l3-epB" eventType="touchUpInside" id="bZ4-N4-jqD"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="98I-jh-ZtZ" firstAttribute="centerX" secondItem="boo-Uv-klO" secondAttribute="centerX" id="4tB-jZ-AdF"/>
+                        <constraint firstAttribute="bottom" secondItem="2NZ-5x-aXa" secondAttribute="bottom" id="HDe-1V-kAD"/>
+                        <constraint firstItem="98I-jh-ZtZ" firstAttribute="centerY" secondItem="boo-Uv-klO" secondAttribute="centerY" id="Pvy-mZ-sFV"/>
+                        <constraint firstItem="ZQy-2D-h6w" firstAttribute="leading" secondItem="boo-Uv-klO" secondAttribute="leading" id="RwT-Sy-l8Y"/>
+                        <constraint firstItem="2NZ-5x-aXa" firstAttribute="top" secondItem="boo-Uv-klO" secondAttribute="top" id="TsK-67-A91"/>
+                        <constraint firstItem="lME-kR-y32" firstAttribute="centerY" secondItem="boo-Uv-klO" secondAttribute="centerY" id="VCd-jy-Kac"/>
+                        <constraint firstAttribute="trailing" secondItem="cd4-ry-QF5" secondAttribute="trailing" constant="14" id="kQN-fo-WaD"/>
+                        <constraint firstItem="lME-kR-y32" firstAttribute="leading" secondItem="boo-Uv-klO" secondAttribute="leading" constant="15" id="kU9-EE-M9h"/>
+                        <constraint firstAttribute="height" constant="44" id="laL-1y-8Ft"/>
+                        <constraint firstAttribute="bottom" secondItem="ZQy-2D-h6w" secondAttribute="bottom" id="lwF-uW-uUV"/>
+                        <constraint firstAttribute="trailing" secondItem="2NZ-5x-aXa" secondAttribute="trailing" id="n7o-en-OzA"/>
+                        <constraint firstItem="ZQy-2D-h6w" firstAttribute="top" secondItem="boo-Uv-klO" secondAttribute="top" id="pW2-IL-fwr"/>
+                        <constraint firstItem="cd4-ry-QF5" firstAttribute="centerY" secondItem="boo-Uv-klO" secondAttribute="centerY" id="vns-at-f0e"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="boo-Uv-klO" secondAttribute="bottom" id="hmX-5v-XW9"/>
+                <constraint firstAttribute="trailing" secondItem="boo-Uv-klO" secondAttribute="trailing" id="j6u-s5-T4c"/>
+                <constraint firstItem="boo-Uv-klO" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="vnd-3J-BBM"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="32.824427480916029" y="120.07042253521128"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="back_black" width="12" height="20"/>
+        <image name="program_tips" width="20" height="20"/>
+    </resources>
+</document>

+ 31 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseSortView/MyCourseSearchView.h

@@ -0,0 +1,31 @@
+//
+//  MyCourseSearchView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, MY_COURSE_SORT) {
+    MY_COURSE_SORT_RANK,
+    MY_COURSE_SORT_SEARCH,
+};
+
+typedef void(^MyCourseSortCallback)(MY_COURSE_SORT type, NSString * _Nullable searchKey);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyCourseSearchView : UIView
+
+@property (nonatomic, assign) BOOL arrowUp;
+
++ (instancetype)sharedInstance;
+
+- (void)searchActionCallback:(MyCourseSortCallback)callback;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 65 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseSortView/MyCourseSearchView.m

@@ -0,0 +1,65 @@
+//
+//  MyCourseSearchView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyCourseSearchView.h"
+
+@interface MyCourseSearchView ()<UITextFieldDelegate>
+
+@property (weak, nonatomic) IBOutlet UITextField *searchField;
+
+@property (nonatomic, copy) MyCourseSortCallback callback;
+
+
+@end
+
+@implementation MyCourseSearchView
+
++ (instancetype)sharedInstance {
+    MyCourseSearchView *view = [[[NSBundle mainBundle] loadNibNamed:@"MyCourseSearchView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)searchActionCallback:(MyCourseSortCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)chooseRank:(id)sender {
+    [self endEditing:YES];
+    if (self.callback) {
+        self.callback(MY_COURSE_SORT_RANK, nil);
+    }
+}
+
+- (IBAction)searchAction:(id)sender {
+    [self endEditing:YES];
+    if (self.callback) {
+        self.callback(MY_COURSE_SORT_SEARCH, self.searchField.text);
+    }
+}
+
+- (BOOL)textFieldShouldReturn:(UITextField *)textField {
+    [self endEditing:YES];
+    if (self.callback) {
+        self.callback(MY_COURSE_SORT_SEARCH, textField.text);
+    }
+    return YES;
+}
+
++ (CGFloat)getViewHeight {
+    return 58.0f;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 129 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseSortView/MyCourseSearchView.xib

@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MyCourseSearchView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="64"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ypg-l8-Rgd">
+                    <rect key="frame" x="14" y="12" width="41" height="34"/>
+                    <subviews>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="筛选" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JbG-oJ-9Y1">
+                            <rect key="frame" x="0.0" y="8.6666666666666679" width="28" height="17"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.074509803920000006" green="0.078431372550000003" blue="0.08235294118" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sort_up_grey" translatesAutoresizingMaskIntoConstraints="NO" id="aG3-fG-AR8">
+                            <rect key="frame" x="32" y="14.666666666666668" width="9" height="5"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="9" id="VIv-ab-N47"/>
+                            </constraints>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CNb-m9-7cz">
+                            <rect key="frame" x="0.0" y="0.0" width="41" height="34"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="chooseRank:" destination="iN0-l3-epB" eventType="touchUpInside" id="qTC-X8-xv5"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="CNb-m9-7cz" firstAttribute="leading" secondItem="Ypg-l8-Rgd" secondAttribute="leading" id="3Ko-sR-Sfo"/>
+                        <constraint firstItem="aG3-fG-AR8" firstAttribute="centerY" secondItem="JbG-oJ-9Y1" secondAttribute="centerY" id="5Pv-pc-saN"/>
+                        <constraint firstAttribute="trailing" secondItem="CNb-m9-7cz" secondAttribute="trailing" id="AHI-d6-4bY"/>
+                        <constraint firstItem="JbG-oJ-9Y1" firstAttribute="centerY" secondItem="Ypg-l8-Rgd" secondAttribute="centerY" id="AM6-bB-BQb"/>
+                        <constraint firstAttribute="height" constant="34" id="BDR-wh-jff"/>
+                        <constraint firstItem="aG3-fG-AR8" firstAttribute="leading" secondItem="JbG-oJ-9Y1" secondAttribute="trailing" constant="4" id="GKm-Li-G2a"/>
+                        <constraint firstItem="CNb-m9-7cz" firstAttribute="top" secondItem="Ypg-l8-Rgd" secondAttribute="top" id="LqW-5k-uBk"/>
+                        <constraint firstAttribute="trailing" secondItem="aG3-fG-AR8" secondAttribute="trailing" id="oob-Rf-G6r"/>
+                        <constraint firstItem="JbG-oJ-9Y1" firstAttribute="leading" secondItem="Ypg-l8-Rgd" secondAttribute="leading" id="tiT-ut-MJE"/>
+                        <constraint firstAttribute="bottom" secondItem="CNb-m9-7cz" secondAttribute="bottom" id="w2y-M0-GGk"/>
+                    </constraints>
+                </view>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="afT-Br-uER">
+                    <rect key="frame" x="67" y="12" width="312" height="34"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="search_green" translatesAutoresizingMaskIntoConstraints="NO" id="TDe-Bu-KkR">
+                            <rect key="frame" x="12" y="9" width="16" height="16"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="16" id="dva-6g-68u"/>
+                                <constraint firstAttribute="width" constant="16" id="vS0-WG-a1n"/>
+                            </constraints>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CM2-S3-m7O">
+                            <rect key="frame" x="253" y="3" width="56" height="28"/>
+                            <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="28" id="JIY-oi-nMf"/>
+                                <constraint firstAttribute="width" constant="56" id="PIP-R2-4Sh"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" title="搜索"/>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="14"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <connections>
+                                <action selector="searchAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="ouv-ni-pJU"/>
+                            </connections>
+                        </button>
+                        <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="请输入搜索关键词" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="ZbY-Gz-MYd">
+                            <rect key="frame" x="34" y="0.0" width="207" height="34"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <textInputTraits key="textInputTraits"/>
+                        </textField>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="ZbY-Gz-MYd" firstAttribute="top" secondItem="afT-Br-uER" secondAttribute="top" id="7sA-K4-RGK"/>
+                        <constraint firstItem="TDe-Bu-KkR" firstAttribute="centerY" secondItem="afT-Br-uER" secondAttribute="centerY" id="G55-Ie-9Rm"/>
+                        <constraint firstItem="CM2-S3-m7O" firstAttribute="centerY" secondItem="afT-Br-uER" secondAttribute="centerY" id="LQP-CB-Egm"/>
+                        <constraint firstAttribute="bottom" secondItem="ZbY-Gz-MYd" secondAttribute="bottom" id="dv2-Hw-7Wd"/>
+                        <constraint firstItem="ZbY-Gz-MYd" firstAttribute="leading" secondItem="TDe-Bu-KkR" secondAttribute="trailing" constant="6" id="jZe-s7-n8Q"/>
+                        <constraint firstItem="TDe-Bu-KkR" firstAttribute="leading" secondItem="afT-Br-uER" secondAttribute="leading" constant="12" id="oW6-Ub-o9t"/>
+                        <constraint firstItem="CM2-S3-m7O" firstAttribute="leading" secondItem="ZbY-Gz-MYd" secondAttribute="trailing" constant="12" id="rMo-2L-q7X"/>
+                        <constraint firstAttribute="height" constant="34" id="rYi-Wd-MfN"/>
+                        <constraint firstAttribute="trailing" secondItem="CM2-S3-m7O" secondAttribute="trailing" constant="3" id="uGB-M0-dSp"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="17"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="Ypg-l8-Rgd" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="FYK-PB-ZgN"/>
+                <constraint firstAttribute="trailing" secondItem="afT-Br-uER" secondAttribute="trailing" constant="14" id="dsj-NO-EbS"/>
+                <constraint firstItem="Ypg-l8-Rgd" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="12" id="gwS-lP-Rdk"/>
+                <constraint firstItem="afT-Br-uER" firstAttribute="centerY" secondItem="Ypg-l8-Rgd" secondAttribute="centerY" id="l2b-DF-DD2"/>
+                <constraint firstItem="afT-Br-uER" firstAttribute="leading" secondItem="Ypg-l8-Rgd" secondAttribute="trailing" constant="12" id="t9H-no-QBP"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="searchField" destination="ZbY-Gz-MYd" id="uG1-ld-TiF"/>
+            </connections>
+            <point key="canvasLocation" x="32.824427480916029" y="-2.1126760563380285"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="search_green" width="16" height="16"/>
+        <image name="sort_up_grey" width="9" height="5"/>
+    </resources>
+</document>

+ 19 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VIPCourseGroup/MyProgramCourseGroupCell.h

@@ -0,0 +1,19 @@
+//
+//  MyProgramCourseGroupCell.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import <UIKit/UIKit.h>
+#import "ProgramCourseGroupModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyProgramCourseGroupCell : UITableViewCell
+
+- (void)configWithSource:(ProgramCourseGroupModel *)model isVipCourse:(BOOL)isVipCourse;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 93 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VIPCourseGroup/MyProgramCourseGroupCell.m

@@ -0,0 +1,93 @@
+//
+//  MyProgramCourseGroupCell.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyProgramCourseGroupCell.h"
+
+@interface MyProgramCourseGroupCell ()
+
+@property (weak, nonatomic) IBOutlet UILabel *programTitle;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseStatus;
+
+@property (weak, nonatomic) IBOutlet UIImageView *studentAvatar;
+
+@property (weak, nonatomic) IBOutlet UILabel *studentName;
+
+@property (weak, nonatomic) IBOutlet UIView *subjectView;
+
+@property (weak, nonatomic) IBOutlet UILabel *subjectLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseDesc;
+
+@end
+
+@implementation MyProgramCourseGroupCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+- (void)configWithSource:(ProgramCourseGroupModel *)model isVipCourse:(BOOL)isVipCourse {
+    NSString *courseGroupTitle = @"";
+    if (isVipCourse) {
+        courseGroupTitle = [NSString stringWithFormat:@"VIP定制课-%@", model.studentName];
+    }
+    else {
+        courseGroupTitle = [NSString stringWithFormat:@"趣纠课-%@", model.studentName];
+    }
+    
+    self.programTitle.text = courseGroupTitle;
+    /// 状态
+    [self evaluateGroupStatus:model.status];
+    
+    [self.studentAvatar sd_setImageWithURL:[NSURL URLWithString:[model.studentAvatar getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:STUDENT_AVATAR]];
+    
+    self.studentName.text = [NSString returnNoNullStringWithString:model.studentName];
+    
+    self.subjectLabel.text = [NSString returnNoNullStringWithString:model.subjectName];
+    
+    // 课程描述
+    NSMutableAttributedString *attrs = [[NSMutableAttributedString alloc] initWithString:@"已上课时 " attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightRegular],NSForegroundColorAttributeName:HexRGB(0x999999)}];
+    NSAttributedString *finishNumAttr = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%.0f", model.completeCourseNum] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightSemibold],NSForegroundColorAttributeName:THEMECOLOR}];
+    [attrs appendAttributedString:finishNumAttr];
+    
+    NSAttributedString *totalDescAttr = [[NSAttributedString alloc] initWithString:@" /总课时 " attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightRegular],NSForegroundColorAttributeName:HexRGB(0x999999)}];
+    [attrs appendAttributedString:totalDescAttr];
+    NSAttributedString *totalNumAttr = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%.0f", model.courseNum] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f weight:UIFontWeightSemibold],NSForegroundColorAttributeName:THEMECOLOR}];
+    [attrs appendAttributedString:totalNumAttr];
+    self.courseDesc.attributedText = attrs;
+}
+
+
+- (void)evaluateGroupStatus:(NSString *)status {
+    if ([status isEqualToString:@"ING"]) {
+        self.courseStatus.text = @"已开课";
+        self.courseStatus.textColor = THEMECOLOR;
+    }
+    else if ([status isEqualToString:@"NOT_START"]) {
+        self.courseStatus.text = @"未开课";
+        self.courseStatus.textColor = HexRGB(0xFF802C);
+    }
+    else if ([status isEqualToString:@"COMPLETE"]) {
+        self.courseStatus.text = @"已结课";
+        self.courseStatus.textColor = HexRGB(0x999999);
+    }
+    else if ([status isEqualToString:@"CANCEL"]) {
+        self.courseStatus.text = @"已取消";
+        self.courseStatus.textColor = HexRGB(0x999999);
+    }
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end

+ 147 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VIPCourseGroup/MyProgramCourseGroupCell.xib

@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="123" id="KGk-i7-Jjw" customClass="MyProgramCourseGroupCell">
+            <rect key="frame" x="0.0" y="0.0" width="320" height="106"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="320" height="106"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hOG-9r-FYS">
+                        <rect key="frame" x="14" y="0.0" width="292" height="94"/>
+                        <subviews>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="VIP定制课-张涵宇" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fSB-R2-WNn">
+                                <rect key="frame" x="12" y="12" width="130.33333333333334" height="22"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="22" id="yBY-pf-3Gt"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                                <color key="textColor" red="0.074509803921568626" green="0.078431372549019607" blue="0.082352941176470587" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="未开课" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YcB-0r-jIC">
+                                <rect key="frame" x="238" y="12" width="42" height="17"/>
+                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                                <color key="textColor" red="1" green="0.50196078431372548" blue="0.17254901960784313" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" image="student_avatar" translatesAutoresizingMaskIntoConstraints="NO" id="Vki-dh-9s6">
+                                <rect key="frame" x="12" y="42" width="40" height="40"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="40" id="1t4-E5-ggF"/>
+                                    <constraint firstAttribute="height" constant="40" id="TJ2-qk-5z4"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="20"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </imageView>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="向冰冰" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6KB-MT-3Xa">
+                                <rect key="frame" x="62" y="43" width="39" height="17"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="17" id="6JM-FU-U7f"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrange_course_icon" translatesAutoresizingMaskIntoConstraints="NO" id="thQ-Vr-ooa">
+                                <rect key="frame" x="63" y="68" width="12" height="14"/>
+                            </imageView>
+                            <view contentMode="scaleToFill" horizontalCompressionResistancePriority="752" translatesAutoresizingMaskIntoConstraints="NO" id="fHv-aO-hTk">
+                                <rect key="frame" x="106" y="43" width="38" height="17"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="单簧管" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Fmo-ut-d02">
+                                        <rect key="frame" x="4" y="2.6666666666666643" width="30" height="12"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="10"/>
+                                        <color key="textColor" red="1" green="0.5490196078431373" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="1" green="0.94509803921568625" blue="0.87058823529411766" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstItem="Fmo-ut-d02" firstAttribute="centerY" secondItem="fHv-aO-hTk" secondAttribute="centerY" id="88h-UI-mze"/>
+                                    <constraint firstAttribute="trailing" secondItem="Fmo-ut-d02" secondAttribute="trailing" constant="4" id="JOf-3A-rAe"/>
+                                    <constraint firstAttribute="height" constant="17" id="ovP-MY-OYD"/>
+                                    <constraint firstItem="Fmo-ut-d02" firstAttribute="leading" secondItem="fHv-aO-hTk" secondAttribute="leading" constant="4" id="uHB-Xv-Do1"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="4"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="已上课时 34 /总课时 20" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JcJ-gf-HY4">
+                                <rect key="frame" x="79" y="67" width="129" height="16"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="16" id="LXf-Qg-nV3"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        <constraints>
+                            <constraint firstItem="YcB-0r-jIC" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="fSB-R2-WNn" secondAttribute="trailing" constant="10" id="0Y7-8G-mFF"/>
+                            <constraint firstItem="fHv-aO-hTk" firstAttribute="leading" secondItem="6KB-MT-3Xa" secondAttribute="trailing" constant="5" id="4St-wE-Cud"/>
+                            <constraint firstItem="Vki-dh-9s6" firstAttribute="top" secondItem="fSB-R2-WNn" secondAttribute="bottom" constant="8" id="7BC-Sv-XIT"/>
+                            <constraint firstItem="fHv-aO-hTk" firstAttribute="centerY" secondItem="6KB-MT-3Xa" secondAttribute="centerY" id="Cyj-9i-Qcu"/>
+                            <constraint firstItem="fSB-R2-WNn" firstAttribute="leading" secondItem="hOG-9r-FYS" secondAttribute="leading" constant="12" id="GbP-2m-C6c"/>
+                            <constraint firstItem="thQ-Vr-ooa" firstAttribute="top" secondItem="6KB-MT-3Xa" secondAttribute="bottom" constant="8" id="IDW-ds-9YC"/>
+                            <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="fHv-aO-hTk" secondAttribute="trailing" constant="12" id="Jb1-0I-kqm"/>
+                            <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="JcJ-gf-HY4" secondAttribute="trailing" constant="12" id="N3u-Qa-brC"/>
+                            <constraint firstItem="6KB-MT-3Xa" firstAttribute="leading" secondItem="Vki-dh-9s6" secondAttribute="trailing" constant="10" id="N81-aa-HFk"/>
+                            <constraint firstItem="6KB-MT-3Xa" firstAttribute="top" secondItem="fSB-R2-WNn" secondAttribute="bottom" constant="9" id="RhP-KQ-ExU"/>
+                            <constraint firstItem="JcJ-gf-HY4" firstAttribute="leading" secondItem="thQ-Vr-ooa" secondAttribute="trailing" constant="4" id="S19-6a-nNB"/>
+                            <constraint firstItem="JcJ-gf-HY4" firstAttribute="centerY" secondItem="thQ-Vr-ooa" secondAttribute="centerY" id="Vg7-2b-0SI"/>
+                            <constraint firstItem="YcB-0r-jIC" firstAttribute="top" secondItem="hOG-9r-FYS" secondAttribute="top" constant="12" id="ZvC-KZ-QO8"/>
+                            <constraint firstItem="fSB-R2-WNn" firstAttribute="top" secondItem="hOG-9r-FYS" secondAttribute="top" constant="12" id="e2X-jz-1wa"/>
+                            <constraint firstItem="Vki-dh-9s6" firstAttribute="leading" secondItem="hOG-9r-FYS" secondAttribute="leading" constant="12" id="k25-T3-H2k"/>
+                            <constraint firstItem="thQ-Vr-ooa" firstAttribute="leading" secondItem="Vki-dh-9s6" secondAttribute="trailing" constant="11" id="w3I-Ch-OAi"/>
+                            <constraint firstAttribute="trailing" secondItem="YcB-0r-jIC" secondAttribute="trailing" constant="12" id="zpd-wE-jND"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="10"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+                <constraints>
+                    <constraint firstAttribute="bottom" secondItem="hOG-9r-FYS" secondAttribute="bottom" constant="12" id="5Sf-z3-Tz9"/>
+                    <constraint firstItem="hOG-9r-FYS" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="Imi-54-xvz"/>
+                    <constraint firstAttribute="trailing" secondItem="hOG-9r-FYS" secondAttribute="trailing" constant="14" id="KzP-2w-x9d"/>
+                    <constraint firstItem="hOG-9r-FYS" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="cGE-R5-38a"/>
+                </constraints>
+            </tableViewCellContentView>
+            <viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <connections>
+                <outlet property="courseDesc" destination="JcJ-gf-HY4" id="Ck1-zp-SxF"/>
+                <outlet property="courseStatus" destination="YcB-0r-jIC" id="V7K-v4-pNK"/>
+                <outlet property="programTitle" destination="fSB-R2-WNn" id="9y7-Iv-5m1"/>
+                <outlet property="studentAvatar" destination="Vki-dh-9s6" id="uiX-dC-eFf"/>
+                <outlet property="studentName" destination="6KB-MT-3Xa" id="1lk-4e-JjH"/>
+                <outlet property="subjectLabel" destination="Fmo-ut-d02" id="Jfa-Vr-NFF"/>
+                <outlet property="subjectView" destination="fHv-aO-hTk" id="RS8-s9-veB"/>
+            </connections>
+            <point key="canvasLocation" x="33.587786259541986" y="47.183098591549296"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="arrange_course_icon" width="12" height="14"/>
+        <image name="student_avatar" width="150" height="150"/>
+    </resources>
+</document>

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VIPCourseGroup/MyVipCourseGroupView.h

@@ -0,0 +1,18 @@
+//
+//  MyVipCourseGroupView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "KSJXBodyView.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyVipCourseGroupView : KSJXBodyView
+
+@property (nonatomic, strong) NSMutableArray *subjectList;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 298 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VIPCourseGroup/MyVipCourseGroupView.m

@@ -0,0 +1,298 @@
+//
+//  MyVipCourseGroupView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyVipCourseGroupView.h"
+#import "MyProgramCourseGroupCell.h"
+#import "MyCourseSearchView.h"
+#import "StateView.h"
+#import "Reachability.h"
+#import "ProgramCourseGroupModel.h"
+
+@interface MyVipCourseGroupView ()<UITableViewDelegate,UITableViewDataSource>
+
+@property (nonatomic, assign) BOOL isLoadMore;
+@property (nonatomic, assign) NSInteger rows;
+@property (nonatomic, assign) NSInteger pages;
+
+@property (nonatomic, strong) NSMutableArray *dataArray;
+
+@property (nonatomic, strong) StateView *promptView;
+@property (nonatomic, strong) UIView *promptPlaceView;
+
+@property (nonatomic, assign) BOOL networkAvaiable; // 网络是否可用
+
+@property (nonatomic, strong) MyCourseSearchView *searchView;
+
+@property (nonatomic, strong) NSString *searchKey;
+
+@property (nonatomic, strong) NSString *subjectId;
+
+@property (nonatomic, strong) NSString *status;
+
+@end
+
+@implementation MyVipCourseGroupView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+        self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height) style:UITableViewStylePlain];
+        self.tableView.backgroundColor = [UIColor clearColor];
+        self.tableView.showsVerticalScrollIndicator = NO;
+        
+        self.tableView.dataSource = self;
+        self.tableView.delegate = self;
+        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+        [self addSubview:self.tableView];
+        self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
+        [self.tableView registerNib:[UINib nibWithNibName:@"MyProgramCourseGroupCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"MyProgramCourseGroupCell"];
+
+        UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, iPhoneXSafeBottomMargin)];
+        bottomView.backgroundColor = [UIColor clearColor];
+        self.tableView.tableFooterView = bottomView;
+        
+        MJWeakSelf;
+        self.tableView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
+            [weakSelf resetParamenter];
+            [weakSelf requestData];
+        }];
+        self.tableView.mj_footer = [KSGifRefreshFooter footerWithRefreshingBlock:^{
+            if (weakSelf.isLoadMore) {
+                weakSelf.pages += 1;
+                [weakSelf requestData];
+            }
+            else {
+                [weakSelf.tableView.mj_footer endRefreshingWithNoMoreData];
+            }
+        }];
+    }
+    return self;
+}
+
+- (void)refreshAndRequestData {
+    [self resetParamenter];
+    [self requestData];
+}
+
+- (void)resetParamenter {
+    self.isLoadMore = YES;
+    self.pages = 1;
+    self.rows = 10;
+    
+    self.dataArray = [NSMutableArray array];
+    [self.tableView.mj_footer resetNoMoreData];
+    [self setPromptString:@"暂无内容" imageName:@"empty_course" inView:self.tableView];
+    [self.tableView reloadData];
+}
+
+- (void)endRefresh {
+    @weakObj(self);
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        @strongObj(self);
+        [self.tableView.mj_header endRefreshing];
+        [self.tableView.mj_footer endRefreshing];
+    });
+}
+
+
+- (void)requestData {
+    [KSNetworkingManager myCourseGroupRequest:KS_POST courseType:@"VIP" search:self.searchKey subjectId:self.subjectId status:self.status success:^(NSDictionary * _Nonnull dic) {
+        [self endRefresh];
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            NSArray *sourceArray = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"rows"];
+            for (NSDictionary *parm in sourceArray) {
+                ProgramCourseGroupModel *model = [[ProgramCourseGroupModel alloc] initWithDictionary:parm];
+                [self.dataArray addObject:model];
+            }
+            if (sourceArray.count < self.rows) {
+                self.isLoadMore = NO;
+            }
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+        [self.tableView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    } faliure:^(NSError * _Nonnull error) {
+        [self endRefresh];
+        if (self.networkAvaiable == NO) {
+            [self setPromptString:@"暂无网络" imageName:@"no_networking" inView:self.tableView];
+        }
+        [self.dataArray removeAllObjects];
+        [self.tableView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    }];
+    
+    
+}
+
+- (void)beginRefreshImmediately {
+    [self.tableView.mj_header beginRefreshing];
+}
+
+- (void)beginFirstRefresh {
+    if (!self.isHeaderRefreshed) {
+        [self beginRefreshImmediately];
+    }
+}
+- (void)selectCellAtIndexPath:(NSIndexPath *)indexPath {
+    
+    if (self.lastSelectedIndexPath == indexPath) {
+        return;
+    }
+    if (self.lastSelectedIndexPath != nil) {
+        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.lastSelectedIndexPath];
+        [cell setSelected:NO animated:NO];
+    }
+    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
+    [cell setSelected:YES animated:NO];
+    self.lastSelectedIndexPath = indexPath;
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    CGFloat searchViewHeight = [MyCourseSearchView getViewHeight];
+
+    if (![self.subviews containsObject:self.searchView]) {
+        [self addSubview:self.searchView];
+        [self.searchView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.mas_equalTo(self);
+            make.height.mas_equalTo(searchViewHeight);
+        }];
+    }
+
+    [self.tableView mas_remakeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.bottom.mas_equalTo(self);
+        make.top.mas_equalTo(self.searchView.mas_bottom);
+    }];
+}
+
+#pragma mark - UITableViewDataSource
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return self.dataArray.count;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
+    return 106.0f;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    ProgramCourseGroupModel *model = self.dataArray[indexPath.row];
+    MyProgramCourseGroupCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyProgramCourseGroupCell"];
+    [cell configWithSource:model isVipCourse:NO];
+    return cell;
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    // 课程详情
+}
+
+#pragma mark ------ lazying
+- (MyCourseSearchView *)searchView {
+    if (!_searchView) {
+        _searchView = [MyCourseSearchView sharedInstance];
+        MJWeakSelf;
+        [_searchView searchActionCallback:^(MY_COURSE_SORT type, NSString * _Nullable searchKey) {
+            [weakSelf searchAction:type searchKey:searchKey];
+        }];
+    }
+    return _searchView;
+}
+
+- (void)searchAction:(MY_COURSE_SORT)type searchKey:(NSString *)searchKey {
+    switch (type) {
+        case MY_COURSE_SORT_RANK:
+        {
+            
+        }
+            break;
+        case MY_COURSE_SORT_SEARCH:
+        {
+            [self evaluateSource:searchKey];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)evaluateSource:(NSString *)searchKey {
+    self.searchKey = searchKey;
+    [self refreshAndRequestData];
+}
+
+/**
+ 设置没有数据时的显示
+ 
+ @param promptString 提示语
+ @param imgName 图片名称
+ @param view 显示在什么地方
+ */
+- (void)setPromptString:(NSString *)promptString imageName:(NSString *)imgName inView:(UIView *)view {
+    if (self.promptView != nil) {
+        [self.promptView removeFromSuperview];
+    }
+    else {
+        self.promptView = [[StateView alloc]init];
+        self.promptView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight - 300);
+    }
+    _promptPlaceView = view;
+    //当请求不到数据时 ,自定义提示view 将会出现;
+    self.promptView.imageName = imgName;
+    self.promptView.alpha = 0.0f;
+    [self.promptView setText:promptString];
+    [view addSubview:self.promptView];
+}
+
+// 结束刷新后调用方法
+- (void)changePromptLabelStateWithArray:(NSMutableArray *)array {
+    NSInteger count;
+    if (array.count) {
+        count = array.count;
+    } else {
+        count = 0;
+    }
+    
+    [UIView animateWithDuration:0.1 animations:^{
+        [[self promptView] setAlpha:count ? 0.0f :1.0f ] ;
+    }] ;
+    
+}
+
+- (BOOL)networkAvaiable {
+    return [self checkNetworkAvaiable];
+}
+
+- (BOOL)checkNetworkAvaiable {
+    BOOL isExistenceNetwork = YES;
+    Reachability *reach = [Reachability reachabilityWithHostName:@"www.apple.com"];
+    switch ([reach currentReachabilityStatus]) {
+        case NotReachable:
+            isExistenceNetwork = NO;
+            //NSLog(@"notReachable");
+            break;
+        case ReachableViaWiFi:
+            isExistenceNetwork = YES;
+            //NSLog(@"WIFI");
+            break;
+        case ReachableViaWWAN:
+            isExistenceNetwork = YES;
+            //NSLog(@"3G");
+            break;
+    }
+    return isExistenceNetwork;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VideoCourseGroup/MyVideoCourseGroupView.h

@@ -0,0 +1,18 @@
+//
+//  MyVideoCourseGroupView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "KSJXBodyView.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyVideoCourseGroupView : KSJXBodyView
+
+@property (nonatomic, strong) NSMutableArray *subjectList;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 304 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VideoCourseGroup/MyVideoCourseGroupView.m

@@ -0,0 +1,304 @@
+//
+//  MyVideoCourseGroupView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyVideoCourseGroupView.h"
+#import "MyCourseSearchView.h"
+#import "MyVideoGroupListCell.h"
+#import "VideoCourseModel.h"
+#import "StateView.h"
+#import "Reachability.h"
+#import "KSBaseWKWebViewController.h"
+
+@interface MyVideoCourseGroupView ()<UITableViewDelegate,UITableViewDataSource>
+
+@property (nonatomic, assign) BOOL isLoadMore;
+@property (nonatomic, assign) NSInteger rows;
+@property (nonatomic, assign) NSInteger pages;
+
+@property (nonatomic, strong) NSMutableArray *dataArray;
+
+@property (nonatomic, strong) StateView *promptView;
+@property (nonatomic, strong) UIView *promptPlaceView;
+
+@property (nonatomic, assign) BOOL networkAvaiable; // 网络是否可用
+
+@property (nonatomic, strong) MyCourseSearchView *searchView;
+
+@property (nonatomic, strong) NSString *searchKey;
+
+@property (nonatomic, strong) NSString *subjectId;
+
+@property (nonatomic, strong) NSString *audioStatus;
+
+@end
+
+@implementation MyVideoCourseGroupView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+        self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height) style:UITableViewStylePlain];
+        self.tableView.backgroundColor = [UIColor clearColor];
+        self.tableView.showsVerticalScrollIndicator = NO;
+        
+        self.tableView.dataSource = self;
+        self.tableView.delegate = self;
+        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+        [self addSubview:self.tableView];
+        self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
+        [self.tableView registerNib:[UINib nibWithNibName:@"MyVideoGroupListCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"MyVideoGroupListCell"];
+
+        UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, iPhoneXSafeBottomMargin)];
+        bottomView.backgroundColor = [UIColor clearColor];
+        self.tableView.tableFooterView = bottomView;
+        
+        MJWeakSelf;
+        self.tableView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
+            [weakSelf resetParamenter];
+            [weakSelf requestData];
+        }];
+        self.tableView.mj_footer = [KSGifRefreshFooter footerWithRefreshingBlock:^{
+            if (weakSelf.isLoadMore) {
+                weakSelf.pages += 1;
+                [weakSelf requestData];
+            }
+            else {
+                [weakSelf.tableView.mj_footer endRefreshingWithNoMoreData];
+            }
+        }];
+    }
+    return self;
+}
+
+- (void)refreshAndRequestData {
+    [self resetParamenter];
+    [self requestData];
+}
+
+- (void)resetParamenter {
+    self.isLoadMore = YES;
+    self.pages = 1;
+    self.rows = 10;
+    self.audioStatus = @"PASS";
+    self.dataArray = [NSMutableArray array];
+    [self.tableView.mj_footer resetNoMoreData];
+    [self setPromptString:@"暂无内容" imageName:@"empty_course" inView:self.tableView];
+    [self.tableView reloadData];
+}
+
+- (void)endRefresh {
+    @weakObj(self);
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        @strongObj(self);
+        [self.tableView.mj_header endRefreshing];
+        [self.tableView.mj_footer endRefreshing];
+    });
+}
+
+
+- (void)requestData {
+    [KSNetworkingManager videoLessonListRequest:KS_POST lessonSubject:self.searchKey auditStatus:self.audioStatus pageNo:self.pages pageSize:self.rows success:^(NSDictionary * _Nonnull dic) {
+        [self endRefresh];
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            NSArray *sourceArray = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"rows"];
+            for (NSDictionary *parm in sourceArray) {
+                VideoCourseModel *model = [[VideoCourseModel alloc] initWithDictionary:parm];
+                [self.dataArray addObject:model];
+            }
+            
+            if (sourceArray.count < self.rows) {
+                self.isLoadMore = NO;
+            }
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+        [self.tableView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    } faliure:^(NSError * _Nonnull error) {
+        [self endRefresh];
+        if (self.networkAvaiable == NO) {
+            [self setPromptString:@"暂无网络" imageName:@"no_networking" inView:self.tableView];
+        }
+        [self.dataArray removeAllObjects];
+        [self.tableView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    }];
+}
+
+- (void)beginRefreshImmediately {
+    [self.tableView.mj_header beginRefreshing];
+}
+
+- (void)beginFirstRefresh {
+    if (!self.isHeaderRefreshed) {
+        [self beginRefreshImmediately];
+    }
+}
+- (void)selectCellAtIndexPath:(NSIndexPath *)indexPath {
+    
+    if (self.lastSelectedIndexPath == indexPath) {
+        return;
+    }
+    if (self.lastSelectedIndexPath != nil) {
+        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.lastSelectedIndexPath];
+        [cell setSelected:NO animated:NO];
+    }
+    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
+    [cell setSelected:YES animated:NO];
+    self.lastSelectedIndexPath = indexPath;
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    CGFloat searchViewHeight = [MyCourseSearchView getViewHeight];
+
+    if (![self.subviews containsObject:self.searchView]) {
+        [self addSubview:self.searchView];
+        [self.searchView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.mas_equalTo(self);
+            make.height.mas_equalTo(searchViewHeight);
+        }];
+    }
+
+    [self.tableView mas_remakeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.bottom.mas_equalTo(self);
+        make.top.mas_equalTo(self.searchView.mas_bottom);
+    }];
+}
+
+#pragma mark - UITableViewDataSource
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return self.dataArray.count;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
+    return 117.0f;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    VideoCourseModel *model = self.dataArray[indexPath.row];
+    MyVideoGroupListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyVideoGroupListCell"];
+    [cell configWithSource:model];
+    return cell;
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    // 课程详情
+    
+    VideoCourseModel *model = [self.dataArray objectAtIndex:indexPath.row];
+    NSString *url = [NSString stringWithFormat:@"%@%@%@", WEBHOST, @"/#/videoDetail?groupId=",model.internalBaseClassIdentifier];
+    KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+    ctrl.url = url;
+    [self.naviController pushViewController:ctrl animated:YES];
+}
+
+#pragma mark ------ lazying
+- (MyCourseSearchView *)searchView {
+    if (!_searchView) {
+        _searchView = [MyCourseSearchView sharedInstance];
+        MJWeakSelf;
+        [_searchView searchActionCallback:^(MY_COURSE_SORT type, NSString * _Nullable searchKey) {
+            [weakSelf searchAction:type searchKey:searchKey];
+        }];
+    }
+    return _searchView;
+}
+
+- (void)searchAction:(MY_COURSE_SORT)type searchKey:(NSString *)searchKey {
+    switch (type) {
+        case MY_COURSE_SORT_RANK:
+        {
+            
+        }
+            break;
+        case MY_COURSE_SORT_SEARCH:
+        {
+            [self evaluateSource:searchKey];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)evaluateSource:(NSString *)searchKey {
+    self.searchKey = searchKey;
+    [self refreshAndRequestData];
+}
+
+/**
+ 设置没有数据时的显示
+ 
+ @param promptString 提示语
+ @param imgName 图片名称
+ @param view 显示在什么地方
+ */
+- (void)setPromptString:(NSString *)promptString imageName:(NSString *)imgName inView:(UIView *)view {
+    if (self.promptView != nil) {
+        [self.promptView removeFromSuperview];
+    }
+    else {
+        self.promptView = [[StateView alloc]init];
+        self.promptView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight - 300);
+    }
+    _promptPlaceView = view;
+    //当请求不到数据时 ,自定义提示view 将会出现;
+    self.promptView.imageName = imgName;
+    self.promptView.alpha = 0.0f;
+    [self.promptView setText:promptString];
+    [view addSubview:self.promptView];
+}
+
+// 结束刷新后调用方法
+- (void)changePromptLabelStateWithArray:(NSMutableArray *)array {
+    NSInteger count;
+    if (array.count) {
+        count = array.count;
+    } else {
+        count = 0;
+    }
+    
+    [UIView animateWithDuration:0.1 animations:^{
+        [[self promptView] setAlpha:count ? 0.0f :1.0f ] ;
+    }] ;
+    
+}
+
+- (BOOL)networkAvaiable {
+    return [self checkNetworkAvaiable];
+}
+
+- (BOOL)checkNetworkAvaiable {
+    BOOL isExistenceNetwork = YES;
+    Reachability *reach = [Reachability reachabilityWithHostName:@"www.apple.com"];
+    switch ([reach currentReachabilityStatus]) {
+        case NotReachable:
+            isExistenceNetwork = NO;
+            //NSLog(@"notReachable");
+            break;
+        case ReachableViaWiFi:
+            isExistenceNetwork = YES;
+            //NSLog(@"WIFI");
+            break;
+        case ReachableViaWWAN:
+            isExistenceNetwork = YES;
+            //NSLog(@"3G");
+            break;
+    }
+    return isExistenceNetwork;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 19 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VideoCourseGroup/MyVideoGroupListCell.h

@@ -0,0 +1,19 @@
+//
+//  MyVideoGroupListCell.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import <UIKit/UIKit.h>
+#import "VideoCourseModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MyVideoGroupListCell : UITableViewCell
+
+- (void)configWithSource:(VideoCourseModel *)model;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 71 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VideoCourseGroup/MyVideoGroupListCell.m

@@ -0,0 +1,71 @@
+//
+//  MyVideoGroupListCell.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "MyVideoGroupListCell.h"
+
+@interface MyVideoGroupListCell ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *coverImage;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseTitle;
+
+@property (weak, nonatomic) IBOutlet UILabel *descLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *subjectLabel;
+
+
+@property (weak, nonatomic) IBOutlet UILabel *courseCount;
+
+@property (weak, nonatomic) IBOutlet UIView *musicView;
+
+@property (weak, nonatomic) IBOutlet UILabel *musicLabel;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *musicRight;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *musicLabelLeft;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *musicLabelRight;
+
+@end
+
+@implementation MyVideoGroupListCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+- (void)configWithSource:(VideoCourseModel *)model {
+    [self.coverImage sd_setImageWithURL:[NSURL URLWithString:[model.lessonCoverUrl getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"video_placeholder"]];
+    self.courseTitle.text = [NSString returnNoNullStringWithString:model.lessonName];
+    self.descLabel.text = [NSString stringWithFormat:@"%.0f人学习",model.countStudent];
+    self.subjectLabel.text = [NSString returnNoNullStringWithString:model.lessonSubjectName];
+    self.courseCount.text = [NSString stringWithFormat:@"%.0f课时",model.lessonCount];
+    
+    // 曲目
+    if (model.musicNum > 0) {
+        self.musicLabel.text = [NSString stringWithFormat:@"%zd首曲目", model.musicNum];
+        self.musicRight.constant = 4.0f;
+        self.musicLabelLeft.constant = 6.0f;
+        self.musicLabelRight.constant = 6.0f;
+    }
+    else {
+        self.musicView.hidden = YES;
+        self.musicLabel.text = @"";
+        self.musicRight.constant = 0.0f;
+        self.musicLabelLeft.constant = 0.0f;
+        self.musicLabelRight.constant = 0.0f;
+    }
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end

+ 196 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/VideoCourseGroup/MyVideoGroupListCell.xib

@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="122" id="KGk-i7-Jjw" customClass="MyVideoGroupListCell">
+            <rect key="frame" x="0.0" y="0.0" width="371" height="117"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="371" height="117"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Udr-EQ-mCS">
+                        <rect key="frame" x="14" y="0.0" width="343" height="105"/>
+                        <subviews>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="video_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="yHe-XE-Lr9">
+                                <rect key="frame" x="12" y="12" width="146" height="81"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="146" id="4pS-KZ-UWw"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="6"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </imageView>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="X9f-x2-drl">
+                                <rect key="frame" x="126" y="75" width="28" height="14"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="长笛" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="exN-B6-D82">
+                                        <rect key="frame" x="4" y="1" width="20" height="12"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="12" id="ikn-PM-oTz"/>
+                                        </constraints>
+                                        <fontDescription key="fontDescription" type="system" pointSize="10"/>
+                                        <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.40000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstItem="exN-B6-D82" firstAttribute="leading" secondItem="X9f-x2-drl" secondAttribute="leading" constant="4" id="Pp4-io-kgG"/>
+                                    <constraint firstItem="exN-B6-D82" firstAttribute="top" secondItem="X9f-x2-drl" secondAttribute="top" constant="1" id="Sdc-Bh-yPV"/>
+                                    <constraint firstAttribute="trailing" secondItem="exN-B6-D82" secondAttribute="trailing" constant="4" id="ZoE-Wu-dfN"/>
+                                    <constraint firstAttribute="bottom" secondItem="exN-B6-D82" secondAttribute="bottom" constant="1" id="bTK-Fb-JWN"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="3"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="F1K-0G-zso">
+                                <rect key="frame" x="227.33333333333334" y="43" width="42.666666666666657" height="18"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="4课时" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="v90-bW-vHn">
+                                        <rect key="frame" x="6.0000000000000018" y="0.0" width="30.666666666666671" height="18"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                                        <color key="textColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.96078431369999995" green="0.96470588239999999" blue="0.98039215690000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="bottom" secondItem="v90-bW-vHn" secondAttribute="bottom" id="5h0-Iy-yWB"/>
+                                    <constraint firstItem="v90-bW-vHn" firstAttribute="top" secondItem="F1K-0G-zso" secondAttribute="top" id="7xe-eT-jkE"/>
+                                    <constraint firstItem="v90-bW-vHn" firstAttribute="leading" secondItem="F1K-0G-zso" secondAttribute="leading" constant="6" id="dlG-Su-nI6"/>
+                                    <constraint firstAttribute="trailing" secondItem="v90-bW-vHn" secondAttribute="trailing" constant="6" id="ok0-iJ-Pn6"/>
+                                    <constraint firstAttribute="height" constant="18" id="z1A-ue-NeB"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="3"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="s0F-Lb-ssK">
+                                <rect key="frame" x="170" y="43" width="53.333333333333343" height="18"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3首曲目" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iyS-6i-p8d">
+                                        <rect key="frame" x="6" y="0.0" width="41.333333333333336" height="18"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                                        <color key="textColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.96078431369999995" green="0.96470588239999999" blue="0.98039215690000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstItem="iyS-6i-p8d" firstAttribute="leading" secondItem="s0F-Lb-ssK" secondAttribute="leading" constant="6" id="D1W-ya-XTp"/>
+                                    <constraint firstAttribute="trailing" secondItem="iyS-6i-p8d" secondAttribute="trailing" constant="6" id="KdW-az-aHD"/>
+                                    <constraint firstItem="iyS-6i-p8d" firstAttribute="top" secondItem="s0F-Lb-ssK" secondAttribute="top" id="RPS-ph-dP9"/>
+                                    <constraint firstAttribute="height" constant="18" id="q2C-Mr-nFf"/>
+                                    <constraint firstAttribute="bottom" secondItem="iyS-6i-p8d" secondAttribute="bottom" id="vd2-Ha-5o7"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="3"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pzH-fK-xWs">
+                                <rect key="frame" x="170" y="71" width="57" height="19"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="24人学习" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="V8h-ma-5pB">
+                                        <rect key="frame" x="2" y="2" width="53" height="15"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                        <color key="textColor" red="1" green="0.40784313729999999" blue="0.1529411765" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="1" green="0.50196078430000002" blue="0.17254901959999999" alpha="0.070000000000000007" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="trailing" secondItem="V8h-ma-5pB" secondAttribute="trailing" constant="2" id="AZZ-tj-271"/>
+                                    <constraint firstAttribute="height" constant="19" id="XZu-Oe-rZV"/>
+                                    <constraint firstItem="V8h-ma-5pB" firstAttribute="centerY" secondItem="pzH-fK-xWs" secondAttribute="centerY" id="d0g-JM-wy3"/>
+                                    <constraint firstItem="V8h-ma-5pB" firstAttribute="leading" secondItem="pzH-fK-xWs" secondAttribute="leading" constant="2" id="lox-Zw-sVG"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="2"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="从零开始学竖笛视频课" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mt0-5a-cZX">
+                                <rect key="frame" x="170" y="14" width="161" height="21"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="21" id="cxi-yY-VOh"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/>
+                                <color key="textColor" red="0.074509803920000006" green="0.078431372550000003" blue="0.08235294118" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <constraints>
+                            <constraint firstItem="pzH-fK-xWs" firstAttribute="leading" secondItem="yHe-XE-Lr9" secondAttribute="trailing" constant="12" id="1Ve-VI-WjA"/>
+                            <constraint firstItem="X9f-x2-drl" firstAttribute="bottom" secondItem="yHe-XE-Lr9" secondAttribute="bottom" constant="-4" id="1qi-mC-voS"/>
+                            <constraint firstItem="mt0-5a-cZX" firstAttribute="leading" secondItem="yHe-XE-Lr9" secondAttribute="trailing" constant="12" id="4qP-St-sut"/>
+                            <constraint firstItem="pzH-fK-xWs" firstAttribute="bottom" secondItem="yHe-XE-Lr9" secondAttribute="bottom" constant="-3" id="NmF-IN-1l6"/>
+                            <constraint firstItem="mt0-5a-cZX" firstAttribute="top" secondItem="Udr-EQ-mCS" secondAttribute="top" constant="14" id="PRJ-as-u9Y"/>
+                            <constraint firstItem="F1K-0G-zso" firstAttribute="leading" secondItem="s0F-Lb-ssK" secondAttribute="trailing" constant="4" id="SXq-85-l63"/>
+                            <constraint firstItem="yHe-XE-Lr9" firstAttribute="leading" secondItem="Udr-EQ-mCS" secondAttribute="leading" constant="12" id="Tv8-dG-A6n"/>
+                            <constraint firstAttribute="trailing" secondItem="mt0-5a-cZX" secondAttribute="trailing" constant="12" id="VuQ-5P-99N"/>
+                            <constraint firstItem="X9f-x2-drl" firstAttribute="trailing" secondItem="yHe-XE-Lr9" secondAttribute="trailing" constant="-4" id="e5C-xp-Phb"/>
+                            <constraint firstItem="yHe-XE-Lr9" firstAttribute="top" secondItem="Udr-EQ-mCS" secondAttribute="top" constant="12" id="gU6-wa-Z8R"/>
+                            <constraint firstItem="F1K-0G-zso" firstAttribute="top" secondItem="mt0-5a-cZX" secondAttribute="bottom" constant="8" id="rAb-fS-D7G"/>
+                            <constraint firstAttribute="bottom" secondItem="yHe-XE-Lr9" secondAttribute="bottom" constant="12" id="rqi-SV-VFi"/>
+                            <constraint firstItem="s0F-Lb-ssK" firstAttribute="top" secondItem="mt0-5a-cZX" secondAttribute="bottom" constant="8" id="stU-Hk-Cos"/>
+                            <constraint firstItem="s0F-Lb-ssK" firstAttribute="leading" secondItem="yHe-XE-Lr9" secondAttribute="trailing" constant="12" id="ve6-AF-Aw1"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="6"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+                <constraints>
+                    <constraint firstAttribute="trailing" secondItem="Udr-EQ-mCS" secondAttribute="trailing" constant="14" id="03X-JT-0rr"/>
+                    <constraint firstItem="Udr-EQ-mCS" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="AAZ-RO-HON"/>
+                    <constraint firstAttribute="bottom" secondItem="Udr-EQ-mCS" secondAttribute="bottom" constant="12" id="RrG-Pu-XNv"/>
+                    <constraint firstItem="Udr-EQ-mCS" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="Vg0-bH-ZXt"/>
+                </constraints>
+            </tableViewCellContentView>
+            <viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <connections>
+                <outlet property="courseCount" destination="v90-bW-vHn" id="5bp-SD-Cny"/>
+                <outlet property="courseTitle" destination="mt0-5a-cZX" id="t4L-p5-nxr"/>
+                <outlet property="coverImage" destination="yHe-XE-Lr9" id="QyM-LP-5tb"/>
+                <outlet property="descLabel" destination="V8h-ma-5pB" id="6Ou-No-PkP"/>
+                <outlet property="musicLabel" destination="iyS-6i-p8d" id="U0g-N3-JfH"/>
+                <outlet property="musicLabelLeft" destination="D1W-ya-XTp" id="Apx-TQ-du0"/>
+                <outlet property="musicLabelRight" destination="KdW-az-aHD" id="ktN-uz-yML"/>
+                <outlet property="musicRight" destination="SXq-85-l63" id="dX3-8A-FC9"/>
+                <outlet property="musicView" destination="s0F-Lb-ssK" id="HdR-vE-j7d"/>
+                <outlet property="subjectLabel" destination="exN-B6-D82" id="jpA-FQ-AhE"/>
+            </connections>
+            <point key="canvasLocation" x="72.51908396946564" y="46.478873239436624"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="video_placeholder" width="103" height="72"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 16 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertCell.h

@@ -0,0 +1,16 @@
+//
+//  FansGroupAlertCell.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FansGroupAlertCell : UITableViewCell
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 26 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertCell.m

@@ -0,0 +1,26 @@
+//
+//  FansGroupAlertCell.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/11/20.
+//
+
+#import "FansGroupAlertCell.h"
+
+@implementation FansGroupAlertCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end

+ 25 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertCell.xib

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="83" id="KGk-i7-Jjw" customClass="FansGroupAlertCell">
+            <rect key="frame" x="0.0" y="0.0" width="320" height="83"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="320" height="83"/>
+                <autoresizingMask key="autoresizingMask"/>
+            </tableViewCellContentView>
+            <viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <point key="canvasLocation" x="39.694656488549619" y="33.450704225352112"/>
+        </tableViewCell>
+    </objects>
+</document>

+ 8 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertView.h

@@ -7,10 +7,18 @@
 
 #import <UIKit/UIKit.h>
 
+typedef void(^FansGroupChatCallback)(NSString *imGroupId);
+
 NS_ASSUME_NONNULL_BEGIN
 
 @interface FansGroupAlertView : UIView
 
++ (instancetype)sharedInstance;
+
+- (void)configWithSource:(NSMutableArray *)fansGroupArray;
+
+- (void)groupChatConversation:(FansGroupChatCallback)callback;
+
 @end
 
 NS_ASSUME_NONNULL_END

+ 40 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertView.m

@@ -7,8 +7,48 @@
 
 #import "FansGroupAlertView.h"
 
+@interface FansGroupAlertView ()<UITableViewDelegate, UITableViewDataSource>
+
+@property (nonatomic, copy) FansGroupChatCallback callback;
+
+@property (nonatomic, copy) UITableView *tableView;
+
+@end
+
 @implementation FansGroupAlertView
 
++ (instancetype)sharedInstance {
+    FansGroupAlertView *view = [[[NSBundle mainBundle] loadNibNamed:@"FansGroupAlertView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configWithSource:(NSMutableArray *)fansGroupArray {
+    
+}
+
+- (void)groupChatConversation:(FansGroupChatCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+
+- (UITableView *)tableView {
+    if (!_tableView) {
+        if (!_tableView) {
+            _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
+            _tableView.backgroundColor = [UIColor clearColor];
+            _tableView.delegate = self;
+            _tableView.dataSource = self;
+            _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+            _tableView.rowHeight = 62.0f;
+            // cell
+            [_tableView registerNib:[UINib nibWithNibName:@"DownloadStatusCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"DownloadStatusCell"];
+        }
+        return _tableView;
+    }
+    return _tableView;
+}
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.

+ 37 - 2
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/FansGroupAlert/FansGroupAlertView.xib

@@ -4,6 +4,7 @@
     <dependencies>
         <deployment identifier="iOS"/>
         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -13,19 +14,49 @@
             <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
             <autoresizingMask key="autoresizingMask"/>
             <subviews>
-                <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sqT-l2-2xZ">
-                    <rect key="frame" x="46.666666666666657" y="368" width="300" height="325"/>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sqT-l2-2xZ">
+                    <rect key="frame" x="46.666666666666657" y="338.66666666666669" width="300" height="175.00000000000006"/>
                     <subviews>
                         <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="fansGroup_alert_top" translatesAutoresizingMaskIntoConstraints="NO" id="2UF-fm-A6l">
                             <rect key="frame" x="0.0" y="0.0" width="300" height="113"/>
                         </imageView>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Yue-SE-dsU">
+                            <rect key="frame" x="0.0" y="113" width="300" height="62"/>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="62" id="rff-qF-IJm"/>
+                            </constraints>
+                        </view>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cancle_button" translatesAutoresizingMaskIntoConstraints="NO" id="vb1-ly-0S5">
+                            <rect key="frame" x="274" y="13" width="13" height="13"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="13" id="4aE-dY-8hc"/>
+                                <constraint firstAttribute="height" constant="13" id="Vnf-vq-Nxw"/>
+                            </constraints>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DIk-4o-f6z">
+                            <rect key="frame" x="260" y="0.0" width="40" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="40" id="k0W-Q9-clu"/>
+                                <constraint firstAttribute="width" constant="40" id="xRK-5e-qqV"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                        </button>
                     </subviews>
                     <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <constraints>
+                        <constraint firstItem="Yue-SE-dsU" firstAttribute="top" secondItem="2UF-fm-A6l" secondAttribute="bottom" id="4CQ-22-Cns"/>
+                        <constraint firstAttribute="trailing" secondItem="vb1-ly-0S5" secondAttribute="trailing" constant="13" id="78Z-MM-r6O"/>
                         <constraint firstAttribute="width" constant="300" id="7q4-Wf-OUU"/>
                         <constraint firstAttribute="trailing" secondItem="2UF-fm-A6l" secondAttribute="trailing" id="DUz-5t-U1V"/>
+                        <constraint firstAttribute="trailing" secondItem="Yue-SE-dsU" secondAttribute="trailing" id="PCt-KQ-7bw"/>
+                        <constraint firstAttribute="trailing" secondItem="DIk-4o-f6z" secondAttribute="trailing" id="QXQ-yG-Omh"/>
+                        <constraint firstItem="vb1-ly-0S5" firstAttribute="top" secondItem="sqT-l2-2xZ" secondAttribute="top" constant="13" id="SSw-yP-HBh"/>
+                        <constraint firstItem="Yue-SE-dsU" firstAttribute="leading" secondItem="sqT-l2-2xZ" secondAttribute="leading" id="Yr5-HU-Z25"/>
                         <constraint firstItem="2UF-fm-A6l" firstAttribute="leading" secondItem="sqT-l2-2xZ" secondAttribute="leading" id="cHl-3b-AQT"/>
                         <constraint firstItem="2UF-fm-A6l" firstAttribute="top" secondItem="sqT-l2-2xZ" secondAttribute="top" id="e3B-JJ-mJz"/>
+                        <constraint firstItem="DIk-4o-f6z" firstAttribute="top" secondItem="sqT-l2-2xZ" secondAttribute="top" id="iLk-H4-NuC"/>
+                        <constraint firstAttribute="bottom" secondItem="Yue-SE-dsU" secondAttribute="bottom" id="sRl-Is-9HK"/>
                     </constraints>
                 </view>
             </subviews>
@@ -41,6 +72,10 @@
         </view>
     </objects>
     <resources>
+        <image name="cancle_button" width="20" height="20"/>
         <image name="fansGroup_alert_top" width="300" height="113"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
     </resources>
 </document>

+ 9 - 8
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/MinePageLiveCourse/MineLiveCourseGroupCell.xib

@@ -11,14 +11,14 @@
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
         <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="MineLiveCourseGroupCell">
-            <rect key="frame" x="0.0" y="0.0" width="285" height="287"/>
+            <rect key="frame" x="0.0" y="0.0" width="285" height="294"/>
             <autoresizingMask key="autoresizingMask"/>
             <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
-                <rect key="frame" x="0.0" y="0.0" width="285" height="287"/>
+                <rect key="frame" x="0.0" y="0.0" width="285" height="294"/>
                 <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                 <subviews>
                     <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oRV-eY-dq7">
-                        <rect key="frame" x="0.0" y="0.0" width="285" height="287"/>
+                        <rect key="frame" x="0.0" y="0.0" width="285" height="294"/>
                         <subviews>
                             <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_page_live_tag" translatesAutoresizingMaskIntoConstraints="NO" id="xdA-OV-wj5">
                                 <rect key="frame" x="12" y="15" width="20" height="16"/>
@@ -116,7 +116,7 @@
                                 <nil key="highlightedColor"/>
                             </label>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="L2D-Md-biT">
-                                <rect key="frame" x="12" y="254" width="65" height="19"/>
+                                <rect key="frame" x="12" y="261" width="65" height="19"/>
                                 <subviews>
                                     <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="6人已购买" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Jy4-WH-Grt">
                                         <rect key="frame" x="4" y="2.3333333333333153" width="57" height="14.333333333333336"/>
@@ -139,7 +139,7 @@
                                 </userDefinedRuntimeAttributes>
                             </view>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="¥120" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6cN-Qs-aEM">
-                                <rect key="frame" x="173.66666666666666" y="251" width="49" height="24"/>
+                                <rect key="frame" x="173.66666666666666" y="258" width="49" height="24"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="24" id="dVD-1n-VbO"/>
                                 </constraints>
@@ -148,7 +148,7 @@
                                 <nil key="highlightedColor"/>
                             </label>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="/4课时" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Vjg-7W-RnJ">
-                                <rect key="frame" x="230.66666666666666" y="256" width="42.333333333333343" height="17"/>
+                                <rect key="frame" x="230.66666666666666" y="263" width="42.333333333333343" height="17"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                 <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
                                 <nil key="highlightedColor"/>
@@ -163,6 +163,7 @@
                             <constraint firstItem="yTY-zb-NMC" firstAttribute="top" secondItem="vAB-E9-FHQ" secondAttribute="top" constant="7" id="8OW-Xf-9H7"/>
                             <constraint firstAttribute="bottom" secondItem="Vjg-7W-RnJ" secondAttribute="bottom" constant="14" id="9SP-Sg-vZv"/>
                             <constraint firstItem="Vjg-7W-RnJ" firstAttribute="leading" secondItem="6cN-Qs-aEM" secondAttribute="trailing" constant="8" id="9ak-Kw-gjF"/>
+                            <constraint firstItem="L2D-Md-biT" firstAttribute="top" relation="greaterThanOrEqual" secondItem="fVi-EI-HNi" secondAttribute="bottom" constant="8" id="CMG-Mi-kxN"/>
                             <constraint firstItem="0Gb-VJ-opm" firstAttribute="centerY" secondItem="xdA-OV-wj5" secondAttribute="centerY" id="CR4-UW-XoV"/>
                             <constraint firstItem="xdA-OV-wj5" firstAttribute="top" secondItem="oRV-eY-dq7" secondAttribute="top" constant="15" id="Gzd-oJ-mYe"/>
                             <constraint firstAttribute="trailing" secondItem="Vjg-7W-RnJ" secondAttribute="trailing" constant="12" id="Nfj-7d-Hgh"/>
@@ -199,7 +200,7 @@
                 <constraint firstItem="oRV-eY-dq7" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="b67-JI-fdi"/>
                 <constraint firstAttribute="trailing" secondItem="oRV-eY-dq7" secondAttribute="trailing" id="ion-cs-TCG"/>
             </constraints>
-            <size key="customSize" width="285" height="291"/>
+            <size key="customSize" width="285" height="298"/>
             <connections>
                 <outlet property="courseCount" destination="Vjg-7W-RnJ" id="AC9-29-iiy"/>
                 <outlet property="courseName" destination="4zV-AG-v6z" id="PQA-tI-WnM"/>
@@ -212,7 +213,7 @@
                 <outlet property="subjectLabel" destination="jUo-GT-p8T" id="gPU-lT-YWZ"/>
                 <outlet property="teacherDesc" destination="fVi-EI-HNi" id="Abh-M5-AbX"/>
             </connections>
-            <point key="canvasLocation" x="156.4885496183206" y="99.647887323943664"/>
+            <point key="canvasLocation" x="156.4885496183206" y="97.183098591549296"/>
         </collectionViewCell>
     </objects>
     <resources>

+ 27 - 2
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/MinePage/View/VipCourse/MinePageVIPCourseView.m

@@ -99,8 +99,33 @@
 }
 
 - (void)requestData {
-    [self endRefresh];
-    [self changePromptLabelStateWithArray:self.dataArray];
+    [KSNetworkingManager teacherSubjectPriceRequest:KS_POST courseType:@"VIP" page:self.pages rows:self.rows success:^(NSDictionary * _Nonnull dic) {
+        [self endRefresh];
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            NSArray *sourceArray = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"rows"];
+//            for (NSDictionary *parm in sourceArray) {
+//                VideoCourseModel *model = [[VideoCourseModel alloc] initWithDictionary:parm];
+//                [self.dataArray addObject:model];
+//            }
+//            if (sourceArray.count < self.rows) {
+//                self.isLoadMore = NO;
+//            }
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+        [self.tableView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    } faliure:^(NSError * _Nonnull error) {
+        [self endRefresh];
+        if (self.networkAvaiable == NO) {
+            [self setPromptString:@"暂无网络" imageName:@"no_networking" inView:self.tableView];
+        }
+        [self.dataArray removeAllObjects];
+        [self.tableView reloadData];
+        [self changePromptLabelStateWithArray:self.dataArray];
+    }];
+    
 }
 
 - (void)beginRefreshImmediately {

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Widget/View/toneTuning/TunerSettingView.m

@@ -82,6 +82,7 @@
     }
     self.A4Frequence = frequence + 1;
 }
+
 - (IBAction)resetFrequence:(id)sender {
     self.A4Frequence = DEFALUT_A4FREQUENCE;
 }

Some files were not shown because too many files changed in this diff