Browse Source

小组课课程组详情

Steven 4 months ago
parent
commit
77a149a05f
28 changed files with 1830 additions and 28 deletions
  1. 74 0
      KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj
  2. 1 1
      KulexiuForTeacher/KulexiuForTeacher.xcodeproj/xcshareddata/xcschemes/KulexiuForTeacher.xcscheme
  3. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Course/course_group.imageset/Contents.json
  4. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Course/course_group.imageset/course_group@2x.png
  5. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Course/course_group.imageset/course_group@3x.png
  6. 9 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h
  7. 15 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m
  8. 24 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/Controller/GroupCourseGroupViewController.h
  9. 258 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/Controller/GroupCourseGroupViewController.m
  10. 47 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/Model/GroupCourseGroupInfoModel.h
  11. 284 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/Model/GroupCourseGroupInfoModel.m
  12. 23 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupHeadView.h
  13. 134 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupHeadView.m
  14. 317 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupHeadView.xib
  15. 24 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupNavView.h
  16. 47 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupNavView.m
  17. 72 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupNavView.xib
  18. 20 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseListCell.h
  19. 185 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseListCell.m
  20. 243 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseListCell.xib
  21. 2 2
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/VIPCourse/Controller/VipCouseDetailViewController.m
  22. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/VIPCourse/Model/GroupCourseListModel.h
  23. 7 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/VIPCourse/Model/GroupCourseListModel.m
  24. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/VIPCourse/View/ProgramCourseGroupBodyView.h
  25. 10 15
      KulexiuForTeacher/KulexiuForTeacher/Module/Course/VIPCourse/View/ProgramCourseGroupBodyView.m
  26. 2 2
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Controller/MyCourseViewController.m
  27. 6 6
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/GroupCourseGroup/MyGroupCourseGroupView.m
  28. 2 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseSortView/MyCourseRankSortView.m

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

@@ -942,6 +942,14 @@
 		BCA9CE4427FD947C00D558C6 /* AccompanyArrangeCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCA9CE4227FD947C00D558C6 /* AccompanyArrangeCell.xib */; };
 		BCA9CE5027FD954800D558C6 /* AccompanyRemarkCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA9CE4E27FD954800D558C6 /* AccompanyRemarkCell.m */; };
 		BCA9CE5127FD954800D558C6 /* AccompanyRemarkCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCA9CE4F27FD954800D558C6 /* AccompanyRemarkCell.xib */; };
+		BCAAD0BE2D19412A0069872D /* GroupCourseGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAAD0BD2D19412A0069872D /* GroupCourseGroupViewController.m */; };
+		BCAAD0C12D1941830069872D /* GroupCourseGroupNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAAD0C02D1941830069872D /* GroupCourseGroupNavView.m */; };
+		BCAAD0C32D1941880069872D /* GroupCourseGroupNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCAAD0C22D1941880069872D /* GroupCourseGroupNavView.xib */; };
+		BCAAD0C62D19505E0069872D /* GroupCourseGroupHeadView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAAD0C52D19505E0069872D /* GroupCourseGroupHeadView.m */; };
+		BCAAD0C82D19509F0069872D /* GroupCourseGroupHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCAAD0C72D19509F0069872D /* GroupCourseGroupHeadView.xib */; };
+		BCAAD0CE2D195DE60069872D /* GroupCourseGroupInfoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAAD0CD2D195DE60069872D /* GroupCourseGroupInfoModel.m */; };
+		BCAAD0D22D196EAD0069872D /* GroupCourseListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAAD0D02D196EAD0069872D /* GroupCourseListCell.m */; };
+		BCAAD0D32D196EAD0069872D /* GroupCourseListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCAAD0D12D196EAD0069872D /* GroupCourseListCell.xib */; };
 		BCAD01C02872F54F0002CC40 /* LiveVideoListView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAD01BF2872F54F0002CC40 /* LiveVideoListView.m */; };
 		BCAD01C22872F5560002CC40 /* LiveVideoListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCAD01C12872F5560002CC40 /* LiveVideoListView.xib */; };
 		BCAF36EE2CEAE3E8009434AD /* FansGroupAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAF36ED2CEAE3E8009434AD /* FansGroupAlertView.m */; };
@@ -2801,6 +2809,19 @@
 		BCA9CE4D27FD954800D558C6 /* AccompanyRemarkCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccompanyRemarkCell.h; sourceTree = "<group>"; };
 		BCA9CE4E27FD954800D558C6 /* AccompanyRemarkCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AccompanyRemarkCell.m; sourceTree = "<group>"; };
 		BCA9CE4F27FD954800D558C6 /* AccompanyRemarkCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccompanyRemarkCell.xib; sourceTree = "<group>"; };
+		BCAAD0BC2D19412A0069872D /* GroupCourseGroupViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GroupCourseGroupViewController.h; sourceTree = "<group>"; };
+		BCAAD0BD2D19412A0069872D /* GroupCourseGroupViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GroupCourseGroupViewController.m; sourceTree = "<group>"; };
+		BCAAD0BF2D1941830069872D /* GroupCourseGroupNavView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GroupCourseGroupNavView.h; sourceTree = "<group>"; };
+		BCAAD0C02D1941830069872D /* GroupCourseGroupNavView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GroupCourseGroupNavView.m; sourceTree = "<group>"; };
+		BCAAD0C22D1941880069872D /* GroupCourseGroupNavView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GroupCourseGroupNavView.xib; sourceTree = "<group>"; };
+		BCAAD0C42D19505E0069872D /* GroupCourseGroupHeadView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GroupCourseGroupHeadView.h; sourceTree = "<group>"; };
+		BCAAD0C52D19505E0069872D /* GroupCourseGroupHeadView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GroupCourseGroupHeadView.m; sourceTree = "<group>"; };
+		BCAAD0C72D19509F0069872D /* GroupCourseGroupHeadView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GroupCourseGroupHeadView.xib; sourceTree = "<group>"; };
+		BCAAD0CC2D195DE60069872D /* GroupCourseGroupInfoModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GroupCourseGroupInfoModel.h; sourceTree = "<group>"; };
+		BCAAD0CD2D195DE60069872D /* GroupCourseGroupInfoModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GroupCourseGroupInfoModel.m; sourceTree = "<group>"; };
+		BCAAD0CF2D196EAD0069872D /* GroupCourseListCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GroupCourseListCell.h; sourceTree = "<group>"; };
+		BCAAD0D02D196EAD0069872D /* GroupCourseListCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GroupCourseListCell.m; sourceTree = "<group>"; };
+		BCAAD0D12D196EAD0069872D /* GroupCourseListCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GroupCourseListCell.xib; sourceTree = "<group>"; };
 		BCAD01BE2872F54F0002CC40 /* LiveVideoListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveVideoListView.h; sourceTree = "<group>"; };
 		BCAD01BF2872F54F0002CC40 /* LiveVideoListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiveVideoListView.m; sourceTree = "<group>"; };
 		BCAD01C12872F5560002CC40 /* LiveVideoListView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LiveVideoListView.xib; sourceTree = "<group>"; };
@@ -4214,6 +4235,7 @@
 		2779360627E32BBF0010E277 /* Course */ = {
 			isa = PBXGroup;
 			children = (
+				BCAAD0BB2D19410B0069872D /* MyGroupCourse */,
 				BCFB9B862CE487EA00B66BC0 /* VIPCourse */,
 				BC8B6E7E2858879300866917 /* MusicRoom */,
 				BCA9CE2827FD89CE00D558C6 /* AccompanyCourse */,
@@ -7171,6 +7193,50 @@
 			path = View;
 			sourceTree = "<group>";
 		};
+		BCAAD0B82D19410B0069872D /* Controller */ = {
+			isa = PBXGroup;
+			children = (
+				BCAAD0BC2D19412A0069872D /* GroupCourseGroupViewController.h */,
+				BCAAD0BD2D19412A0069872D /* GroupCourseGroupViewController.m */,
+			);
+			path = Controller;
+			sourceTree = "<group>";
+		};
+		BCAAD0B92D19410B0069872D /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				BCAAD0CC2D195DE60069872D /* GroupCourseGroupInfoModel.h */,
+				BCAAD0CD2D195DE60069872D /* GroupCourseGroupInfoModel.m */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
+		BCAAD0BA2D19410B0069872D /* View */ = {
+			isa = PBXGroup;
+			children = (
+				BCAAD0BF2D1941830069872D /* GroupCourseGroupNavView.h */,
+				BCAAD0C02D1941830069872D /* GroupCourseGroupNavView.m */,
+				BCAAD0C22D1941880069872D /* GroupCourseGroupNavView.xib */,
+				BCAAD0C42D19505E0069872D /* GroupCourseGroupHeadView.h */,
+				BCAAD0C52D19505E0069872D /* GroupCourseGroupHeadView.m */,
+				BCAAD0C72D19509F0069872D /* GroupCourseGroupHeadView.xib */,
+				BCAAD0CF2D196EAD0069872D /* GroupCourseListCell.h */,
+				BCAAD0D02D196EAD0069872D /* GroupCourseListCell.m */,
+				BCAAD0D12D196EAD0069872D /* GroupCourseListCell.xib */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		BCAAD0BB2D19410B0069872D /* MyGroupCourse */ = {
+			isa = PBXGroup;
+			children = (
+				BCAAD0B82D19410B0069872D /* Controller */,
+				BCAAD0B92D19410B0069872D /* Model */,
+				BCAAD0BA2D19410B0069872D /* View */,
+			);
+			path = MyGroupCourse;
+			sourceTree = "<group>";
+		};
 		BCAF36EB2CEAE3D7009434AD /* FansGroupAlert */ = {
 			isa = PBXGroup;
 			children = (
@@ -8161,6 +8227,7 @@
 				BC7401372CD264690056756A /* MergeTipsAlert.xib in Resources */,
 				BC86A2CA2CD36B6400A15A53 /* MineWorkSortView.xib in Resources */,
 				275B172B27EB269F0081FDEF /* ChatAddressHeaderView.xib in Resources */,
+				BCAAD0C32D1941880069872D /* GroupCourseGroupNavView.xib in Resources */,
 				BC41104F280678ED00800BD9 /* HomeworkSortView.xib in Resources */,
 				275FA56427F31AEE00EB6240 /* MinePageHeadView.xib in Resources */,
 				BC71D294288811BF0010F14B /* tabbar5.json in Resources */,
@@ -8321,6 +8388,7 @@
 				BC8B6E602856ED0600866917 /* WeiboSDK.bundle in Resources */,
 				BC206EED2CF01838001F2B85 /* ProgramCourseListCell.xib in Resources */,
 				27F9030827E86CCB00C08A19 /* DeviceCheckView.xib in Resources */,
+				BCAAD0D32D196EAD0069872D /* GroupCourseListCell.xib in Resources */,
 				BC71D1FA2887FDD40010F14B /* img_14.png in Resources */,
 				BC523B1228A09F3800E9D66B /* MineHeadView.xib in Resources */,
 				BCC408D62AFCE0D700C60249 /* KSCropImageNavView.xib in Resources */,
@@ -8503,6 +8571,7 @@
 				BCECE21E2B3D5F0800C0D555 /* FeedbackListNavView.xib in Resources */,
 				BC9070A928C71C8E00237958 /* MyCreateGroupHeadView.xib in Resources */,
 				BCA9A5CD2D1910D200C7CC9D /* MyGroupCourseGroupListCell.xib in Resources */,
+				BCAAD0C82D19509F0069872D /* GroupCourseGroupHeadView.xib in Resources */,
 				BCC583F828A9FA8100BAB4CF /* cloud_animation_23.png in Resources */,
 				BC31BF9E2B219C5700F7D538 /* WidgetNavView.xib in Resources */,
 				BC71DF042A89F470003F165E /* TXFullVideoCell.xib in Resources */,
@@ -9014,6 +9083,7 @@
 				27F9030627E86CBD00C08A19 /* DeviceCheckView.m in Sources */,
 				BC31BF932B219C5700F7D538 /* DialPlateView.m in Sources */,
 				BC4217F82C4E3D2B00C70B2F /* KSUserDetailViewController.m in Sources */,
+				BCAAD0D22D196EAD0069872D /* GroupCourseListCell.m in Sources */,
 				BC31BF972B219C5700F7D538 /* WMGaugeViewStyle3D.m in Sources */,
 				275B16EF27EAF9B20081FDEF /* ChatNavView.m in Sources */,
 				BCA353E92859A6FB00377661 /* MusicRoomHomeworkCell.m in Sources */,
@@ -9082,6 +9152,7 @@
 				BC71DEF22A89F470003F165E /* TXChatBottomView.m in Sources */,
 				BCD457B72865651A0010B493 /* LiveMoreDisplayView.m in Sources */,
 				27F9CB0027EC3D42003E0FE4 /* GroupListViewCell.m in Sources */,
+				BCAAD0BE2D19412A0069872D /* GroupCourseGroupViewController.m in Sources */,
 				BC8B6DC028532DB800866917 /* MusicShareModel.m in Sources */,
 				2780C91C27E48A0700A95A4F /* PasswordLoginController.m in Sources */,
 				BCA9A5C82D190E5F00C7CC9D /* MyGroupCourseGroupView.m in Sources */,
@@ -9229,6 +9300,7 @@
 				BC366FD72CF067F700583E61 /* CourseGroupDetailModel.m in Sources */,
 				BC71DEF72A89F470003F165E /* TXChatAreaView.m in Sources */,
 				BCB9FA1F286D539A005D766B /* ScanNavView.m in Sources */,
+				BCAAD0C12D1941830069872D /* GroupCourseGroupNavView.m in Sources */,
 				BC106B782A8F4586000759A9 /* TXLiveMessageSeatApply.m in Sources */,
 				BC28884A2A80DA200064B773 /* KSLoginManager.m in Sources */,
 				2708564E27ED6B7800EC8E72 /* ApplyMemberModel.m in Sources */,
@@ -9271,6 +9343,7 @@
 				2779326427E30FD80010E277 /* FSCalendarDelegationProxy.m in Sources */,
 				BC106B852A8F4586000759A9 /* TXLiveMessageCardMessage.m in Sources */,
 				277935DF27E326DA0010E277 /* KSNetTypeManager.m in Sources */,
+				BCAAD0C62D19505E0069872D /* GroupCourseGroupHeadView.m in Sources */,
 				BC38C4852AFA1F4B00ABFCC2 /* MineWorksBodyView.m in Sources */,
 				2755C08527ED5770007D9070 /* GroupApplyMemberCell.m in Sources */,
 				27A54CEC27E9B96F007309A3 /* ModifyNameBodyView.m in Sources */,
@@ -9390,6 +9463,7 @@
 				BCB9FA622872C8D2005D766B /* UnderwayLiveCell.m in Sources */,
 				BC71DEF42A89F470003F165E /* TXChatAreaTopView.m in Sources */,
 				BCB399B227F94B5A00AFF376 /* LTSCalendarBottomView.m in Sources */,
+				BCAAD0CE2D195DE60069872D /* GroupCourseGroupInfoModel.m in Sources */,
 				BCD160572CED845A00A78B43 /* MyVipCourseGroupView.m in Sources */,
 				BC8B6E84285887A400866917 /* MusicRoomViewController.m in Sources */,
 				BC71DE962A89C937003F165E /* TXNodePlayMessage.m in Sources */,

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

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

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/Course/course_group.imageset/Contents.json

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

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


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


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

@@ -1667,6 +1667,15 @@ NS_ASSUME_NONNULL_BEGIN
 /// @param faliure 失败
 + (void)getCourseGroupDetailRequest:(NSString *)post courseGroupId:(NSString *)courseGroupId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
 
+// courseGroup/queryCourseInfo
+
+/// 查询课程详情头部信息
+/// @param get get
+/// @param courseGroupId 课程组详情
+/// @param success 成功
+/// @param faliure 失败
++ (void)getCourseGroupInfoRequest:(NSString *)get courseGroupId:(NSString *)courseGroupId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
 // /courseSchedule/list
 
 /// 查询课程组关联课程

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

@@ -3070,6 +3070,21 @@
     [self request:post andWithUrl:url and:parm success:success faliure:faliure];
 }
 
+
+// courseGroup/queryCourseInfo
+
+/// 查询课程详情头部信息
+/// @param get get
+/// @param courseGroupId 课程组详情
+/// @param success 成功
+/// @param faliure 失败
++ (void)getCourseGroupInfoRequest:(NSString *)get courseGroupId:(NSString *)courseGroupId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    [self configRequestHeader];
+    NSString *url = [NSString stringWithFormat:@"%@%@",hostURL, @"/api-teacher/courseGroup/queryCourseInfo"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:courseGroupId forKey:@"groupId"];
+    [self request:get andWithUrl:url and:parm success:success faliure:faliure];
+}
 // /courseSchedule/list
 
 /// 查询课程组关联课程

+ 24 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/Controller/GroupCourseGroupViewController.h

@@ -0,0 +1,24 @@
+//
+//  GroupCourseGroupViewController.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/12/23.
+//
+
+#import "KSBaseViewController.h"
+#import "JXCategoryView.h"
+#import "JXPagerView.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GroupCourseGroupViewController : KSBaseViewController
+
+@property (nonatomic, strong) NSString *courseGroupId; // 课程组ID
+
+@property (nonatomic, strong) JXPagerView *pagerView;
+@property (nonatomic, strong, readonly) JXCategoryTitleView *categoryView;
+@property (nonatomic, strong) NSArray <NSString *> *titles;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 258 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/Controller/GroupCourseGroupViewController.m

@@ -0,0 +1,258 @@
+//
+//  GroupCourseGroupViewController.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/12/23.
+//
+
+#import "GroupCourseGroupViewController.h"
+#import "GroupCourseGroupNavView.h"
+#import "GroupCourseGroupHeadView.h"
+#import "JXCategoryView.h"
+#import "JXPagerListRefreshView.h"
+#import "ProgramCourseGroupBodyView.h"
+#import "MusicRoomStudentPageView.h"
+#import "GroupCourseGroupInfoModel.h"
+
+@interface GroupCourseGroupViewController ()<JXPagerViewDelegate,JXCategoryViewDelegate,JXPagerMainTableViewGestureDelegate>
+
+@property (nonatomic, strong) GroupCourseGroupNavView *navView;
+
+@property (nonatomic, strong) GroupCourseGroupHeadView *headView;
+
+@property (nonatomic, strong) NSMutableArray *listViewArray;
+
+@property (nonatomic, assign) NSInteger headHeight;
+
+@property (nonatomic, assign) NSInteger topViewHeight;
+
+@property (nonatomic, assign) BOOL isFirstLoad;
+
+@property (nonatomic, assign) NSInteger enterStartTime;  // 开课前可进入时间配置(分钟)
+
+@property (nonatomic, assign) NSInteger quitEndTime;    // 结束后退出时间配置(分钟)
+
+@property (nonatomic, strong) GroupCourseGroupInfoModel *infoModel;
+
+@end
+
+@implementation GroupCourseGroupViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    self.ks_prefersNavigationBarHidden = YES;
+    [self requestRoomConfig];
+    [self configUI];
+    self.isFirstLoad = YES;
+}
+
+- (void)configUI {
+    [self.scrollView removeFromSuperview];
+    [self.view addSubview:self.navView];
+    CGFloat navHeight = [GroupCourseGroupNavView getViewHeight];
+    [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.mas_equalTo(self.view);
+        make.height.mas_equalTo(navHeight);
+    }];
+    self.headHeight = 44.0f;
+    self.titles = @[@"课程列表",@"上课学生"];
+    [self configCategoryView:navHeight];
+}
+
+- (void)requestRoomConfig {
+    [KSNetworkingManager selectRoomConfigRequest:KS_GET success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            NSDictionary *result = [dic ks_dictionaryValueForKey:@"data"];
+            self.enterStartTime = [result ks_integerValueForKey:@"groupStartTime"];
+            self.quitEndTime = [result ks_integerValueForKey:@"groupEndTime"];
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+}
+
+- (void)requestCourseInfo {
+    
+    [KSNetworkingManager getCourseGroupInfoRequest:KS_GET courseGroupId:self.courseGroupId success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            NSDictionary *parm = [dic ks_dictionaryValueForKey:@"data"];
+            self.infoModel = [[GroupCourseGroupInfoModel alloc] initWithDictionary:parm];
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+        [self refreshHeadView];
+    } faliure:^(NSError * _Nonnull error) {
+        [self refreshHeadView];
+    }];
+}
+
+- (void)refreshHeadView {
+    [self refreshListPage];
+    self.topViewHeight = [GroupCourseGroupHeadView getViewHeight:self.infoModel];
+    [self.headView configWithSource:self.infoModel];
+    [self.pagerView resizeTableHeaderViewHeightWithAnimatable:NO duration:0.3f curve:UIViewAnimationCurveEaseInOut];
+}
+
+- (void)configCategoryView:(NSInteger)topHeight {
+    _categoryView = [[JXCategoryTitleView alloc] initWithFrame:CGRectMake(0, topHeight, KPortraitWidth, self.headHeight)];
+    self.categoryView.titles = self.titles;
+    self.categoryView.delegate = self;
+    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;
+    
+    JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init];
+    lineView.indicatorColor = THEMECOLOR;
+    lineView.indicatorWidth = 16;
+    lineView.indicatorHeight = 4;
+    self.categoryView.indicators = @[lineView];
+    
+    _pagerView = [self preferredPagingView];
+    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];
+    self.pagerView.mainTableView.gestureDelegate = self;
+    self.categoryView.listContainer = (id<JXCategoryViewListContainer>)self.pagerView.listContainerView;
+    self.pagerView.listContainerView.listCellBackgroundColor = [UIColor clearColor];
+    [self.view addSubview:self.pagerView];
+}
+
+- (void)viewDidAppear:(BOOL)animated {
+    [super viewDidAppear:animated];
+    self.navigationController.interactivePopGestureRecognizer.enabled = (self.categoryView.selectedIndex == 0);
+}
+
+- (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+    self.navigationController.interactivePopGestureRecognizer.enabled = YES;
+    // 刷新课程详情
+    [self requestCourseInfo];
+    if (self.isFirstLoad == NO) {
+        [self refreshListPage];
+    }
+    self.isFirstLoad = NO;
+}
+
+- (void)refreshListPage {
+    id value = self.listViewArray[0];
+    if ([value isKindOfClass:[ProgramCourseGroupBodyView class]]) {
+        ProgramCourseGroupBodyView *listView = (ProgramCourseGroupBodyView *)value;
+        listView.enterStartTime = self.enterStartTime;
+        listView.quitEndTime = self.quitEndTime;
+        [listView beginFirstRefresh];
+    }
+}
+
+- (JXPagerView *)preferredPagingView {
+    return [[JXPagerListRefreshView alloc] initWithDelegate:self];
+}
+
+#pragma mark - JXPagerViewDelegate
+
+- (UIView *)tableHeaderViewInPagerView:(JXPagerView *)pagerView {
+    return self.headView;
+}
+
+- (NSUInteger)tableHeaderViewHeightInPagerView:(JXPagerView *)pagerView {
+    return self.topViewHeight;
+}
+
+- (NSUInteger)heightForPinSectionHeaderInPagerView:(JXPagerView *)pagerView {
+    return self.headHeight;
+}
+
+- (UIView *)viewForPinSectionHeaderInPagerView:(JXPagerView *)pagerView {
+    return self.categoryView;
+}
+
+- (NSInteger)numberOfListsInPagerView:(JXPagerView *)pagerView {
+    //和categoryView的item数量一致
+    return self.titles.count;
+}
+
+- (id<JXPagerViewListViewDelegate>)pagerView:(JXPagerView *)pagerView initListAtIndex:(NSInteger)index {
+    if (index == 0) {
+        ProgramCourseGroupBodyView *listView = [[ProgramCourseGroupBodyView alloc] init];
+        listView.naviController = self.navigationController;
+        listView.selectIndex = index;
+        listView.courseGroupId = self.courseGroupId;
+        [self.listViewArray replaceObjectAtIndex:index withObject:listView];
+        self.listViewArray[index] = listView;
+        [listView beginFirstRefresh];
+        return listView;
+    }
+    else {
+        MusicRoomStudentPageView *listView = [[MusicRoomStudentPageView alloc] init];
+        listView.naviController = self.navigationController;
+        listView.selectIndex = index;
+        listView.courseGroupId = self.courseGroupId;
+        [self.listViewArray replaceObjectAtIndex:index withObject:listView];
+        self.listViewArray[index] = listView;
+        [listView beginFirstRefresh];
+        return listView;
+    }
+    return nil;
+}
+
+#pragma mark - JXPagerMainTableViewGestureDelegate
+
+- (BOOL)mainTableViewGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
+    //禁止categoryView左右滑动的时候,上下和左右都可以滚动
+    if (otherGestureRecognizer == self.categoryView.collectionView.panGestureRecognizer) {
+        return NO;
+    }
+    return [gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]];
+}
+
+
+
+- (void)dealloc {
+   [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+
+#pragma mark ---- lazying
+- (GroupCourseGroupNavView *)navView {
+    if (!_navView) {
+        _navView = [GroupCourseGroupNavView sharedInstance];
+        MJWeakSelf;
+        [_navView navActionCallback:^{
+            [weakSelf backAction];
+        }];
+    }
+    return _navView;
+}
+
+- (GroupCourseGroupHeadView *)headView {
+    if (!_headView) {
+        _headView = [GroupCourseGroupHeadView sharedInstance];
+    }
+    return _headView;
+}
+- (NSMutableArray *)listViewArray {
+    if (!_listViewArray) {
+        _listViewArray = [NSMutableArray arrayWithArray:@[@"",@""]];
+    }
+    return _listViewArray;
+}
+
+
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+    // Get the new view controller using [segue destinationViewController].
+    // Pass the selected object to the new view controller.
+}
+*/
+
+@end

+ 47 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/Model/GroupCourseGroupInfoModel.h

@@ -0,0 +1,47 @@
+//
+//  GroupCourseGroupInfoModel.h
+//
+//  Created by Steven  on 2024/12/23
+//  Copyright (c) 2024 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+
+@interface GroupCourseGroupInfoModel : NSObject <NSCoding, NSCopying>
+
+@property (nonatomic, strong) NSString *backgroundPic;
+@property (nonatomic, strong) NSString *courseIntroduce;
+@property (nonatomic, strong) NSString *salesEndDate;
+@property (nonatomic, strong) NSString *status;
+@property (nonatomic, assign) double mixStudentNum;
+@property (nonatomic, strong) NSString *courseGroupName;
+@property (nonatomic, assign) double auditVersion;
+@property (nonatomic, strong) NSString *salesStartDate;
+@property (nonatomic, strong) NSString *teacherName;
+@property (nonatomic, strong) NSString *subjectName;
+@property (nonatomic, assign) BOOL myself;
+@property (nonatomic, strong) NSString *courseStartTime;
+@property (nonatomic, strong) NSString *imGroupId;
+@property (nonatomic, assign) double singleCourseMinutes;
+@property (nonatomic, assign) double teacherId;
+@property (nonatomic, strong) NSString *coursePlan;
+@property (nonatomic, assign) double degreeFlag;
+@property (nonatomic, assign) double studentCount;
+@property (nonatomic, assign) double courseGroupId;
+@property (nonatomic, strong) NSString *avatar;
+@property (nonatomic, assign) double courseNum;
+@property (nonatomic, assign) double existBuy;
+@property (nonatomic, assign) double maxStudentNum;
+@property (nonatomic, strong) NSString *reason;
+@property (nonatomic, assign) double teacherFlag;
+@property (nonatomic, strong) NSString *userName;
+@property (nonatomic, assign) double coursePrice;
+@property (nonatomic, assign) double completeCourseNum;
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+- (NSDictionary *)dictionaryRepresentation;
+
+@end

+ 284 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/Model/GroupCourseGroupInfoModel.m

@@ -0,0 +1,284 @@
+//
+//  GroupCourseGroupInfoModel.m
+//
+//  Created by Steven  on 2024/12/23
+//  Copyright (c) 2024 __MyCompanyName__. All rights reserved.
+//
+
+#import "GroupCourseGroupInfoModel.h"
+
+
+NSString *const kGroupCourseGroupInfoModelBackgroundPic = @"backgroundPic";
+NSString *const kGroupCourseGroupInfoModelCourseIntroduce = @"courseIntroduce";
+NSString *const kGroupCourseGroupInfoModelSalesEndDate = @"salesEndDate";
+NSString *const kGroupCourseGroupInfoModelStatus = @"status";
+NSString *const kGroupCourseGroupInfoModelMixStudentNum = @"mixStudentNum";
+NSString *const kGroupCourseGroupInfoModelCourseGroupName = @"courseGroupName";
+NSString *const kGroupCourseGroupInfoModelAuditVersion = @"auditVersion";
+NSString *const kGroupCourseGroupInfoModelSalesStartDate = @"salesStartDate";
+NSString *const kGroupCourseGroupInfoModelTeacherName = @"teacherName";
+NSString *const kGroupCourseGroupInfoModelSubjectName = @"subjectName";
+NSString *const kGroupCourseGroupInfoModelMyself = @"myself";
+NSString *const kGroupCourseGroupInfoModelCourseStartTime = @"courseStartTime";
+NSString *const kGroupCourseGroupInfoModelImGroupId = @"imGroupId";
+NSString *const kGroupCourseGroupInfoModelSingleCourseMinutes = @"singleCourseMinutes";
+NSString *const kGroupCourseGroupInfoModelTeacherId = @"teacherId";
+NSString *const kGroupCourseGroupInfoModelCoursePlan = @"coursePlan";
+NSString *const kGroupCourseGroupInfoModelDegreeFlag = @"degreeFlag";
+NSString *const kGroupCourseGroupInfoModelStudentCount = @"studentCount";
+NSString *const kGroupCourseGroupInfoModelCourseGroupId = @"courseGroupId";
+NSString *const kGroupCourseGroupInfoModelAvatar = @"avatar";
+NSString *const kGroupCourseGroupInfoModelCourseNum = @"courseNum";
+NSString *const kGroupCourseGroupInfoModelExistBuy = @"existBuy";
+NSString *const kGroupCourseGroupInfoModelMaxStudentNum = @"maxStudentNum";
+NSString *const kGroupCourseGroupInfoModelReason = @"reason";
+NSString *const kGroupCourseGroupInfoModelTeacherFlag = @"teacherFlag";
+NSString *const kGroupCourseGroupInfoModelUserName = @"userName";
+NSString *const kGroupCourseGroupInfoModelCoursePrice = @"coursePrice";
+NSString *const kGroupCourseGroupInfoModelCompleteCourseNum = @"completeCourseNum";
+
+@interface GroupCourseGroupInfoModel ()
+
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
+
+@end
+
+@implementation GroupCourseGroupInfoModel
+
+@synthesize backgroundPic = _backgroundPic;
+@synthesize courseIntroduce = _courseIntroduce;
+@synthesize salesEndDate = _salesEndDate;
+@synthesize status = _status;
+@synthesize mixStudentNum = _mixStudentNum;
+@synthesize courseGroupName = _courseGroupName;
+@synthesize auditVersion = _auditVersion;
+@synthesize salesStartDate = _salesStartDate;
+@synthesize teacherName = _teacherName;
+@synthesize subjectName = _subjectName;
+@synthesize myself = _myself;
+@synthesize courseStartTime = _courseStartTime;
+@synthesize imGroupId = _imGroupId;
+@synthesize singleCourseMinutes = _singleCourseMinutes;
+@synthesize teacherId = _teacherId;
+@synthesize coursePlan = _coursePlan;
+@synthesize degreeFlag = _degreeFlag;
+@synthesize studentCount = _studentCount;
+@synthesize courseGroupId = _courseGroupId;
+@synthesize avatar = _avatar;
+@synthesize courseNum = _courseNum;
+@synthesize existBuy = _existBuy;
+@synthesize maxStudentNum = _maxStudentNum;
+@synthesize reason = _reason;
+@synthesize teacherFlag = _teacherFlag;
+@synthesize userName = _userName;
+@synthesize coursePrice = _coursePrice;
+@synthesize completeCourseNum = _completeCourseNum;
+
++ (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.backgroundPic = [self objectOrNilForKey:kGroupCourseGroupInfoModelBackgroundPic fromDictionary:dict];
+            self.courseIntroduce = [self objectOrNilForKey:kGroupCourseGroupInfoModelCourseIntroduce fromDictionary:dict];
+            self.salesEndDate = [self objectOrNilForKey:kGroupCourseGroupInfoModelSalesEndDate fromDictionary:dict];
+            self.status = [self objectOrNilForKey:kGroupCourseGroupInfoModelStatus fromDictionary:dict];
+            self.mixStudentNum = [[self objectOrNilForKey:kGroupCourseGroupInfoModelMixStudentNum fromDictionary:dict] doubleValue];
+            self.courseGroupName = [self objectOrNilForKey:kGroupCourseGroupInfoModelCourseGroupName fromDictionary:dict];
+            self.auditVersion = [[self objectOrNilForKey:kGroupCourseGroupInfoModelAuditVersion fromDictionary:dict] doubleValue];
+            self.salesStartDate = [self objectOrNilForKey:kGroupCourseGroupInfoModelSalesStartDate fromDictionary:dict];
+            self.teacherName = [self objectOrNilForKey:kGroupCourseGroupInfoModelTeacherName fromDictionary:dict];
+            self.subjectName = [self objectOrNilForKey:kGroupCourseGroupInfoModelSubjectName fromDictionary:dict];
+            self.myself = [[self objectOrNilForKey:kGroupCourseGroupInfoModelMyself fromDictionary:dict] boolValue];
+            self.courseStartTime = [self objectOrNilForKey:kGroupCourseGroupInfoModelCourseStartTime fromDictionary:dict];
+            self.imGroupId = [self objectOrNilForKey:kGroupCourseGroupInfoModelImGroupId fromDictionary:dict];
+            self.singleCourseMinutes = [[self objectOrNilForKey:kGroupCourseGroupInfoModelSingleCourseMinutes fromDictionary:dict] doubleValue];
+            self.teacherId = [[self objectOrNilForKey:kGroupCourseGroupInfoModelTeacherId fromDictionary:dict] doubleValue];
+            self.coursePlan = [self objectOrNilForKey:kGroupCourseGroupInfoModelCoursePlan fromDictionary:dict];
+            self.degreeFlag = [[self objectOrNilForKey:kGroupCourseGroupInfoModelDegreeFlag fromDictionary:dict] doubleValue];
+            self.studentCount = [[self objectOrNilForKey:kGroupCourseGroupInfoModelStudentCount fromDictionary:dict] doubleValue];
+            self.courseGroupId = [[self objectOrNilForKey:kGroupCourseGroupInfoModelCourseGroupId fromDictionary:dict] doubleValue];
+            self.avatar = [self objectOrNilForKey:kGroupCourseGroupInfoModelAvatar fromDictionary:dict];
+            self.courseNum = [[self objectOrNilForKey:kGroupCourseGroupInfoModelCourseNum fromDictionary:dict] doubleValue];
+            self.existBuy = [[self objectOrNilForKey:kGroupCourseGroupInfoModelExistBuy fromDictionary:dict] doubleValue];
+            self.maxStudentNum = [[self objectOrNilForKey:kGroupCourseGroupInfoModelMaxStudentNum fromDictionary:dict] doubleValue];
+            self.reason = [self objectOrNilForKey:kGroupCourseGroupInfoModelReason fromDictionary:dict];
+            self.teacherFlag = [[self objectOrNilForKey:kGroupCourseGroupInfoModelTeacherFlag fromDictionary:dict] doubleValue];
+            self.userName = [self objectOrNilForKey:kGroupCourseGroupInfoModelUserName fromDictionary:dict];
+            self.coursePrice = [[self objectOrNilForKey:kGroupCourseGroupInfoModelCoursePrice fromDictionary:dict] doubleValue];
+            self.completeCourseNum = [[self objectOrNilForKey:kGroupCourseGroupInfoModelCompleteCourseNum fromDictionary:dict] doubleValue];
+    }
+    
+    return self;
+    
+}
+
+- (NSDictionary *)dictionaryRepresentation
+{
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    [mutableDict setValue:self.backgroundPic forKey:kGroupCourseGroupInfoModelBackgroundPic];
+    [mutableDict setValue:self.courseIntroduce forKey:kGroupCourseGroupInfoModelCourseIntroduce];
+    [mutableDict setValue:self.salesEndDate forKey:kGroupCourseGroupInfoModelSalesEndDate];
+    [mutableDict setValue:self.status forKey:kGroupCourseGroupInfoModelStatus];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.mixStudentNum] forKey:kGroupCourseGroupInfoModelMixStudentNum];
+    [mutableDict setValue:self.courseGroupName forKey:kGroupCourseGroupInfoModelCourseGroupName];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.auditVersion] forKey:kGroupCourseGroupInfoModelAuditVersion];
+    [mutableDict setValue:self.salesStartDate forKey:kGroupCourseGroupInfoModelSalesStartDate];
+    [mutableDict setValue:self.teacherName forKey:kGroupCourseGroupInfoModelTeacherName];
+    [mutableDict setValue:self.subjectName forKey:kGroupCourseGroupInfoModelSubjectName];
+    [mutableDict setValue:[NSNumber numberWithBool:self.myself] forKey:kGroupCourseGroupInfoModelMyself];
+    [mutableDict setValue:self.courseStartTime forKey:kGroupCourseGroupInfoModelCourseStartTime];
+    [mutableDict setValue:self.imGroupId forKey:kGroupCourseGroupInfoModelImGroupId];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.singleCourseMinutes] forKey:kGroupCourseGroupInfoModelSingleCourseMinutes];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.teacherId] forKey:kGroupCourseGroupInfoModelTeacherId];
+    [mutableDict setValue:self.coursePlan forKey:kGroupCourseGroupInfoModelCoursePlan];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.degreeFlag] forKey:kGroupCourseGroupInfoModelDegreeFlag];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.studentCount] forKey:kGroupCourseGroupInfoModelStudentCount];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.courseGroupId] forKey:kGroupCourseGroupInfoModelCourseGroupId];
+    [mutableDict setValue:self.avatar forKey:kGroupCourseGroupInfoModelAvatar];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.courseNum] forKey:kGroupCourseGroupInfoModelCourseNum];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.existBuy] forKey:kGroupCourseGroupInfoModelExistBuy];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.maxStudentNum] forKey:kGroupCourseGroupInfoModelMaxStudentNum];
+    [mutableDict setValue:self.reason forKey:kGroupCourseGroupInfoModelReason];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.teacherFlag] forKey:kGroupCourseGroupInfoModelTeacherFlag];
+    [mutableDict setValue:self.userName forKey:kGroupCourseGroupInfoModelUserName];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.coursePrice] forKey:kGroupCourseGroupInfoModelCoursePrice];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.completeCourseNum] forKey:kGroupCourseGroupInfoModelCompleteCourseNum];
+    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.backgroundPic = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelBackgroundPic];
+    self.courseIntroduce = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelCourseIntroduce];
+    self.salesEndDate = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelSalesEndDate];
+    self.status = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelStatus];
+    self.mixStudentNum = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelMixStudentNum];
+    self.courseGroupName = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelCourseGroupName];
+    self.auditVersion = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelAuditVersion];
+    self.salesStartDate = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelSalesStartDate];
+    self.teacherName = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelTeacherName];
+    self.subjectName = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelSubjectName];
+    self.myself = [aDecoder decodeBoolForKey:kGroupCourseGroupInfoModelMyself];
+    self.courseStartTime = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelCourseStartTime];
+    self.imGroupId = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelImGroupId];
+    self.singleCourseMinutes = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelSingleCourseMinutes];
+    self.teacherId = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelTeacherId];
+    self.coursePlan = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelCoursePlan];
+    self.degreeFlag = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelDegreeFlag];
+    self.studentCount = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelStudentCount];
+    self.courseGroupId = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelCourseGroupId];
+    self.avatar = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelAvatar];
+    self.courseNum = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelCourseNum];
+    self.existBuy = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelExistBuy];
+    self.maxStudentNum = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelMaxStudentNum];
+    self.reason = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelReason];
+    self.teacherFlag = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelTeacherFlag];
+    self.userName = [aDecoder decodeObjectForKey:kGroupCourseGroupInfoModelUserName];
+    self.coursePrice = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelCoursePrice];
+    self.completeCourseNum = [aDecoder decodeDoubleForKey:kGroupCourseGroupInfoModelCompleteCourseNum];
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+
+    [aCoder encodeObject:_backgroundPic forKey:kGroupCourseGroupInfoModelBackgroundPic];
+    [aCoder encodeObject:_courseIntroduce forKey:kGroupCourseGroupInfoModelCourseIntroduce];
+    [aCoder encodeObject:_salesEndDate forKey:kGroupCourseGroupInfoModelSalesEndDate];
+    [aCoder encodeObject:_status forKey:kGroupCourseGroupInfoModelStatus];
+    [aCoder encodeDouble:_mixStudentNum forKey:kGroupCourseGroupInfoModelMixStudentNum];
+    [aCoder encodeObject:_courseGroupName forKey:kGroupCourseGroupInfoModelCourseGroupName];
+    [aCoder encodeDouble:_auditVersion forKey:kGroupCourseGroupInfoModelAuditVersion];
+    [aCoder encodeObject:_salesStartDate forKey:kGroupCourseGroupInfoModelSalesStartDate];
+    [aCoder encodeObject:_teacherName forKey:kGroupCourseGroupInfoModelTeacherName];
+    [aCoder encodeObject:_subjectName forKey:kGroupCourseGroupInfoModelSubjectName];
+    [aCoder encodeBool:_myself forKey:kGroupCourseGroupInfoModelMyself];
+    [aCoder encodeObject:_courseStartTime forKey:kGroupCourseGroupInfoModelCourseStartTime];
+    [aCoder encodeObject:_imGroupId forKey:kGroupCourseGroupInfoModelImGroupId];
+    [aCoder encodeDouble:_singleCourseMinutes forKey:kGroupCourseGroupInfoModelSingleCourseMinutes];
+    [aCoder encodeDouble:_teacherId forKey:kGroupCourseGroupInfoModelTeacherId];
+    [aCoder encodeObject:_coursePlan forKey:kGroupCourseGroupInfoModelCoursePlan];
+    [aCoder encodeDouble:_degreeFlag forKey:kGroupCourseGroupInfoModelDegreeFlag];
+    [aCoder encodeDouble:_studentCount forKey:kGroupCourseGroupInfoModelStudentCount];
+    [aCoder encodeDouble:_courseGroupId forKey:kGroupCourseGroupInfoModelCourseGroupId];
+    [aCoder encodeObject:_avatar forKey:kGroupCourseGroupInfoModelAvatar];
+    [aCoder encodeDouble:_courseNum forKey:kGroupCourseGroupInfoModelCourseNum];
+    [aCoder encodeDouble:_existBuy forKey:kGroupCourseGroupInfoModelExistBuy];
+    [aCoder encodeDouble:_maxStudentNum forKey:kGroupCourseGroupInfoModelMaxStudentNum];
+    [aCoder encodeObject:_reason forKey:kGroupCourseGroupInfoModelReason];
+    [aCoder encodeDouble:_teacherFlag forKey:kGroupCourseGroupInfoModelTeacherFlag];
+    [aCoder encodeObject:_userName forKey:kGroupCourseGroupInfoModelUserName];
+    [aCoder encodeDouble:_coursePrice forKey:kGroupCourseGroupInfoModelCoursePrice];
+    [aCoder encodeDouble:_completeCourseNum forKey:kGroupCourseGroupInfoModelCompleteCourseNum];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    GroupCourseGroupInfoModel *copy = [[GroupCourseGroupInfoModel alloc] init];
+    
+    if (copy) {
+
+        copy.backgroundPic = [self.backgroundPic copyWithZone:zone];
+        copy.courseIntroduce = [self.courseIntroduce copyWithZone:zone];
+        copy.salesEndDate = [self.salesEndDate copyWithZone:zone];
+        copy.status = [self.status copyWithZone:zone];
+        copy.mixStudentNum = self.mixStudentNum;
+        copy.courseGroupName = [self.courseGroupName copyWithZone:zone];
+        copy.auditVersion = self.auditVersion;
+        copy.salesStartDate = [self.salesStartDate copyWithZone:zone];
+        copy.teacherName = [self.teacherName copyWithZone:zone];
+        copy.subjectName = [self.subjectName copyWithZone:zone];
+        copy.myself = self.myself;
+        copy.courseStartTime = [self.courseStartTime copyWithZone:zone];
+        copy.imGroupId = [self.imGroupId copyWithZone:zone];
+        copy.singleCourseMinutes = self.singleCourseMinutes;
+        copy.teacherId = self.teacherId;
+        copy.coursePlan = [self.coursePlan copyWithZone:zone];
+        copy.degreeFlag = self.degreeFlag;
+        copy.studentCount = self.studentCount;
+        copy.courseGroupId = self.courseGroupId;
+        copy.avatar = [self.avatar copyWithZone:zone];
+        copy.courseNum = self.courseNum;
+        copy.existBuy = self.existBuy;
+        copy.maxStudentNum = self.maxStudentNum;
+        copy.reason = [self.reason copyWithZone:zone];
+        copy.teacherFlag = self.teacherFlag;
+        copy.userName = [self.userName copyWithZone:zone];
+        copy.coursePrice = self.coursePrice;
+        copy.completeCourseNum = self.completeCourseNum;
+    }
+    
+    return copy;
+}
+
+
+@end

+ 23 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupHeadView.h

@@ -0,0 +1,23 @@
+//
+//  GroupCourseGroupHeadView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/12/23.
+//
+
+#import <UIKit/UIKit.h>
+#import "GroupCourseGroupInfoModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GroupCourseGroupHeadView : UIView
+
++ (instancetype)sharedInstance;
+
+- (void)configWithSource:(GroupCourseGroupInfoModel *)model;
+
++ (CGFloat)getViewHeight:(GroupCourseGroupInfoModel *)source;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 134 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupHeadView.m

@@ -0,0 +1,134 @@
+//
+//  GroupCourseGroupHeadView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/12/23.
+//
+
+#import "GroupCourseGroupHeadView.h"
+
+@interface GroupCourseGroupHeadView ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *coverImage;
+@property (weak, nonatomic) IBOutlet UILabel *courseName;
+
+@property (weak, nonatomic) IBOutlet UIView *orderUserBg;
+@property (weak, nonatomic) IBOutlet UILabel *orderUser;
+@property (weak, nonatomic) IBOutlet UILabel *courseTime;
+@property (weak, nonatomic) IBOutlet UILabel *tagLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *priceLabel;
+@property (weak, nonatomic) IBOutlet UILabel *courseCount;
+@property (weak, nonatomic) IBOutlet UILabel *subjectLabel;
+@property (weak, nonatomic) IBOutlet UILabel *courseDesc;
+
+@property (weak, nonatomic) IBOutlet UIImageView *teacherAvatar;
+@property (weak, nonatomic) IBOutlet UILabel *teacherName;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseIntroduce;
+
+@end
+
+@implementation GroupCourseGroupHeadView
+
+
++ (instancetype)sharedInstance {
+    GroupCourseGroupHeadView *view = [[[NSBundle mainBundle] loadNibNamed:@"GroupCourseGroupHeadView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configWithSource:(GroupCourseGroupInfoModel *)model {
+    [self.coverImage sd_setImageWithURL:[NSURL URLWithString:[model.backgroundPic getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"video_placeholder"]];
+    self.courseName.text = [NSString returnNoNullStringWithString:model.courseGroupName];
+    self.orderUser.text = [NSString stringWithFormat:@"剩余%.0f个名额", model.maxStudentNum - model.studentCount];
+    // time
+    NSDateFormatter *formatter = [NSObject getDateformatter];
+    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
+    NSDate *startDate = [formatter dateFromString:model.courseStartTime];
+    [formatter setDateFormat:@"yyyy-MM-dd HH:mm"];
+    NSString *courseBegin = [formatter stringFromDate:startDate];
+    self.courseTime.text = [NSString returnNoNullStringWithString:courseBegin];
+    self.subjectLabel.text = [NSString returnNoNullStringWithString:model.subjectName];
+    
+    if (model.coursePrice > 0) {
+        NSString *mountMsg = [NSString formatAllDoubleNum:model.coursePrice];
+        self.priceLabel.text = mountMsg;
+        self.tagLabel.hidden = NO;
+    }
+    else {
+        self.priceLabel.text = [NSString  stringWithFormat:@"免费"];
+        self.tagLabel.hidden = YES;
+    }
+    self.courseCount.text = [NSString stringWithFormat:@"/%.0f课时",model.courseNum];
+
+    [self.teacherAvatar sd_setImageWithURL:[NSURL URLWithString:[model.avatar getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:TEACHER_AVATAR]];
+    self.teacherName.text = [NSString returnNoNullStringWithString:model.userName];
+    
+    // 课程
+    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:HexRGB(0x333333)}];
+    [attrs appendAttributedString:totalNumAttr];
+    self.courseDesc.attributedText = attrs;
+    
+    
+    NSString *introduce = model.courseIntroduce;
+    if (![NSString isEmptyString:introduce]) {
+        introduce = [introduce replaceAll:@"\n" WithString:@" "];
+    }
+    else {
+        introduce = @"暂无介绍";
+    }
+    
+    NSMutableParagraphStyle *paragraphStyle = [GroupCourseGroupHeadView getParagraphStyleWithFont:[UIFont systemFontOfSize:13.0f] lineHeight:22.0f];
+    CGFloat baselineOffset = [GroupCourseGroupHeadView getBaseOffline:[UIFont systemFontOfSize:13.0f] lineHeight:22.0f];
+    NSMutableAttributedString *introduceAttrs = [[NSMutableAttributedString alloc] initWithString:introduce attributes:@{NSParagraphStyleAttributeName:paragraphStyle, NSBaselineOffsetAttributeName:@(baselineOffset),NSFontAttributeName:[UIFont systemFontOfSize:13.0f], NSForegroundColorAttributeName:HexRGB(0x777777)}];
+    self.courseIntroduce.attributedText = introduceAttrs;
+}
+
+
++ (CGFloat)getViewHeight:(GroupCourseGroupInfoModel *)source {
+    NSString *introduce = source.courseIntroduce;
+    if (![NSString isEmptyString:introduce]) {
+        introduce = [introduce replaceAll:@"\n" WithString:@" "];
+    }
+    else {
+        introduce = @"暂无介绍";
+    }
+    CGFloat imageHeight = KLandscapeWidth / 16 * 9;
+    CGFloat planHeight = 79 + [GroupCourseGroupHeadView getViewRealHeight:introduce];
+    return 135 + imageHeight + planHeight;
+}
+
++ (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;
+}
+
++ (CGFloat)getViewRealHeight:(NSString *)planString {
+    NSMutableParagraphStyle *paragraphStyle = [self getParagraphStyleWithFont:[UIFont systemFontOfSize:13.0f] lineHeight:22.0f];
+    CGFloat baselineOffset = [self getBaseOffline:[UIFont systemFontOfSize:13.0f] lineHeight:22.0f];
+    CGFloat height = [planString boundingRectWithSize:CGSizeMake(KPortraitWidth - 26, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSParagraphStyleAttributeName:paragraphStyle, NSBaselineOffsetAttributeName:@(baselineOffset),NSFontAttributeName:[UIFont systemFontOfSize:13.0f]} context:nil].size.height + 1 + 42 + 10 + 12;
+    return height;
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 317 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupHeadView.xib

@@ -0,0 +1,317 @@
+<?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="GroupCourseGroupHeadView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="505"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="AnK-wf-4BP">
+                    <rect key="frame" x="0.0" y="0.0" width="393" height="356"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="video_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="aHt-s4-D8T">
+                            <rect key="frame" x="0.0" y="0.0" width="393" height="221"/>
+                            <constraints>
+                                <constraint firstAttribute="width" secondItem="aHt-s4-D8T" secondAttribute="height" multiplier="16:9" id="CuK-sb-2aR"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="6"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0p4-wR-LI6">
+                            <rect key="frame" x="8" y="8" width="12" 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="WXY-Wu-N8t">
+                                    <rect key="frame" x="6" y="9.6666666666666679" width="0.0" height="0.0"/>
+                                    <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 firstItem="WXY-Wu-N8t" firstAttribute="leading" secondItem="0p4-wR-LI6" secondAttribute="leading" constant="6" id="B4W-m4-6WC"/>
+                                <constraint firstItem="WXY-Wu-N8t" firstAttribute="centerY" secondItem="0p4-wR-LI6" secondAttribute="centerY" id="LgV-z8-BK9"/>
+                                <constraint firstAttribute="height" constant="19" id="MaT-L9-H9g"/>
+                                <constraint firstAttribute="trailing" secondItem="WXY-Wu-N8t" secondAttribute="trailing" constant="6" id="sfc-ey-UM7"/>
+                            </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="xNR-qb-bSK">
+                            <rect key="frame" x="14" y="229" width="365" height="22"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="22" id="Mq4-2p-Jrc"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                            <color key="textColor" red="0.10196078431372549" green="0.10196078431372549" blue="0.10196078431372549" 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="cWt-tT-seb">
+                            <rect key="frame" x="347" y="312" width="0.0" height="24"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="24" id="KVO-pT-iPI"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" name="DINAlternate-Bold" family="DIN Alternate" pointSize="20"/>
+                            <color key="textColor" red="0.95686274510000002" green="0.27058823529999998" blue="0.25490196079999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="/1课时" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="C6q-FO-iK4">
+                            <rect key="frame" x="349" y="317" width="32" height="17"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="17" id="rlG-mJ-N7P"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                            <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
+                            <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="9s2-dK-o6k">
+                            <rect key="frame" x="338" y="318" width="7" height="16"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="16" id="hEL-qQ-c3g"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" name="DINAlternate-Bold" family="DIN Alternate" pointSize="14"/>
+                            <color key="textColor" red="0.95686274510000002" green="0.27058823529999998" blue="0.25490196079999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_page_live_tag" translatesAutoresizingMaskIntoConstraints="NO" id="b7F-Ah-faY">
+                            <rect key="frame" x="14" y="263" width="20" height="16"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="16" id="3E7-iL-X34"/>
+                                <constraint firstAttribute="width" constant="20" id="lgh-HS-RTg"/>
+                            </constraints>
+                        </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="Rjf-aS-wHE">
+                            <rect key="frame" x="41" y="261" width="62.666666666666657" height="20"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="20" id="mBc-pd-hfb"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="2024-11-16 09:30" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tI3-dq-1Qx">
+                            <rect key="frame" x="103.66666666666669" y="261" width="117.33333333333331" height="20"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="20" id="lT0-gl-akp"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="x71-SB-35W">
+                            <rect key="frame" x="14" y="291" width="365" height="1"/>
+                            <color key="backgroundColor" red="0.94901960784313721" green="0.94901960784313721" blue="0.94901960784313721" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="1" id="evi-h1-UEz"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" horizontalCompressionResistancePriority="752" translatesAutoresizingMaskIntoConstraints="NO" id="HX4-58-7dZ">
+                            <rect key="frame" x="301" y="261.66666666666669" width="78" height="19"/>
+                            <subviews>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="剩余2个名额" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cfo-DH-vsM">
+                                    <rect key="frame" x="4" y="2.3333333333333153" width="70" 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="cfo-DH-vsM" firstAttribute="leading" secondItem="HX4-58-7dZ" secondAttribute="leading" constant="4" id="2Ye-FI-s79"/>
+                                <constraint firstAttribute="trailing" secondItem="cfo-DH-vsM" secondAttribute="trailing" constant="4" id="NVN-YV-cAP"/>
+                                <constraint firstAttribute="height" constant="19" id="k5A-YY-pam"/>
+                                <constraint firstItem="cfo-DH-vsM" firstAttribute="centerY" secondItem="HX4-58-7dZ" secondAttribute="centerY" id="qgL-Jz-iko"/>
+                            </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="严琦" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YTe-Wh-9ux">
+                            <rect key="frame" x="62" y="304" width="30" height="22"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="22" id="VS0-J4-wTr"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                            <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="BbF-PF-VI1">
+                            <rect key="frame" x="78" y="326" width="0.0" height="16"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="16" id="KXa-mr-Bv8"/>
+                            </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>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrange_course_icon" translatesAutoresizingMaskIntoConstraints="NO" id="0G1-Qu-QuA">
+                            <rect key="frame" x="62" y="327" width="12" height="14"/>
+                        </imageView>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="teacher_avatar" translatesAutoresizingMaskIntoConstraints="NO" id="mbV-Hx-bnE">
+                            <rect key="frame" x="12" y="304" width="40" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="40" id="7xk-1J-YTy"/>
+                                <constraint firstAttribute="width" constant="40" id="QXv-vp-d3y"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="20"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="b7F-Ah-faY" firstAttribute="leading" secondItem="AnK-wf-4BP" secondAttribute="leading" constant="14" id="0ge-CG-MTF"/>
+                        <constraint firstItem="HX4-58-7dZ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="tI3-dq-1Qx" secondAttribute="trailing" constant="10" id="2BH-uG-0TP"/>
+                        <constraint firstItem="9s2-dK-o6k" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="BbF-PF-VI1" secondAttribute="trailing" constant="10" id="2S5-xa-ndw"/>
+                        <constraint firstItem="C6q-FO-iK4" firstAttribute="leading" secondItem="cWt-tT-seb" secondAttribute="trailing" constant="2" id="2hu-7N-a8r"/>
+                        <constraint firstItem="0G1-Qu-QuA" firstAttribute="bottom" secondItem="mbV-Hx-bnE" secondAttribute="bottom" constant="-3" id="6Cy-AD-NID"/>
+                        <constraint firstItem="aHt-s4-D8T" firstAttribute="leading" secondItem="AnK-wf-4BP" secondAttribute="leading" id="6Ud-a4-JIc"/>
+                        <constraint firstItem="cWt-tT-seb" firstAttribute="leading" secondItem="9s2-dK-o6k" secondAttribute="trailing" constant="2" id="86T-Cf-WSC"/>
+                        <constraint firstItem="HX4-58-7dZ" firstAttribute="centerY" secondItem="tI3-dq-1Qx" secondAttribute="centerY" id="D3j-ny-W7N"/>
+                        <constraint firstAttribute="trailing" secondItem="aHt-s4-D8T" secondAttribute="trailing" id="D4L-VW-Jvc"/>
+                        <constraint firstAttribute="bottom" secondItem="C6q-FO-iK4" secondAttribute="bottom" constant="22" id="FPN-Xl-q20"/>
+                        <constraint firstAttribute="trailing" secondItem="C6q-FO-iK4" secondAttribute="trailing" constant="12" id="GKQ-xF-rvr"/>
+                        <constraint firstItem="tI3-dq-1Qx" firstAttribute="leading" secondItem="Rjf-aS-wHE" secondAttribute="trailing" id="HpP-Lw-3EG"/>
+                        <constraint firstItem="Rjf-aS-wHE" firstAttribute="leading" secondItem="b7F-Ah-faY" secondAttribute="trailing" constant="7" id="LLp-NY-23y"/>
+                        <constraint firstAttribute="bottom" secondItem="mbV-Hx-bnE" secondAttribute="bottom" constant="12" id="MI6-Qv-hdA"/>
+                        <constraint firstItem="0p4-wR-LI6" firstAttribute="top" secondItem="aHt-s4-D8T" secondAttribute="top" constant="8" id="NNB-h4-UKg"/>
+                        <constraint firstItem="YTe-Wh-9ux" firstAttribute="leading" secondItem="mbV-Hx-bnE" secondAttribute="trailing" constant="10" id="ODD-Sh-y4P"/>
+                        <constraint firstItem="aHt-s4-D8T" firstAttribute="top" secondItem="AnK-wf-4BP" secondAttribute="top" id="RD4-SY-hRF"/>
+                        <constraint firstItem="0G1-Qu-QuA" firstAttribute="leading" secondItem="YTe-Wh-9ux" secondAttribute="leading" id="RIV-x8-aDI"/>
+                        <constraint firstItem="xNR-qb-bSK" firstAttribute="leading" secondItem="AnK-wf-4BP" secondAttribute="leading" constant="14" id="UPX-5W-f7L"/>
+                        <constraint firstItem="mbV-Hx-bnE" firstAttribute="top" secondItem="YTe-Wh-9ux" secondAttribute="top" id="XgH-DR-7Iz"/>
+                        <constraint firstItem="x71-SB-35W" firstAttribute="top" secondItem="b7F-Ah-faY" secondAttribute="bottom" constant="12" id="XtM-Wm-8Wr"/>
+                        <constraint firstItem="tI3-dq-1Qx" firstAttribute="centerY" secondItem="Rjf-aS-wHE" secondAttribute="centerY" id="Yj8-Wb-KNH"/>
+                        <constraint firstItem="BbF-PF-VI1" firstAttribute="centerY" secondItem="0G1-Qu-QuA" secondAttribute="centerY" id="ZZB-SD-GrJ"/>
+                        <constraint firstItem="C6q-FO-iK4" firstAttribute="bottom" secondItem="cWt-tT-seb" secondAttribute="bottom" constant="-2" id="fOE-3z-phS"/>
+                        <constraint firstItem="BbF-PF-VI1" firstAttribute="leading" secondItem="0G1-Qu-QuA" secondAttribute="trailing" constant="4" id="iK5-a0-Q0L"/>
+                        <constraint firstItem="0p4-wR-LI6" firstAttribute="leading" secondItem="aHt-s4-D8T" secondAttribute="leading" constant="8" id="jH6-0a-VXN"/>
+                        <constraint firstItem="b7F-Ah-faY" firstAttribute="top" secondItem="xNR-qb-bSK" secondAttribute="bottom" constant="12" id="mF7-Yc-eV1"/>
+                        <constraint firstItem="Rjf-aS-wHE" firstAttribute="centerY" secondItem="b7F-Ah-faY" secondAttribute="centerY" id="p8i-WX-5fp"/>
+                        <constraint firstAttribute="trailing" secondItem="xNR-qb-bSK" secondAttribute="trailing" constant="14" id="sO9-to-jgg"/>
+                        <constraint firstItem="cWt-tT-seb" firstAttribute="leading" secondItem="9s2-dK-o6k" secondAttribute="trailing" constant="2" id="t2b-1n-LSD"/>
+                        <constraint firstItem="x71-SB-35W" firstAttribute="leading" secondItem="AnK-wf-4BP" secondAttribute="leading" constant="14" id="tJX-re-JM9"/>
+                        <constraint firstItem="cWt-tT-seb" firstAttribute="bottom" secondItem="9s2-dK-o6k" secondAttribute="bottom" constant="2" id="u52-2A-BdI"/>
+                        <constraint firstItem="mbV-Hx-bnE" firstAttribute="top" secondItem="x71-SB-35W" secondAttribute="bottom" constant="12" id="uE3-UD-ftI"/>
+                        <constraint firstItem="mbV-Hx-bnE" firstAttribute="leading" secondItem="AnK-wf-4BP" secondAttribute="leading" constant="12" id="uGB-Yx-QCx"/>
+                        <constraint firstAttribute="trailing" secondItem="HX4-58-7dZ" secondAttribute="trailing" constant="14" id="uJK-V0-w7v"/>
+                        <constraint firstItem="xNR-qb-bSK" firstAttribute="top" secondItem="aHt-s4-D8T" secondAttribute="bottom" constant="8" id="vZf-3A-AIM"/>
+                        <constraint firstAttribute="trailing" secondItem="x71-SB-35W" secondAttribute="trailing" constant="14" id="voP-FF-TiI"/>
+                        <constraint firstItem="tI3-dq-1Qx" firstAttribute="centerY" secondItem="Rjf-aS-wHE" secondAttribute="centerY" id="w2M-LD-W4V"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="10"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Hda-fO-ads">
+                    <rect key="frame" x="14" y="368" width="365" height="137"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="minePage_course_introduce" translatesAutoresizingMaskIntoConstraints="NO" id="5o1-8f-tcE">
+                            <rect key="frame" x="12" y="12" width="18" height="18"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="18" id="O1p-VD-rue"/>
+                                <constraint firstAttribute="width" constant="18" id="hpR-qd-ntj"/>
+                            </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="qE8-hC-MnO">
+                            <rect key="frame" x="36" y="12" width="59.666666666666657" height="18"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="18" id="7xp-tf-zZB"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/>
+                            <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" text="VIP定制课是客制化的1v1线上课程。老师根据您的学习需求和希望达到的成果定制教学内容。为了提高您的上课体验,约课前请与老师充分沟通,达成一致后课根据老师的空闲时间约定上课时间。" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hIr-WK-MPf">
+                            <rect key="frame" x="12" y="55" width="341" height="70"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                            <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="9E4-IH-PKP">
+                            <rect key="frame" x="12" y="42" width="341" height="1"/>
+                            <color key="backgroundColor" red="0.94901960784313721" green="0.94901960784313721" blue="0.94901960784313721" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="1" id="FlM-Fo-Un1"/>
+                            </constraints>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="trailing" secondItem="9E4-IH-PKP" secondAttribute="trailing" constant="12" id="0BC-2V-ZhJ"/>
+                        <constraint firstItem="5o1-8f-tcE" firstAttribute="leading" secondItem="Hda-fO-ads" secondAttribute="leading" constant="12" id="4H4-Ts-FO6"/>
+                        <constraint firstItem="5o1-8f-tcE" firstAttribute="top" secondItem="Hda-fO-ads" secondAttribute="top" constant="12" id="F2q-x5-ZPb"/>
+                        <constraint firstItem="hIr-WK-MPf" firstAttribute="leading" secondItem="Hda-fO-ads" secondAttribute="leading" constant="12" id="SyT-bL-Uxe"/>
+                        <constraint firstItem="qE8-hC-MnO" firstAttribute="leading" secondItem="5o1-8f-tcE" secondAttribute="trailing" constant="6" id="U7V-EZ-zeW"/>
+                        <constraint firstItem="hIr-WK-MPf" firstAttribute="top" secondItem="9E4-IH-PKP" secondAttribute="bottom" constant="12" id="XbW-GZ-1pg"/>
+                        <constraint firstAttribute="trailing" secondItem="hIr-WK-MPf" secondAttribute="trailing" constant="12" id="Z0g-Wy-LS9"/>
+                        <constraint firstItem="9E4-IH-PKP" firstAttribute="top" secondItem="5o1-8f-tcE" secondAttribute="bottom" constant="12" id="jJ0-qn-N3m"/>
+                        <constraint firstItem="qE8-hC-MnO" firstAttribute="centerY" secondItem="5o1-8f-tcE" secondAttribute="centerY" id="je9-nO-mMF"/>
+                        <constraint firstItem="9E4-IH-PKP" firstAttribute="leading" secondItem="Hda-fO-ads" secondAttribute="leading" constant="12" id="ndi-BE-hjJ"/>
+                        <constraint firstAttribute="bottom" secondItem="hIr-WK-MPf" secondAttribute="bottom" constant="12" id="vJX-zG-Ahr"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="8"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="Hda-fO-ads" secondAttribute="bottom" id="I60-Go-wnP"/>
+                <constraint firstItem="AnK-wf-4BP" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="I9z-3B-cLa"/>
+                <constraint firstAttribute="trailing" secondItem="Hda-fO-ads" secondAttribute="trailing" constant="14" id="OcW-zp-x3h"/>
+                <constraint firstItem="Hda-fO-ads" firstAttribute="top" secondItem="AnK-wf-4BP" secondAttribute="bottom" constant="12" id="RL5-aS-5Cr"/>
+                <constraint firstItem="AnK-wf-4BP" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="b33-8w-dfy"/>
+                <constraint firstAttribute="trailing" secondItem="AnK-wf-4BP" secondAttribute="trailing" id="xnY-5s-jUP"/>
+                <constraint firstItem="Hda-fO-ads" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="yBe-pp-k3f"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="courseCount" destination="C6q-FO-iK4" id="8cI-8x-gjO"/>
+                <outlet property="courseDesc" destination="BbF-PF-VI1" id="H73-9A-dq2"/>
+                <outlet property="courseIntroduce" destination="hIr-WK-MPf" id="NAw-dY-9Zq"/>
+                <outlet property="courseName" destination="xNR-qb-bSK" id="rF1-vK-9cr"/>
+                <outlet property="courseTime" destination="tI3-dq-1Qx" id="e8U-Ch-0KC"/>
+                <outlet property="coverImage" destination="aHt-s4-D8T" id="qLr-1d-crD"/>
+                <outlet property="orderUser" destination="cfo-DH-vsM" id="iAF-ZJ-mTd"/>
+                <outlet property="orderUserBg" destination="HX4-58-7dZ" id="zz9-M5-usj"/>
+                <outlet property="priceLabel" destination="cWt-tT-seb" id="5bF-eZ-Gib"/>
+                <outlet property="subjectLabel" destination="WXY-Wu-N8t" id="0V3-27-9gZ"/>
+                <outlet property="tagLabel" destination="9s2-dK-o6k" id="BNj-8H-303"/>
+                <outlet property="teacherAvatar" destination="mbV-Hx-bnE" id="TMC-Hb-iRX"/>
+                <outlet property="teacherName" destination="YTe-Wh-9ux" id="YK2-8u-Qhn"/>
+            </connections>
+            <point key="canvasLocation" x="43.511450381679388" y="-102.46478873239437"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="arrange_course_icon" width="12" height="14"/>
+        <image name="minePage_course_introduce" width="18" height="18"/>
+        <image name="mine_page_live_tag" width="20" height="16"/>
+        <image name="teacher_avatar" width="150" height="150"/>
+        <image name="video_placeholder" width="103" height="72"/>
+    </resources>
+</document>

+ 24 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupNavView.h

@@ -0,0 +1,24 @@
+//
+//  GroupCourseGroupNavView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/12/23.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^GroupCourseNavCallback)(void);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GroupCourseGroupNavView : UIView
+
++ (instancetype)sharedInstance;
+
+- (void)navActionCallback:(GroupCourseNavCallback)callback;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 47 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupNavView.m

@@ -0,0 +1,47 @@
+//
+//  GroupCourseGroupNavView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/12/23.
+//
+
+#import "GroupCourseGroupNavView.h"
+
+@interface GroupCourseGroupNavView ()
+
+@property (nonatomic, copy) GroupCourseNavCallback callback;
+
+@end
+
+@implementation GroupCourseGroupNavView
+
++ (instancetype)sharedInstance {
+    GroupCourseGroupNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"GroupCourseGroupNavView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)navActionCallback:(GroupCourseNavCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)backAction:(id)sender {
+    if (self.callback) {
+        self.callback();
+    }
+}
+
+
++ (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

+ 72 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseGroupNavView.xib

@@ -0,0 +1,72 @@
+<?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"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="GroupCourseGroupNavView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="80"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Twy-FB-6kP">
+                    <rect key="frame" x="0.0" y="36" width="393" height="44"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="back_black" translatesAutoresizingMaskIntoConstraints="NO" id="hhu-eK-oE8">
+                            <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="oAo-cF-u9t">
+                            <rect key="frame" x="0.0" y="2" width="40" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="40" id="fF4-db-O85"/>
+                                <constraint firstAttribute="height" constant="40" id="ibI-7c-nrz"/>
+                            </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="cJm-fm-hWg"/>
+                            </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="cob-Lg-OoP">
+                            <rect key="frame" x="152" y="9.6666666666666643" width="89.333333333333314" height="25"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="25" id="Gjp-Qd-ItY"/>
+                            </constraints>
+                            <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>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="44" id="02L-uT-zoh"/>
+                        <constraint firstItem="hhu-eK-oE8" firstAttribute="centerY" secondItem="Twy-FB-6kP" secondAttribute="centerY" id="7Qy-nK-Vdm"/>
+                        <constraint firstItem="hhu-eK-oE8" firstAttribute="leading" secondItem="Twy-FB-6kP" secondAttribute="leading" constant="15" id="FOl-iX-cKS"/>
+                        <constraint firstItem="cob-Lg-OoP" firstAttribute="centerX" secondItem="Twy-FB-6kP" secondAttribute="centerX" id="Pkh-Fs-b5h"/>
+                        <constraint firstItem="oAo-cF-u9t" firstAttribute="leading" secondItem="Twy-FB-6kP" secondAttribute="leading" id="Qpn-s1-qEP"/>
+                        <constraint firstItem="oAo-cF-u9t" firstAttribute="centerY" secondItem="hhu-eK-oE8" secondAttribute="centerY" id="Rvz-s3-waO"/>
+                        <constraint firstItem="cob-Lg-OoP" firstAttribute="centerY" secondItem="oAo-cF-u9t" secondAttribute="centerY" id="r29-py-C6z"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="Twy-FB-6kP" secondAttribute="trailing" id="M2m-0F-MjX"/>
+                <constraint firstAttribute="bottom" secondItem="Twy-FB-6kP" secondAttribute="bottom" id="hke-Ti-OVP"/>
+                <constraint firstItem="Twy-FB-6kP" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="ux3-v8-rVl"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="43.511450381679388" y="-54.225352112676056"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="back_black" width="12" height="20"/>
+    </resources>
+</document>

+ 20 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseListCell.h

@@ -0,0 +1,20 @@
+//
+//  GroupCourseListCell.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/12/23.
+//
+
+#import <UIKit/UIKit.h>
+#import "GroupCourseListModel.h"
+#import "ProgramCourseListCell.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GroupCourseListCell : UITableViewCell
+
+- (void)configWithSource:(GroupCourseListModel *)model beforeTime:(NSInteger)beforeTime callback:(GroupListModelCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 185 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseListCell.m

@@ -0,0 +1,185 @@
+//
+//  GroupCourseListCell.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2024/12/23.
+//
+
+#import "GroupCourseListCell.h"
+
+@interface GroupCourseListCell ()
+
+@property (weak, nonatomic) IBOutlet UIButton *enterButton;
+
+@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseGroupName;
+
+@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
+
+@property (weak, nonatomic) IBOutlet UIImageView *arriveStatus;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *arriveStatusWidth;
+
+@property (weak, nonatomic) IBOutlet UIView *subjectView;
+@property (weak, nonatomic) IBOutlet UILabel *subjectLabel;
+
+@property (nonatomic, strong) GroupCourseListModel *sourceModel;
+
+@property (nonatomic, copy) GroupListModelCallback callback;
+
+@property (nonatomic, assign) NSInteger beforeTime;
+
+@property (weak, nonatomic) IBOutlet UILabel *coursPlanLabel;
+
+@end
+
+@implementation GroupCourseListCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+- (void)configWithSource:(GroupCourseListModel *)model beforeTime:(NSInteger)beforeTime callback:(GroupListModelCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+    self.sourceModel = model;
+    NSDateFormatter *formatter = [NSObject getDateformatter];
+    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
+    NSDate *startDate = [formatter dateFromString:model.startTime];
+    NSDate *endDate = [formatter dateFromString:model.endTime];
+    [formatter setDateFormat:@"yyyy-MM-dd HH:mm"];
+    NSString *lessonBegin = [formatter stringFromDate:startDate];
+    [formatter setDateFormat:@"HH:mm"];
+    NSString *lessonEnd = [formatter stringFromDate:endDate];
+    self.timeLabel.text = [NSString stringWithFormat:@"%@~%@",[NSString returnNoNullStringWithString:lessonBegin],[NSString returnNoNullStringWithString:lessonEnd]];
+    self.courseGroupName.text = [NSString returnNoNullStringWithString:model.courseGroupName];
+    [self configNameWithStudent:model.courseStudentVos];
+    self.subjectLabel.text = [NSString returnNoNullStringWithString:model.subjectName];
+    if ([NSString isEmptyString:model.subjectName]) {
+        self.subjectView.hidden = YES;
+    }
+    else {
+        self.subjectView.hidden = NO;
+    }
+    [self evaluateWithSource:model];
+    
+    // 描述
+    NSString *planDesc = model.coursePlan;
+    
+    if ([NSString isEmptyString:planDesc]) {
+        planDesc = @"暂无课程规划";
+    }
+    NSMutableParagraphStyle *paragraphStyle = [GroupCourseListCell getParagraphStyleWithFont:[UIFont systemFontOfSize:13.0f] lineHeight:22.0f];
+    CGFloat baselineOffset = [GroupCourseListCell getBaseOffline:[UIFont systemFontOfSize:13.0f] lineHeight:22.0f];
+    NSMutableAttributedString *attrs = [[NSMutableAttributedString alloc] initWithString:planDesc attributes:@{NSParagraphStyleAttributeName:paragraphStyle, NSBaselineOffsetAttributeName:@(baselineOffset),NSFontAttributeName:[UIFont systemFontOfSize:13.0f], NSForegroundColorAttributeName:HexRGB(0x777777)}];
+    self.coursPlanLabel.attributedText = attrs;
+}
+
+- (void)configNameWithStudent:(NSArray *)studentArray {
+    NSString *nameDesc = nil;
+    NSMutableArray *nameArray = [NSMutableArray array];
+    for (CourseStudentVos *stuModel in studentArray) {
+        if (![NSString isEmptyString:stuModel.userName]) {
+            [nameArray addObject:stuModel.userName];
+        }
+    }
+    if (nameArray.count > 2) {
+        nameDesc = [NSString stringWithFormat:@"%@、%@等%zd人", nameArray[0], nameArray[1], nameArray.count];
+    }
+    else {
+        nameDesc = [nameArray componentsJoinedByString:@"、"];
+    }
+    self.nameLabel.text = nameDesc;
+}
+
+
+- (void)evaluateWithSource:(GroupCourseListModel *)model {
+    NSString *imageName = model.attendanceStatus ? @"course_attendence" : @"course_noArrive";
+    if ([model.status isEqualToString:@"ING"]) {
+        self.statusLabel.text = @"进行中";
+        self.statusLabel.textColor = THEMECOLOR;
+        self.arriveStatus.hidden = YES;
+        self.arriveStatusWidth.constant = 0.0f;
+        self.enterButton.hidden = NO;
+        self.enterButton.userInteractionEnabled = YES;
+    }
+    else if ([model.status isEqualToString:@"NOT_START"]) {
+        self.statusLabel.text = @"未开始";
+        self.statusLabel.textColor = HexRGB(0xFF802C);
+        self.arriveStatus.hidden = YES;
+        self.arriveStatusWidth.constant = 0.0f;
+        
+        // 判断按钮显示调课还是进入教室
+        NSDate *currentDate = [NSDate date];
+        NSDate *beginDate = [self getCourseBeginDate:model.startTime];
+        NSTimeInterval beginTimeInterval = [beginDate timeIntervalSinceDate:currentDate];
+        BOOL canChange = NO;
+        if (beginTimeInterval > self.beforeTime * 60) {
+            canChange = YES;
+        }
+        if (canChange) {
+            self.enterButton.hidden = YES;
+            self.enterButton.userInteractionEnabled = NO;
+        }
+        else {
+            self.enterButton.hidden = NO;
+            self.enterButton.userInteractionEnabled = YES;
+        }
+    }
+    else if ([model.status isEqualToString:@"COMPLETE"]) {
+        self.statusLabel.text = @"已结束";
+        self.statusLabel.textColor = HexRGB(0x999999);
+        self.arriveStatus.hidden = NO;
+        self.arriveStatusWidth.constant = 36.0f;
+        self.enterButton.hidden = YES;
+        self.enterButton.userInteractionEnabled = NO;
+    }
+    [self.arriveStatus setImage:[UIImage imageNamed:imageName]];
+}
+
+
+
+- (IBAction)enterClassRoom:(id)sender {
+    if (self.callback) {
+        self.callback(self.sourceModel);
+    }
+}
+
+- (NSDate *)getCourseBeginDate:(NSString *)beginTime {
+    NSDateFormatter *dateFormatter = [NSObject getDateformatter];
+    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
+    NSDate *beginDate = [dateFormatter dateFromString:beginTime];
+    return beginDate;
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
++ (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;
+}
+
++ (CGFloat)getViewRealHeight:(NSString *)planString {
+    NSMutableParagraphStyle *paragraphStyle = [self getParagraphStyleWithFont:[UIFont systemFontOfSize:13.0f] lineHeight:22.0f];
+    CGFloat baselineOffset = [self getBaseOffline:[UIFont systemFontOfSize:13.0f] lineHeight:22.0f];
+    CGFloat height = [planString boundingRectWithSize:CGSizeMake(KPortraitWidth - 26, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSParagraphStyleAttributeName:paragraphStyle, NSBaselineOffsetAttributeName:@(baselineOffset),NSFontAttributeName:[UIFont systemFontOfSize:13.0f]} context:nil].size.height + 1 + 42 + 10 + 12;
+    return height;
+}
+
+@end

+ 243 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/MyGroupCourse/View/GroupCourseListCell.xib

@@ -0,0 +1,243 @@
+<?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="189" id="KGk-i7-Jjw" customClass="GroupCourseListCell">
+            <rect key="frame" x="0.0" y="0.0" width="320" height="189"/>
+            <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="189"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LWM-GL-2PH">
+                        <rect key="frame" x="14" y="0.0" width="292" height="177"/>
+                        <subviews>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iLa-EZ-zRx">
+                                <rect key="frame" x="0.0" y="0.0" width="292" height="111"/>
+                                <subviews>
+                                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gqH-Nk-A1o">
+                                        <rect key="frame" x="10" y="46" width="272" height="1"/>
+                                        <color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="calibratedRGB"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="1" id="EuM-DR-pbM"/>
+                                        </constraints>
+                                    </view>
+                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" image="course_time" translatesAutoresizingMaskIntoConstraints="NO" id="sqA-d1-zSQ">
+                                        <rect key="frame" x="12" y="15" width="16" height="16"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="16" id="bQx-Mq-diy"/>
+                                            <constraint firstAttribute="width" constant="16" id="p2n-Kf-OZ5"/>
+                                        </constraints>
+                                    </imageView>
+                                    <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="ZYo-j3-z1x">
+                                        <rect key="frame" x="35" y="14" width="0.0" height="18"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="18" id="dJl-Sb-ip9"/>
+                                        </constraints>
+                                        <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                                        <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" 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="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ppo-xJ-iwM">
+                                        <rect key="frame" x="238" y="12" width="42" height="22"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="22" id="TFc-SF-woq"/>
+                                        </constraints>
+                                        <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                                        <color key="textColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="course_group" translatesAutoresizingMaskIntoConstraints="NO" id="HoS-AU-9Xu">
+                                        <rect key="frame" x="12" y="59" width="40" height="40"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="40" id="ahR-zj-ifd"/>
+                                            <constraint firstAttribute="width" constant="40" id="qep-w8-8cv"/>
+                                        </constraints>
+                                    </imageView>
+                                    <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="gRy-bX-ROl">
+                                        <rect key="frame" x="62" y="58" width="0.0" height="21"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="21" id="bqC-gq-peK"/>
+                                        </constraints>
+                                        <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                                        <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" horizontalCompressionResistancePriority="752" image="merge_next" translatesAutoresizingMaskIntoConstraints="NO" id="Sa1-UP-VsZ">
+                                        <rect key="frame" x="268" y="73" width="12" height="12"/>
+                                        <constraints>
+                                            <constraint firstAttribute="width" constant="12" id="BpF-1U-NnJ"/>
+                                            <constraint firstAttribute="height" constant="12" id="cX3-gL-Fr8"/>
+                                        </constraints>
+                                    </imageView>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="749" text="" textAlignment="natural" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RGo-uj-cZC">
+                                        <rect key="frame" x="62" y="83" width="0.0" height="17"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="17" id="rqY-aO-o1b"/>
+                                        </constraints>
+                                        <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                                        <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <view contentMode="scaleToFill" horizontalCompressionResistancePriority="752" translatesAutoresizingMaskIntoConstraints="NO" id="drt-My-D0t">
+                                        <rect key="frame" x="67" y="83" width="8" 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="Mey-Xj-mmX">
+                                                <rect key="frame" x="4" y="8.6666666666666714" width="0.0" height="0.0"/>
+                                                <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="XF5-8r-fEl"/>
+                                            <constraint firstItem="Mey-Xj-mmX" firstAttribute="centerY" secondItem="drt-My-D0t" secondAttribute="centerY" id="aC3-vI-T6x"/>
+                                            <constraint firstItem="Mey-Xj-mmX" firstAttribute="leading" secondItem="drt-My-D0t" secondAttribute="leading" constant="4" id="lhh-pn-QD0"/>
+                                            <constraint firstAttribute="trailing" secondItem="Mey-Xj-mmX" secondAttribute="trailing" constant="4" id="v46-hj-Rkg"/>
+                                        </constraints>
+                                        <userDefinedRuntimeAttributes>
+                                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                <real key="value" value="4"/>
+                                            </userDefinedRuntimeAttribute>
+                                        </userDefinedRuntimeAttributes>
+                                    </view>
+                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Sta-67-USN">
+                                        <rect key="frame" x="67" y="59.666666666666657" width="36" height="18"/>
+                                        <constraints>
+                                            <constraint firstAttribute="width" constant="36" id="G8H-lt-3Tu"/>
+                                            <constraint firstAttribute="height" constant="18" id="cpK-rP-URc"/>
+                                        </constraints>
+                                    </imageView>
+                                    <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LoT-BK-0di">
+                                        <rect key="frame" x="218" y="12" width="62" height="22"/>
+                                        <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="22" id="ae9-jw-tHc"/>
+                                            <constraint firstAttribute="width" constant="62" id="qy7-Kr-ynt"/>
+                                        </constraints>
+                                        <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
+                                        <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="11"/>
+                                            </userDefinedRuntimeAttribute>
+                                        </userDefinedRuntimeAttributes>
+                                    </button>
+                                </subviews>
+                                <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                                <constraints>
+                                    <constraint firstAttribute="trailing" secondItem="LoT-BK-0di" secondAttribute="trailing" constant="12" id="3Jw-qQ-51b"/>
+                                    <constraint firstItem="drt-My-D0t" firstAttribute="leading" secondItem="RGo-uj-cZC" secondAttribute="trailing" constant="5" id="3fY-QR-qYD"/>
+                                    <constraint firstItem="Sta-67-USN" firstAttribute="centerY" secondItem="gRy-bX-ROl" secondAttribute="centerY" id="7Ni-vZ-Xzm"/>
+                                    <constraint firstItem="Sa1-UP-VsZ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="drt-My-D0t" secondAttribute="trailing" constant="5" id="Aoi-ZV-feJ"/>
+                                    <constraint firstItem="ZYo-j3-z1x" firstAttribute="leading" secondItem="sqA-d1-zSQ" secondAttribute="trailing" constant="7" id="E5t-0T-7e8"/>
+                                    <constraint firstAttribute="trailing" secondItem="Sa1-UP-VsZ" secondAttribute="trailing" constant="12" id="E6J-hS-iYJ"/>
+                                    <constraint firstItem="RGo-uj-cZC" firstAttribute="top" secondItem="gRy-bX-ROl" secondAttribute="bottom" constant="4" id="Jo2-75-YiS"/>
+                                    <constraint firstItem="sqA-d1-zSQ" firstAttribute="leading" secondItem="iLa-EZ-zRx" secondAttribute="leading" constant="12" id="LAe-M7-WH4"/>
+                                    <constraint firstAttribute="trailing" secondItem="gqH-Nk-A1o" secondAttribute="trailing" constant="10" id="NZX-6q-dw0"/>
+                                    <constraint firstItem="gqH-Nk-A1o" firstAttribute="top" secondItem="sqA-d1-zSQ" secondAttribute="bottom" constant="15" id="RJ7-H0-2yF"/>
+                                    <constraint firstItem="HoS-AU-9Xu" firstAttribute="leading" secondItem="iLa-EZ-zRx" secondAttribute="leading" constant="12" id="SOH-Yn-Lga"/>
+                                    <constraint firstItem="ppo-xJ-iwM" firstAttribute="centerY" secondItem="ZYo-j3-z1x" secondAttribute="centerY" id="Zsf-Pt-Ca2"/>
+                                    <constraint firstAttribute="bottom" secondItem="Sa1-UP-VsZ" secondAttribute="bottom" constant="26" id="aS1-rw-Wih"/>
+                                    <constraint firstItem="LoT-BK-0di" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="ZYo-j3-z1x" secondAttribute="trailing" constant="5" id="ach-gw-EIT"/>
+                                    <constraint firstItem="Sa1-UP-VsZ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Sta-67-USN" secondAttribute="trailing" constant="5" id="bCe-97-Chy"/>
+                                    <constraint firstItem="LoT-BK-0di" firstAttribute="top" secondItem="iLa-EZ-zRx" secondAttribute="top" constant="12" id="eBk-gi-6zc"/>
+                                    <constraint firstItem="gqH-Nk-A1o" firstAttribute="leading" secondItem="iLa-EZ-zRx" secondAttribute="leading" constant="10" id="eUd-64-Goa"/>
+                                    <constraint firstItem="gRy-bX-ROl" firstAttribute="top" secondItem="HoS-AU-9Xu" secondAttribute="top" constant="-1" id="efS-dz-5Nl"/>
+                                    <constraint firstItem="drt-My-D0t" firstAttribute="centerY" secondItem="RGo-uj-cZC" secondAttribute="centerY" id="f1N-WP-1bZ"/>
+                                    <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="drt-My-D0t" secondAttribute="trailing" constant="12" id="hyC-mw-Zs0"/>
+                                    <constraint firstAttribute="trailing" secondItem="ppo-xJ-iwM" secondAttribute="trailing" constant="12" id="k1b-fC-hlN"/>
+                                    <constraint firstItem="gRy-bX-ROl" firstAttribute="leading" secondItem="HoS-AU-9Xu" secondAttribute="trailing" constant="10" id="kDm-en-hLE"/>
+                                    <constraint firstItem="sqA-d1-zSQ" firstAttribute="top" secondItem="iLa-EZ-zRx" secondAttribute="top" constant="15" id="p83-xS-z25"/>
+                                    <constraint firstItem="ZYo-j3-z1x" firstAttribute="centerY" secondItem="sqA-d1-zSQ" secondAttribute="centerY" id="qe2-nZ-cdT"/>
+                                    <constraint firstItem="RGo-uj-cZC" firstAttribute="leading" secondItem="gRy-bX-ROl" secondAttribute="leading" id="rKF-mN-Y0Y"/>
+                                    <constraint firstAttribute="bottom" secondItem="HoS-AU-9Xu" secondAttribute="bottom" constant="12" id="tEa-Zs-UqB"/>
+                                    <constraint firstItem="Sta-67-USN" firstAttribute="leading" secondItem="gRy-bX-ROl" secondAttribute="trailing" constant="5" id="xs5-jm-4XI"/>
+                                    <constraint firstItem="HoS-AU-9Xu" firstAttribute="top" secondItem="gqH-Nk-A1o" secondAttribute="bottom" constant="12" id="xuv-B6-fks"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="10"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qeE-Ft-83e">
+                                <rect key="frame" x="12" y="111" width="268" height="54"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="严琦老师带您零基础学习大号,通过4节课的学习掌握大号演奏的基本方式,培养良好的吐息习惯。" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vGB-9D-omH">
+                                        <rect key="frame" x="7" y="6" width="254" height="42"/>
+                                        <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" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="trailing" secondItem="vGB-9D-omH" secondAttribute="trailing" constant="7" id="DLq-xj-fag"/>
+                                    <constraint firstItem="vGB-9D-omH" firstAttribute="top" secondItem="qeE-Ft-83e" secondAttribute="top" constant="6" id="Z09-cf-MNg"/>
+                                    <constraint firstAttribute="bottom" secondItem="vGB-9D-omH" secondAttribute="bottom" constant="6" id="fJp-91-trb"/>
+                                    <constraint firstItem="vGB-9D-omH" firstAttribute="leading" secondItem="qeE-Ft-83e" secondAttribute="leading" constant="7" id="jKA-Ho-vFW"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="6"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <constraints>
+                            <constraint firstItem="iLa-EZ-zRx" firstAttribute="leading" secondItem="LWM-GL-2PH" secondAttribute="leading" id="0Cf-dH-Khh"/>
+                            <constraint firstItem="qeE-Ft-83e" firstAttribute="leading" secondItem="LWM-GL-2PH" secondAttribute="leading" constant="12" id="DbI-ss-oAn"/>
+                            <constraint firstItem="iLa-EZ-zRx" firstAttribute="top" secondItem="LWM-GL-2PH" secondAttribute="top" id="L5s-Id-E27"/>
+                            <constraint firstAttribute="trailing" secondItem="qeE-Ft-83e" secondAttribute="trailing" constant="12" id="ZcC-r7-XNd"/>
+                            <constraint firstAttribute="trailing" secondItem="iLa-EZ-zRx" secondAttribute="trailing" id="mfx-s6-tdv"/>
+                            <constraint firstItem="qeE-Ft-83e" firstAttribute="top" secondItem="iLa-EZ-zRx" secondAttribute="bottom" id="rM8-gQ-B7T"/>
+                            <constraint firstAttribute="bottom" secondItem="qeE-Ft-83e" secondAttribute="bottom" constant="12" id="uTX-mt-T4L"/>
+                        </constraints>
+                    </view>
+                </subviews>
+                <constraints>
+                    <constraint firstItem="LWM-GL-2PH" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="3ne-Oq-aif"/>
+                    <constraint firstAttribute="trailing" secondItem="LWM-GL-2PH" secondAttribute="trailing" constant="14" id="Js8-9I-hdI"/>
+                    <constraint firstAttribute="bottom" secondItem="LWM-GL-2PH" secondAttribute="bottom" constant="12" id="P4t-7v-kiq"/>
+                    <constraint firstItem="LWM-GL-2PH" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="gfz-hv-2lh"/>
+                </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="arriveStatus" destination="Sta-67-USN" id="AzA-fm-0EI"/>
+                <outlet property="arriveStatusWidth" destination="G8H-lt-3Tu" id="IXD-CG-QGz"/>
+                <outlet property="coursPlanLabel" destination="vGB-9D-omH" id="2bk-vl-lGD"/>
+                <outlet property="courseGroupName" destination="gRy-bX-ROl" id="Qmi-4e-GSd"/>
+                <outlet property="enterButton" destination="LoT-BK-0di" id="mAz-tk-FWv"/>
+                <outlet property="nameLabel" destination="RGo-uj-cZC" id="fsp-J1-2MS"/>
+                <outlet property="statusLabel" destination="ppo-xJ-iwM" id="Pvp-Q0-2WW"/>
+                <outlet property="subjectLabel" destination="Mey-Xj-mmX" id="hj8-RB-ATf"/>
+                <outlet property="subjectView" destination="drt-My-D0t" id="uLE-77-rMO"/>
+                <outlet property="timeLabel" destination="ZYo-j3-z1x" id="4sI-nh-mmz"/>
+            </connections>
+            <point key="canvasLocation" x="42.748091603053432" y="98.943661971830991"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="course_group" width="40" height="40"/>
+        <image name="course_time" width="16" height="16"/>
+        <image name="merge_next" width="14" height="14"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 2 - 2
KulexiuForTeacher/KulexiuForTeacher/Module/Course/VIPCourse/Controller/VipCouseDetailViewController.m

@@ -81,8 +81,8 @@
     [KSNetworkingManager selectRoomConfigRequest:KS_GET success:^(NSDictionary * _Nonnull dic) {
         if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
             NSDictionary *result = [dic ks_dictionaryValueForKey:@"data"];
-            self.joinRoomBeforeTime = [result ks_integerValueForKey:@"practiceStartTime"];
-            self.quitRomeEndTime = [result ks_integerValueForKey:@"practiceEndTime"];
+            self.joinRoomBeforeTime = [result ks_integerValueForKey:@"vipStartTime"];
+            self.quitRomeEndTime = [result ks_integerValueForKey:@"vipEndTime"];
         }
         else {
             [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/VIPCourse/Model/GroupCourseListModel.h

@@ -21,6 +21,7 @@
 @property (nonatomic, strong) NSString *courseGroupName;
 @property (nonatomic, assign) BOOL attendanceStatus;
 @property (nonatomic, strong) NSString *subjectName;
+@property (nonatomic, strong) NSString *coursePlan;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
 - (instancetype)initWithDictionary:(NSDictionary *)dict;

+ 7 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Course/VIPCourse/Model/GroupCourseListModel.m

@@ -18,6 +18,7 @@ NSString *const kGroupCourseListModelStartTime = @"startTime";
 NSString *const kGroupCourseListModelCourseGroupName = @"courseGroupName";
 NSString *const kGroupCourseListModelAttendanceStatus = @"attendanceStatus";
 NSString *const kGroupCourseListModelSubjectName = @"subjectName";
+NSString *const kGroupCourseListModelCoursePlan = @"coursePlan";
 
 @interface GroupCourseListModel ()
 
@@ -37,6 +38,7 @@ NSString *const kGroupCourseListModelSubjectName = @"subjectName";
 @synthesize courseGroupName = _courseGroupName;
 @synthesize attendanceStatus = _attendanceStatus;
 @synthesize subjectName = _subjectName;
+@synthesize coursePlan = _coursePlan;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
 {
@@ -74,6 +76,7 @@ NSString *const kGroupCourseListModelSubjectName = @"subjectName";
 
     }
     self.subjectName = [self objectOrNilForKey:kGroupCourseListModelSubjectName fromDictionary:dict];
+    self.coursePlan = [self objectOrNilForKey:kGroupCourseListModelCoursePlan fromDictionary:dict];
     return self;
     
 }
@@ -101,7 +104,7 @@ NSString *const kGroupCourseListModelSubjectName = @"subjectName";
     [mutableDict setValue:self.courseGroupName forKey:kGroupCourseListModelCourseGroupName];
     [mutableDict setValue:[NSNumber numberWithBool:self.attendanceStatus] forKey:kGroupCourseListModelAttendanceStatus];
     [mutableDict setValue:self.subjectName forKey:kGroupCourseListModelSubjectName];
-    
+    [mutableDict setValue:self.coursePlan forKey:kGroupCourseListModelCoursePlan];
     return [NSDictionary dictionaryWithDictionary:mutableDict];
 }
 
@@ -138,6 +141,7 @@ NSString *const kGroupCourseListModelSubjectName = @"subjectName";
     self.courseGroupName = [aDecoder decodeObjectForKey:kGroupCourseListModelCourseGroupName];
     self.attendanceStatus = [aDecoder decodeBoolForKey:kGroupCourseListModelAttendanceStatus];
     self.subjectName = [aDecoder decodeObjectForKey:kGroupCourseListModelSubjectName];
+    self.coursePlan = [aDecoder decodeObjectForKey:kGroupCourseListModelCoursePlan];
     return self;
 }
 
@@ -154,6 +158,7 @@ NSString *const kGroupCourseListModelSubjectName = @"subjectName";
     [aCoder encodeObject:_courseGroupName forKey:kGroupCourseListModelCourseGroupName];
     [aCoder encodeBool:_attendanceStatus forKey:kGroupCourseListModelAttendanceStatus];
     [aCoder encodeObject:_subjectName forKey:kGroupCourseListModelSubjectName];
+    [aCoder encodeObject:_coursePlan forKey:kGroupCourseListModelCoursePlan];
 }
 
 - (id)copyWithZone:(NSZone *)zone
@@ -172,6 +177,7 @@ NSString *const kGroupCourseListModelSubjectName = @"subjectName";
         copy.courseGroupName = [self.courseGroupName copyWithZone:zone];
         copy.attendanceStatus = self.attendanceStatus;
         copy.subjectName = [self.subjectName copyWithZone:zone];
+        copy.coursePlan = [self.coursePlan copyWithZone:zone];
     }
     
     return copy;

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Course/VIPCourse/View/ProgramCourseGroupBodyView.h

@@ -11,6 +11,7 @@ typedef NS_ENUM(NSInteger, COURSE_GROUP_TYPE) {
     COURSE_GROUP_TYPE_VIP,
     COURSE_GROUP_TYPE_ACCOMPANY,
     COURSE_GROUP_TYPE_MUSICROOM,
+    COURSE_GROUP_TYPE_GROUP,
 };
 
 NS_ASSUME_NONNULL_BEGIN

+ 10 - 15
KulexiuForTeacher/KulexiuForTeacher/Module/Course/VIPCourse/View/ProgramCourseGroupBodyView.m

@@ -20,6 +20,7 @@
 #import "RecordCheckManager.h"
 #import <KSFullDatePicker.h>
 #import "KSSmallChoosePicker.h"
+#import "GroupCourseListCell.h"
 
 @interface ProgramCourseGroupBodyView ()<UITableViewDelegate,UITableViewDataSource>
 
@@ -73,6 +74,7 @@
         self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
         [self.tableView registerNib:[UINib nibWithNibName:@"ProgramCourseListCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"ProgramCourseListCell"];
         [self.tableView registerNib:[UINib nibWithNibName:@"MusicRoomCourseListCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"MusicRoomCourseListCell"];
+        [self.tableView registerNib:[UINib nibWithNibName:@"GroupCourseListCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"GroupCourseListCell"];
         
         UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, iPhoneXSafeBottomMargin)];
         bottomView.backgroundColor = [UIColor clearColor];
@@ -127,21 +129,6 @@
     });
 }
 
-- (void)requestRoomConfig {
-    [KSNetworkingManager selectRoomConfigRequest:KS_GET success:^(NSDictionary * _Nonnull dic) {
-        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
-            NSDictionary *result = [dic ks_dictionaryValueForKey:@"data"];
-            self.joinRoomBeforeTime = [result ks_integerValueForKey:@"practiceStartTime"];
-            self.quitRomeEndTime = [result ks_integerValueForKey:@"practiceEndTime"];
-        }
-        else {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
-        }
-    } faliure:^(NSError * _Nonnull error) {
-        
-    }];
-}
-
 - (void)requestData {
     [KSNetworkingManager courseScheduleListRequest:KS_POST courseGroupId:self.courseGroupId classMonth:self.classDate attendanceStatus:self.attendanceStatus courseStatus:self.courseStatus success:^(NSDictionary * _Nonnull dic) {
         [self endRefresh];
@@ -235,6 +222,14 @@
         }];
         return cell;
     }
+    else if (self.courseType == COURSE_GROUP_TYPE_GROUP) {
+        GroupCourseListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"GroupCourseListCell"];
+        MJWeakSelf;
+        [cell configWithSource:model beforeTime:self.enterStartTime callback:^(GroupCourseListModel * _Nonnull model) {
+            [weakSelf enterClassRoom:model];
+        }];
+        return cell;
+    }
     else {
         MusicRoomCourseListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MusicRoomCourseListCell"];
         MJWeakSelf;

+ 2 - 2
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/Controller/MyCourseViewController.m

@@ -86,7 +86,7 @@
     self.categoryView.titleSelectedColor = HexRGB(0x333333);
     self.categoryView.titleColor = HexRGB(0x666666);
     self.categoryView.titleColorGradientEnabled = YES;
-    self.categoryView.cellSpacing = 10.0f;
+//    self.categoryView.cellSpacing = 10.0f;
     
     JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init];
     lineView.indicatorHeight = 4.0f;
@@ -350,7 +350,7 @@
 
 - (NSMutableArray *)listViewArray {
     if (!_listViewArray) {
-        _listViewArray = [NSMutableArray arrayWithArray:@[@"",@"",@"",@"",@""]];
+        _listViewArray = [NSMutableArray arrayWithArray:@[@"",@"",@"",@"",@"",@""]];
     }
     return _listViewArray;
 }

+ 6 - 6
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/GroupCourseGroup/MyGroupCourseGroupView.m

@@ -12,6 +12,7 @@
 #import "Reachability.h"
 #import "LiveLessonModel.h"
 #import "MyCourseRankSortView.h"
+#import "GroupCourseGroupViewController.h"
 
 @interface MyGroupCourseGroupView ()<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
 @property (nonatomic, strong) NSMutableArray *dataArray;
@@ -61,7 +62,7 @@
         self.collectionView.dataSource = self;
         self.collectionView.showsVerticalScrollIndicator = NO;
         self.collectionView.showsHorizontalScrollIndicator = NO;
-        [self.collectionView registerNib:[UINib nibWithNibName:@"MyLiveCourseGroupListCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:@"MyLiveCourseGroupListCell"];
+        [self.collectionView registerNib:[UINib nibWithNibName:@"MyGroupCourseGroupListCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:@"MyGroupCourseGroupListCell"];
         [self addSubview:self.collectionView];
         self.collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
         MJWeakSelf;
@@ -197,11 +198,10 @@
 }
 
 - (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];
+    LiveLessonModel *model = self.dataArray[indexPath.row];
+    GroupCourseGroupViewController *ctrl = [[GroupCourseGroupViewController alloc] init];
+    ctrl.courseGroupId = model.courseGroupId;
+    [self.naviController pushViewController:ctrl animated:YES];
 }
 
 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

+ 2 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Home/MyCourse/View/MyCourseSortView/MyCourseRankSortView.m

@@ -192,8 +192,9 @@
                 topHeight += (buttonHeight + topSpace);
             }
         }
-        topHeight += 18; // 底部区域
     }
+    topHeight += 18; // 底部区域
+
     if (topHeight > 303) {
         topHeight = 303.0f;
     }