Browse Source

创建群聊修改

Steven 1 year ago
parent
commit
ff348387a2
31 changed files with 1304 additions and 182 deletions
  1. 317 3
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. 29 2
      KulexiuForStudent/KulexiuForStudent.xcworkspace/xcshareddata/swiftpm/Package.resolved
  3. 0 1
      KulexiuForStudent/KulexiuForStudent/AppDelegate.h
  4. 48 134
      KulexiuForStudent/KulexiuForStudent/AppDelegate.m
  5. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Institution/Mine/tenant_message.imageset/Contents.json
  6. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Institution/Mine/tenant_message.imageset/tenant_message@2x.png
  7. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Institution/Mine/tenant_message.imageset/tenant_message@3x.png
  8. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/MessageCenter/tenant_clearMsg.imageset/Contents.json
  9. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/MessageCenter/tenant_clearMsg.imageset/tenant_clearMsg@2x.png
  10. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/MessageCenter/tenant_clearMsg.imageset/tenant_clearMsg@3x.png
  11. 26 7
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSAccompanyWebViewController.m
  12. 20 20
      KulexiuForStudent/KulexiuForStudent/Common/Define/KSDomain.h
  13. 2 0
      KulexiuForStudent/KulexiuForStudent/Common/Tools/Extension/NSDate+Extension.h
  14. 18 0
      KulexiuForStudent/KulexiuForStudent/Common/Tools/Extension/NSDate+Extension.m
  15. 1 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Home/Controller/TenantDarkViewController.m
  16. 14 3
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/Controller/InsititutionMineViewController.m
  17. 18 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/Controller/TenantNotiferCenterController.h
  18. 254 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/Controller/TenantNotiferCenterController.m
  19. 10 1
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineNavView.h
  20. 12 1
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineNavView.m
  21. 52 2
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineNavView.xib
  22. 21 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferMessageCell.h
  23. 96 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferMessageCell.m
  24. 116 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferMessageCell.xib
  25. 22 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferNavView.h
  26. 48 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferNavView.m
  27. 96 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferNavView.xib
  28. 2 2
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/TabbarController/InstitutionTabBarController.m
  29. 34 4
      KulexiuForStudent/KulexiuForStudent/Module/Chat/Controller/TXCustom/KSTXBaseChatViewController.m
  30. 2 1
      KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/TuningFunction/Tuner.swift
  31. 2 1
      KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/TuningFunction/TunerForkManager.swift

+ 317 - 3
KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj

@@ -697,6 +697,11 @@
 		BC802DBA28BC8C810079E350 /* HomeHotVideoCourseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC802DB928BC8C810079E350 /* HomeHotVideoCourseView.xib */; };
 		BC802DBD28BC8E2C0079E350 /* HomeHotLiveCourseView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC802DBC28BC8E2C0079E350 /* HomeHotLiveCourseView.m */; };
 		BC802DBF28BC8E350079E350 /* HomeHotLiveCourseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC802DBE28BC8E350079E350 /* HomeHotLiveCourseView.xib */; };
+		BC83A8362AD27C470033D48B /* TenantNotiferCenterController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC83A8352AD27C470033D48B /* TenantNotiferCenterController.m */; };
+		BC83A83A2AD2825F0033D48B /* TenantNotiferMessageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC83A8382AD2825F0033D48B /* TenantNotiferMessageCell.m */; };
+		BC83A83B2AD2825F0033D48B /* TenantNotiferMessageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC83A8392AD2825F0033D48B /* TenantNotiferMessageCell.xib */; };
+		BC83A83E2AD28A9F0033D48B /* TenantNotiferNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC83A83D2AD28A9F0033D48B /* TenantNotiferNavView.m */; };
+		BC83A8402AD28AA60033D48B /* TenantNotiferNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC83A83F2AD28AA60033D48B /* TenantNotiferNavView.xib */; };
 		BC84183F2AC2D96600D8F90E /* PasswordCheckBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC84183E2AC2D96600D8F90E /* PasswordCheckBodyView.m */; };
 		BC8418412AC2D96C00D8F90E /* PasswordCheckBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC8418402AC2D96C00D8F90E /* PasswordCheckBodyView.xib */; };
 		BC89AC092AB0840E00B077AF /* TenantRecommendMusicView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC89AC082AB0840E00B077AF /* TenantRecommendMusicView.m */; };
@@ -1092,6 +1097,8 @@
 		BCFE54002814E1BE00AD6786 /* HomeVideoGroupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE53FE2814E1BE00AD6786 /* HomeVideoGroupModel.m */; };
 		BCFE540328152A8500AD6786 /* KSOrderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE540228152A8500AD6786 /* KSOrderManager.m */; };
 		BCFE5406281545C600AD6786 /* HomeAlbumModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE5405281545C500AD6786 /* HomeAlbumModel.m */; };
+		BCFEE18D2AD15BD4000E888F /* AudioKitEX in Frameworks */ = {isa = PBXBuildFile; productRef = BCFEE18C2AD15BD4000E888F /* AudioKitEX */; };
+		BCFEE1932AD15C0E000E888F /* SoundpipeAudioKit in Frameworks */ = {isa = PBXBuildFile; productRef = BCFEE1922AD15C0E000E888F /* SoundpipeAudioKit */; };
 		BCFEED4D28F7E4720078A2B7 /* SmallToolViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFEED4C28F7E4720078A2B7 /* SmallToolViewController.m */; };
 		BCFEED5E28F7E4910078A2B7 /* WidgetFunctionView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFEED4F28F7E4910078A2B7 /* WidgetFunctionView.m */; };
 		BCFEED5F28F7E4910078A2B7 /* WidgetNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFEED5028F7E4910078A2B7 /* WidgetNavView.m */; };
@@ -2329,6 +2336,14 @@
 		BC802DBB28BC8E2C0079E350 /* HomeHotLiveCourseView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeHotLiveCourseView.h; sourceTree = "<group>"; };
 		BC802DBC28BC8E2C0079E350 /* HomeHotLiveCourseView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeHotLiveCourseView.m; sourceTree = "<group>"; };
 		BC802DBE28BC8E350079E350 /* HomeHotLiveCourseView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeHotLiveCourseView.xib; sourceTree = "<group>"; };
+		BC83A8342AD27C470033D48B /* TenantNotiferCenterController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TenantNotiferCenterController.h; sourceTree = "<group>"; };
+		BC83A8352AD27C470033D48B /* TenantNotiferCenterController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TenantNotiferCenterController.m; sourceTree = "<group>"; };
+		BC83A8372AD2825F0033D48B /* TenantNotiferMessageCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TenantNotiferMessageCell.h; sourceTree = "<group>"; };
+		BC83A8382AD2825F0033D48B /* TenantNotiferMessageCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TenantNotiferMessageCell.m; sourceTree = "<group>"; };
+		BC83A8392AD2825F0033D48B /* TenantNotiferMessageCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TenantNotiferMessageCell.xib; sourceTree = "<group>"; };
+		BC83A83C2AD28A9F0033D48B /* TenantNotiferNavView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TenantNotiferNavView.h; sourceTree = "<group>"; };
+		BC83A83D2AD28A9F0033D48B /* TenantNotiferNavView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TenantNotiferNavView.m; sourceTree = "<group>"; };
+		BC83A83F2AD28AA60033D48B /* TenantNotiferNavView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TenantNotiferNavView.xib; sourceTree = "<group>"; };
 		BC84183D2AC2D96600D8F90E /* PasswordCheckBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PasswordCheckBodyView.h; sourceTree = "<group>"; };
 		BC84183E2AC2D96600D8F90E /* PasswordCheckBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PasswordCheckBodyView.m; sourceTree = "<group>"; };
 		BC8418402AC2D96C00D8F90E /* PasswordCheckBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PasswordCheckBodyView.xib; sourceTree = "<group>"; };
@@ -2999,6 +3014,8 @@
 			buildActionMask = 2147483647;
 			files = (
 				BCA1136828A3A5CF007FAFB9 /* Accelerate.framework in Frameworks */,
+				BCFEE1932AD15C0E000E888F /* SoundpipeAudioKit in Frameworks */,
+				BCFEE18D2AD15BD4000E888F /* AudioKitEX in Frameworks */,
 				BC8B6E152856E20800866917 /* WebKit.framework in Frameworks */,
 				BC8A45CB283DDEA100094BBB /* AVFoundation.framework in Frameworks */,
 				BCD9294F28F8FCA4006793E4 /* AudioKit in Frameworks */,
@@ -5105,6 +5122,8 @@
 				BC2932FC2AAEF4AB0024D98E /* InsititutionMineViewController.m */,
 				BC2932FE2AAEFC810024D98E /* INSSettingViewController.h */,
 				BC2932FF2AAEFC810024D98E /* INSSettingViewController.m */,
+				BC83A8342AD27C470033D48B /* TenantNotiferCenterController.h */,
+				BC83A8352AD27C470033D48B /* TenantNotiferCenterController.m */,
 			);
 			path = Controller;
 			sourceTree = "<group>";
@@ -5131,6 +5150,12 @@
 				BCCC361F2AAF0EDF000D60CA /* SettingBottomView.h */,
 				BCCC361D2AAF0EDE000D60CA /* SettingBottomView.m */,
 				BCCC361E2AAF0EDF000D60CA /* SettingBottomView.xib */,
+				BC83A8372AD2825F0033D48B /* TenantNotiferMessageCell.h */,
+				BC83A8382AD2825F0033D48B /* TenantNotiferMessageCell.m */,
+				BC83A8392AD2825F0033D48B /* TenantNotiferMessageCell.xib */,
+				BC83A83C2AD28A9F0033D48B /* TenantNotiferNavView.h */,
+				BC83A83D2AD28A9F0033D48B /* TenantNotiferNavView.m */,
+				BC83A83F2AD28AA60033D48B /* TenantNotiferNavView.xib */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -7025,6 +7050,8 @@
 			name = KulexiuForStudent;
 			packageProductDependencies = (
 				BCD9294E28F8FCA4006793E4 /* AudioKit */,
+				BCFEE18C2AD15BD4000E888F /* AudioKitEX */,
+				BCFEE1922AD15C0E000E888F /* SoundpipeAudioKit */,
 			);
 			productName = KulexiuForStudent;
 			productReference = 275E8AA527E18F8800DD3F6E /* KulexiuForStudent.app */;
@@ -7105,6 +7132,8 @@
 			mainGroup = 275E8A9C27E18F8800DD3F6E;
 			packageReferences = (
 				BCD9294D28F8FCA4006793E4 /* XCRemoteSwiftPackageReference "AudioKit" */,
+				BCFEE18B2AD15BD4000E888F /* XCRemoteSwiftPackageReference "AudioKitEX" */,
+				BCFEE1912AD15C0E000E888F /* XCRemoteSwiftPackageReference "SoundpipeAudioKit" */,
 			);
 			productRefGroup = 275E8AA627E18F8800DD3F6E /* Products */;
 			projectDirPath = "";
@@ -7295,6 +7324,7 @@
 				2723B66327F15CFC00E0B90B /* ModifyNameBodyView.xib in Resources */,
 				BC71D255288804CD0010F14B /* img_5.png in Resources */,
 				BCFEED6728F7E4910078A2B7 /* WidgetBottomButtonView.xib in Resources */,
+				BC83A8402AD28AA60033D48B /* TenantNotiferNavView.xib in Resources */,
 				BCB6348327F6D29600ACFDCF /* LiveSeatApplyView.xib in Resources */,
 				BCFDA65328BCA2000022B497 /* accomapny_animation_3.png in Resources */,
 				BC8C2C612823F57100FBA5D5 /* MyAddressListCell.xib in Resources */,
@@ -7373,6 +7403,7 @@
 				BC106C472A933B8B000759A9 /* LiveRoomBottomView.xib in Resources */,
 				2723B66F27F15CFC00E0B90B /* AboutUsBodyView.xib in Resources */,
 				275FA23827E7356B00CFEA2E /* FirstSettingBodyView.xib in Resources */,
+				BC83A83B2AD2825F0033D48B /* TenantNotiferMessageCell.xib in Resources */,
 				BC542E622840A60E00633781 /* UseBodyView.xib in Resources */,
 				BC106C422A9339FB000759A9 /* LiveAlertView.xib in Resources */,
 				BCC583B428A9EC6400BAB4CF /* cloud_animation_9.png in Resources */,
@@ -7672,6 +7703,7 @@
 				BCB909132852EF0000F5FF69 /* KSDragWindowManager.m in Sources */,
 				2779359827E324A80010E277 /* TZAssetModel.m in Sources */,
 				BCC0F6AC2A8CDD4000C4EFA4 /* HTTPResult.m in Sources */,
+				BC83A83A2AD2825F0033D48B /* TenantNotiferMessageCell.m in Sources */,
 				277935A027E324A80010E277 /* UIView+TZLayout.m in Sources */,
 				BCA3DBBD29014B9800AE1C49 /* TunerForkManager.swift in Sources */,
 				2779351227E324A50010E277 /* KSNetworkAccessibleManager.m in Sources */,
@@ -7946,12 +7978,14 @@
 				BC106C372A9338A7000759A9 /* TXLiveChatListCell.m in Sources */,
 				BC106C242A933869000759A9 /* TXTestGenerateUserSig.m in Sources */,
 				2723B61F27F157D500E0B90B /* GroupNoticeModel.m in Sources */,
+				BC83A8362AD27C470033D48B /* TenantNotiferCenterController.m in Sources */,
 				275FA1E627E7351900CFEA2E /* KSUpdateAlert.m in Sources */,
 				BCB5B2D52ABB1E13005BF25D /* KSEmptyStatusView.m in Sources */,
 				2779355027E324A70010E277 /* VoDiskCache.m in Sources */,
 				BCFEED6228F7E4910078A2B7 /* WidgetDotView.m in Sources */,
 				BCC0F6ED2A8CE4AF00C4EFA4 /* ZoomControl.m in Sources */,
 				BCF472E72AB019CD0032BE16 /* TenantDarkViewController.m in Sources */,
+				BC83A83E2AD28A9F0033D48B /* TenantNotiferNavView.m in Sources */,
 				BC106C032A933829000759A9 /* TXLiveMessageOpenLive.m in Sources */,
 				2779353927E324A60010E277 /* UIView+XIBView.m in Sources */,
 				2779355827E324A70010E277 /* UIImage+Addtions.m in Sources */,
@@ -8589,9 +8623,136 @@
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/SocialLibraries/Sina/SinaSDK",
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/UMSocialSDKPlugin",
 				);
-				MARKETING_VERSION = 1.5.1;
+				MARKETING_VERSION = 1.5.2;
 				MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
 				MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
+				OTHER_LDFLAGS = (
+					"$(inherited)",
+					"-ObjC",
+					"-l\"AFNetworking\"",
+					"-l\"CHIPageControl\"",
+					"-l\"IQKeyboardManager\"",
+					"-l\"JXCategoryView\"",
+					"-l\"JXPagingView\"",
+					"-l\"MBProgressHUD\"",
+					"-l\"MJExtension\"",
+					"-l\"MJRefresh\"",
+					"-l\"Masonry\"",
+					"-l\"NTLBridge\"",
+					"-l\"QCloudCOSXML\"",
+					"-l\"QCloudCore\"",
+					"-l\"RSKImageCropper\"",
+					"-l\"Reachability\"",
+					"-l\"ReactiveObjC\"",
+					"-l\"SDWebImage\"",
+					"-l\"SSZipArchive\"",
+					"-l\"SocketRocket\"",
+					"-l\"TIMCommon\"",
+					"-l\"TUIChat\"",
+					"-l\"TUIConversation\"",
+					"-l\"TUICore\"",
+					"-l\"TUIGroup\"",
+					"-l\"TUISearch\"",
+					"-l\"TYCyclePagerView\"",
+					"-l\"Whiteboard\"",
+					"-l\"YYModel\"",
+					"-l\"c++\"",
+					"-l\"iOS-KS3SDK\"",
+					"-l\"iconv\"",
+					"-l\"icucore\"",
+					"-l\"jcore-noidfa-ios-2.7.1\"",
+					"-l\"jpush-ios-4.3.0\"",
+					"-l\"lottie-ios\"",
+					"-l\"opencore-amrnb\"",
+					"-l\"opencore-amrwb\"",
+					"-l\"resolv\"",
+					"-l\"sqlite3\"",
+					"-l\"stdc++\"",
+					"-l\"z\"",
+					"-framework",
+					"\"AVFoundation\"",
+					"-framework",
+					"\"Accelerate\"",
+					"-framework",
+					"\"AlipaySDK\"",
+					"-framework",
+					"\"AssetsLibrary\"",
+					"-framework",
+					"\"AudioToolbox\"",
+					"-framework",
+					"\"Bugly\"",
+					"-framework",
+					"\"CFNetwork\"",
+					"-framework",
+					"\"CoreFoundation\"",
+					"-framework",
+					"\"CoreGraphics\"",
+					"-framework",
+					"\"CoreMedia\"",
+					"-framework",
+					"\"CoreMotion\"",
+					"-framework",
+					"\"CoreServices\"",
+					"-framework",
+					"\"CoreTelephony\"",
+					"-framework",
+					"\"CoreText\"",
+					"-framework",
+					"\"Foundation\"",
+					"-framework",
+					"\"GLKit\"",
+					"-framework",
+					"\"ImSDK_Plus\"",
+					"-framework",
+					"\"ImageIO\"",
+					"-framework",
+					"\"MetalKit\"",
+					"-framework",
+					"\"QuartzCore\"",
+					"-framework",
+					"\"ReplayKit\"",
+					"-framework",
+					"\"RongChatRoom\"",
+					"-framework",
+					"\"RongCustomerService\"",
+					"-framework",
+					"\"RongDiscussion\"",
+					"-framework",
+					"\"RongIMKit\"",
+					"-framework",
+					"\"RongIMLib\"",
+					"-framework",
+					"\"RongIMLibCore\"",
+					"-framework",
+					"\"RongLocation\"",
+					"-framework",
+					"\"RongPublicService\"",
+					"-framework",
+					"\"RongRTCLib\"",
+					"-framework",
+					"\"RongSight\"",
+					"-framework",
+					"\"Security\"",
+					"-framework",
+					"\"StoreKit\"",
+					"-framework",
+					"\"SystemConfiguration\"",
+					"-framework",
+					"\"TXFFmpeg\"",
+					"-framework",
+					"\"TXLiteAVSDK_Professional\"",
+					"-framework",
+					"\"TXSoundTouch\"",
+					"-framework",
+					"\"UIKit\"",
+					"-framework",
+					"\"VideoToolbox\"",
+					"-framework",
+					"\"WebKit\"",
+					"-weak_framework",
+					"\"UserNotifications\"",
+					"-ld_classic",
+				);
 				PRODUCT_BUNDLE_IDENTIFIER = com.Colexiu.KulexiuForStudent;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_EMIT_LOC_STRINGS = YES;
@@ -8668,9 +8829,136 @@
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/SocialLibraries/Sina/SinaSDK",
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/UMSocialSDKPlugin",
 				);
-				MARKETING_VERSION = 1.5.1;
+				MARKETING_VERSION = 1.5.2;
 				MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
 				MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17";
+				OTHER_LDFLAGS = (
+					"$(inherited)",
+					"-ObjC",
+					"-l\"AFNetworking\"",
+					"-l\"CHIPageControl\"",
+					"-l\"IQKeyboardManager\"",
+					"-l\"JXCategoryView\"",
+					"-l\"JXPagingView\"",
+					"-l\"MBProgressHUD\"",
+					"-l\"MJExtension\"",
+					"-l\"MJRefresh\"",
+					"-l\"Masonry\"",
+					"-l\"NTLBridge\"",
+					"-l\"QCloudCOSXML\"",
+					"-l\"QCloudCore\"",
+					"-l\"RSKImageCropper\"",
+					"-l\"Reachability\"",
+					"-l\"ReactiveObjC\"",
+					"-l\"SDWebImage\"",
+					"-l\"SSZipArchive\"",
+					"-l\"SocketRocket\"",
+					"-l\"TIMCommon\"",
+					"-l\"TUIChat\"",
+					"-l\"TUIConversation\"",
+					"-l\"TUICore\"",
+					"-l\"TUIGroup\"",
+					"-l\"TUISearch\"",
+					"-l\"TYCyclePagerView\"",
+					"-l\"Whiteboard\"",
+					"-l\"YYModel\"",
+					"-l\"c++\"",
+					"-l\"iOS-KS3SDK\"",
+					"-l\"iconv\"",
+					"-l\"icucore\"",
+					"-l\"jcore-noidfa-ios-2.7.1\"",
+					"-l\"jpush-ios-4.3.0\"",
+					"-l\"lottie-ios\"",
+					"-l\"opencore-amrnb\"",
+					"-l\"opencore-amrwb\"",
+					"-l\"resolv\"",
+					"-l\"sqlite3\"",
+					"-l\"stdc++\"",
+					"-l\"z\"",
+					"-framework",
+					"\"AVFoundation\"",
+					"-framework",
+					"\"Accelerate\"",
+					"-framework",
+					"\"AlipaySDK\"",
+					"-framework",
+					"\"AssetsLibrary\"",
+					"-framework",
+					"\"AudioToolbox\"",
+					"-framework",
+					"\"Bugly\"",
+					"-framework",
+					"\"CFNetwork\"",
+					"-framework",
+					"\"CoreFoundation\"",
+					"-framework",
+					"\"CoreGraphics\"",
+					"-framework",
+					"\"CoreMedia\"",
+					"-framework",
+					"\"CoreMotion\"",
+					"-framework",
+					"\"CoreServices\"",
+					"-framework",
+					"\"CoreTelephony\"",
+					"-framework",
+					"\"CoreText\"",
+					"-framework",
+					"\"Foundation\"",
+					"-framework",
+					"\"GLKit\"",
+					"-framework",
+					"\"ImSDK_Plus\"",
+					"-framework",
+					"\"ImageIO\"",
+					"-framework",
+					"\"MetalKit\"",
+					"-framework",
+					"\"QuartzCore\"",
+					"-framework",
+					"\"ReplayKit\"",
+					"-framework",
+					"\"RongChatRoom\"",
+					"-framework",
+					"\"RongCustomerService\"",
+					"-framework",
+					"\"RongDiscussion\"",
+					"-framework",
+					"\"RongIMKit\"",
+					"-framework",
+					"\"RongIMLib\"",
+					"-framework",
+					"\"RongIMLibCore\"",
+					"-framework",
+					"\"RongLocation\"",
+					"-framework",
+					"\"RongPublicService\"",
+					"-framework",
+					"\"RongRTCLib\"",
+					"-framework",
+					"\"RongSight\"",
+					"-framework",
+					"\"Security\"",
+					"-framework",
+					"\"StoreKit\"",
+					"-framework",
+					"\"SystemConfiguration\"",
+					"-framework",
+					"\"TXFFmpeg\"",
+					"-framework",
+					"\"TXLiteAVSDK_Professional\"",
+					"-framework",
+					"\"TXSoundTouch\"",
+					"-framework",
+					"\"UIKit\"",
+					"-framework",
+					"\"VideoToolbox\"",
+					"-framework",
+					"\"WebKit\"",
+					"-weak_framework",
+					"\"UserNotifications\"",
+					"-ld_classic",
+				);
 				PRODUCT_BUNDLE_IDENTIFIER = com.Colexiu.KulexiuForStudent;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_EMIT_LOC_STRINGS = YES;
@@ -8816,7 +9104,23 @@
 			repositoryURL = "https://github.com/AudioKit/AudioKit.git";
 			requirement = {
 				kind = exactVersion;
-				version = 5.0.0;
+				version = 5.4.4;
+			};
+		};
+		BCFEE18B2AD15BD4000E888F /* XCRemoteSwiftPackageReference "AudioKitEX" */ = {
+			isa = XCRemoteSwiftPackageReference;
+			repositoryURL = "https://github.com/AudioKit/AudioKitEX.git";
+			requirement = {
+				kind = exactVersion;
+				version = 5.4.1;
+			};
+		};
+		BCFEE1912AD15C0E000E888F /* XCRemoteSwiftPackageReference "SoundpipeAudioKit" */ = {
+			isa = XCRemoteSwiftPackageReference;
+			repositoryURL = "https://github.com/AudioKit/SoundpipeAudioKit.git";
+			requirement = {
+				kind = exactVersion;
+				version = 5.4.1;
 			};
 		};
 /* End XCRemoteSwiftPackageReference section */
@@ -8827,6 +9131,16 @@
 			package = BCD9294D28F8FCA4006793E4 /* XCRemoteSwiftPackageReference "AudioKit" */;
 			productName = AudioKit;
 		};
+		BCFEE18C2AD15BD4000E888F /* AudioKitEX */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = BCFEE18B2AD15BD4000E888F /* XCRemoteSwiftPackageReference "AudioKitEX" */;
+			productName = AudioKitEX;
+		};
+		BCFEE1922AD15C0E000E888F /* SoundpipeAudioKit */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = BCFEE1912AD15C0E000E888F /* XCRemoteSwiftPackageReference "SoundpipeAudioKit" */;
+			productName = SoundpipeAudioKit;
+		};
 /* End XCSwiftPackageProductDependency section */
 	};
 	rootObject = 275E8A9D27E18F8800DD3F6E /* Project object */;

+ 29 - 2
KulexiuForStudent/KulexiuForStudent.xcworkspace/xcshareddata/swiftpm/Package.resolved

@@ -5,8 +5,35 @@
       "kind" : "remoteSourceControl",
       "location" : "https://github.com/AudioKit/AudioKit.git",
       "state" : {
-        "revision" : "36ea09c87bf703291a60e694742d56ff221c56ae",
-        "version" : "5.0.0"
+        "revision" : "576528c7618838ed3bdb967b4e176841994aa01d",
+        "version" : "5.4.4"
+      }
+    },
+    {
+      "identity" : "audiokitex",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/AudioKit/AudioKitEX.git",
+      "state" : {
+        "revision" : "ab5b5623e70b2f3c578a5e64ce23d3aea709bb41",
+        "version" : "5.4.1"
+      }
+    },
+    {
+      "identity" : "kissfft",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/AudioKit/KissFFT",
+      "state" : {
+        "revision" : "dd0636e151724b8ba2e0908eba4d99a6ff24d00c",
+        "version" : "1.0.0"
+      }
+    },
+    {
+      "identity" : "soundpipeaudiokit",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/AudioKit/SoundpipeAudioKit.git",
+      "state" : {
+        "revision" : "3be2802b20088de37f34f993966d918b65401a60",
+        "version" : "5.4.1"
       }
     }
   ],

+ 0 - 1
KulexiuForStudent/KulexiuForStudent/AppDelegate.h

@@ -31,7 +31,6 @@
 - (void)showMemoAlert;
 
 - (void)initTableBar;
-- (void)requestRongCloudToken;
 - (void)appTrackActionAuth;
 
 - (void)initLoginView;

+ 48 - 134
KulexiuForStudent/KulexiuForStudent/AppDelegate.m

@@ -34,6 +34,7 @@
 #import "HomeworkDetailViewController.h"
 #import "MyCourseViewController.h"
 #import "NotiferMessageViewController.h"
+#import "TenantNotiferCenterController.h"
 #import "LaunchAnimationViewController.h"
 #import "KSEnterLiveroomManager.h"
 
@@ -506,81 +507,7 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
                 self.outLinkParm = [NSMutableDictionary dictionaryWithDictionary:dict];
                 return;
             }
-            NSString *action = [dict ks_stringValueForKey:@"action"];
-            if ([action isEqualToString:@"app"]) {
-                NSString *pageType = [dict ks_stringValueForKey:@"pageTag"];
-                if ([pageType isEqualToString:@"buyPractice"] || [pageType isEqualToString:@"courseRemind"]) { // 课表
-                    [self.tabBarController tabBarSelectedWithIndex:1];
-                    CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                    [navCtrl popToRootViewControllerAnimated:YES];
-                }
-                else if ([pageType isEqualToString:@"homework"]) {
-                    NSString *parmString = [dict ks_stringValueForKey:@"params"];
-                    NSData *parmData = [parmString mj_JSONData];
-                    NSDictionary *parm = [NSJSONSerialization JSONObjectWithData:parmData options:NSJSONReadingMutableContainers error:&error];
-                    if (!error) {
-                        HomeworkDetailViewController *detailVC = [[HomeworkDetailViewController alloc] init];
-                        detailVC.courseId = [parm ks_stringValueForKey:@"courseId"];
-                        CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                        [navCtrl pushViewController:detailVC animated:YES];
-                    }
-                }
-                else if ([pageType isEqualToString:@"message"]) {
-                    UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
-                    if ([vc isKindOfClass:[UITabBarController class]]) {
-                        KSTabBarViewController *tabCtrl = (KSTabBarViewController *)vc;
-                        CustomNavViewController *navCtrl = (CustomNavViewController *)tabCtrl.selectedViewController;
-                        if ([navCtrl.visibleViewController isKindOfClass:NSClassFromString(@"NotiferMessageViewController")]) {
-                            NotiferMessageViewController *ctrl = (NotiferMessageViewController *)navCtrl.visibleViewController;
-                            [ctrl refreshView];
-                        }
-                        else {
-                            [self.tabBarController tabBarSelectedWithIndex:0];
-                            CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                            NotiferMessageViewController *ctrl = [[NotiferMessageViewController alloc] init];
-                            [navCtrl pushViewController:ctrl animated:YES];
-                        }
-                    }
-                    else {
-                        [self.tabBarController tabBarSelectedWithIndex:0];
-                        CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                        NotiferMessageViewController *ctrl = [[NotiferMessageViewController alloc] init];
-                        [navCtrl pushViewController:ctrl animated:YES];
-                    }
-                }
-                else {  // 统一跳转消息列表
-                    UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
-                    if ([vc isKindOfClass:[UITabBarController class]]) {
-                        KSTabBarViewController *tabCtrl = (KSTabBarViewController *)vc;
-                        CustomNavViewController *navCtrl = (CustomNavViewController *)tabCtrl.selectedViewController;
-                        if ([navCtrl.visibleViewController isKindOfClass:NSClassFromString(@"NotiferMessageViewController")]) {
-                            NotiferMessageViewController *ctrl = (NotiferMessageViewController *)navCtrl.visibleViewController;
-                            [ctrl refreshView];
-                        }
-                        else {
-                            [self.tabBarController tabBarSelectedWithIndex:0];
-                            CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                            NotiferMessageViewController *ctrl = [[NotiferMessageViewController alloc] init];
-                            [navCtrl pushViewController:ctrl animated:YES];
-                        }
-                    }
-                    else {
-                        [self.tabBarController tabBarSelectedWithIndex:0];
-                        CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                        NotiferMessageViewController *ctrl = [[NotiferMessageViewController alloc] init];
-                        [navCtrl pushViewController:ctrl animated:YES];
-                    }
-                }
-            }
-            else {
-                NSString *webUrl = [dict ks_stringValueForKey:@"url"];
-                if (![NSString isEmptyString:webUrl]) {
-                    KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-                    webCtrl.url = webUrl;
-                    CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                    [navCtrl pushViewController:webCtrl animated:YES];
-                }
-            }
+            [self handSource:dict];
         }
     }
     else {
@@ -744,60 +671,7 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
                     self.outLinkParm = [NSMutableDictionary dictionaryWithDictionary:dict];
                     return NO;
                 }
-                NSString *action = [dict ks_stringValueForKey:@"action"];
-                if ([action isEqualToString:@"app"]) {
-                    NSString *pageType = [dict ks_stringValueForKey:@"pageTag"];
-                    DISPLAY_INDEX index = DISPLAY_INDEX_FIRST;
-                    if ([pageType isEqualToString:@"practiceClass"]) { // 我的课程 ->陪练课
-                        index = DISPLAY_INDEX_FIRST;
-                        MyCourseViewController *ctrl = [[MyCourseViewController alloc] init];
-                        [ctrl displayWithIndex:index];
-                        CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                        [navCtrl pushViewController:ctrl animated:YES];
-                    }
-                    else if ([pageType isEqualToString:@"liveClass"]) { // 我的课程 ->直播课
-                        index = DISPLAY_INDEX_LIVE;
-                        MyCourseViewController *ctrl = [[MyCourseViewController alloc] init];
-                        [ctrl displayWithIndex:index];
-                        CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                        [navCtrl pushViewController:ctrl animated:YES];
-                    }
-                    else if ([pageType isEqualToString:@"videoClass"]) { // 我的课程 ->视频课
-                        index = DISPLAY_INDEX_VIEO;
-                        MyCourseViewController *ctrl = [[MyCourseViewController alloc] init];
-                        [ctrl displayWithIndex:index];
-                        CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                        [navCtrl pushViewController:ctrl animated:YES];
-                    }
-                    else if ([pageType isEqualToString:@"liveRoom"]) { // 直播
-                        NSString *parmString = [dict ks_stringValueForKey:@"params"];
-                        NSData *parmData = [parmString mj_JSONData];
-                        NSError *error;
-                        NSDictionary *parm = [NSJSONSerialization JSONObjectWithData:parmData options:NSJSONReadingMutableContainers error:&error];
-                        if (!error) {
-                            CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                            [KSEnterLiveroomManager joinLiveWithRoomId:[parm ks_stringValueForKey:@"liveRoomId"] inController:navCtrl callback:^{
-                                                            
-                            }];
-                        }
-                    }
-                }
-                else {  // 空 或者 h5
-                    NSString *webUrl = [dict ks_stringValueForKey:@"url"];
-                    if (![NSString isEmptyString:webUrl]) {
-                        KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
-                        webCtrl.url = webUrl;
-                        
-                        UIViewController *vc = self.window.rootViewController;
-                        if ([vc isKindOfClass:[self.tabBarController class]]) {
-                            CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
-                            [navCtrl pushViewController:webCtrl animated:YES];
-                        }
-                        else {
-                            UserDefaultSetObjectForKey(linkUrl, WEB_URL);
-                        }
-                    }
-                }
+                [self handSource:dict];
             }
         }
     }
@@ -834,11 +708,43 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
     return _alertView;
 }
 
-
-- (void)handleNotiferSource {
-    if (self.outLinkParm) {
-        NSDictionary *dict = [NSDictionary dictionaryWithDictionary:self.outLinkParm];
-        NSString *action = [dict ks_stringValueForKey:@"action"];
+- (void)handSource:(NSDictionary *)dict {
+    
+    NSString *action = [dict ks_stringValueForKey:@"action"];
+    NSString *clientType = [dict ks_stringValueForKey:@"clientType"];
+    if ([clientType isEqualToString:@"TENANT"]) { // 机构
+        NSString *webUrl = [dict ks_stringValueForKey:@"url"];
+        if (![NSString isEmptyString:webUrl]) {
+            KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
+            webCtrl.url = webUrl;
+            CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
+            [navCtrl pushViewController:webCtrl animated:YES];
+        }
+        else {  // 统一跳转消息列表
+            UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
+            if ([vc isKindOfClass:[UITabBarController class]]) {
+                KSTabBarViewController *tabCtrl = (KSTabBarViewController *)vc;
+                CustomNavViewController *navCtrl = (CustomNavViewController *)tabCtrl.selectedViewController;
+                if ([navCtrl.visibleViewController isKindOfClass:NSClassFromString(@"TenantNotiferCenterController")]) {
+                    TenantNotiferCenterController *ctrl = (TenantNotiferCenterController *)navCtrl.visibleViewController;
+                    [ctrl refreshView];
+                }
+                else {
+                    [self.tabBarController tabBarSelectedWithIndex:3];
+                    CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
+                    TenantNotiferCenterController *ctrl = [[TenantNotiferCenterController alloc] init];
+                    [navCtrl pushViewController:ctrl animated:YES];
+                }
+            }
+            else {
+                [self.tabBarController tabBarSelectedWithIndex:3];
+                CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
+                TenantNotiferCenterController *ctrl = [[TenantNotiferCenterController alloc] init];
+                [navCtrl pushViewController:ctrl animated:YES];
+            }
+        }
+    }
+    else {  // 平台
         if ([action isEqualToString:@"app"]) {
             NSString *pageType = [dict ks_stringValueForKey:@"pageTag"];
             if ([pageType isEqualToString:@"practiceClass"]) { // 我的课程 ->陪练课
@@ -947,6 +853,14 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
                 [navCtrl pushViewController:webCtrl animated:YES];
             }
         }
+    }
+    
+}
+
+
+- (void)handleNotiferSource {
+    if (self.outLinkParm) {
+        [self handSource:self.outLinkParm];
         self.outLinkParm = nil;
     }
 }

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Institution/Mine/tenant_message.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Institution/Mine/tenant_message.imageset/tenant_message@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Institution/Mine/tenant_message.imageset/tenant_message@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/MessageCenter/tenant_clearMsg.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/MessageCenter/tenant_clearMsg.imageset/tenant_clearMsg@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/MessageCenter/tenant_clearMsg.imageset/tenant_clearMsg@3x.png


+ 26 - 7
KulexiuForStudent/KulexiuForStudent/Common/Base/KSAccompanyWebViewController.m

@@ -16,6 +16,7 @@
 #import "KSCloudBeatView.h"
 #import "MidiPlayerEngine.h"
 #import "AccompanyLoadingView.h"
+#import "KSPremissionAlert.h"
 
 #define KSMidiSongFileKey (@"KSDownloadMidiSong")
 #import "KulexiuForStudent-swift.h"
@@ -389,12 +390,18 @@
                  [self sendDataToSocketService:sendData];
             }
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"openCamera"]) { // 开启摄像头
-                 PREMISSIONTYPE canOpenCamera = [RecordCheckManager checkCameraPremissionAvaiable:YES showInView:self.view];
-                 if (canOpenCamera == PREMISSIONTYPE_YES) {
-                      self.isCameraOpen = YES;
-                      [self.videoRecordManager configSessiondisplayInView:self.viewContainer];
-                      [self postMessage:parm];
-                 }
+                PREMISSIONTYPE canOpenCamera = [RecordCheckManager checkCameraPremissionAvaiable:NO showInView:nil];
+                PREMISSIONTYPE albumEnable =  [RecordCheckManager checkPhotoLibraryPremissionAvaiable:NO showInView:nil];
+                
+                if (canOpenCamera == PREMISSIONTYPE_YES) {
+                    self.isCameraOpen = YES;
+                    [self.videoRecordManager configSessiondisplayInView:self.viewContainer];
+                    [self postMessage:parm];
+                }
+                if (albumEnable == PREMISSIONTYPE_NO) {
+                    [self showAlertWithMessage:@"请开启相册访问权限" type:CHECKDEVICETYPE_CAMREA];
+                }
+                
             }
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"closeCamera"]) { // 关闭摄像头
                 self.isCameraOpen = NO;
@@ -710,6 +717,19 @@
     }
 }
     
+- (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {
+    [KSPremissionAlert shareInstanceDisplayImage:deviceType message:message showInView:self.view cancel:^{
+        
+    } confirm:^{
+        [self openSettingView];
+    }];
+    
+}
+
+- (void)openSettingView {
+    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
+
+}
 
 - (void)downloadUrl:(NSString *)url success:(void(^)(void))success faliure:(void(^)(void))faliure {
 //    [LOADING_MANAGER showHUD];
@@ -722,7 +742,6 @@
         }
         
     } faliure:^(NSError * _Nonnull error) {
-//        faliure();
     }];
 }
 

+ 20 - 20
KulexiuForStudent/KulexiuForStudent/Common/Define/KSDomain.h

@@ -18,16 +18,16 @@
 
 // 测试环境
 
-//#define hostURL (@"https://dev.colexiu.com")
-//#define SEALCLASSHOST (@"https://dev.colexiu.com/api-classroom")
-//#define WEBHOST (@"https://dev.colexiu.com/student")
-//#define TENANT_WEBHOST (@"https://dev.colexiu.com/tenant")
-//#define SOCKET_URL (@"wss://dev.colexiu.com/audioAnalysis")
-//#define JSPUSH_ENVIRONMENT (NO)
-//#define RCIM_KEY (@"0vnjpoad0jbdz")
-//#define SUBMIT_UUID (NO)
-//#define CONFIG_TXSDKAPPID (1400805079)
-//#define TXOfflinePushCertificateIDForAPNS (39557)
+#define hostURL (@"https://dev.colexiu.com")
+#define SEALCLASSHOST (@"https://dev.colexiu.com/api-classroom")
+#define WEBHOST (@"https://dev.colexiu.com/student")
+#define TENANT_WEBHOST (@"https://dev.colexiu.com/tenant")
+#define SOCKET_URL (@"wss://dev.colexiu.com/audioAnalysis")
+#define JSPUSH_ENVIRONMENT (NO)
+#define RCIM_KEY (@"0vnjpoad0jbdz")
+#define SUBMIT_UUID (NO)
+#define CONFIG_TXSDKAPPID (1400805079)
+#define TXOfflinePushCertificateIDForAPNS (39557)
 
 
 // 开发环境
@@ -56,16 +56,16 @@
 
 //#else
 
-#define hostURL (@"https://online.colexiu.com")
-#define SEALCLASSHOST (@"https://online.colexiu.com/api-classroom")
-#define WEBHOST (@"https://online.colexiu.com/student")
-#define TENANT_WEBHOST (@"https://online.colexiu.com//tenant")
-#define SOCKET_URL (@"wss://online.colexiu.com/audioAnalysis")
-#define JSPUSH_ENVIRONMENT (YES)
-#define RCIM_KEY (@"e5t4ouvpe42pa")
-#define SUBMIT_UUID (YES)
-#define CONFIG_TXSDKAPPID (1400799837)
-#define TXOfflinePushCertificateIDForAPNS (39560)
+//#define hostURL (@"https://online.colexiu.com")
+//#define SEALCLASSHOST (@"https://online.colexiu.com/api-classroom")
+//#define WEBHOST (@"https://online.colexiu.com/student")
+//#define TENANT_WEBHOST (@"https://online.colexiu.com//tenant")
+//#define SOCKET_URL (@"wss://online.colexiu.com/audioAnalysis")
+//#define JSPUSH_ENVIRONMENT (YES)
+//#define RCIM_KEY (@"e5t4ouvpe42pa")
+//#define SUBMIT_UUID (YES)
+//#define CONFIG_TXSDKAPPID (1400799837)
+//#define TXOfflinePushCertificateIDForAPNS (39560)
 
 //#endif
 

+ 2 - 0
KulexiuForStudent/KulexiuForStudent/Common/Tools/Extension/NSDate+Extension.h

@@ -167,6 +167,8 @@
  */
 - (BOOL)isToday;
 
+/// 是否今年
+- (BOOL)isCurrentYear;
 /**
  *  Add days to self
  *

+ 18 - 0
KulexiuForStudent/KulexiuForStudent/Common/Tools/Extension/NSDate+Extension.m

@@ -373,10 +373,28 @@
             && [components1 day] == [components2 day]);
 }
 
+- (BOOL)isSameYear:(NSDate *)anotherDate {
+    NSCalendar *calendar = [NSCalendar currentCalendar];
+    NSDateComponents *components1 = [calendar components:(NSCalendarUnitYear
+                                                          | NSCalendarUnitMonth
+                                                          | NSCalendarUnitDay)
+                                                fromDate:self];
+    NSDateComponents *components2 = [calendar components:(NSCalendarUnitYear
+                                                          | NSCalendarUnitMonth
+                                                          | NSCalendarUnitDay)
+                                                fromDate:anotherDate];
+    return ([components1 year] == [components2 year]);
+}
+
 - (BOOL)isToday {
     return [self isSameDay:[NSDate date]];
 }
 
+/// 是否今年
+- (BOOL)isCurrentYear {
+    return [self isSameYear:[NSDate date]];
+}
+
 - (NSDate *)dateByAddingDays:(NSUInteger)days {
     NSDateComponents *c = [[NSDateComponents alloc] init];
     c.day = days;

+ 1 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Home/Controller/TenantDarkViewController.m

@@ -95,6 +95,7 @@
     
     AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
     [appDelegate appTrackActionAuth];
+    [appDelegate handleNotiferSource];
 }
 
 

+ 14 - 3
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/Controller/InsititutionMineViewController.m

@@ -13,6 +13,7 @@
 #import "KSBaseWKWebViewController.h"
 #import "INSSettingViewController.h"
 #import "FeedbackViewController.h"
+#import "TenantNotiferCenterController.h"
 
 @interface InsititutionMineViewController ()<UIScrollViewDelegate>
 
@@ -66,7 +67,6 @@
     [_bodyView operationCallback:^(INSMINETYPE type) {
         [weakSelf operationAction:type];
     }];
-
 }
 
 
@@ -189,13 +189,24 @@
     if (!_navView) {
         _navView = [InstitutionMineNavView shareInstance];
         MJWeakSelf;
-        [_navView mineNavAction:^{
-            [weakSelf settingAction];
+        [_navView mineNavAction:^(TENANT_NAV type) {
+            if (type == TENANT_NAV_SETTING) {
+                [weakSelf settingAction];
+            }
+            else {
+                [weakSelf notiferCenter];
+            }
         }];
+        
     }
     return _navView;
 }
 
+- (void)notiferCenter {
+    TenantNotiferCenterController *ctrl = [[TenantNotiferCenterController alloc] init];
+    [self.navigationController pushViewController:ctrl animated:YES];
+}
+
 - (void)settingAction {
     INSSettingViewController *settingVC = [[INSSettingViewController alloc] init];
     [self.navigationController pushViewController:settingVC animated:YES];

+ 18 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/Controller/TenantNotiferCenterController.h

@@ -0,0 +1,18 @@
+//
+//  TenantNotiferCenterController.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2023/10/8.
+//
+
+#import "KSBaseViewController.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TenantNotiferCenterController : KSBaseViewController
+
+- (void)refreshView;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 254 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/Controller/TenantNotiferCenterController.m

@@ -0,0 +1,254 @@
+//
+//  TenantNotiferCenterController.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2023/10/8.
+//
+
+#import "TenantNotiferCenterController.h"
+#import "TenantNotiferNavView.h"
+#import "NotiferMessageModel.h"
+#import "TenantNotiferMessageCell.h"
+#import "KSBaseWKWebViewController.h"
+
+@interface TenantNotiferCenterController ()<UITableViewDelegate, UITableViewDataSource>
+
+@property (nonatomic, strong) TenantNotiferNavView *navView;
+
+@property (nonatomic, assign) BOOL hasUnreadCount;
+
+@property (nonatomic, strong) UITableView *tableView;
+
+@end
+
+@implementation TenantNotiferCenterController
+
+- (void)refreshView {
+    [self queryUnReadCount];
+    [self resetSourceAndRequest];
+}
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    self.ks_prefersNavigationBarHidden = YES;
+    [self configUI];
+}
+
+- (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+    [self queryUnReadCount];
+    [self resetSourceAndRequest];
+}
+
+- (void)configUI {
+    [self.scrollView removeFromSuperview];
+    self.view.backgroundColor = [UIColor whiteColor];
+    [self.view addSubview:self.navView];
+    [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.mas_equalTo(self.view);
+        make.height.mas_equalTo(kNaviBarHeight);
+    }];
+    [self.view addSubview:self.tableView];
+    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(self.view);
+        make.top.mas_equalTo(self.navView.mas_bottom);
+        make.bottom.mas_equalTo(self.view.mas_bottom).offset(-iPhoneXSafeBottomMargin);
+    }];
+    
+    MJWeakSelf;
+    self.tableView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
+        [weakSelf resetSourceAndRequest];
+    }];
+    self.tableView.mj_footer = [KSGifRefreshFooter footerWithRefreshingBlock:^{
+        if (weakSelf.isLoadMore) {
+            weakSelf.pages += 1;
+            [weakSelf requestData];
+        }
+        else {
+            [weakSelf.tableView.mj_footer endRefreshingWithNoMoreData];
+        }
+    }];
+}
+
+- (void)resetSourceAndRequest {
+    [self resetParamenter];
+    [self requestData];
+    [self queryUnReadCount];
+}
+
+- (void)resetParamenter {
+    self.pages = 1;
+    self.isLoadMore = YES;
+    self.dataArray = [NSMutableArray array];
+    [self.tableView.mj_footer resetNoMoreData];
+    [self setPromptString:@"暂无消息~" imageName:@"tenant_wd_img_zwsj" inView:self.tableView];
+    [self.tableView reloadData];
+}
+
+- (void)queryUnReadCount {
+    
+}
+
+- (void)endRefresh {
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        [self.tableView.mj_header endRefreshing];
+        [self.tableView.mj_footer endRefreshing];
+    });
+}
+- (void)requestData {
+    NSString *groupType = nil;
+    [LOADING_MANAGER showHUD];
+    [KSNetworkingManager sysMessageListRequest:KS_POST group:groupType page:self.pages rows:self.rows success:^(NSDictionary * _Nonnull dic) {
+        [LOADING_MANAGER removeHUD];
+        [self endRefresh];
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            // rows
+            NSArray *sourceArray = [[dic ks_dictionaryValueForKey:@"data"] ks_arrayValueForKey:@"rows"];
+            for (NSDictionary *parm in sourceArray) {
+                NotiferMessageModel *model = [[NotiferMessageModel alloc] initWithDictionary:parm];
+                [self.dataArray addObject:model];
+            }
+            if (sourceArray.count < self.rows) {
+                self.isLoadMore = NO;
+            }
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+        [self.tableView reloadData];
+        [self changePromptLabelState];
+
+    } faliure:^(NSError * _Nonnull error) {
+        [LOADING_MANAGER removeHUD];
+        [self endRefresh];
+        if (self.networkAvaiable == NO) {
+            [self setPromptString:@"暂无网络" imageName:@"no_networking" inView:self.tableView];
+        }
+        [self.dataArray removeAllObjects];
+        [self.tableView reloadData];
+        [self changePromptLabelState];
+    }];
+}
+
+
+- (void)clearNotiferAction {
+    [KSNetworkingManager batchSetReadRequest:KS_POST success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"清除成功"];
+            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+                [self resetSourceAndRequest];
+            });
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+}
+
+#pragma mark ----- table data source
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    return self.dataArray.count;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    NotiferMessageModel *model = self.dataArray[indexPath.row];
+    TenantNotiferMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TenantNotiferMessageCell"];
+    [cell configCellWithSource:model];
+    return cell;
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    // 选择跳转
+    NotiferMessageModel *model = self.dataArray[indexPath.row];
+    if (model.readStatus == 0) {
+        TenantNotiferMessageCell *cell = [tableView cellForRowAtIndexPath:indexPath];
+        [self readMessage:model baseCell:cell];
+    }
+    else {
+        // 跳转页面
+        [self toDetailViewWithTypeString:model.memo];
+    }
+}
+
+- (void)readMessage:(NotiferMessageModel *)model baseCell:(TenantNotiferMessageCell *)cell {
+    [KSNetworkingManager setReadMessage:KS_POST messageId:model.internalBaseClassIdentifier success:^(NSDictionary * _Nonnull dic) {
+        if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
+            [self queryUnReadCount];
+            model.readStatus = 1;
+            cell.isRead = YES;
+            // 跳转页面
+            [self toDetailViewWithTypeString:model.memo];
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+}
+
+- (void)toDetailViewWithTypeString:(NSString *)memo {
+    if (![NSString isEmptyString:memo]) {
+        NSData *jsonData = [memo mj_JSONData];
+        NSError *error;
+        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
+        if (!error) {
+            NSString *webUrl = [dict ks_stringValueForKey:@"url"];
+            if (![NSString isEmptyString:webUrl]) {
+                KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
+                webCtrl.url = webUrl;
+                CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
+                [navCtrl pushViewController:webCtrl animated:YES];
+            }
+        }
+        
+    }
+}
+
+#pragma mark ---- lazying
+- (TenantNotiferNavView *)navView {
+    if (!_navView) {
+        _navView = [TenantNotiferNavView shareInstance];
+        MJWeakSelf;
+        [_navView notiferNavAction:^(BOOL isBack) {
+            if (isBack) {
+                [weakSelf backAction];
+            }
+            else {
+                [weakSelf clearNotiferAction];
+            }
+        }];
+    }
+    return _navView;
+}
+
+
+- (UITableView *)tableView {
+    if (!_tableView) {
+        _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
+        _tableView.backgroundColor = [UIColor clearColor];
+        _tableView.delegate = self;
+        _tableView.dataSource = self;
+        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+        [_tableView registerNib:[UINib nibWithNibName:@"TenantNotiferMessageCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"TenantNotiferMessageCell"];
+        _tableView.rowHeight = 77.0f;
+        UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 15)];
+        bottomView.backgroundColor = [UIColor clearColor];
+        _tableView.tableFooterView = bottomView;
+    }
+    return _tableView;
+}
+/*
+#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

+ 10 - 1
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineNavView.h

@@ -7,12 +7,21 @@
 
 #import <UIKit/UIKit.h>
 
-typedef void(^INSMineNavAction)(void);
+typedef NS_ENUM(NSInteger, TENANT_NAV) {
+    TENANT_NAV_SETTING, // 设置
+    TENANT_NAV_NOTIFER, // 通知
+};
+
+typedef void(^INSMineNavAction)(TENANT_NAV type);
 
 NS_ASSUME_NONNULL_BEGIN
 
 @interface InstitutionMineNavView : UIView
 
+@property (weak, nonatomic) IBOutlet UIView *dotView;
+
+@property (weak, nonatomic) IBOutlet UILabel *countLabel;
+
 @property (weak, nonatomic) IBOutlet UIView *lineView;
 
 + (instancetype)shareInstance;

+ 12 - 1
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineNavView.m

@@ -15,6 +15,10 @@
 @end
 
 @implementation InstitutionMineNavView
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    self.dotView.hidden = YES;
+}
 
 + (instancetype)shareInstance {
     InstitutionMineNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"InstitutionMineNavView" owner:nil options:nil] firstObject];
@@ -29,10 +33,17 @@
 
 - (IBAction)buttonAction:(id)sender {
     if (self.callback) {
-        self.callback();
+        self.callback(TENANT_NAV_SETTING);
+    }
+}
+
+- (IBAction)notiferCenter:(id)sender {
+    if (self.callback) {
+        self.callback(TENANT_NAV_NOTIFER);
     }
 }
 
+
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.

+ 52 - 2
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineNavView.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22154" 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="21679"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22130"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -38,11 +38,58 @@
                                         <constraint firstAttribute="height" constant="1" id="0G9-bs-BQy"/>
                                     </constraints>
                                 </view>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tAW-JD-scX">
+                                    <rect key="frame" x="300" y="2" width="40" height="40"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="40" id="ZeB-Tg-9ku"/>
+                                        <constraint firstAttribute="height" constant="40" id="miw-QQ-O1U"/>
+                                    </constraints>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <state key="normal" image="tenant_message"/>
+                                    <connections>
+                                        <action selector="notiferCenter:" destination="iN0-l3-epB" eventType="touchUpInside" id="SxD-tr-FGg"/>
+                                    </connections>
+                                </button>
+                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ewR-Ap-6SH">
+                                    <rect key="frame" x="324.66666666666669" y="10" width="15" height="15"/>
+                                    <subviews>
+                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nJu-gF-rv4">
+                                            <rect key="frame" x="4" y="0.0" width="7" height="15"/>
+                                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="10"/>
+                                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                            <nil key="highlightedColor"/>
+                                        </label>
+                                    </subviews>
+                                    <color key="backgroundColor" red="1" green="0.062745098039215685" blue="0.21176470588235294" alpha="1" colorSpace="calibratedRGB"/>
+                                    <constraints>
+                                        <constraint firstItem="nJu-gF-rv4" firstAttribute="centerY" secondItem="ewR-Ap-6SH" secondAttribute="centerY" id="EjO-tU-DgT"/>
+                                        <constraint firstAttribute="height" constant="15" id="Kwu-pT-hdP"/>
+                                        <constraint firstItem="nJu-gF-rv4" firstAttribute="leading" secondItem="ewR-Ap-6SH" secondAttribute="leading" constant="4" id="QwM-4Q-ZGz"/>
+                                        <constraint firstItem="nJu-gF-rv4" firstAttribute="top" secondItem="ewR-Ap-6SH" secondAttribute="top" id="jeP-D3-21n"/>
+                                        <constraint firstAttribute="bottom" secondItem="nJu-gF-rv4" secondAttribute="bottom" id="qVQ-CG-3fB"/>
+                                        <constraint firstAttribute="trailing" secondItem="nJu-gF-rv4" secondAttribute="trailing" constant="4" id="rIP-t9-KRX"/>
+                                    </constraints>
+                                    <userDefinedRuntimeAttributes>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                            <real key="value" value="1"/>
+                                        </userDefinedRuntimeAttribute>
+                                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                            <color key="value" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </userDefinedRuntimeAttribute>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                            <real key="value" value="7.5"/>
+                                        </userDefinedRuntimeAttribute>
+                                    </userDefinedRuntimeAttributes>
+                                </view>
                             </subviews>
                             <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                             <constraints>
+                                <constraint firstItem="ewR-Ap-6SH" firstAttribute="top" secondItem="tAW-JD-scX" secondAttribute="top" constant="8" id="41i-7K-12d"/>
                                 <constraint firstItem="i9Z-nS-HTl" firstAttribute="centerY" secondItem="8bj-IM-ZrU" secondAttribute="centerY" id="4Tu-xn-BLJ"/>
                                 <constraint firstAttribute="trailing" secondItem="i9Z-nS-HTl" secondAttribute="trailing" constant="8" id="4Vr-rS-9Zc"/>
+                                <constraint firstItem="ewR-Ap-6SH" firstAttribute="centerX" secondItem="tAW-JD-scX" secondAttribute="trailing" constant="-8" id="5vI-xl-Ceq"/>
+                                <constraint firstItem="i9Z-nS-HTl" firstAttribute="leading" secondItem="tAW-JD-scX" secondAttribute="trailing" constant="5" id="Djb-kb-b1v"/>
+                                <constraint firstItem="tAW-JD-scX" firstAttribute="centerY" secondItem="8bj-IM-ZrU" secondAttribute="centerY" id="aKL-y0-trw"/>
                                 <constraint firstAttribute="height" constant="44" id="cAd-fz-cWk"/>
                                 <constraint firstItem="uBH-qe-Dun" firstAttribute="leading" secondItem="8bj-IM-ZrU" secondAttribute="leading" id="cEw-66-In8"/>
                                 <constraint firstAttribute="trailing" secondItem="uBH-qe-Dun" secondAttribute="trailing" id="lVV-uo-rck"/>
@@ -69,6 +116,8 @@
             <nil key="simulatedBottomBarMetrics"/>
             <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
             <connections>
+                <outlet property="countLabel" destination="nJu-gF-rv4" id="RUO-nS-dlN"/>
+                <outlet property="dotView" destination="ewR-Ap-6SH" id="sqW-uk-dYf"/>
                 <outlet property="lineView" destination="uBH-qe-Dun" id="0H2-1A-4tV"/>
             </connections>
             <point key="canvasLocation" x="37.404580152671755" y="-161.97183098591549"/>
@@ -76,5 +125,6 @@
     </objects>
     <resources>
         <image name="insititution_setting" width="24" height="24"/>
+        <image name="tenant_message" width="24" height="24"/>
     </resources>
 </document>

+ 21 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferMessageCell.h

@@ -0,0 +1,21 @@
+//
+//  TenantNotiferMessageCell.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2023/10/8.
+//
+
+#import <UIKit/UIKit.h>
+#import "NotiferMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TenantNotiferMessageCell : UITableViewCell
+
+@property (nonatomic, assign) BOOL isRead; // 是否已读
+
+- (void)configCellWithSource:(NotiferMessageModel *)model;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 96 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferMessageCell.m

@@ -0,0 +1,96 @@
+//
+//  TenantNotiferMessageCell.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2023/10/8.
+//
+
+#import "TenantNotiferMessageCell.h"
+#import "NSDate+Extension.h"
+
+@interface TenantNotiferMessageCell ()
+
+@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
+
+@property (weak, nonatomic) IBOutlet UIImageView *messageTypeView;
+
+@property (weak, nonatomic) IBOutlet UIView *redDot;
+
+@property (weak, nonatomic) IBOutlet UILabel *topTitleLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *descMessageLabel;
+
+@property (nonatomic, strong) NotiferMessageModel *model;
+
+@end
+
+@implementation TenantNotiferMessageCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+- (void)configCellWithSource:(NotiferMessageModel *)model {
+    self.model = model;
+    self.isRead = model.readStatus == 1 ? YES : NO;
+    // 根据type设置图片
+    NSDateFormatter *dateFormatter = [NSObject getDateformatter];
+    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
+    NSDate *messageDate = [dateFormatter dateFromString:model.sendTime];
+    NSDate *currentDate = [NSDate date];
+    NSTimeInterval interval = [currentDate timeIntervalSinceDate:messageDate];
+    NSString *timeDesc = @"";
+    if (interval >= 0 && interval < 10 * 60) {
+        timeDesc = @"刚刚";
+    }
+    else if ([messageDate isToday]) {
+        [dateFormatter setDateFormat:@"HH:mm"];
+        timeDesc = [dateFormatter stringFromDate:messageDate];
+    }
+    else if ([messageDate isCurrentYear]) {
+        [dateFormatter setDateFormat:@"MM-dd"];
+        timeDesc = [dateFormatter stringFromDate:messageDate];
+    }
+    else {
+        [dateFormatter setDateFormat:@"yyyy-MM-dd"];
+        timeDesc = [dateFormatter stringFromDate:messageDate];
+    }
+    self.timeLabel.text = [NSString returnNoNullStringWithString:timeDesc];
+    self.topTitleLabel.text = [NSString returnNoNullStringWithString:model.title];
+    
+    self.descMessageLabel.text = [NSString returnNoNullStringWithString:model.content];
+    
+//    NSString *messgage = [NSString returnNoNullStringWithString:self.model.content];
+//    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
+//    [paragraphStyle setLineSpacing:4];//调整行间距
+//    paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
+//    
+//    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:messgage attributes:@{NSParagraphStyleAttributeName:paragraphStyle,NSFontAttributeName:[UIFont systemFontOfSize:13.0f],NSForegroundColorAttributeName:HexRGB(0x7a7a7a)}];
+//    self.descMessageLabel.attributedText = attrStr;
+    
+//    if (![NSString isEmptyString:imgName]) {
+//        [self.messageTypeView setImage:[UIImage imageNamed:imgName]];
+//    }
+//    else {
+//        [self.messageTypeView setImage:[UIImage imageNamed:@"notifer_unknow"]];
+//    }
+}
+
+- (void)setIsRead:(BOOL)isRead {
+    _isRead = isRead;
+    if (isRead) {
+        self.redDot.hidden = YES;
+    }
+    else {
+        self.redDot.hidden = NO;
+    }
+}
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end

+ 116 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferMessageCell.xib

@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22154" 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="22130"/>
+        <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="77" id="KGk-i7-Jjw" customClass="TenantNotiferMessageCell">
+            <rect key="frame" x="0.0" y="0.0" width="392" height="77"/>
+            <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="392" height="77"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sXQ-qt-Apo">
+                        <rect key="frame" x="0.0" y="0.0" width="392" height="77"/>
+                        <subviews>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="notifer_unknow" translatesAutoresizingMaskIntoConstraints="NO" id="enL-C5-C4b">
+                                <rect key="frame" x="13" y="16" width="45" height="45"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="45" id="SiN-WL-srC"/>
+                                    <constraint firstAttribute="height" constant="45" id="sp4-QE-pK2"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="22.5"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </imageView>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="您好,长笛基础教学·李老师的直播课60分钟后…教学·李老师的直播课60分钟后…" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VaQ-F3-F4D">
+                                <rect key="frame" x="68" y="40" width="311" height="15.666666666666664"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                                <color key="textColor" red="0.46666666666666667" green="0.46666666666666667" blue="0.46666666666666667" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2022-3-25" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yv6-Zy-niG">
+                                <rect key="frame" x="304" y="20" width="75" height="14"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="75" id="aG8-Pe-LAx"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                <color key="textColor" red="0.46666666666666667" green="0.46666666666666667" blue="0.46666666666666667" 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="4hp-bA-Hl4">
+                                <rect key="frame" x="68" y="16" width="65.666666666666686" height="22"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="22" id="Naf-BW-EaS"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="DUl-Lh-1pe">
+                                <rect key="frame" x="47" y="16" width="11" height="11"/>
+                                <color key="backgroundColor" red="1" green="0.062745098039215685" blue="0.21176470588235294" alpha="1" colorSpace="calibratedRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="11" id="HC8-2f-3o9"/>
+                                    <constraint firstAttribute="width" constant="11" id="bfc-G1-AUa"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="6.5"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <constraints>
+                            <constraint firstItem="yv6-Zy-niG" firstAttribute="centerY" secondItem="4hp-bA-Hl4" secondAttribute="centerY" id="8a6-g0-Zp0"/>
+                            <constraint firstItem="VaQ-F3-F4D" firstAttribute="leading" secondItem="4hp-bA-Hl4" secondAttribute="leading" id="AWh-41-mxE"/>
+                            <constraint firstItem="4hp-bA-Hl4" firstAttribute="top" secondItem="enL-C5-C4b" secondAttribute="top" id="C8K-ei-ZIZ"/>
+                            <constraint firstItem="enL-C5-C4b" firstAttribute="leading" secondItem="sXQ-qt-Apo" secondAttribute="leading" constant="13" id="Lxm-H6-WF7"/>
+                            <constraint firstAttribute="trailing" secondItem="yv6-Zy-niG" secondAttribute="trailing" constant="13" id="Ua4-8b-grZ"/>
+                            <constraint firstItem="DUl-Lh-1pe" firstAttribute="top" secondItem="enL-C5-C4b" secondAttribute="top" id="a7v-8v-T9t"/>
+                            <constraint firstItem="yv6-Zy-niG" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="4hp-bA-Hl4" secondAttribute="trailing" constant="10" id="bB4-7H-0wV"/>
+                            <constraint firstItem="DUl-Lh-1pe" firstAttribute="trailing" secondItem="enL-C5-C4b" secondAttribute="trailing" id="eJ9-uX-ODl"/>
+                            <constraint firstItem="enL-C5-C4b" firstAttribute="centerY" secondItem="sXQ-qt-Apo" secondAttribute="centerY" id="j56-5l-eTD"/>
+                            <constraint firstItem="VaQ-F3-F4D" firstAttribute="top" secondItem="4hp-bA-Hl4" secondAttribute="bottom" constant="2" id="s4z-0X-1DW"/>
+                            <constraint firstItem="4hp-bA-Hl4" firstAttribute="leading" secondItem="enL-C5-C4b" secondAttribute="trailing" constant="10" id="sxe-xL-JHx"/>
+                            <constraint firstAttribute="trailing" secondItem="VaQ-F3-F4D" secondAttribute="trailing" constant="13" id="tJx-9I-eP0"/>
+                        </constraints>
+                    </view>
+                </subviews>
+                <constraints>
+                    <constraint firstAttribute="trailing" secondItem="sXQ-qt-Apo" secondAttribute="trailing" id="5zW-Nu-vOe"/>
+                    <constraint firstItem="sXQ-qt-Apo" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="Jfq-zd-Cw8"/>
+                    <constraint firstItem="sXQ-qt-Apo" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="VWi-Az-BZr"/>
+                    <constraint firstAttribute="bottom" secondItem="sXQ-qt-Apo" secondAttribute="bottom" id="tld-IZ-rTY"/>
+                </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="descMessageLabel" destination="VaQ-F3-F4D" id="jio-ct-VA1"/>
+                <outlet property="messageTypeView" destination="enL-C5-C4b" id="tmB-WJ-OBP"/>
+                <outlet property="redDot" destination="DUl-Lh-1pe" id="JkK-Es-W4O"/>
+                <outlet property="timeLabel" destination="yv6-Zy-niG" id="Z9G-gW-5BN"/>
+                <outlet property="topTitleLabel" destination="4hp-bA-Hl4" id="KnM-ZK-7Ua"/>
+            </connections>
+            <point key="canvasLocation" x="117.55725190839694" y="11.267605633802818"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="notifer_unknow" width="43" height="42"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferNavView.h

@@ -0,0 +1,22 @@
+//
+//  TenantNotiferNavView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2023/10/8.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^TenantNotiferCallback)(BOOL isBack);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TenantNotiferNavView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)notiferNavAction:(TenantNotiferCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 48 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferNavView.m

@@ -0,0 +1,48 @@
+//
+//  TenantNotiferNavView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2023/10/8.
+//
+
+#import "TenantNotiferNavView.h"
+
+@interface TenantNotiferNavView ()
+
+@property (nonatomic, copy) TenantNotiferCallback callback;
+
+
+@end
+
+@implementation TenantNotiferNavView
+
++ (instancetype)shareInstance {
+    TenantNotiferNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"TenantNotiferNavView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)notiferNavAction:(TenantNotiferCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)backAction:(id)sender {
+    if (self.callback) {
+        self.callback(YES);
+    }
+}
+- (IBAction)clearAction:(id)sender {
+    if (self.callback) {
+        self.callback(NO);
+    }
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 96 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantNotiferNavView.xib

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22154" 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="22130"/>
+        <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="TenantNotiferNavView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="88"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ewD-EU-Ade">
+                    <rect key="frame" x="0.0" y="44" width="393" height="44"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="back_black" translatesAutoresizingMaskIntoConstraints="NO" id="6Lo-Bf-n4R">
+                            <rect key="frame" x="14" y="12" width="12" height="20"/>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Gvz-dw-AFR">
+                            <rect key="frame" x="0.0" y="0.0" width="44" height="44"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="44" id="cKm-34-QXi"/>
+                            </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="LIU-Jn-s6K"/>
+                            </connections>
+                        </button>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="tenant_clearMsg" translatesAutoresizingMaskIntoConstraints="NO" id="znT-ZX-LJW">
+                            <rect key="frame" x="300.66666666666669" y="13" width="18" height="18"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="18" id="TWf-Gg-7Us"/>
+                                <constraint firstAttribute="height" constant="18" id="ngl-g1-GHg"/>
+                            </constraints>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="JnV-fS-tbt">
+                            <rect key="frame" x="300.66666666666669" y="0.0" width="79.333333333333314" height="44"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="clearAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Ua5-2u-1S5"/>
+                            </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="dhz-NW-nkR">
+                            <rect key="frame" x="159.66666666666666" y="11" width="74" height="22"/>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" 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="0YO-CY-enM">
+                            <rect key="frame" x="322.66666666666669" y="13.666666666666664" width="57.333333333333314" height="17"/>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="znT-ZX-LJW" firstAttribute="centerY" secondItem="0YO-CY-enM" secondAttribute="centerY" id="35Q-Zt-9Ci"/>
+                        <constraint firstAttribute="bottom" secondItem="JnV-fS-tbt" secondAttribute="bottom" id="6Hz-yu-VE5"/>
+                        <constraint firstItem="6Lo-Bf-n4R" firstAttribute="leading" secondItem="ewD-EU-Ade" secondAttribute="leading" constant="14" id="CrL-tz-G21"/>
+                        <constraint firstItem="JnV-fS-tbt" firstAttribute="top" secondItem="ewD-EU-Ade" secondAttribute="top" id="Dgj-Tf-6rM"/>
+                        <constraint firstItem="znT-ZX-LJW" firstAttribute="centerY" secondItem="ewD-EU-Ade" secondAttribute="centerY" id="ELV-bx-VOY"/>
+                        <constraint firstAttribute="bottom" secondItem="Gvz-dw-AFR" secondAttribute="bottom" id="NFy-ao-xz4"/>
+                        <constraint firstItem="dhz-NW-nkR" firstAttribute="centerY" secondItem="ewD-EU-Ade" secondAttribute="centerY" id="SVG-iu-hxz"/>
+                        <constraint firstItem="Gvz-dw-AFR" firstAttribute="top" secondItem="ewD-EU-Ade" secondAttribute="top" id="SbP-CY-gfh"/>
+                        <constraint firstItem="0YO-CY-enM" firstAttribute="leading" secondItem="znT-ZX-LJW" secondAttribute="trailing" constant="4" id="Umu-oU-nPe"/>
+                        <constraint firstItem="6Lo-Bf-n4R" firstAttribute="centerY" secondItem="ewD-EU-Ade" secondAttribute="centerY" id="XmC-AW-SRg"/>
+                        <constraint firstItem="JnV-fS-tbt" firstAttribute="leading" secondItem="znT-ZX-LJW" secondAttribute="leading" id="aU8-2f-9q4"/>
+                        <constraint firstAttribute="trailing" secondItem="0YO-CY-enM" secondAttribute="trailing" constant="13" id="bhc-qs-EjL"/>
+                        <constraint firstItem="dhz-NW-nkR" firstAttribute="centerX" secondItem="ewD-EU-Ade" secondAttribute="centerX" id="cup-1P-8L1"/>
+                        <constraint firstItem="0YO-CY-enM" firstAttribute="trailing" secondItem="JnV-fS-tbt" secondAttribute="trailing" id="gLF-xe-W03"/>
+                        <constraint firstAttribute="height" constant="44" id="xXZ-XN-iPS"/>
+                        <constraint firstItem="Gvz-dw-AFR" firstAttribute="leading" secondItem="ewD-EU-Ade" secondAttribute="leading" id="xzi-4d-JAu"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="ewD-EU-Ade" secondAttribute="bottom" id="0I5-fx-mUs"/>
+                <constraint firstAttribute="trailing" secondItem="ewD-EU-Ade" secondAttribute="trailing" id="LHX-o0-mBJ"/>
+                <constraint firstItem="ewD-EU-Ade" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="zdz-tQ-gv5"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="64.885496183206101" y="-54.929577464788736"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="back_black" width="12" height="20"/>
+        <image name="tenant_clearMsg" width="18" height="18"/>
+    </resources>
+</document>

+ 2 - 2
KulexiuForStudent/KulexiuForStudent/InstitutionModule/TabbarController/InstitutionTabBarController.m

@@ -86,8 +86,8 @@
 }
 
 - (void)tabBarSelectedWithIndex:(NSInteger)index {
-    if (index == 2) { // 跳转到聊天
-        index = 1;
+    if (index >= 2) { // 跳转到聊天
+        index -= 1;
     }
     [self setSelectedIndex:index];
     UIViewController *controller = [self.viewControllers objectAtIndex:index];

+ 34 - 4
KulexiuForStudent/KulexiuForStudent/Module/Chat/Controller/TXCustom/KSTXBaseChatViewController.m

@@ -44,6 +44,9 @@
 #import "KSEnterLiveroomManager.h"
 #import "KSAccompanyWebViewController.h"
 
+#import "RecordCheckManager.h"
+#import "KSPremissionAlert.h"
+
 static UIView *gCustomTopView;
 
 @interface KSTXBaseChatViewController ()
@@ -122,12 +125,39 @@ static UIView *gCustomTopView;
     }];
 }
 - (void)showMusic:(NSString *)songId {
-    KSAccompanyWebViewController *detailCtrl = [[KSAccompanyWebViewController alloc] init];
-    detailCtrl.url = [NSString stringWithFormat:@"%@/accompany?id=%@",hostURL, songId];
-    detailCtrl.parmDic = @{@"isOpenLight" : @(YES), @"orientation" : @(0),@"isHideTitle" : @(YES)};
-    [self.navigationController pushViewController:detailCtrl animated:YES];
+    PREMISSIONTYPE micEnable = [RecordCheckManager checkPermissionShowAlert:NO showInView:nil];
+    PREMISSIONTYPE cameraEnable = [RecordCheckManager checkCameraPremissionAvaiable:NO showInView:nil];
+    if (micEnable == PREMISSIONTYPE_YES && cameraEnable == PREMISSIONTYPE_YES) {
+        KSAccompanyWebViewController *detailCtrl = [[KSAccompanyWebViewController alloc] init];
+        detailCtrl.url = [NSString stringWithFormat:@"%@/accompany?id=%@",hostURL, songId];
+        detailCtrl.parmDic = @{@"isOpenLight" : @(YES), @"orientation" : @(0),@"isHideTitle" : @(YES)};
+        [self.navigationController pushViewController:detailCtrl animated:YES];
+    }
+    else {
+        if (micEnable == PREMISSIONTYPE_NO && cameraEnable == PREMISSIONTYPE_NO) { // 如果麦克风权限和摄像头权限都没有
+            [self showAlertWithMessage:@"请开启相机和麦克风访问权限" type:CHECKDEVICETYPE_BOTH];
+        }
+        else if (micEnable == PREMISSIONTYPE_NO) { // 如果没有麦克风权限
+            [self showAlertWithMessage:@"请开启麦克风访问权限" type:CHECKDEVICETYPE_MIC];
+        }
+        else if (cameraEnable == PREMISSIONTYPE_NO) { // 如果没有摄像头权限
+            [self showAlertWithMessage:@"请开启相机访问权限" type:CHECKDEVICETYPE_CAMREA];
+        }
+    }
 }
 
+- (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {
+    [KSPremissionAlert shareInstanceDisplayImage:deviceType message:message showInView:self.view cancel:^{
+        
+    } confirm:^{
+        [self openSettingView];
+    }];
+    
+}
+
+- (void)openSettingView {
+    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
+}
 
 - (void)displayTeacherInfo:(NSString *)teacherId {
     KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];

+ 2 - 1
KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/TuningFunction/Tuner.swift

@@ -7,7 +7,8 @@
 
 import Foundation
 import AudioKit
-
+import AudioKitEX
+import SoundpipeAudioKit
 
 private let flats = ["C", "D♭","D","E♭","E","F","G♭","G","A♭","A","B♭","B"]
 private let sharps = ["C", "C♯","D","D♯","E","F","F♯","G","G♯","A","A♯","B"]

+ 2 - 1
KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/TuningFunction/TunerForkManager.swift

@@ -7,6 +7,7 @@
 
 import Foundation
 import AudioKit
+import SoundpipeAudioKit
 
 @objc public class TunerForkManager : NSObject {
     
@@ -26,7 +27,7 @@ import AudioKit
         } catch {
             print("Couldn't start AudioEngine.")
         }
-        if osc.isPlaying {
+        if osc.isStarted {
             osc.stop()
         }
         osc.frequency = frequence