Steven 2 年之前
父節點
當前提交
6adb27fda6
共有 25 個文件被更改,包括 1443 次插入60 次删除
  1. 68 0
      KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj
  2. 二進制
      KulexiuForTeacher/KulexiuForTeacher.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate
  3. 10 10
      KulexiuForTeacher/KulexiuForTeacher.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  4. 183 49
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LiveRoomViewController.m
  5. 3 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSChatroomMessageCenter.h
  6. 3 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSChatroomMessageCenter.m
  7. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSDownSeatAllMessage.h
  8. 39 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSDownSeatAllMessage.m
  9. 17 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSRejectAllSeatMessage.h
  10. 39 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSRejectAllSeatMessage.m
  11. 33 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/RCChatroomSeatsControl.h
  12. 50 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/RCChatroomSeatsControl.m
  13. 31 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveApplyControlView.h
  14. 68 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveApplyControlView.m
  15. 87 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveApplyControlView.xib
  16. 23 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveDownSeatView.h
  17. 44 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveDownSeatView.m
  18. 57 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveDownSeatView.xib
  19. 26 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveMemberSeatCell.h
  20. 68 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveMemberSeatCell.m
  21. 95 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveMemberSeatCell.xib
  22. 33 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveSeatActionView.h
  23. 201 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveSeatActionView.m
  24. 35 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/SeatBodyView.h
  25. 213 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/SeatBodyView.m

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

@@ -435,6 +435,17 @@
 		BC0238062865C4F6005560CA /* KSLiveChatroomMemberUp.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0238052865C4F6005560CA /* KSLiveChatroomMemberUp.m */; };
 		BC0238092865C601005560CA /* KSRCShopRushMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0238082865C601005560CA /* KSRCShopRushMessage.m */; };
 		BC02380F2865C6F9005560CA /* RCChatroomLikeCount.m in Sources */ = {isa = PBXBuildFile; fileRef = BC02380D2865C6F9005560CA /* RCChatroomLikeCount.m */; };
+		BC02BCDA28B3243F005CB483 /* LiveSeatActionView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC02BCD928B3243F005CB483 /* LiveSeatActionView.m */; };
+		BC02BCDD28B324A5005CB483 /* SeatBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC02BCDC28B324A5005CB483 /* SeatBodyView.m */; };
+		BC02BCE428B324C9005CB483 /* LiveApplyControlView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC02BCDE28B324C8005CB483 /* LiveApplyControlView.m */; };
+		BC02BCE528B324C9005CB483 /* LiveApplyControlView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC02BCDF28B324C8005CB483 /* LiveApplyControlView.xib */; };
+		BC02BCE628B324C9005CB483 /* LiveDownSeatView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC02BCE228B324C9005CB483 /* LiveDownSeatView.m */; };
+		BC02BCE728B324C9005CB483 /* LiveDownSeatView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC02BCE328B324C9005CB483 /* LiveDownSeatView.xib */; };
+		BC02BCEB28B324FE005CB483 /* LiveMemberSeatCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC02BCE928B324FD005CB483 /* LiveMemberSeatCell.m */; };
+		BC02BCEC28B324FE005CB483 /* LiveMemberSeatCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC02BCEA28B324FD005CB483 /* LiveMemberSeatCell.xib */; };
+		BC02BCF128B32771005CB483 /* KSDownSeatAllMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BC02BCEF28B32770005CB483 /* KSDownSeatAllMessage.m */; };
+		BC02BCF228B32771005CB483 /* KSRejectAllSeatMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = BC02BCF028B32771005CB483 /* KSRejectAllSeatMessage.m */; };
+		BC02BCF528B328AA005CB483 /* RCChatroomSeatsControl.m in Sources */ = {isa = PBXBuildFile; fileRef = BC02BCF328B328A9005CB483 /* RCChatroomSeatsControl.m */; };
 		BC063D842823CEFE000EB350 /* AddressListModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC063D822823CEFD000EB350 /* AddressListModel.m */; };
 		BC0A2282284751DF0065C1AB /* MetronomeAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0A2278284751DF0065C1AB /* MetronomeAlertView.m */; };
 		BC0A2283284751DF0065C1AB /* MetronomeControlView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0A227B284751DF0065C1AB /* MetronomeControlView.m */; };
@@ -1807,6 +1818,25 @@
 		BC0238082865C601005560CA /* KSRCShopRushMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSRCShopRushMessage.m; sourceTree = "<group>"; };
 		BC02380D2865C6F9005560CA /* RCChatroomLikeCount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCChatroomLikeCount.m; sourceTree = "<group>"; };
 		BC02380E2865C6F9005560CA /* RCChatroomLikeCount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCChatroomLikeCount.h; sourceTree = "<group>"; };
+		BC02BCD828B3243F005CB483 /* LiveSeatActionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveSeatActionView.h; sourceTree = "<group>"; };
+		BC02BCD928B3243F005CB483 /* LiveSeatActionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiveSeatActionView.m; sourceTree = "<group>"; };
+		BC02BCDB28B324A5005CB483 /* SeatBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SeatBodyView.h; sourceTree = "<group>"; };
+		BC02BCDC28B324A5005CB483 /* SeatBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SeatBodyView.m; sourceTree = "<group>"; };
+		BC02BCDE28B324C8005CB483 /* LiveApplyControlView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveApplyControlView.m; sourceTree = "<group>"; };
+		BC02BCDF28B324C8005CB483 /* LiveApplyControlView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LiveApplyControlView.xib; sourceTree = "<group>"; };
+		BC02BCE028B324C8005CB483 /* LiveApplyControlView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveApplyControlView.h; sourceTree = "<group>"; };
+		BC02BCE128B324C8005CB483 /* LiveDownSeatView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveDownSeatView.h; sourceTree = "<group>"; };
+		BC02BCE228B324C9005CB483 /* LiveDownSeatView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveDownSeatView.m; sourceTree = "<group>"; };
+		BC02BCE328B324C9005CB483 /* LiveDownSeatView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LiveDownSeatView.xib; sourceTree = "<group>"; };
+		BC02BCE828B324FD005CB483 /* LiveMemberSeatCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveMemberSeatCell.h; sourceTree = "<group>"; };
+		BC02BCE928B324FD005CB483 /* LiveMemberSeatCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveMemberSeatCell.m; sourceTree = "<group>"; };
+		BC02BCEA28B324FD005CB483 /* LiveMemberSeatCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LiveMemberSeatCell.xib; sourceTree = "<group>"; };
+		BC02BCED28B32770005CB483 /* KSRejectAllSeatMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSRejectAllSeatMessage.h; sourceTree = "<group>"; };
+		BC02BCEE28B32770005CB483 /* KSDownSeatAllMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSDownSeatAllMessage.h; sourceTree = "<group>"; };
+		BC02BCEF28B32770005CB483 /* KSDownSeatAllMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSDownSeatAllMessage.m; sourceTree = "<group>"; };
+		BC02BCF028B32771005CB483 /* KSRejectAllSeatMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSRejectAllSeatMessage.m; sourceTree = "<group>"; };
+		BC02BCF328B328A9005CB483 /* RCChatroomSeatsControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCChatroomSeatsControl.m; sourceTree = "<group>"; };
+		BC02BCF428B328A9005CB483 /* RCChatroomSeatsControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCChatroomSeatsControl.h; sourceTree = "<group>"; };
 		BC063D822823CEFD000EB350 /* AddressListModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddressListModel.m; sourceTree = "<group>"; };
 		BC063D832823CEFE000EB350 /* AddressListModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddressListModel.h; sourceTree = "<group>"; };
 		BC0A2278284751DF0065C1AB /* MetronomeAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MetronomeAlertView.m; sourceTree = "<group>"; };
@@ -2895,6 +2925,12 @@
 				BC0238082865C601005560CA /* KSRCShopRushMessage.m */,
 				BC02380E2865C6F9005560CA /* RCChatroomLikeCount.h */,
 				BC02380D2865C6F9005560CA /* RCChatroomLikeCount.m */,
+				BC02BCF428B328A9005CB483 /* RCChatroomSeatsControl.h */,
+				BC02BCF328B328A9005CB483 /* RCChatroomSeatsControl.m */,
+				BC02BCEE28B32770005CB483 /* KSDownSeatAllMessage.h */,
+				BC02BCEF28B32770005CB483 /* KSDownSeatAllMessage.m */,
+				BC02BCED28B32770005CB483 /* KSRejectAllSeatMessage.h */,
+				BC02BCF028B32771005CB483 /* KSRejectAllSeatMessage.m */,
 			);
 			path = LiveRoomMessage;
 			sourceTree = "<group>";
@@ -4304,6 +4340,7 @@
 		27D83F4627F3EBAA00062476 /* View */ = {
 			isa = PBXGroup;
 			children = (
+				BC02BCD728B32418005CB483 /* SeatListView */,
 				BCD457B82865652C0010B493 /* AnimationView */,
 				BCD457B3286565190010B493 /* LiveMoreDisplayView.h */,
 				BCD457B52865651A0010B493 /* LiveMoreDisplayView.m */,
@@ -4748,6 +4785,26 @@
 			path = View;
 			sourceTree = "<group>";
 		};
+		BC02BCD728B32418005CB483 /* SeatListView */ = {
+			isa = PBXGroup;
+			children = (
+				BC02BCD828B3243F005CB483 /* LiveSeatActionView.h */,
+				BC02BCD928B3243F005CB483 /* LiveSeatActionView.m */,
+				BC02BCDB28B324A5005CB483 /* SeatBodyView.h */,
+				BC02BCDC28B324A5005CB483 /* SeatBodyView.m */,
+				BC02BCE028B324C8005CB483 /* LiveApplyControlView.h */,
+				BC02BCDE28B324C8005CB483 /* LiveApplyControlView.m */,
+				BC02BCDF28B324C8005CB483 /* LiveApplyControlView.xib */,
+				BC02BCE128B324C8005CB483 /* LiveDownSeatView.h */,
+				BC02BCE228B324C9005CB483 /* LiveDownSeatView.m */,
+				BC02BCE328B324C9005CB483 /* LiveDownSeatView.xib */,
+				BC02BCE828B324FD005CB483 /* LiveMemberSeatCell.h */,
+				BC02BCE928B324FD005CB483 /* LiveMemberSeatCell.m */,
+				BC02BCEA28B324FD005CB483 /* LiveMemberSeatCell.xib */,
+			);
+			path = SeatListView;
+			sourceTree = "<group>";
+		};
 		BC0A2277284751DF0065C1AB /* MetronomeView */ = {
 			isa = PBXGroup;
 			children = (
@@ -6748,6 +6805,7 @@
 				BCEA752D2819134400886A86 /* CardBindResultBodyView.xib in Resources */,
 				BC1365BD280D163200EB03E2 /* MyVideoSearchView.xib in Resources */,
 				BC14A61428A0AC880086395C /* MineTeachToolView.xib in Resources */,
+				BC02BCEC28B324FE005CB483 /* LiveMemberSeatCell.xib in Resources */,
 				27F9030127E864AE00C08A19 /* NetworkBodyView.xib in Resources */,
 				BCB14112288A49710022C13A /* HomeButtonView.xib in Resources */,
 				BC4BCE7F2823B66A00522C8B /* AddressDetailBodyView.xib in Resources */,
@@ -6811,6 +6869,7 @@
 				275E3DE927F4679E0010EC30 /* LiveRoomHeadView.xib in Resources */,
 				BC6BEAA3288A4C2A00022109 /* KSHomeButton.xib in Resources */,
 				BCC5840928A9FA8100BAB4CF /* cloud_animation_11.png in Resources */,
+				BC02BCE528B324C9005CB483 /* LiveApplyControlView.xib in Resources */,
 				27D83F4E27F3EC2100062476 /* CreateLiveBodyView.xib in Resources */,
 				BCEA75282819103B00886A86 /* UnbindBodyView.xib in Resources */,
 				BC8B6E602856ED0600866917 /* WeiboSDK.bundle in Resources */,
@@ -6980,6 +7039,7 @@
 				BCF61BDE280417190000ACFE /* MyStyleVideoView.xib in Resources */,
 				BC513E7C28A4D868003F58C4 /* musicRoom_animation.json in Resources */,
 				BCC03F89280460C000461B7C /* InstrumentHeaderView.xib in Resources */,
+				BC02BCE728B324C9005CB483 /* LiveDownSeatView.xib in Resources */,
 				BCD6D16728195A98009A773E /* WithdrawApplyBodyView.xib in Resources */,
 				BC5EB5BC2804083800B4A3B0 /* MyStyleIntroduceCell.xib in Resources */,
 				BC71D1FC2887FDD40010F14B /* img_25.png in Resources */,
@@ -7103,6 +7163,7 @@
 				277931CD27E30FC20010E277 /* KSPremissionAlert.m in Sources */,
 				2779323927E30FC30010E277 /* LLCollectionViewCell.m in Sources */,
 				2779326A27E30FD80010E277 /* FSCalendarWeekdayView.m in Sources */,
+				BC02BCF228B32771005CB483 /* KSRejectAllSeatMessage.m in Sources */,
 				2723B69127F1803F00E0B90B /* HomeHeadView.m in Sources */,
 				BCDB0931280583C100D0BDAD /* NSObject+KSDateFormatter.m in Sources */,
 				BC4BCE702823A02F00522C8B /* AddressBottomView.m in Sources */,
@@ -7185,6 +7246,7 @@
 				277932E627E310070010E277 /* TZVideoPlayerController.m in Sources */,
 				BC4BCE752823A1AE00522C8B /* AddressDetailViewController.m in Sources */,
 				BCDB093E2805C0EF00D0BDAD /* NewClassPopCell.m in Sources */,
+				BC02BCDD28B324A5005CB483 /* SeatBodyView.m in Sources */,
 				BCC9F41B27F69BD200647449 /* RecentSharedWhiteboardCell.m in Sources */,
 				BCB635B627F6FB0A00ACFDCF /* SeatTipsView.m in Sources */,
 				BCB9FA672872C8F0005D766B /* FinishedLiveCell.m in Sources */,
@@ -7270,6 +7332,7 @@
 				2755C07027EC7F21007D9070 /* ChatComplainBodyView.m in Sources */,
 				2755C06727EC71BB007D9070 /* GroupSettingBodyView.m in Sources */,
 				BCA353DF285976CF00377661 /* MusicRoomCourseInfoCell.m in Sources */,
+				BC02BCEB28B324FE005CB483 /* LiveMemberSeatCell.m in Sources */,
 				BCA9CE2E27FD8A9200D558C6 /* AccompanyNavView.m in Sources */,
 				BCC9F44727F69BD200647449 /* ClassSongMessage.m in Sources */,
 				2728086A27E6C12000DB71EA /* FirstSettingBodyView.m in Sources */,
@@ -7314,6 +7377,7 @@
 				27F9CB0B27EC5C06003E0FE4 /* KSSelectConversationViewController.m in Sources */,
 				BC8B6DBF28532DB800866917 /* MusicSheetVoList.m in Sources */,
 				2755C08D27ED5DB2007D9070 /* GroupApplyChooseCell.m in Sources */,
+				BC02BCF128B32771005CB483 /* KSDownSeatAllMessage.m in Sources */,
 				BCA7C33F284760AB009D20EC /* NSObject+KeyWindow.m in Sources */,
 				2779321A27E30FC30010E277 /* SkipTextView.m in Sources */,
 				277931C927E30FC20010E277 /* DiskFreeSpaceManager.m in Sources */,
@@ -7484,6 +7548,7 @@
 				BCB633F827F6A18200ACFDCF /* KSTipsView.m in Sources */,
 				275E3DF627F467ED0010EC30 /* KSChatroomTextCell.m in Sources */,
 				BC0A22B72847523E0065C1AB /* MemberBottomView.m in Sources */,
+				BC02BCDA28B3243F005CB483 /* LiveSeatActionView.m in Sources */,
 				2779323D27E30FC30010E277 /* VoDiskCache.m in Sources */,
 				BC7CFFC52817F29800CAEB21 /* CashRecordViewController.m in Sources */,
 				277931D727E30FC20010E277 /* UIImage+ResizeImage.m in Sources */,
@@ -7586,6 +7651,7 @@
 				BC6BEAA4288A4C2A00022109 /* KSHomeButton.m in Sources */,
 				27A2F63027E70E57009E2380 /* UserInfo.m in Sources */,
 				BCEA751A2818D59300886A86 /* BankNameModel.m in Sources */,
+				BC02BCE428B324C9005CB483 /* LiveApplyControlView.m in Sources */,
 				277932E827E310070010E277 /* NSBundle+TZImagePicker.m in Sources */,
 				BC8A2CF828476C3000122BBE /* MusicScoreViewController.m in Sources */,
 				BC0A2282284751DF0065C1AB /* MetronomeAlertView.m in Sources */,
@@ -7604,6 +7670,7 @@
 				BCDBC59D286156E700647197 /* LiveRoomViewController.m in Sources */,
 				BCC9F40B27F69BD200647449 /* CREmojiCollectionCell.m in Sources */,
 				2779320927E30FC30010E277 /* KSRecordPowerAnimationView.m in Sources */,
+				BC02BCE628B324C9005CB483 /* LiveDownSeatView.m in Sources */,
 				27BC3B3327F2FD2D00D81E30 /* VideoListBodyView.m in Sources */,
 				BC0A2283284751DF0065C1AB /* MetronomeControlView.m in Sources */,
 				BCFE541028178FF600AD6786 /* MyIncomeViewController.m in Sources */,
@@ -7711,6 +7778,7 @@
 				BC6BEAAA288E3D7400022109 /* HomeNewHeadView.m in Sources */,
 				BCC9F43E27F69BD200647449 /* AccompanyDownloadMessage.m in Sources */,
 				277D431A27E9991200107DB7 /* ModifyViewController.m in Sources */,
+				BC02BCF528B328AA005CB483 /* RCChatroomSeatsControl.m in Sources */,
 				277932EB27E310070010E277 /* TZProgressView.m in Sources */,
 				27BC3B1B27F2B37500D81E30 /* MyMusicBodyView.m in Sources */,
 				275E3DB027F45CA60010EC30 /* KSLiveChatroomLike.m in Sources */,

二進制
KulexiuForTeacher/KulexiuForTeacher.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate


+ 10 - 10
KulexiuForTeacher/KulexiuForTeacher.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -390,8 +390,8 @@
             filePath = "KulexiuForTeacher/Module/Live/Controller/LiveRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "1882"
-            endingLineNumber = "1882"
+            startingLineNumber = "2016"
+            endingLineNumber = "2016"
             landmarkName = "-showAnimationView:showMessag:"
             landmarkType = "7">
          </BreakpointContent>
@@ -585,8 +585,8 @@
             filePath = "KulexiuForTeacher/Module/Live/Controller/LiveRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "1122"
-            endingLineNumber = "1122"
+            startingLineNumber = "1126"
+            endingLineNumber = "1126"
             landmarkName = "-didReceiveMessageNotification:"
             landmarkType = "7">
          </BreakpointContent>
@@ -777,8 +777,8 @@
             filePath = "KulexiuForTeacher/Module/Live/Controller/LiveRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "485"
-            endingLineNumber = "485"
+            startingLineNumber = "489"
+            endingLineNumber = "489"
             landmarkName = "-configTimerManager"
             landmarkType = "7">
          </BreakpointContent>
@@ -857,8 +857,8 @@
             filePath = "KulexiuForTeacher/Module/Live/Controller/LiveRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "401"
-            endingLineNumber = "401"
+            startingLineNumber = "405"
+            endingLineNumber = "405"
             landmarkName = "-setupLiveroomConfig:"
             landmarkType = "7">
          </BreakpointContent>
@@ -873,8 +873,8 @@
             filePath = "KulexiuForTeacher/Module/Live/Controller/LiveRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "423"
-            endingLineNumber = "423"
+            startingLineNumber = "427"
+            endingLineNumber = "427"
             landmarkName = "-setupLiveroomConfig:"
             landmarkType = "7">
          </BreakpointContent>

+ 183 - 49
KulexiuForTeacher/KulexiuForTeacher/Module/Live/Controller/LiveRoomViewController.m

@@ -20,7 +20,6 @@
 #import "LiveRoomHeadView.h"
 #import "LiveRoomBottomView.h"
 #import "SeatContentView.h"
-#import "LiveSeatApplyView.h"
 #import "SeatTipsView.h"
 #import "KSLiveStreamVideo.h"
 #import "KSRCMessageModel.h"
@@ -32,6 +31,7 @@
 #import "KSShareChooseViewController.h"
 #import "KSChatLiveMessage.h"
 
+#import "LiveSeatActionView.h"
 typedef NS_ENUM(NSInteger, LIVEPAGE) {
     LIVEPAGE_PREVIEW,
     LIVEPAGE_LIVE,
@@ -126,7 +126,9 @@ typedef NS_ENUM(NSInteger, LIVEPAGE) {
  */
 @property(nonatomic, assign) BOOL isNeedScrollToButtom;
 
-@property (nonatomic, strong) LiveSeatApplyView *seatApplyView;
+@property (nonatomic, strong) UIView *seatCtrlView;
+
+@property (nonatomic, strong) LiveSeatActionView *seatActionView;
 
 @property (nonatomic, strong) NSMutableArray *seatApplyArray;  // 申请连麦数组
 // 远端连麦用户
@@ -153,6 +155,8 @@ typedef NS_ENUM(NSInteger, LIVEPAGE) {
 
 @property (nonatomic, copy) LiveRoomBackAction callback;
 
+@property (nonatomic, strong)  UITapGestureRecognizer *gesture;
+
 @end
 
 
@@ -1289,7 +1293,7 @@ typedef NS_ENUM(NSInteger, LIVEPAGE) {
     else {
         [self hideSeatTips];
     }
-    [self.seatApplyView refreshSeatApplyTable:self.seatApplyArray];
+    [self.seatActionView refreshSeatApplyTable:self.seatApplyArray];
 }
 
 - (void)showSeatTips:(NSInteger)count {
@@ -1565,7 +1569,7 @@ typedef NS_ENUM(NSInteger, LIVEPAGE) {
     return _seatApplyTips;
 }
 - (void)displaySeatView {
-    [self.view addSubview:self.seatApplyView];
+    [self.view addSubview:self.seatCtrlView];
     [self refreshSeatApplyView];
 }
 
@@ -1717,75 +1721,205 @@ typedef NS_ENUM(NSInteger, LIVEPAGE) {
     return _seatContainer;
 }
 
-- (LiveSeatApplyView *)seatApplyView {
-    if (!_seatApplyView) {
-        _seatApplyView = [LiveSeatApplyView shareInstance];
-        _seatApplyView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
+- (UIView *)seatCtrlView {
+    if (!_seatCtrlView) {
+        _seatCtrlView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, KPortraitHeight)];
+        _seatCtrlView.backgroundColor = [UIColor clearColor];
+        self.gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideSeatCtrlView)];
+        self.gesture.delegate = self;
+        [_seatCtrlView addGestureRecognizer:self.gesture];
+        [_seatCtrlView addSubview:self.seatActionView];
+        UIView *headView = [[UIView alloc] initWithFrame:CGRectMake(0, KPortraitHeight - 300 - iPhoneXSafeBottomMargin - 16, KPortraitWidth, 16)];
+        headView.backgroundColor = [UIColor whiteColor];
+        [_seatCtrlView addSubview:headView];
+        if (@available(iOS 11.0, *)) {
+            headView.layer.cornerRadius = 8;
+            headView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner; // 左上圆角
+        }
+        else {
+            UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:headView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(8, 8)];
+            CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
+            maskLayer.frame = headView.bounds;
+            maskLayer.path = path.CGPath;
+            headView.layer.mask = maskLayer;
+        }
+        
+    }
+    return _seatCtrlView;
+}
+
+- (void)hideSeatCtrlView {
+    if (_seatCtrlView) {
+        [_seatCtrlView removeFromSuperview];
+    }
+}
+
+- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
+    if (gestureRecognizer == self.gesture) {
+        if ([touch.view isDescendantOfView:self.seatActionView]) {
+            return NO;
+        }
+    }
+    
+    return YES;
+}
+
+- (LiveSeatActionView *)seatActionView {
+    if (!_seatActionView) {
+        _seatActionView = [[LiveSeatActionView alloc] initWithFrame:CGRectMake(0, kScreenHeight - 300 - iPhoneXSafeBottomMargin, kScreenWidth, 300 + iPhoneXSafeBottomMargin)];
         MJWeakSelf;
-        [_seatApplyView operationMemberAction:^(LIVESEATACTION action, LiveSeatMember * _Nonnull member) {
-            [weakSelf opreationSeatStudentAction:action member:member];
+        [_seatActionView opreationCallback:^(LIVESECONTROL action, LiveSeatMember * _Nonnull member) {
+            [weakSelf opreationSeatApplyAction:action member:member];
         }];
     }
-    return _seatApplyView;
+    return _seatActionView;
 }
 
-- (void)opreationSeatStudentAction:(LIVESEATACTION)action member:(LiveSeatMember *)member {
-    switch (action) {
-        case LIVESEATACTION_APPROVE: // 同意
+- (void)opreationSeatApplyAction:(LIVESECONTROL)control member:(LiveSeatMember *)member {
+    switch (control) {
+        case LIVESECONTROL_ALLOW: // 允许连麦
         {
-            // 判断连麦人数超过4人 无法点击
-            NSInteger count = [self queryConnectingCount];
-            if (count >= 4) {
-                [self MBPShow:@"最多可连麦4人"];
-                return;
-            }
-            KSLiveChatroomSeatResponse *responseMessage = [[KSLiveChatroomSeatResponse alloc] init];
-            responseMessage.type = SEATRESPONSE_TEACHERAPPROVE;
-            responseMessage.teacherId = self.createrId;
-            responseMessage.teacherName = self.createrName;
-            responseMessage.audienceId = member.userId;
-            responseMessage.audienceName = member.name;
-            MJWeakSelf;
-            [self sendMessage:responseMessage displayMessage:NO callback:^(BOOL success) {
-                [weakSelf refreshSeatArrayRemoveMember:NO member:member];
+            RCChatroomSeatsControl *message = [[RCChatroomSeatsControl alloc] init];
+            message.userId = self.createrId;
+            message.userName = self.createrName;
+            message.seatBan = NO;
+            [self sendMessage:message displayMessage:NO callback:^(BOOL success) {
+                            
             }];
         }
             break;
-        case LIVESEATACTION_REJECT: // 拒绝
+        case LIVESECONTROL_FORBIDDEN: // 禁止连麦
         {
-            KSLiveChatroomSeatResponse *responseMessage = [[KSLiveChatroomSeatResponse alloc] init];
-            responseMessage.type = SEATRESPONSE_TEACHERREJECT;
-            responseMessage.teacherId = self.createrId;
-            responseMessage.teacherName = self.createrName;
-            responseMessage.audienceId = member.userId;
-            responseMessage.audienceName = member.name;
+            RCChatroomSeatsControl *message = [[RCChatroomSeatsControl alloc] init];
+            message.userId = self.createrId;
+            message.userName = self.createrName;
+            message.seatBan = YES;
+            [self sendMessage:message displayMessage:NO callback:^(BOOL success) {
+                            
+            }];
+        }
+            break;
+        case LIVESECONTROL_APPROVE: // 上麦
+        {
+            if (member) {
+                // 判断连麦人数超过4人 无法点击
+                NSInteger count = [self queryConnectingCount];
+                if (count >= 4) {
+                    [self MBPShow:@"最多可连麦4人"];
+                    return;
+                }
+                KSLiveChatroomSeatResponse *responseMessage = [[KSLiveChatroomSeatResponse alloc] init];
+                responseMessage.type = SEATRESPONSE_TEACHERAPPROVE;
+                responseMessage.teacherId = self.createrId;
+                responseMessage.teacherName = self.createrName;
+                responseMessage.audienceId = member.userId;
+                responseMessage.audienceName = member.name;
+                MJWeakSelf;
+                [self sendMessage:responseMessage displayMessage:NO callback:^(BOOL success) {
+                    [weakSelf refreshSeatArrayRemoveMember:NO member:member];
+                }];
+            }
+        }
+            break;
+        case LIVESECONTROL_DOWNSEAT:   // 下麦
+        {
+            if (member) {
+                KSLiveChatroomSeatApply *kickSeatMessage = [[KSLiveChatroomSeatApply alloc] init];
+                kickSeatMessage.type = SEATHANDLE_KICKSEAT;
+                kickSeatMessage.teacherId = self.createrId;
+                kickSeatMessage.teacherName = self.createrName;
+                kickSeatMessage.audienceId = member.userId;
+                kickSeatMessage.audienceName = member.name;
+                
+                MJWeakSelf;
+                [self sendMessage:kickSeatMessage displayMessage:NO callback:^(BOOL success) {
+                    [weakSelf refreshSeatArrayRemoveMember:YES member:member];
+                }];
+            }
+        }
+            break;
+        case LIVESECONTROL_DOWNSEATALL:
+        {
+            KSDownSeatAllMessage *message = [[KSDownSeatAllMessage alloc] init];
             MJWeakSelf;
-            [self sendMessage:responseMessage displayMessage:NO callback:^(BOOL success) {
-                [weakSelf refreshSeatArrayRemoveMember:YES member:member];
+            [self sendMessage:message displayMessage:NO callback:^(BOOL success) {
+//                [weakSelf removeSeatMember:NO];
             }];
         }
             break;
-        case LIVESEATACTION_KICK: // 下麦
+        case LIVESECONTROL_REFUSEALL:
         {
-            
-            KSLiveChatroomSeatApply *kickSeatMessage = [[KSLiveChatroomSeatApply alloc] init];
-            kickSeatMessage.type = SEATHANDLE_KICKSEAT;
-            kickSeatMessage.teacherId = self.createrId;
-            kickSeatMessage.teacherName = self.createrName;
-            kickSeatMessage.audienceId = member.userId;
-            kickSeatMessage.audienceName = member.name;
-            
+            KSRejectAllSeatMessage *message = [[KSRejectAllSeatMessage alloc] init];
             MJWeakSelf;
-            [self sendMessage:kickSeatMessage displayMessage:NO callback:^(BOOL success) {
-                [weakSelf refreshSeatArrayRemoveMember:YES member:member];
+            [self sendMessage:message displayMessage:NO callback:^(BOOL success) {
+//                [weakSelf removeSeatMember:YES];
             }];
         }
             break;
+            
         default:
             break;
     }
 }
 
+
+//- (void)opreationSeatStudentAction:(LIVESEATACTION)action member:(LiveSeatMember *)member {
+//    switch (action) {
+//        case LIVESEATACTION_APPROVE: // 同意
+//        {
+//            // 判断连麦人数超过4人 无法点击
+//            NSInteger count = [self queryConnectingCount];
+//            if (count >= 4) {
+//                [self MBPShow:@"最多可连麦4人"];
+//                return;
+//            }
+//            KSLiveChatroomSeatResponse *responseMessage = [[KSLiveChatroomSeatResponse alloc] init];
+//            responseMessage.type = SEATRESPONSE_TEACHERAPPROVE;
+//            responseMessage.teacherId = self.createrId;
+//            responseMessage.teacherName = self.createrName;
+//            responseMessage.audienceId = member.userId;
+//            responseMessage.audienceName = member.name;
+//            MJWeakSelf;
+//            [self sendMessage:responseMessage displayMessage:NO callback:^(BOOL success) {
+//                [weakSelf refreshSeatArrayRemoveMember:NO member:member];
+//            }];
+//        }
+//            break;
+//        case LIVESEATACTION_REJECT: // 拒绝
+//        {
+//            KSLiveChatroomSeatResponse *responseMessage = [[KSLiveChatroomSeatResponse alloc] init];
+//            responseMessage.type = SEATRESPONSE_TEACHERREJECT;
+//            responseMessage.teacherId = self.createrId;
+//            responseMessage.teacherName = self.createrName;
+//            responseMessage.audienceId = member.userId;
+//            responseMessage.audienceName = member.name;
+//            MJWeakSelf;
+//            [self sendMessage:responseMessage displayMessage:NO callback:^(BOOL success) {
+//                [weakSelf refreshSeatArrayRemoveMember:YES member:member];
+//            }];
+//        }
+//            break;
+//        case LIVESEATACTION_KICK: // 下麦
+//        {
+//            
+//            KSLiveChatroomSeatApply *kickSeatMessage = [[KSLiveChatroomSeatApply alloc] init];
+//            kickSeatMessage.type = SEATHANDLE_KICKSEAT;
+//            kickSeatMessage.teacherId = self.createrId;
+//            kickSeatMessage.teacherName = self.createrName;
+//            kickSeatMessage.audienceId = member.userId;
+//            kickSeatMessage.audienceName = member.name;
+//            
+//            MJWeakSelf;
+//            [self sendMessage:kickSeatMessage displayMessage:NO callback:^(BOOL success) {
+//                [weakSelf refreshSeatArrayRemoveMember:YES member:member];
+//            }];
+//        }
+//            break;
+//        default:
+//            break;
+//    }
+//}
+
 - (void)refreshSeatArrayRemoveMember:(BOOL)isRemove member:(LiveSeatMember *)member {
     if (isRemove) {
         [self.seatApplyArray removeObject:member];

+ 3 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSChatroomMessageCenter.h

@@ -24,6 +24,9 @@
 #import "KSRCShopRushMessage.h"
 #import "RCChatroomLikeCount.h"
 
+#import "RCChatroomSeatsControl.h"
+#import "KSDownSeatAllMessage.h"
+#import "KSRejectAllSeatMessage.h"
 
 typedef void(^RCChatroomMessageSuccess)(long messageId);
 typedef void(^RCChatroomMessageError)(RCErrorCode errorCode, long messageId);

+ 3 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSChatroomMessageCenter.m

@@ -41,7 +41,9 @@
     [[RCIM sharedRCIM] registerMessageType:[KSLiveChatroomMemberUp class]];
     [[RCIM sharedRCIM] registerMessageType:[KSRCShopRushMessage class]];
     [[RCIM sharedRCIM] registerMessageType:[RCChatroomLikeCount class]];
-    
+    [[RCIM sharedRCIM] registerMessageType:[KSDownSeatAllMessage class]];
+    [[RCIM sharedRCIM] registerMessageType:[KSRejectAllSeatMessage class]];
+    [[RCIM sharedRCIM] registerMessageType:[RCChatroomSeatsControl class]];
 }
 
 + (void)sendChatMessage:(NSString *)roomId content:(RCMessageContent *)content

+ 17 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSDownSeatAllMessage.h

@@ -0,0 +1,17 @@
+//
+//  KSDownSeatAllMessage.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/7/18.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSDownSeatAllMessage : RCMessageContent
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 39 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSDownSeatAllMessage.m

@@ -0,0 +1,39 @@
+//
+//  KSDownSeatAllMessage.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/7/18.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "KSDownSeatAllMessage.h"
+
+@implementation KSDownSeatAllMessage
+
+- (NSData *)encode {
+    NSMutableDictionary *multableDict = [NSMutableDictionary dictionary];
+    
+    return [NSJSONSerialization dataWithJSONObject:multableDict options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) return;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return;
+}
+
+
++ (NSString *)getObjectName {
+  return @"RC:Chatroom:DownSeatAll";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+
+@end

+ 17 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSRejectAllSeatMessage.h

@@ -0,0 +1,17 @@
+//
+//  KSRejectAllSeatMessage.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/7/18.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSRejectAllSeatMessage : RCMessageContent
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 39 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/KSRejectAllSeatMessage.m

@@ -0,0 +1,39 @@
+//
+//  KSRejectAllSeatMessage.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/7/18.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "KSRejectAllSeatMessage.h"
+
+@implementation KSRejectAllSeatMessage
+
+- (NSData *)encode {
+    NSMutableDictionary *multableDict = [NSMutableDictionary dictionary];
+    
+    return [NSJSONSerialization dataWithJSONObject:multableDict options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) return;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return;
+}
+
+
++ (NSString *)getObjectName {
+  return @"RC:Chatroom:RejectSeatAll";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+
+@end

+ 33 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/RCChatroomSeatsControl.h

@@ -0,0 +1,33 @@
+//
+//  RCChatroomSeatsControl.h
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/21.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <RongIMLibCore/RongIMLibCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface RCChatroomSeatsControl : RCMessageContent
+
+/**
+ 用户id
+*/
+@property(nonatomic, copy, nonnull) NSString *userId;
+
+/**
+ 用户名称
+*/
+@property(nonatomic, copy, nonnull) NSString *userName;
+
+/**
+ 是否禁止连麦 YES 禁止 NO 开启
+ */
+@property(nonatomic, assign) BOOL seatBan;
+
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 50 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/LiveRoomMessage/RCChatroomSeatsControl.m

@@ -0,0 +1,50 @@
+//
+//  RCChatroomSeatsControl.m
+//  StudentDaya
+//
+//  Created by Kyle on 2022/2/21.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "RCChatroomSeatsControl.h"
+
+@implementation RCChatroomSeatsControl
+
+- (NSData *)encode {
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    if (self.userId) {
+        [mutableDict setObject:self.userId forKey:@"userId"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"userId"];
+    }
+    if (self.userName) {
+        [mutableDict setObject:self.userName forKey:@"userName"];
+    } else {
+        [mutableDict setObject:@"" forKey:@"userName"];
+    }
+    [mutableDict setObject:@(self.seatBan) forKey:@"seatBan"];
+    return [NSJSONSerialization dataWithJSONObject:mutableDict options:kNilOptions error:nil];
+}
+
+- (void)decodeWithData:(NSData *)data {
+    if (data == nil) return;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+    NSDictionary *json = [[NSDictionary alloc] initWithDictionary:dictionary];
+    if (json == nil) return;
+    self.userId = [json stringValueForKey:@"userId"];
+    self.userName = [json stringValueForKey:@"userName"];
+    self.seatBan = [[json stringValueForKey:@"seatBan"] boolValue];
+}
+
++ (NSString *)getObjectName {
+    return @"RC:Chatroom:SeatsCtrl";
+}
+
+- (NSArray<NSString *> *)getSearchableWords {
+  return nil;
+}
+
++ (RCMessagePersistent)persistentFlag {
+  return MessagePersistent_NONE;
+}
+@end

+ 31 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveApplyControlView.h

@@ -0,0 +1,31 @@
+//
+//  LiveApplyControlView.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/7/19.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, APPLYACTION) {
+    APPLYACTION_REFUSEALL,  // 全部拒绝
+    APPLYACTION_FORBIDDEN, // 禁止连麦
+    APPLYACTION_ALLOW,   // 允许连麦
+};
+
+typedef void(^LiveSeatAction)(APPLYACTION action);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveApplyControlView : UIView
+
+@property (nonatomic, assign) BOOL isForbiddenApply;
+
++ (instancetype)shareInstance;
+
+- (void)controlSeatCallback:(LiveSeatAction)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 68 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveApplyControlView.m

@@ -0,0 +1,68 @@
+//
+//  LiveApplyControlView.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/7/19.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "LiveApplyControlView.h"
+
+@interface LiveApplyControlView ()
+
+@property (nonatomic, copy) LiveSeatAction callback;
+
+@property (weak, nonatomic) IBOutlet UIButton *controlButton;
+
+@end
+
+@implementation LiveApplyControlView
+
++ (instancetype)shareInstance {
+    LiveApplyControlView *view = [[[NSBundle mainBundle] loadNibNamed:@"LiveApplyControlView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)controlSeatCallback:(LiveSeatAction)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+// 全部下麦
+- (IBAction)forceAllDownSeat:(id)sender {
+    if (self.callback) {
+        self.callback(APPLYACTION_REFUSEALL);
+    }
+}
+
+
+- (IBAction)seatControlAction:(id)sender {
+    if (self.isForbiddenApply) {
+        self.callback(APPLYACTION_ALLOW);
+    }
+    else {
+        self.callback(APPLYACTION_FORBIDDEN);
+    }
+    self.isForbiddenApply = !self.isForbiddenApply;
+}
+
+- (void)setIsForbiddenApply:(BOOL)isForbiddenApply {
+    _isForbiddenApply = isForbiddenApply;
+    if (isForbiddenApply) {
+        [self.controlButton setTitle:@"允许连麦" forState:UIControlStateNormal];
+    }
+    else {
+        [self.controlButton setTitle:@"禁止连麦" forState:UIControlStateNormal];
+    }
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 87 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveApplyControlView.xib

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <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="LiveApplyControlView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="69"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qJN-QP-Nvg">
+                    <rect key="frame" x="14" y="13.5" width="187.5" height="42"/>
+                    <color key="backgroundColor" red="0.89411764709999997" green="0.97254901959999995" blue="0.96862745100000003" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="42" id="bF0-Ir-h4d"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" title="全部拒绝">
+                        <color key="titleColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
+                    </state>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                            <real key="value" value="1"/>
+                        </userDefinedRuntimeAttribute>
+                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                            <color key="value" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
+                        </userDefinedRuntimeAttribute>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="8"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                    <connections>
+                        <action selector="forceAllDownSeat:" destination="iN0-l3-epB" eventType="touchUpInside" id="sAF-Uc-w8t"/>
+                    </connections>
+                </button>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qrw-No-lUM">
+                    <rect key="frame" x="212.5" y="13.5" width="187.5" height="42"/>
+                    <color key="backgroundColor" red="0.89411764709999997" green="0.97254901959999995" blue="0.96862745100000003" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="42" id="Bso-0S-J3u"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" title="禁止连麦">
+                        <color key="titleColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
+                    </state>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                            <real key="value" value="1"/>
+                        </userDefinedRuntimeAttribute>
+                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                            <color key="value" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
+                        </userDefinedRuntimeAttribute>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="8"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                    <connections>
+                        <action selector="seatControlAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="a3u-fG-5Ff"/>
+                    </connections>
+                </button>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="qrw-No-lUM" firstAttribute="leading" secondItem="qJN-QP-Nvg" secondAttribute="trailing" constant="11" id="FEB-tj-qdA"/>
+                <constraint firstAttribute="trailing" secondItem="qrw-No-lUM" secondAttribute="trailing" constant="14" id="PEK-cn-gun"/>
+                <constraint firstItem="qJN-QP-Nvg" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="Z1w-tK-uMf"/>
+                <constraint firstItem="qrw-No-lUM" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="ZuI-X4-Kby"/>
+                <constraint firstItem="qJN-QP-Nvg" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="w0j-IZ-OWc"/>
+                <constraint firstItem="qrw-No-lUM" firstAttribute="width" secondItem="qJN-QP-Nvg" secondAttribute="width" id="yFd-av-36t"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="controlButton" destination="qrw-No-lUM" id="DzU-1i-VSL"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="-53.236607142857139"/>
+        </view>
+    </objects>
+</document>

+ 23 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveDownSeatView.h

@@ -0,0 +1,23 @@
+//
+//  LiveDownSeatView.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/7/19.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^LiveDownSeatAllBlock)(void);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveDownSeatView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)downSeatAllAction:(LiveDownSeatAllBlock)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 44 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveDownSeatView.m

@@ -0,0 +1,44 @@
+//
+//  LiveDownSeatView.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/7/19.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "LiveDownSeatView.h"
+
+@interface LiveDownSeatView ()
+
+@property (nonatomic, copy) LiveDownSeatAllBlock callback;
+
+@end
+
+@implementation LiveDownSeatView
+
++ (instancetype)shareInstance {
+    LiveDownSeatView *view = [[[NSBundle mainBundle] loadNibNamed:@"LiveDownSeatView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)downSeatAllAction:(LiveDownSeatAllBlock)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)downSeatAllMemeberAction:(id)sender {
+    if (self.callback) {
+        self.callback();
+    }
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 57 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveDownSeatView.xib

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <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="LiveDownSeatView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="65"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fwf-Zw-PZ8">
+                    <rect key="frame" x="14" y="11.5" width="386" height="42"/>
+                    <color key="backgroundColor" red="0.89411764705882346" green="0.97254901960784312" blue="0.96862745098039216" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="42" id="RHA-V6-OdQ"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" title="全部下麦">
+                        <color key="titleColor" red="0.0039215686274509803" green="0.75686274509803919" blue="0.70980392156862748" alpha="1" colorSpace="calibratedRGB"/>
+                    </state>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                            <real key="value" value="1"/>
+                        </userDefinedRuntimeAttribute>
+                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                            <color key="value" red="0.0039215686274509803" green="0.75686274509803919" blue="0.70980392156862748" alpha="1" colorSpace="calibratedRGB"/>
+                        </userDefinedRuntimeAttribute>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="8"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                    <connections>
+                        <action selector="downSeatAllMemeberAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="593-Fg-cHL"/>
+                    </connections>
+                </button>
+            </subviews>
+            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="Fwf-Zw-PZ8" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="9Xq-KH-g40"/>
+                <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="Fwf-Zw-PZ8" secondAttribute="trailing" constant="14" id="L68-xr-Uma"/>
+                <constraint firstItem="Fwf-Zw-PZ8" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="14" id="qIL-1k-aKG"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="131.8840579710145" y="-16.40625"/>
+        </view>
+    </objects>
+</document>

+ 26 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveMemberSeatCell.h

@@ -0,0 +1,26 @@
+//
+//  LiveMemberSeatCell.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/7/19.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "LiveSeatMember.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(NSInteger, SEATOPERATION) {
+    SEATOPERATION_APPROVE,
+    SEATOPERATION_DOWNSEAT,
+};
+typedef void(^SeatCallback)(SEATOPERATION action, LiveSeatMember * _Nonnull member);
+
+@interface LiveMemberSeatCell : UITableViewCell
+
+- (void)configCellWithSource:(LiveSeatMember *)member isApply:(BOOL)isApply callback:(SeatCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 68 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveMemberSeatCell.m

@@ -0,0 +1,68 @@
+//
+//  LiveMemberSeatCell.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/7/19.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "LiveMemberSeatCell.h"
+
+@interface LiveMemberSeatCell ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *userAvatar;
+
+@property (weak, nonatomic) IBOutlet UILabel *userName;
+
+@property (weak, nonatomic) IBOutlet UILabel *seatStatus;
+
+@property (weak, nonatomic) IBOutlet UIButton *approveButton;
+
+@property (nonatomic, strong) LiveSeatMember *member;
+
+@property (nonatomic, copy) SeatCallback callback;
+
+@property (nonatomic, assign) BOOL isApply;
+
+@end
+
+
+@implementation LiveMemberSeatCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+- (void)configCellWithSource:(LiveSeatMember *)member isApply:(BOOL)isApply callback:(SeatCallback)callback {
+    self.isApply = isApply;
+    if (callback) {
+        self.callback = callback;
+    }
+    self.member = member;
+    [self.userAvatar sd_setImageWithURL:[NSURL URLWithString:member.avatar] placeholderImage:[UIImage imageNamed:USERDEFAULT_LOGO]];
+    if (isApply) {
+        [self.approveButton setTitle:@"上麦" forState:UIControlStateNormal];
+        self.seatStatus.text = @"申请连麦中";
+    }
+    else {
+        [self.approveButton setTitle:@"下麦" forState:UIControlStateNormal];
+        self.seatStatus.text = @"连麦中";
+    }
+}
+
+- (IBAction)sureAction:(id)sender {
+    if (self.callback) {
+        SEATOPERATION action = self.isApply ? SEATOPERATION_APPROVE : SEATOPERATION_DOWNSEAT;
+        self.callback(action, self.member);
+    }
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end

+ 95 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveMemberSeatCell.xib

@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="90" id="KGk-i7-Jjw" customClass="LiveMemberSeatCell">
+            <rect key="frame" x="0.0" y="0.0" width="320" height="90"/>
+            <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="90"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="user_default_avatal" translatesAutoresizingMaskIntoConstraints="NO" id="Hp8-nb-Ip1">
+                        <rect key="frame" x="14" y="21" width="48" height="48"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="48" id="7Nv-6R-Tex"/>
+                            <constraint firstAttribute="width" constant="48" id="Qhs-Q2-J9D"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="24"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </imageView>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="zhangsn " textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hVS-iw-n4a">
+                        <rect key="frame" x="72" y="21" width="62.5" height="28"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="28" id="F6v-ri-t2x"/>
+                        </constraints>
+                        <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                        <color key="textColor" red="0.1019607843" green="0.1019607843" blue="0.1019607843" 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="c41-sP-dnU">
+                        <rect key="frame" x="72" y="49" width="54" height="18"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="18" id="0hJ-qN-z8x"/>
+                        </constraints>
+                        <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                        <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="calibratedRGB"/>
+                        <nil key="highlightedColor"/>
+                    </label>
+                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Xv9-FJ-fKY">
+                        <rect key="frame" x="242" y="31" width="64" height="28"/>
+                        <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="28" id="9lg-ak-Ngh"/>
+                            <constraint firstAttribute="width" constant="64" id="GSW-Rw-e62"/>
+                        </constraints>
+                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                        <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                        <state key="normal" title="上麦"/>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="8"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                        <connections>
+                            <action selector="sureAction:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="71g-F6-Ka6"/>
+                        </connections>
+                    </button>
+                </subviews>
+                <constraints>
+                    <constraint firstAttribute="trailing" secondItem="Xv9-FJ-fKY" secondAttribute="trailing" constant="14" id="5cg-Lq-OV6"/>
+                    <constraint firstItem="c41-sP-dnU" firstAttribute="top" secondItem="hVS-iw-n4a" secondAttribute="bottom" id="N3o-hi-Y5y"/>
+                    <constraint firstItem="Hp8-nb-Ip1" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="a7J-Fv-WVe"/>
+                    <constraint firstItem="Xv9-FJ-fKY" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="hVS-iw-n4a" secondAttribute="trailing" constant="10" id="dX3-IL-iTv"/>
+                    <constraint firstItem="c41-sP-dnU" firstAttribute="leading" secondItem="hVS-iw-n4a" secondAttribute="leading" id="lVP-H4-oTW"/>
+                    <constraint firstItem="Hp8-nb-Ip1" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="qUp-WW-yB0"/>
+                    <constraint firstItem="Xv9-FJ-fKY" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="r4I-nk-UDj"/>
+                    <constraint firstItem="hVS-iw-n4a" firstAttribute="top" secondItem="Hp8-nb-Ip1" secondAttribute="top" id="zMz-pt-SBr"/>
+                    <constraint firstItem="hVS-iw-n4a" firstAttribute="leading" secondItem="Hp8-nb-Ip1" secondAttribute="trailing" constant="10" id="zVC-tL-Hys"/>
+                </constraints>
+            </tableViewCellContentView>
+            <viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
+            <connections>
+                <outlet property="approveButton" destination="Xv9-FJ-fKY" id="zkI-Cd-eJc"/>
+                <outlet property="seatStatus" destination="c41-sP-dnU" id="nzQ-l5-vNc"/>
+                <outlet property="userAvatar" destination="Hp8-nb-Ip1" id="n99-Fi-xXT"/>
+                <outlet property="userName" destination="hVS-iw-n4a" id="Uec-E8-Bh7"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="117.52232142857142"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="user_default_avatal" width="52" height="52"/>
+    </resources>
+</document>

+ 33 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveSeatActionView.h

@@ -0,0 +1,33 @@
+//
+//  LiveSeatActionView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2022/8/22.
+//
+
+#import <UIKit/UIKit.h>
+#import "LiveSeatMember.h"
+
+typedef NS_ENUM(NSInteger, LIVESECONTROL) {
+    LIVESECONTROL_APPROVE,     // 上麦
+    LIVESECONTROL_DOWNSEAT,    // 下麦
+    LIVESECONTROL_DOWNSEATALL, // 全部下麦
+    LIVESECONTROL_REFUSEALL,   // 全部拒绝
+    LIVESECONTROL_ALLOW,       // 允许连麦
+    LIVESECONTROL_FORBIDDEN,   // 禁止连麦
+};
+
+typedef void(^LiveSeatActionCallback)(LIVESECONTROL action, LiveSeatMember * _Nonnull member);
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveSeatActionView : UIView
+
+- (void)refreshSeatApplyTable:(NSArray *)seatMemberArray;
+
+- (void)opreationCallback:(LiveSeatActionCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 201 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/LiveSeatActionView.m

@@ -0,0 +1,201 @@
+//
+//  LiveSeatActionView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2022/8/22.
+//
+
+#import "LiveSeatActionView.h"
+#import "SeatBodyView.h"
+#import "JXCategoryTitleView.h"
+#import "JXPagerView.h"
+#import "JXCategoryView.h"
+#import "JXPagerListRefreshView.h"
+
+
+@interface LiveSeatActionView ()<JXPagerViewDelegate, JXPagerMainTableViewGestureDelegate,JXCategoryViewDelegate>
+
+@property (nonatomic, strong) JXPagerView *pagerView;
+@property (nonatomic, strong, readonly) JXCategoryTitleView *categoryView;
+@property (nonatomic, strong) NSArray <NSString *> *titles;
+
+@property (nonatomic, strong) NSMutableArray *listViewArray;
+
+@property (nonatomic, assign) NSInteger selectedIndex;
+@property (nonatomic, copy) LiveSeatActionCallback callback;
+
+@property (nonatomic, strong) NSMutableArray *seatArray;
+
+@property (nonatomic, strong) NSMutableArray *applyArray;
+
+@property (nonatomic, assign) CGFloat header_height;
+
+@end
+
+@implementation LiveSeatActionView
+- (void)opreationCallback:(LiveSeatActionCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        self.backgroundColor = HexRGB(0xffffff);
+        _header_height = 40.0f;
+        _titles = @[@"连麦中",@"申请中"];
+        [self configUI];
+    }
+    return self;
+}
+
+- (void)configUI {
+    _categoryView = [[JXCategoryTitleView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, self.header_height)];
+    self.categoryView.titles = self.titles;
+    self.categoryView.delegate = self;
+    self.categoryView.titleFont = [UIFont systemFontOfSize:16.0f];
+    self.categoryView.titleSelectedFont = [UIFont systemFontOfSize:16.0f weight:UIFontWeightMedium];
+    self.categoryView.titleSelectedColor = HexRGB(0x333333);
+    self.categoryView.titleColor = HexRGB(0x666666);
+    self.categoryView.titleColorGradientEnabled = YES;
+    
+    JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init];
+    lineView.indicatorColor = HexRGB(0x01c1b5);
+    lineView.indicatorWidth = 30;
+    lineView.indicatorHeight = 2;
+    self.categoryView.indicators = @[lineView];
+    
+    _pagerView = [self preferredPagingView];
+    self.pagerView.frame = CGRectMake(0, 0, KPortraitWidth, 300+ iPhoneXSafeBottomMargin);
+    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 addSubview:self.pagerView];
+}
+
+- (JXPagerView *)preferredPagingView {
+    return [[JXPagerListRefreshView alloc] initWithDelegate:self];
+}
+
+- (void)refreshSeatApplyTable:(NSArray *)seatMemberArray {
+    self.seatArray = [NSMutableArray array];
+    self.applyArray = [NSMutableArray array];
+    for (LiveSeatMember *member in seatMemberArray) {
+        if (member.isConnected) {
+            [self.seatArray addObject:member];
+        }
+        else {
+            [self.applyArray addObject:member];
+        }
+    }
+    for (NSInteger index = 0; index < self.titles.count; index++) {
+        id value = self.listViewArray[index];
+        if ([value isKindOfClass:[SeatBodyView class]]) {
+            SeatBodyView *listView = (SeatBodyView *)value;
+            if (index == 0) {
+                listView.memberArray = [self.seatArray mutableCopy];
+            }
+            else {
+                listView.memberArray = [self.applyArray mutableCopy];
+            }
+        }
+    }
+}
+
+
+
+#pragma mark - JXPagerViewDelegate
+
+- (UIView *)tableHeaderViewInPagerView:(JXPagerView *)pagerView {
+    return [UIView new];
+}
+
+- (NSUInteger)tableHeaderViewHeightInPagerView:(JXPagerView *)pagerView {
+    return CGFLOAT_MIN;
+}
+
+- (NSUInteger)heightForPinSectionHeaderInPagerView:(JXPagerView *)pagerView {
+    return self.header_height;
+}
+
+- (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 {
+    SeatBodyView *listView = [[SeatBodyView alloc] init];
+    MJWeakSelf;
+    [listView operationMemberAction:^(LIVESECONTROL action, LiveSeatMember * _Nullable member) {
+        [weakSelf opreationMemberSeat:action member:member];
+    }];
+    [self.listViewArray replaceObjectAtIndex:index withObject:listView];
+    if (index == 0) {
+        listView.selectIndex = 0;
+        listView.memberArray = [self.seatArray mutableCopy];
+    }else if (index == 1) {
+        listView.selectIndex = 1;
+        listView.memberArray = [self.applyArray mutableCopy];
+    }
+    [listView beginFirstRefresh];
+    return listView;
+}
+
+- (void)opreationMemberSeat:(LIVESECONTROL)action member:(LiveSeatMember *)member {
+    if (self.callback) {
+        self.callback(action, member);
+    }
+}
+
+#pragma mark - JXCategoryViewDelegate
+- (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index {
+    self.selectedIndex = index;
+    if (self.listViewArray.count > index) {
+        id value = self.listViewArray[index];
+        if ([value isKindOfClass:[SeatBodyView class]]) {
+            SeatBodyView *listView = (SeatBodyView *)value;
+            if (index == 0) {
+                listView.memberArray = [self.seatArray mutableCopy];
+            }
+            else {
+                listView.memberArray = [self.applyArray mutableCopy];
+            }
+        }
+    }
+}
+
+#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]];
+}
+
+
+- (NSMutableArray *)listViewArray {
+    if (!_listViewArray) {
+        _listViewArray = [NSMutableArray arrayWithArray:@[@"",@""]];
+    }
+    return _listViewArray;
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 35 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/SeatBodyView.h

@@ -0,0 +1,35 @@
+//
+//  SeatBodyView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2022/8/22.
+//
+
+#import <UIKit/UIKit.h>
+#import "JXPagerView.h"
+#import "LiveSeatMember.h"
+#import "LiveSeatActionView.h"
+
+typedef void(^LiveSeatCallback)(LIVESECONTROL action, LiveSeatMember * _Nullable member);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SeatBodyView : UIView <JXPagerViewListViewDelegate>
+
+@property (nonatomic, weak) UINavigationController *naviController;
+
+@property (nonatomic, strong) UITableView *tableView;
+
+@property (nonatomic, assign) NSInteger selectIndex;
+
+- (void)operationMemberAction:(LiveSeatCallback)callback;
+
+@property (nonatomic, strong) NSMutableArray *memberArray; // 成员列表
+
+@property (nonatomic, assign) BOOL isHeaderRefreshed;   //默认为YES
+
+- (void)beginFirstRefresh;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 213 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Live/View/SeatListView/SeatBodyView.m

@@ -0,0 +1,213 @@
+//
+//  SeatBodyView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2022/8/22.
+//
+
+#import "SeatBodyView.h"
+#import "LiveMemberSeatCell.h"
+#import "LiveDownSeatView.h"
+#import "LiveApplyControlView.h"
+
+@interface SeatBodyView ()<UITableViewDelegate,UITableViewDataSource>
+
+@property (nonatomic, copy) void(^scrollCallback)(UIScrollView *scrollView);
+@property (nonatomic, strong) NSIndexPath *lastSelectedIndexPath;
+
+@property (nonatomic, strong) LiveDownSeatView *downSeatView;
+
+@property (nonatomic, strong) LiveApplyControlView *controlView;
+
+@property (nonatomic, strong) LiveSeatCallback callback;
+
+@end
+
+@implementation SeatBodyView
+
+
+- (void)operationMemberAction:(LiveSeatCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self) {
+        self.backgroundColor = [UIColor clearColor];
+        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height) style:UITableViewStylePlain];
+        self.tableView.backgroundColor = [UIColor clearColor];
+        self.tableView.showsVerticalScrollIndicator = NO;
+
+        self.tableView.dataSource = self;
+        self.tableView.delegate = self;
+        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+        self.tableView.rowHeight = 50;
+        [self addSubview:self.tableView];
+        UIView *headView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 10)];
+        headView.backgroundColor = [UIColor clearColor];
+        self.tableView.tableHeaderView = headView;
+        [self.tableView registerNib:[UINib nibWithNibName:@"LiveMemberSeatCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"LiveMemberSeatCell"];
+    }
+    return self;
+}
+
+- (void)setMemberArray:(NSMutableArray *)memberArray {
+    _memberArray = memberArray;
+    [self.tableView reloadData];
+}
+
+- (void)beginRefreshImmediately {
+    [self.tableView reloadData];
+}
+
+- (void)selectCellAtIndexPath:(NSIndexPath *)indexPath {
+    
+    if (self.lastSelectedIndexPath == indexPath) {
+        return;
+    }
+    if (self.lastSelectedIndexPath != nil) {
+        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.lastSelectedIndexPath];
+        [cell setSelected:NO animated:NO];
+    }
+    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
+    [cell setSelected:YES animated:NO];
+    self.lastSelectedIndexPath = indexPath;
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    CGFloat headerHeight = 55;
+    self.tableView.frame = CGRectMake(0, headerHeight, self.bounds.size.width, self.bounds.size.height - headerHeight);
+    if (self.selectIndex == 0) {
+        if (!_downSeatView) {
+            _downSeatView = [LiveDownSeatView shareInstance];
+            _downSeatView.frame = CGRectMake(0, 0, KPortraitWidth, headerHeight);
+            MJWeakSelf;
+            [_downSeatView downSeatAllAction:^{
+                [weakSelf downSeatAllOperation];
+            }];
+            [self addSubview:_downSeatView];
+        }
+    }
+    else {
+        if (!_controlView) {
+            _controlView = [LiveApplyControlView shareInstance];
+            _controlView.frame = CGRectMake(0, 0, KPortraitWidth, headerHeight);
+            MJWeakSelf;
+            [_controlView controlSeatCallback:^(APPLYACTION action) {
+                [weakSelf seatControlAction:action];
+            }];
+            [self addSubview:_controlView];
+        }
+    }
+}
+
+- (void)seatControlAction:(APPLYACTION)action {
+    if (action == APPLYACTION_REFUSEALL) {
+        if (self.callback) {
+            self.callback(LIVESECONTROL_REFUSEALL, nil);
+        }
+    }
+    else if (action == APPLYACTION_FORBIDDEN) {
+        if (self.callback) {
+            self.callback(LIVESECONTROL_FORBIDDEN, nil);
+        }
+    }
+    else if (action == APPLYACTION_ALLOW) {
+        if (self.callback) {
+            self.callback(LIVESECONTROL_ALLOW, nil);
+        }
+    }
+}
+
+// 全部下麦
+- (void)downSeatAllOperation {
+    if (self.callback) {
+        self.callback(LIVESECONTROL_DOWNSEATALL, nil);
+    }
+}
+
+- (void)beginFirstRefresh {
+    if (!self.isHeaderRefreshed) {
+        [self beginRefreshImmediately];
+    }
+}
+
+
+#pragma mark - UITableViewDataSource, UITableViewDelegate
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return self.memberArray.count;
+}
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+    return 1;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    BOOL isApply = NO;
+    if (self.selectIndex == 0) {
+        isApply = NO;
+    }
+    else {
+        isApply = YES;
+    }
+    LiveSeatMember *member = self.memberArray[indexPath.row];
+    
+    LiveMemberSeatCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LiveMemberSeatCell"];
+    MJWeakSelf;
+    [cell configCellWithSource:member isApply:isApply callback:^(SEATOPERATION action, LiveSeatMember * _Nonnull member) {
+        [weakSelf opreationMemberSeatAction:action member:member];
+    }];
+    return cell;
+}
+
+- (void)opreationMemberSeatAction:(SEATOPERATION)action member:(LiveSeatMember *)member {
+    if (action == SEATOPERATION_APPROVE) { // 同意连麦
+        if (self.callback) {
+            self.callback(LIVESECONTROL_APPROVE, member);
+        }
+    }
+    else { // 下麦
+        if (self.callback) {
+            self.callback(LIVESECONTROL_DOWNSEAT, member);
+        }
+    }
+}
+
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
+    !self.scrollCallback ?: self.scrollCallback(scrollView);
+}
+#pragma mark - JXPagingViewListViewDelegate
+
+- (UIView *)listView {
+    return self;
+}
+
+- (UIScrollView *)listScrollView {
+    return self.tableView;
+}
+
+- (void)listViewDidScrollCallback:(void (^)(UIScrollView *))callback {
+    self.scrollCallback = callback;
+}
+
+- (void)listDidAppear {
+    NSLog(@"listDidAppear");
+    // 刷新数据
+//    [self refreshAndRequestData];
+}
+
+- (void)listDidDisappear {
+    NSLog(@"listDidDisappear");
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end