소스 검색

合成封面优化

Steven 1 년 전
부모
커밋
115ca65297
68개의 변경된 파일2519개의 추가작업 그리고 694개의 파일을 삭제
  1. 74 10
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Institution/Mine/tenant_mine_musicProduct.imageset/Contents.json
  3. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Institution/Mine/tenant_mine_musicProduct.imageset/tenant_mine_musicProduct@2x.png
  4. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Institution/Mine/tenant_mine_musicProduct.imageset/tenant_mine_musicProduct@3x.png
  5. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_choose_image.imageset/Contents.json
  6. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_choose_image.imageset/cover_choose_image@2x.png
  7. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_choose_image.imageset/cover_choose_image@3x.png
  8. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_crop_image.imageset/Contents.json
  9. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_crop_image.imageset/cover_crop_image@2x.png
  10. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_crop_image.imageset/cover_crop_image@3x.png
  11. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/minework_Line.imageset/Contents.json
  12. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/minework_Line.imageset/minework_Line@2x.png
  13. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/minework_Line.imageset/minework_Line@3x.png
  14. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/Contents.json
  15. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/progressLoading_bg@2x.png
  16. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/progressLoading_bg@3x.png
  17. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progress_dot.imageset/Contents.json
  18. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progress_dot.imageset/progress_dot@2x.png
  19. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progress_dot.imageset/progress_dot@3x.png
  20. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/Contents.json
  21. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/videoMerge_cover@2x.png
  22. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/videoMerge_cover@3x.png
  23. 50 33
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSAccompanyWebViewController.m
  24. 196 71
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSBaseWKWebViewController.m
  25. 2 1
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.h
  26. 3 1
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.m
  27. 3 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSVideoRecordManager.m
  28. 7 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/LoadingManager/KSHudLoagingManager.m
  29. 19 19
      KulexiuForStudent/KulexiuForStudent/Common/Define/KSDomain.h
  30. 2 0
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSAudioAnimationView.h
  31. 8 1
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSAudioAnimationView.m
  32. 200 38
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMediaMergeView.m
  33. 4 4
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMergeAudioControlView.xib
  34. 1 1
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSPlayerSliderView.m
  35. 0 272
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MusicPublistAlert.xib
  36. 4 5
      KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/MediaEditor/KSMediaEditor.m
  37. 7 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/Controller/InsititutionMineViewController.m
  38. 1 1
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineBodyView.h
  39. 104 1
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineBodyView.m
  40. 10 187
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineBodyView.xib
  41. 22 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantMineFunctionView.h
  42. 51 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantMineFunctionView.m
  43. 78 0
      KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantMineFunctionView.xib
  44. 10 4
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/Controller/KSDraftMergeViewController.m
  45. 26 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/Controller/KSVideoCropViewController.h
  46. 253 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/Controller/KSVideoCropViewController.m
  47. 4 5
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/Controller/MineWorksViewController.m
  48. 24 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/KSCropImageNavView.h
  49. 60 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/KSCropImageNavView.m
  50. 101 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/KSCropImageNavView.xib
  51. 25 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/KSVideoImageSlider.h
  52. 133 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/KSVideoImageSlider.m
  53. 2 1
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MineWorksBodyView.m
  54. 1 1
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MineWorksNavView.m
  55. 11 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MineWorksNavView.xib
  56. 21 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPubHeader.h
  57. 7 12
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublicContentView.h
  58. 14 26
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublicContentView.m
  59. 222 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublicContentView.xib
  60. 32 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublistAlert.h
  61. 135 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublistAlert.m
  62. 90 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublistAlert.xib
  63. 27 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCoverChooseView.h
  64. 59 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCoverChooseView.m
  65. 177 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCoverChooseView.xib
  66. 18 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCropImageViewCell.h
  67. 28 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCropImageViewCell.m
  68. 39 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCropImageViewCell.xib

+ 74 - 10
KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj

@@ -526,8 +526,6 @@
 		BC38C3F42AF8B3BA00ABFCC2 /* UIView+KSCovertImage.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C3F32AF8B3BA00ABFCC2 /* UIView+KSCovertImage.m */; };
 		BC38C3F82AF8B3E000ABFCC2 /* KSNewAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C3F62AF8B3E000ABFCC2 /* KSNewAlertView.m */; };
 		BC38C3F92AF8B3E000ABFCC2 /* KSNewAlertView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC38C3F72AF8B3E000ABFCC2 /* KSNewAlertView.xib */; };
-		BC38C3FD2AF8B3F900ABFCC2 /* MusicPublistAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC38C3FA2AF8B3F800ABFCC2 /* MusicPublistAlert.xib */; };
-		BC38C3FE2AF8B3F900ABFCC2 /* MusicPublistAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C3FC2AF8B3F900ABFCC2 /* MusicPublistAlert.m */; };
 		BC38C4512AFA095D00ABFCC2 /* KSDraftMergeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C4352AFA095D00ABFCC2 /* KSDraftMergeViewController.m */; };
 		BC38C4522AFA095D00ABFCC2 /* MineWorksViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C4382AFA095D00ABFCC2 /* MineWorksViewController.m */; };
 		BC38C4532AFA095D00ABFCC2 /* UserMusicFormalModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C43B2AFA095D00ABFCC2 /* UserMusicFormalModel.m */; };
@@ -543,6 +541,8 @@
 		BC38C4632AFA0AA600ABFCC2 /* KSNewGifRefreshFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C4612AFA0AA600ABFCC2 /* KSNewGifRefreshFooter.m */; };
 		BC38C4982AFA4B9C00ABFCC2 /* KSProgressLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C4962AFA4B9B00ABFCC2 /* KSProgressLoadingView.m */; };
 		BC38C4992AFA4B9C00ABFCC2 /* KSProgressLoadingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC38C4972AFA4B9C00ABFCC2 /* KSProgressLoadingView.xib */; };
+		BC38C4A12AFA4F6600ABFCC2 /* TenantMineFunctionView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C4A02AFA4F6600ABFCC2 /* TenantMineFunctionView.m */; };
+		BC38C4A32AFA4F6C00ABFCC2 /* TenantMineFunctionView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC38C4A22AFA4F6C00ABFCC2 /* TenantMineFunctionView.xib */; };
 		BC3A4EAB28DAC0CD001C4428 /* ShareLiveDisplayView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC3A4EAA28DAC0CD001C4428 /* ShareLiveDisplayView.m */; };
 		BC3A4EAD28DAC0D6001C4428 /* ShareLiveDisplayView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC3A4EAC28DAC0D6001C4428 /* ShareLiveDisplayView.xib */; };
 		BC3A4EB128DAE074001C4428 /* KSQRCreateManager.m in Sources */ = {isa = PBXBuildFile; fileRef = BC3A4EB028DAE074001C4428 /* KSQRCreateManager.m */; };
@@ -956,6 +956,18 @@
 		BCC0F6E62A8CE24400C4EFA4 /* WhiteUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC0F6E02A8CE24400C4EFA4 /* WhiteUtils.m */; };
 		BCC0F6E92A8CE37E00C4EFA4 /* VideoMaskView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC0F6E72A8CE37D00C4EFA4 /* VideoMaskView.m */; };
 		BCC0F6ED2A8CE4AF00C4EFA4 /* ZoomControl.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC0F6EB2A8CE4AF00C4EFA4 /* ZoomControl.m */; };
+		BCC408ED2AFCE6A000C60249 /* KSVideoCropViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408EB2AFCE69F00C60249 /* KSVideoCropViewController.m */; };
+		BCC409002AFCE6B500C60249 /* VideoCoverChooseView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408EF2AFCE6B200C60249 /* VideoCoverChooseView.m */; };
+		BCC409012AFCE6B500C60249 /* MusicPublicContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC408F02AFCE6B200C60249 /* MusicPublicContentView.xib */; };
+		BCC409022AFCE6B500C60249 /* KSCropImageNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408F12AFCE6B200C60249 /* KSCropImageNavView.m */; };
+		BCC409032AFCE6B500C60249 /* VideoCropImageViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC408F22AFCE6B200C60249 /* VideoCropImageViewCell.xib */; };
+		BCC409042AFCE6B500C60249 /* KSVideoImageSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408F72AFCE6B300C60249 /* KSVideoImageSlider.m */; };
+		BCC409052AFCE6B500C60249 /* MusicPublistAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC408F82AFCE6B300C60249 /* MusicPublistAlert.xib */; };
+		BCC409062AFCE6B500C60249 /* VideoCropImageViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408F92AFCE6B400C60249 /* VideoCropImageViewCell.m */; };
+		BCC409072AFCE6B500C60249 /* MusicPublicContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408FB2AFCE6B400C60249 /* MusicPublicContentView.m */; };
+		BCC409082AFCE6B500C60249 /* KSCropImageNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC408FC2AFCE6B400C60249 /* KSCropImageNavView.xib */; };
+		BCC409092AFCE6B500C60249 /* MusicPublistAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408FE2AFCE6B500C60249 /* MusicPublistAlert.m */; };
+		BCC4090A2AFCE6B500C60249 /* VideoCoverChooseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC408FF2AFCE6B500C60249 /* VideoCoverChooseView.xib */; };
 		BCC5839028A9E8A800BAB4CF /* AccompanyLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC5838F28A9E8A800BAB4CF /* AccompanyLoadingView.m */; };
 		BCC5839228A9E8AF00BAB4CF /* AccompanyLoadingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC5839128A9E8AF00BAB4CF /* AccompanyLoadingView.xib */; };
 		BCC583B428A9EC6400BAB4CF /* cloud_animation_9.png in Resources */ = {isa = PBXBuildFile; fileRef = BCC5839528A9EC6400BAB4CF /* cloud_animation_9.png */; };
@@ -2091,9 +2103,6 @@
 		BC38C3F52AF8B3E000ABFCC2 /* KSNewAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSNewAlertView.h; sourceTree = "<group>"; };
 		BC38C3F62AF8B3E000ABFCC2 /* KSNewAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSNewAlertView.m; sourceTree = "<group>"; };
 		BC38C3F72AF8B3E000ABFCC2 /* KSNewAlertView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSNewAlertView.xib; sourceTree = "<group>"; };
-		BC38C3FA2AF8B3F800ABFCC2 /* MusicPublistAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MusicPublistAlert.xib; sourceTree = "<group>"; };
-		BC38C3FB2AF8B3F900ABFCC2 /* MusicPublistAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicPublistAlert.h; sourceTree = "<group>"; };
-		BC38C3FC2AF8B3F900ABFCC2 /* MusicPublistAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MusicPublistAlert.m; sourceTree = "<group>"; };
 		BC38C4352AFA095D00ABFCC2 /* KSDraftMergeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSDraftMergeViewController.m; sourceTree = "<group>"; };
 		BC38C4362AFA095D00ABFCC2 /* MineWorksViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MineWorksViewController.h; sourceTree = "<group>"; };
 		BC38C4372AFA095D00ABFCC2 /* KSDraftMergeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSDraftMergeViewController.h; sourceTree = "<group>"; };
@@ -2119,6 +2128,9 @@
 		BC38C4952AFA4B9900ABFCC2 /* KSProgressLoadingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSProgressLoadingView.h; sourceTree = "<group>"; };
 		BC38C4962AFA4B9B00ABFCC2 /* KSProgressLoadingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSProgressLoadingView.m; sourceTree = "<group>"; };
 		BC38C4972AFA4B9C00ABFCC2 /* KSProgressLoadingView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSProgressLoadingView.xib; sourceTree = "<group>"; };
+		BC38C49F2AFA4F6600ABFCC2 /* TenantMineFunctionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TenantMineFunctionView.h; sourceTree = "<group>"; };
+		BC38C4A02AFA4F6600ABFCC2 /* TenantMineFunctionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TenantMineFunctionView.m; sourceTree = "<group>"; };
+		BC38C4A22AFA4F6C00ABFCC2 /* TenantMineFunctionView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TenantMineFunctionView.xib; sourceTree = "<group>"; };
 		BC3A4EA928DAC0CD001C4428 /* ShareLiveDisplayView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShareLiveDisplayView.h; sourceTree = "<group>"; };
 		BC3A4EAA28DAC0CD001C4428 /* ShareLiveDisplayView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShareLiveDisplayView.m; sourceTree = "<group>"; };
 		BC3A4EAC28DAC0D6001C4428 /* ShareLiveDisplayView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShareLiveDisplayView.xib; sourceTree = "<group>"; };
@@ -2763,6 +2775,26 @@
 		BCC0F6E82A8CE37E00C4EFA4 /* VideoMaskView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoMaskView.h; sourceTree = "<group>"; };
 		BCC0F6EB2A8CE4AF00C4EFA4 /* ZoomControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZoomControl.m; sourceTree = "<group>"; };
 		BCC0F6EC2A8CE4AF00C4EFA4 /* ZoomControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZoomControl.h; sourceTree = "<group>"; };
+		BCC408EB2AFCE69F00C60249 /* KSVideoCropViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSVideoCropViewController.m; sourceTree = "<group>"; };
+		BCC408EC2AFCE69F00C60249 /* KSVideoCropViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSVideoCropViewController.h; sourceTree = "<group>"; };
+		BCC408EE2AFCE6B100C60249 /* MusicPubHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicPubHeader.h; sourceTree = "<group>"; };
+		BCC408EF2AFCE6B200C60249 /* VideoCoverChooseView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoCoverChooseView.m; sourceTree = "<group>"; };
+		BCC408F02AFCE6B200C60249 /* MusicPublicContentView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MusicPublicContentView.xib; sourceTree = "<group>"; };
+		BCC408F12AFCE6B200C60249 /* KSCropImageNavView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSCropImageNavView.m; sourceTree = "<group>"; };
+		BCC408F22AFCE6B200C60249 /* VideoCropImageViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VideoCropImageViewCell.xib; sourceTree = "<group>"; };
+		BCC408F32AFCE6B200C60249 /* MusicPublistAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicPublistAlert.h; sourceTree = "<group>"; };
+		BCC408F42AFCE6B300C60249 /* VideoCropImageViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoCropImageViewCell.h; sourceTree = "<group>"; };
+		BCC408F52AFCE6B300C60249 /* MusicPublicContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicPublicContentView.h; sourceTree = "<group>"; };
+		BCC408F62AFCE6B300C60249 /* VideoCoverChooseView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoCoverChooseView.h; sourceTree = "<group>"; };
+		BCC408F72AFCE6B300C60249 /* KSVideoImageSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSVideoImageSlider.m; sourceTree = "<group>"; };
+		BCC408F82AFCE6B300C60249 /* MusicPublistAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MusicPublistAlert.xib; sourceTree = "<group>"; };
+		BCC408F92AFCE6B400C60249 /* VideoCropImageViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoCropImageViewCell.m; sourceTree = "<group>"; };
+		BCC408FA2AFCE6B400C60249 /* KSCropImageNavView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSCropImageNavView.h; sourceTree = "<group>"; };
+		BCC408FB2AFCE6B400C60249 /* MusicPublicContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MusicPublicContentView.m; sourceTree = "<group>"; };
+		BCC408FC2AFCE6B400C60249 /* KSCropImageNavView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSCropImageNavView.xib; sourceTree = "<group>"; };
+		BCC408FD2AFCE6B400C60249 /* KSVideoImageSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSVideoImageSlider.h; sourceTree = "<group>"; };
+		BCC408FE2AFCE6B500C60249 /* MusicPublistAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MusicPublistAlert.m; sourceTree = "<group>"; };
+		BCC408FF2AFCE6B500C60249 /* VideoCoverChooseView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VideoCoverChooseView.xib; sourceTree = "<group>"; };
 		BCC5838E28A9E8A800BAB4CF /* AccompanyLoadingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AccompanyLoadingView.h; sourceTree = "<group>"; };
 		BCC5838F28A9E8A800BAB4CF /* AccompanyLoadingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AccompanyLoadingView.m; sourceTree = "<group>"; };
 		BCC5839128A9E8AF00BAB4CF /* AccompanyLoadingView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccompanyLoadingView.xib; sourceTree = "<group>"; };
@@ -5109,6 +5141,9 @@
 				BC2932F62AAEC46B0024D98E /* InstitutionMineBodyView.h */,
 				BC2932F72AAEC46B0024D98E /* InstitutionMineBodyView.m */,
 				BC2932F92AAEC4720024D98E /* InstitutionMineBodyView.xib */,
+				BC38C49F2AFA4F6600ABFCC2 /* TenantMineFunctionView.h */,
+				BC38C4A02AFA4F6600ABFCC2 /* TenantMineFunctionView.m */,
+				BC38C4A22AFA4F6C00ABFCC2 /* TenantMineFunctionView.xib */,
 				BCCC36182AAF0D77000D60CA /* INSSettingBodyView.h */,
 				BCCC36192AAF0D77000D60CA /* INSSettingBodyView.m */,
 				BCCC361B2AAF0D7C000D60CA /* INSSettingBodyView.xib */,
@@ -5282,9 +5317,6 @@
 				BC38C3D62AF893B300ABFCC2 /* KSAudioAnimationView.h */,
 				BC38C3E72AF893B300ABFCC2 /* KSAudioAnimationView.m */,
 				BC38C3DD2AF893B300ABFCC2 /* KSAudioAnimationView.xib */,
-				BC38C3FB2AF8B3F900ABFCC2 /* MusicPublistAlert.h */,
-				BC38C3FC2AF8B3F900ABFCC2 /* MusicPublistAlert.m */,
-				BC38C3FA2AF8B3F800ABFCC2 /* MusicPublistAlert.xib */,
 				BC38C3F52AF8B3E000ABFCC2 /* KSNewAlertView.h */,
 				BC38C3F62AF8B3E000ABFCC2 /* KSNewAlertView.m */,
 				BC38C3F72AF8B3E000ABFCC2 /* KSNewAlertView.xib */,
@@ -5340,6 +5372,8 @@
 				BC38C4352AFA095D00ABFCC2 /* KSDraftMergeViewController.m */,
 				BC38C4362AFA095D00ABFCC2 /* MineWorksViewController.h */,
 				BC38C4382AFA095D00ABFCC2 /* MineWorksViewController.m */,
+				BCC408EC2AFCE69F00C60249 /* KSVideoCropViewController.h */,
+				BCC408EB2AFCE69F00C60249 /* KSVideoCropViewController.m */,
 			);
 			path = Controller;
 			sourceTree = "<group>";
@@ -5370,6 +5404,24 @@
 				BC38C4402AFA095D00ABFCC2 /* MineWorksOpenDisplayCell.h */,
 				BC38C4472AFA095D00ABFCC2 /* MineWorksOpenDisplayCell.m */,
 				BC38C4482AFA095D00ABFCC2 /* MineWorksOpenDisplayCell.xib */,
+				BCC408FA2AFCE6B400C60249 /* KSCropImageNavView.h */,
+				BCC408F12AFCE6B200C60249 /* KSCropImageNavView.m */,
+				BCC408FC2AFCE6B400C60249 /* KSCropImageNavView.xib */,
+				BCC408FD2AFCE6B400C60249 /* KSVideoImageSlider.h */,
+				BCC408F72AFCE6B300C60249 /* KSVideoImageSlider.m */,
+				BCC408EE2AFCE6B100C60249 /* MusicPubHeader.h */,
+				BCC408F52AFCE6B300C60249 /* MusicPublicContentView.h */,
+				BCC408FB2AFCE6B400C60249 /* MusicPublicContentView.m */,
+				BCC408F02AFCE6B200C60249 /* MusicPublicContentView.xib */,
+				BCC408F32AFCE6B200C60249 /* MusicPublistAlert.h */,
+				BCC408FE2AFCE6B500C60249 /* MusicPublistAlert.m */,
+				BCC408F82AFCE6B300C60249 /* MusicPublistAlert.xib */,
+				BCC408F62AFCE6B300C60249 /* VideoCoverChooseView.h */,
+				BCC408EF2AFCE6B200C60249 /* VideoCoverChooseView.m */,
+				BCC408FF2AFCE6B500C60249 /* VideoCoverChooseView.xib */,
+				BCC408F42AFCE6B300C60249 /* VideoCropImageViewCell.h */,
+				BCC408F92AFCE6B400C60249 /* VideoCropImageViewCell.m */,
+				BCC408F22AFCE6B200C60249 /* VideoCropImageViewCell.xib */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -7276,6 +7328,7 @@
 				BC71D2872888083B0010F14B /* tabbar3.json in Resources */,
 				BCC583C028A9EC6400BAB4CF /* cloud_animation_15.png in Resources */,
 				BC119280280FB10900A716F7 /* AccompanyRemarkCell.xib in Resources */,
+				BCC409012AFCE6B500C60249 /* MusicPublicContentView.xib in Resources */,
 				BC8A45B6283DC33400094BBB /* NoWiredTipsAlert.xib in Resources */,
 				BC71D271288804CD0010F14B /* img_26.png in Resources */,
 				BC12639F28FF8E7400509E90 /* HomeRecommendMusicView.xib in Resources */,
@@ -7291,6 +7344,7 @@
 				BC5367C4283F6D58008428E8 /* HomeLiveCourseView.xib in Resources */,
 				BC2DFF5D28C097DC0056105A /* styleAnimation.json in Resources */,
 				BC71D266288804CD0010F14B /* img_43.png in Resources */,
+				BCC4090A2AFCE6B500C60249 /* VideoCoverChooseView.xib in Resources */,
 				BC71D257288804CD0010F14B /* img_28.png in Resources */,
 				BC71D279288804CD0010F14B /* img_34.png in Resources */,
 				BC71D24C288804CD0010F14B /* img_3.png in Resources */,
@@ -7362,7 +7416,6 @@
 				BCC0F6662A8CD8F500C4EFA4 /* TXDanChatCell.xib in Resources */,
 				BCFDA65728BCA2000022B497 /* musicRoom_animation.json in Resources */,
 				BC8418412AC2D96C00D8F90E /* PasswordCheckBodyView.xib in Resources */,
-				BC38C3FD2AF8B3F900ABFCC2 /* MusicPublistAlert.xib in Resources */,
 				BCC0F6622A8CD8F500C4EFA4 /* MainDisplayView.xib in Resources */,
 				BC71D278288804CD0010F14B /* img_20.png in Resources */,
 				BC71D247288804CD0010F14B /* img_0.png in Resources */,
@@ -7482,6 +7535,7 @@
 				BC802D8F28B8964C0079E350 /* LiveApplyView.xib in Resources */,
 				BC71D24E288804CD0010F14B /* img_16.png in Resources */,
 				27F9033727E87C8B00C08A19 /* MineNavView.xib in Resources */,
+				BC38C4A32AFA4F6C00ABFCC2 /* TenantMineFunctionView.xib in Resources */,
 				BC8A45AB283DC33400094BBB /* TrackChooseView.xib in Resources */,
 				BCFEED6028F7E4910078A2B7 /* WidgetSpeedView.xib in Resources */,
 				BCC0F6B32A8CDD4000C4EFA4 /* low_staff.png in Resources */,
@@ -7498,6 +7552,7 @@
 				BCC5839228A9E8AF00BAB4CF /* AccompanyLoadingView.xib in Resources */,
 				BCB9FA37286D7C38005D766B /* GuideListView.xib in Resources */,
 				BC71D2882888083B0010F14B /* tabbar2.json in Resources */,
+				BCC409052AFCE6B500C60249 /* MusicPublistAlert.xib in Resources */,
 				BC50171727FC0D8E00F8BCBC /* SubjectChooseBodyView.xib in Resources */,
 				BC71D26F288804CD0010F14B /* img_24.png in Resources */,
 				BCCE95E92AB057C400AB6385 /* MorePageSearchView.xib in Resources */,
@@ -7511,6 +7566,8 @@
 				BC0D1F72281015B000C5D9E5 /* VideoCourseCell.xib in Resources */,
 				BC8A45B1283DC33400094BBB /* CloudHelpView.xib in Resources */,
 				BCFDA64A28BCA2000022B497 /* accomapny_animation.json in Resources */,
+				BCC409032AFCE6B500C60249 /* VideoCropImageViewCell.xib in Resources */,
+				BCC409082AFCE6B500C60249 /* KSCropImageNavView.xib in Resources */,
 				BCFDA63028BC99410022B497 /* HomeBannerCell.xib in Resources */,
 				BC71D25E288804CD0010F14B /* img_51.png in Resources */,
 				BCC0F6AF2A8CDD4000C4EFA4 /* tick.wav in Resources */,
@@ -7720,6 +7777,7 @@
 				BC5367C7283F6D6B008428E8 /* HomeVideoCourseView.m in Sources */,
 				BC802D8528B872AB0079E350 /* KSLiveAlertView.m in Sources */,
 				BC9AA0B52ABC1C2400CD954D /* GroupQuitAlert.m in Sources */,
+				BCC409042AFCE6B500C60249 /* KSVideoImageSlider.m in Sources */,
 				2779357D27E324A80010E277 /* KSMessageInputView.m in Sources */,
 				277935BE27E324A90010E277 /* FSCalendarCalculator.m in Sources */,
 				BCB6347727F6D29600ACFDCF /* LiveRoomLikeLayer.m in Sources */,
@@ -7786,6 +7844,7 @@
 				BCFEED4D28F7E4720078A2B7 /* SmallToolViewController.m in Sources */,
 				BC106C3A2A9338A7000759A9 /* TXSeatContainerView.m in Sources */,
 				BC8A45B2283DC33400094BBB /* CloudFeedbackView.m in Sources */,
+				BCC409062AFCE6B500C60249 /* VideoCropImageViewCell.m in Sources */,
 				BC60E3CD287D552800B05441 /* DeleteAccountBodyView.m in Sources */,
 				BC494A7C286958EC00CCD343 /* MusicRoomCourseInfoCell.m in Sources */,
 				BCB6347127F6D29600ACFDCF /* KSChatEmojiBoardView.m in Sources */,
@@ -7798,6 +7857,7 @@
 				2779352627E324A60010E277 /* UIAlertController+Extend.m in Sources */,
 				BC11925E280FA89A00A716F7 /* HomeworkBodyView.m in Sources */,
 				275FA1EB27E7351900CFEA2E /* KSBaseWKWebViewController.m in Sources */,
+				BCC409072AFCE6B500C60249 /* MusicPublicContentView.m in Sources */,
 				BC106C232A933869000759A9 /* TXLiveMessageCenter.m in Sources */,
 				BCB909142852EF0000F5FF69 /* KSDragWindow.m in Sources */,
 				BC38C3CF2AF8930D00ABFCC2 /* kSNewPlayer.m in Sources */,
@@ -7987,7 +8047,6 @@
 				2779359327E324A80010E277 /* TZImageCropManager.m in Sources */,
 				BCCC361A2AAF0D77000D60CA /* INSSettingBodyView.m in Sources */,
 				2723B66727F15CFC00E0B90B /* ModifyBodyView.m in Sources */,
-				BC38C3FE2AF8B3F900ABFCC2 /* MusicPublistAlert.m in Sources */,
 				2779357727E324A70010E277 /* GRScanManager.m in Sources */,
 				277935D527E324A90010E277 /* ALCalendarManager.m in Sources */,
 				BC02130127FC6ADD0040569F /* UIView+SubViewExtension.m in Sources */,
@@ -8010,6 +8069,7 @@
 				2779355027E324A70010E277 /* VoDiskCache.m in Sources */,
 				BCFEED6228F7E4910078A2B7 /* WidgetDotView.m in Sources */,
 				BCC0F6ED2A8CE4AF00C4EFA4 /* ZoomControl.m in Sources */,
+				BCC409002AFCE6B500C60249 /* VideoCoverChooseView.m in Sources */,
 				BCF472E72AB019CD0032BE16 /* TenantDarkViewController.m in Sources */,
 				BC83A83E2AD28A9F0033D48B /* TenantNotiferNavView.m in Sources */,
 				BC106C032A933829000759A9 /* TXLiveMessageOpenLive.m in Sources */,
@@ -8049,6 +8109,7 @@
 				BC0D95142AC2752400E54D3F /* UIViewController+KSExtension.m in Sources */,
 				BC119263280FA90100A716F7 /* HomeworkDetailModel.m in Sources */,
 				BCC0F6A52A8CDD3F00C4EFA4 /* CREmojiCollectionCell.m in Sources */,
+				BCC409092AFCE6B500C60249 /* MusicPublistAlert.m in Sources */,
 				2723B62427F157D500E0B90B /* NoticeEditBodyView.m in Sources */,
 				BCFEED6628F7E4910078A2B7 /* WidgetSpeedView.m in Sources */,
 				BCFDA65F28BCAEC80022B497 /* HomeInformationBodyView.m in Sources */,
@@ -8175,6 +8236,7 @@
 				BCD9295D28F9447B006793E4 /* WMGaugeViewStyleFlatThin.m in Sources */,
 				275FA22B27E7356B00CFEA2E /* HomeViewController.m in Sources */,
 				BC106C362A9338A7000759A9 /* TXLiveLoadingView.m in Sources */,
+				BCC408ED2AFCE6A000C60249 /* KSVideoCropViewController.m in Sources */,
 				BC2888762A8101C80064B773 /* KSChatSearchBar.m in Sources */,
 				BCFE53F12812898700AD6786 /* HomeVideoCourseCell.m in Sources */,
 				BCC0F6B52A8CDD4000C4EFA4 /* OnlineClassManager.m in Sources */,
@@ -8277,6 +8339,7 @@
 				2779357C27E324A70010E277 /* NSString+MD5.m in Sources */,
 				BC0D952E2AC2AA6F00E54D3F /* ForgetPasswordViewController.m in Sources */,
 				BC106C112A933829000759A9 /* TXConstMessage.m in Sources */,
+				BCC409022AFCE6B500C60249 /* KSCropImageNavView.m in Sources */,
 				2779355D27E324A70010E277 /* KSHoldButton.m in Sources */,
 				2723B62027F157D500E0B90B /* GroupNoticeCell.m in Sources */,
 				277935A627E324A80010E277 /* MSSBrowseLocalViewController.m in Sources */,
@@ -8350,6 +8413,7 @@
 				BC119293280FBC1100A716F7 /* HomeworkAddView.m in Sources */,
 				BC4CC417288FD689004AD8EC /* LaunchAnimationView.m in Sources */,
 				BC106BFF2A933829000759A9 /* TXLiveMessageCardMessage.m in Sources */,
+				BC38C4A12AFA4F6600ABFCC2 /* TenantMineFunctionView.m in Sources */,
 				277935C627E324A90010E277 /* SDQWMaskCustomModel.m in Sources */,
 				BC3A4EAB28DAC0CD001C4428 /* ShareLiveDisplayView.m in Sources */,
 				BCC0F6A42A8CDD3F00C4EFA4 /* InputView.m in Sources */,

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

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

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


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


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_choose_image.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_choose_image.imageset/cover_choose_image@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_choose_image.imageset/cover_choose_image@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_crop_image.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_crop_image.imageset/cover_crop_image@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/cover_crop_image.imageset/cover_crop_image@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/minework_Line.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/minework_Line.imageset/minework_Line@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/minework_Line.imageset/minework_Line@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/progressLoading_bg@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/progressLoading_bg@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progress_dot.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progress_dot.imageset/progress_dot@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/progress_dot.imageset/progress_dot@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/videoMerge_cover@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/videoMerge_cover@3x.png


+ 50 - 33
KulexiuForStudent/KulexiuForStudent/Common/Base/KSAccompanyWebViewController.m

@@ -402,26 +402,30 @@
 
 - (void)viewWillDisappear:(BOOL)animated {
     [super viewWillDisappear:animated];
-    if (_AQManager) {
-        [_AQManager freeAudioQueue];
-        _AQManager = nil;
-    }
+    
     if (_socketManager) {
         [self.socketManager SRWebSocketClose];
         _socketManager = nil;
     }
-    // 返回不保存视频
-    [self ignorRecordVideo];
+    // 停止播放和录制
     [self stopSession];
-    
-    // 如果退出评测页面 清除 playerEngine
-    if (self.playerEngine) {
-        [self.playerEngine cleanup];
-        self.playerEngine = nil;
-    }
+    [self stopPlayAction];
+    [self stopRecordService];
     [self stopTuner];
+    
     BOOL isBack = [self isViewPopDismiss];
-    if (isBack) {
+    if (isBack) { // 页面销毁才删除
+        if (_AQManager) {
+            [_AQManager freeAudioQueue];
+            _AQManager = nil;
+        }
+        // 如果退出评测页面 清除 playerEngine
+        if (self.playerEngine) {
+            [self.playerEngine cleanup];
+            self.playerEngine = nil;
+        }
+        // 返回不保存视频
+        [self ignorRecordVideo];
         [self freeMp3Player];
     }
 }
@@ -810,6 +814,7 @@
                     NSString *fileName = [[accompanyUrl componentsSeparatedByString:@"/"] lastObject];
                     NSString *filePath = [self getAccompanyFilePathWithName:fileName];
                     NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:filePath];
+                    self.accompanyUrl = accompanyUrl;
                     if ([self checkSongHasSaveAccompanyWithSongUrl:accompanyUrl]) {
                         [self configVideoRecord:fileUrl];
                     }
@@ -904,21 +909,26 @@
             // 音视频合成
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"openAdjustRecording"]) {
                 KSMediaMergeView *mergeView = [[KSMediaMergeView alloc] init];
-                [self.view addSubview:mergeView];
-                [mergeView mas_makeConstraints:^(MASConstraintMaker *make) {
-                    make.left.right.top.bottom.mas_equalTo(self.view);
-                }];
-                NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
-                mergeView.recordId = [content ks_stringValueForKey:@"recordId"];
-                mergeView.songName = [content ks_stringValueForKey:@"title"];
-                mergeView.coverImage = [content ks_stringValueForKey:@"coverImg"];
-                if (self.AQManager) {
+                
+                if (self.AQManager && self.AQManager.audioUrl) {
                     self.recordUrl = self.AQManager.audioUrl;
+                    [self.view addSubview:mergeView];
+                    [mergeView mas_makeConstraints:^(MASConstraintMaker *make) {
+                        make.left.right.top.bottom.mas_equalTo(self.view);
+                    }];
+                    NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
+                    mergeView.recordId = [content ks_stringValueForKey:@"recordId"];
+                    mergeView.songName = [content ks_stringValueForKey:@"title"];
+                    mergeView.coverImage = [content ks_stringValueForKey:@"coverImg"];
+                    MJWeakSelf;
+                    [mergeView configWithVideoUrl:self.videoRecordManager.videoFileURL bgAudioUrl:self.bgAudioUrl remoteBgUrl:self.accompanyUrl  recordUrl:self.recordUrl offsetTime:self.offsetTime mergeCallback:^{
+                        [weakSelf musicPublishCallBack:content];
+                    }];
+                }
+                else {
+                    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"麦克风被占用"];
                 }
-                MJWeakSelf;
-                [mergeView configWithVideoUrl:self.videoRecordManager.videoFileURL bgAudioUrl:self.bgAudioUrl remoteBgUrl:self.accompanyUrl  recordUrl:self.recordUrl offsetTime:self.offsetTime mergeCallback:^{
-                    [weakSelf musicPublishCallBack:content];
-                }];
+                
             }
             else {
                 [super handleScriptMessageSource:parm];
@@ -934,6 +944,7 @@
     [parm setValue:@{} forKey:@"content"];
     [self postMessage:parm];
 }
+
 - (void)uploadVideoWithParm:(NSMutableDictionary *)contentParm sendParm:(NSMutableDictionary *)sendParm {
     MJWeakSelf;
     [self.videoRecordManager uploadRecordVideoSuccess:^(NSString * _Nonnull videoUrl) {
@@ -961,7 +972,6 @@
 
 - (void)openSettingView {
     [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
-    
 }
 
 - (void)downloadUrl:(NSString *)url success:(void(^)(void))success faliure:(void(^)(void))faliure {
@@ -980,6 +990,7 @@
 
 - (void)configVideoRecord:(NSURL *)path {
     self.videoRecordManager.bgAudioUrl = path;
+    self.bgAudioUrl = path;
 }
 
 - (void)showBeatViewRepeatCount:(NSInteger)repeatCount supplement:(NSInteger)supplement {
@@ -1321,7 +1332,9 @@
 }
 
 - (void)showSuccessMessage:(NSString *)message {
-    [LOADING_MANAGER MBShowAUTOHidingInWindow:message];
+    if (![NSString isEmptyString:message]) {
+        [LOADING_MANAGER MBShowAUTOHidingInWindow:message];
+    }
     // 成功
     if (self.endRecordParm) {
         [self postMessage:self.endRecordParm];
@@ -1434,14 +1447,18 @@
 
 #pragma mark ----- 播放控制
 - (void)playAction {
-    self.isPlaying = YES;
-    [self.playerEngine playMIDIFile];
+    if (self.playerEngine) {
+        self.isPlaying = YES;
+        [self.playerEngine playMIDIFile];
+    }
 }
 
 - (void)stopPlayAction {
-    self.isPlaying = NO;
-    if ([self.playerEngine isPlayingFile]) {
-        [self.playerEngine stopPlayingMIDIFile];
+    if (self.playerEngine) {
+        self.isPlaying = NO;
+        if ([self.playerEngine isPlayingFile]) {
+            [self.playerEngine stopPlayingMIDIFile];
+        }
     }
 }
 

+ 196 - 71
KulexiuForStudent/KulexiuForStudent/Common/Base/KSBaseWKWebViewController.m

@@ -29,6 +29,7 @@
 #import "KSUMShareManager.h"
 #import "UserInfoManager.h"
 #import "KSWebLoadRefreshView.h"
+#import "KSVideoCropViewController.h"
 
 typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     CHOOSETYPE_XML,
@@ -37,7 +38,7 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     CHOOSETYPE_ALL,
 };
 
-@interface KSBaseWKWebViewController ()<UIDocumentPickerDelegate>
+@interface KSBaseWKWebViewController ()<UIDocumentPickerDelegate,UIDocumentInteractionControllerDelegate>
 
 @property (nonatomic, assign) BOOL isOutLink;  // 外部链接
 
@@ -68,6 +69,8 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
 
 @property (nonatomic, strong) KSUMShareManager *shareManager;
 
+@property (nonatomic, assign) BOOL isDownloadFile;
+
 @end
 
 @implementation KSBaseWKWebViewController
@@ -190,10 +193,15 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
         }
     }
     else {
-        KSBaseViewController *nextCtrl = [self getNextViewController];
-        if (nextCtrl) {
-            if (nextCtrl.ks_landScape != self.ks_landScape) {
-                [self changeOrientation:NO];
+        if ([self.presentedViewController isKindOfClass:NSClassFromString(@"TZImagePickerController")] || [self.presentedViewController isKindOfClass:NSClassFromString(@"RSKImageCropViewController")] || [self.presentedViewController isKindOfClass:NSClassFromString(@"KSVideoCropViewController")]) {
+            NSLog(@"-----");
+        }
+        else {
+            KSBaseViewController *nextCtrl = [self getNextViewController];
+            if (nextCtrl) {
+                if (nextCtrl.ks_landScape != self.ks_landScape) {
+                    [self changeOrientation:NO];
+                }
             }
         }
     }
@@ -612,6 +620,98 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"shareTripartite"]) { // 分享到微信
         [self shareToWeChat:parm];
     }
+    else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"saveFile"]) { // 下载资源
+        NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
+
+        NSString *url = [content ks_stringValueForKey:@"url"];
+        [self downFile:url];
+    }
+    else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"videoCrop"]) { // 选择封面
+        NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
+        KSVideoCropViewController *ctrl = [[KSVideoCropViewController alloc] init];
+        NSString *videoUrl = [content ks_stringValueForKey:@"url"];
+        [ctrl configWithVideoRemoteUrl:videoUrl];
+        [ctrl changeLandScape];
+        MJWeakSelf;
+        [ctrl chooseCropImageCallback:^(UIImage * _Nonnull cropImage) {
+            [weakSelf videCropImage:cropImage content:content];
+        }];
+        ctrl.modalPresentationStyle = UIModalPresentationFullScreen;
+        [self.navigationController presentViewController:ctrl animated:YES completion:nil];
+    }
+}
+
+- (void)videCropImage:(UIImage *)cover content:(NSDictionary *)content {
+    NSData *imgData = [UIImage turnsImaegDataByImage:cover];
+    NSString *fileName = @"videoCoverImage";
+
+    [LOADING_MANAGER showCustomLoading:@"上传中..."];
+    [UPLOAD_MANAGER configBucketName:@"klx"];
+    [UPLOAD_MANAGER uploadFile:imgData fileName:fileName fileSuffix:[UIImage typeForImageData:imgData] progress:^(int64_t bytesWritten, int64_t totalBytes) {
+        // 显示进度
+        int progress = (int)(bytesWritten / totalBytes * 100);
+        __block NSString *tipsMessage = [NSString stringWithFormat:@"上传中 %d%%",progress];
+        dispatch_main_async_safe(^{
+            [LOADING_MANAGER.loadingView setDisplayText:tipsMessage];
+        });
+    } successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
+        [LOADING_MANAGER removeCustomLoading];
+        NSString *fileUrl = [fileUrlArray lastObject];
+        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:content];
+        [content setValue:fileUrl forKey:@"videoCover"];
+        NSMutableDictionary *sendParm = [NSMutableDictionary dictionary];
+        [sendParm setValue:@"videoCrop" forKey:@"api"];
+        [sendParm setValue:dic forKey:@"content"];
+        [self postMessage:sendParm];
+    } faliure:^(NSError * _Nullable error, NSString * _Nullable descMessaeg) {
+        [LOADING_MANAGER removeCustomLoading];
+    }];
+}
+
+
+- (void)downFile:(NSString *)fileUrl {
+    [LOADING_MANAGER showCustomLoading:@"文件下载中..."];
+    [KSNetworkingManager downloadFileRequestWithFileUrl:fileUrl progress:^(int64_t bytesRead, int64_t totalBytes) {
+        
+    } success:^(NSURL * _Nonnull fileUrl) {
+        [LOADING_MANAGER removeCustomLoading];
+        [self saveFileWithUrl:fileUrl];
+    } faliure:^(NSError * _Nonnull error) {
+        [LOADING_MANAGER removeCustomLoading];
+        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"下载失败"];
+    }];
+}
+
+- (void)saveFileWithUrl:(NSURL *)fileUrl {
+    if ([fileUrl.absoluteString hasSuffix:@".mp4"]) { // 视频
+        [LOADING_MANAGER showCustomLoading:@"视频保存中..."];
+        [[TZImageManager manager] saveVideoWithUrl:fileUrl completion:^(PHAsset *asset, NSError *error) {
+            if (!error) {
+                dispatch_main_async_safe(^{
+                    [LOADING_MANAGER removeCustomLoading];
+                    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"视频已保存到相册"];
+                });
+            }
+            else {
+                dispatch_main_async_safe(^{
+                    [LOADING_MANAGER removeCustomLoading];
+                    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"保存视频错误"];
+                });
+            }
+        }];
+    }
+    else { // 音频
+        [self saveFileToPhone:fileUrl];
+    }
+}
+
+- (void)saveFileToPhone:(NSURL *)fileUrl {
+    self.isDownloadFile = YES;
+
+    UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithURL:fileUrl inMode:UIDocumentPickerModeExportToService];
+    documentPicker.delegate = self;
+    documentPicker.modalPresentationStyle = UIModalPresentationFormSheet;
+    [self presentViewController:documentPicker animated:YES completion:nil];
 }
 
 - (void)chooseFileWithType:(NSString *)typeStr maxNumber:(NSInteger)maxCount bucket:(NSString *)bucket {
@@ -1255,7 +1355,12 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
 
 #pragma mark ---- UIDocumentPickerDelegate
 - (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
-    [self fileChooseErrorCallback];
+    if (self.isDownloadFile) {
+        self.isDownloadFile = NO;
+    }
+    else {
+        [self fileChooseErrorCallback];
+    }
 }
 
 - (void)fileChooseErrorCallback {
@@ -1266,71 +1371,6 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     }
 }
 
-- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
-    NSArray *array = [[url absoluteString] componentsSeparatedByString:@"/"];
-    NSString *fileName = [array lastObject];
-    fileName = [fileName stringByRemovingPercentEncoding];
-    
-    if (self.fileChooseType == CHOOSETYPE_XML) {
-        if (![fileName hasSuffix:@".xml"]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传XML格式文件"];
-            [self fileChooseErrorCallback];
-            return;
-        }
-    }
-    else if (self.fileChooseType == CHOOSETYPE_MIDI) {
-        if (![fileName hasSuffix:@".mid"] || [fileName hasSuffix:@".midi"]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传mid格式文件"];
-            [self fileChooseErrorCallback];
-            return;
-        }
-    }
-    else if (self.fileChooseType == CHOOSETYPE_MP3) {
-        if (![fileName hasSuffix:@".mp3"]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传mp3格式文件"];
-            [self fileChooseErrorCallback];
-            return;
-        }
-    }
-    else {
-        if (![fileName hasSuffix:@".mp3"] && ![fileName hasSuffix:@".aac"]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"暂不支持此格式!"];
-            [self fileChooseErrorCallback];
-            return;
-        }
-    }
-    
-    __block NSString * fileUrl = @"";
-    if ([KSICloudManager iCloudEnable]) {
-        [KSICloudManager downloadWithDocumentURL:url callBack:^(id obj) {
-            NSData *data = obj;
-            
-            //写入沙盒Documents
-             NSString *pathStr = [NSHomeDirectory() stringByAppendingString:[NSString stringWithFormat:@"/Documents/%@",fileName]];
-            [data writeToFile:pathStr atomically:YES];
-            
-            if (![[NSFileManager defaultManager] fileExistsAtPath:pathStr]) {
-                BOOL isSuccess = [data writeToFile:pathStr atomically:YES];
-                if (isSuccess) {
-                    fileUrl = pathStr;
-                }
-                else {
-                    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"写入文件错误!"];
-                    [self fileChooseErrorCallback];
-                }
-            }
-            else {
-                fileUrl = pathStr;
-            }
-            [self uploadFile:fileName fileUrl:pathStr];
-            
-        }];
-    }
-    else {
-        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"iCloud不可用!"];
-        [self fileChooseErrorCallback];
-    }
-}
 
 - (void)uploadFile:(NSString *)fileName fileUrl:(NSString *)fileUrl {
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@@ -1399,6 +1439,91 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
         [self.errorView removeFromSuperview];
     }
 }
+
+#pragma mark - UIDocumentInteractionControllerDelegate
+-(UIViewController*)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController*)controller{
+    return self;
+}
+-(UIView*)documentInteractionControllerViewForPreview:(UIDocumentInteractionController*)controller {
+    return self.view;
+}
+-(CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController*)controller {
+    return self.view.frame;
+}
+#pragma mark - UIDocumentPickerDelegate
+- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls {
+    if (self.isDownloadFile) {
+        self.isDownloadFile = NO;
+        //保存成功
+       [LOADING_MANAGER MBShowAUTOHidingInWindow:@"保存成功"];
+    }
+    else {
+        NSURL *url =  [urls lastObject];
+        NSArray *array = [[url absoluteString] componentsSeparatedByString:@"/"];
+        NSString *fileName = [array lastObject];
+        fileName = [fileName stringByRemovingPercentEncoding];
+        
+        if (self.fileChooseType == CHOOSETYPE_XML) {
+            if (![fileName hasSuffix:@".xml"]) {
+                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传XML格式文件"];
+                [self fileChooseErrorCallback];
+                return;
+            }
+        }
+        else if (self.fileChooseType == CHOOSETYPE_MIDI) {
+            if (![fileName hasSuffix:@".mid"] || [fileName hasSuffix:@".midi"]) {
+                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传mid格式文件"];
+                [self fileChooseErrorCallback];
+                return;
+            }
+        }
+        else if (self.fileChooseType == CHOOSETYPE_MP3) {
+            if (![fileName hasSuffix:@".mp3"]) {
+                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传mp3格式文件"];
+                [self fileChooseErrorCallback];
+                return;
+            }
+        }
+        else {
+            if (![fileName hasSuffix:@".mp3"] && ![fileName hasSuffix:@".aac"]) {
+                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"暂不支持此格式!"];
+                [self fileChooseErrorCallback];
+                return;
+            }
+        }
+        
+        __block NSString * fileUrl = @"";
+        if ([KSICloudManager iCloudEnable]) {
+            [KSICloudManager downloadWithDocumentURL:url callBack:^(id obj) {
+                NSData *data = obj;
+                
+                //写入沙盒Documents
+                 NSString *pathStr = [NSHomeDirectory() stringByAppendingString:[NSString stringWithFormat:@"/Documents/%@",fileName]];
+                [data writeToFile:pathStr atomically:YES];
+                
+                if (![[NSFileManager defaultManager] fileExistsAtPath:pathStr]) {
+                    BOOL isSuccess = [data writeToFile:pathStr atomically:YES];
+                    if (isSuccess) {
+                        fileUrl = pathStr;
+                    }
+                    else {
+                        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"写入文件错误!"];
+                        [self fileChooseErrorCallback];
+                    }
+                }
+                else {
+                    fileUrl = pathStr;
+                }
+                [self uploadFile:fileName fileUrl:pathStr];
+                
+            }];
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"iCloud不可用!"];
+            [self fileChooseErrorCallback];
+        }
+    }
+}
 /*
 #pragma mark - Navigation
 

+ 2 - 1
KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.h

@@ -971,9 +971,10 @@ NS_ASSUME_NONNULL_BEGIN
 /// @param desc 描述
 /// @param type 草稿 DRAFT 作品FORMAL,
 /// @param musicPracticeRecordId 云教练id
+/// @param videoImg 视频封面
 /// @param success 成功
 /// @param faliure 失败
-+ (void)saveMusicMessage:(NSString *)post jsonConfig:(NSString *)jsonConfig img:(NSString *)img videoUrl:(NSString *)videoUrl accompanyUrl:(NSString *)accompanyUrl desc:(NSString *)desc type:(NSString *)type musicPracticeRecordId:(NSString *)musicPracticeRecordId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
++ (void)saveMusicMessage:(NSString *)post jsonConfig:(NSString *)jsonConfig img:(NSString *)img videoUrl:(NSString *)videoUrl accompanyUrl:(NSString *)accompanyUrl desc:(NSString *)desc type:(NSString *)type musicPracticeRecordId:(NSString *)musicPracticeRecordId videoImg:(NSString *)videoImg success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
 
 // /userMusic/page
 

+ 3 - 1
KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.m

@@ -1856,9 +1856,10 @@
 /// @param desc 描述
 /// @param type 草稿 DRAFT 作品FORMAL,
 /// @param musicPracticeRecordId 云教练id
+/// @param videoImg 视频封面
 /// @param success 成功
 /// @param faliure 失败
-+ (void)saveMusicMessage:(NSString *)post jsonConfig:(NSString *)jsonConfig img:(NSString *)img videoUrl:(NSString *)videoUrl accompanyUrl:(NSString *)accompanyUrl desc:(NSString *)desc type:(NSString *)type musicPracticeRecordId:(NSString *)musicPracticeRecordId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
++ (void)saveMusicMessage:(NSString *)post jsonConfig:(NSString *)jsonConfig img:(NSString *)img videoUrl:(NSString *)videoUrl accompanyUrl:(NSString *)accompanyUrl desc:(NSString *)desc type:(NSString *)type musicPracticeRecordId:(NSString *)musicPracticeRecordId videoImg:(NSString *)videoImg success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
     [self configRequestMethodJSON];
     NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-student/userMusic/save"];
     NSMutableDictionary *parm = [NSMutableDictionary dictionary];
@@ -1868,6 +1869,7 @@
     [parm setValue:accompanyUrl forKey:@"accompanyUrl"];
     [parm setValue:desc forKey:@"desc"];
     [parm setValue:type forKey:@"type"];
+    [parm setValue:videoImg forKey:@"videoImg"];
     [parm setValue:musicPracticeRecordId forKey:@"musicPracticeRecordId"];
     
     [self request:post andWithUrl:url and:parm success:success faliure:faliure];

+ 3 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/KSVideoRecordManager.m

@@ -306,6 +306,9 @@
     self.videoFileURL = outputFileURL;
     [self resetSession];
     self.skipSaveRecord = NO;
+    if (self.callback) {
+        self.callback(YES, @"");
+    }
 }
 
 - (void)saveVideoCallback:(KSVideoRecordCallback)callback {

+ 7 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/LoadingManager/KSHudLoagingManager.m

@@ -134,6 +134,13 @@
     return _loadingView;
 }
 
+- (KSProgressLoadingView *)progressLoading {
+    if (!_progressLoading) {
+        _progressLoading = [KSProgressLoadingView shareInstance];
+    }
+    return _progressLoading;
+}
+
 /// 加载进度loading
 /// - Parameters:
 ///   - text: 文本

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

@@ -18,31 +18,31 @@
 
 // 开发环境
 
-#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://test.colexiu.com")
-//#define SEALCLASSHOST (@"https://test.colexiu.com/api-classroom")
-//#define WEBHOST (@"https://test.colexiu.com/student")
-//#define TENANT_WEBHOST (@"https://test.colexiu.com/tenant")
-//#define SOCKET_URL (@"wss://test.colexiu.com/audioAnalysis")
+//#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://test.colexiu.com")
+#define SEALCLASSHOST (@"https://test.colexiu.com/api-classroom")
+#define WEBHOST (@"https://test.colexiu.com/student")
+#define TENANT_WEBHOST (@"https://test.colexiu.com/tenant")
+#define SOCKET_URL (@"wss://test.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://ponline.colexiu.com")
 //#define SEALCLASSHOST (@"https://ponline.colexiu.com/api-classroom")

+ 2 - 0
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSAudioAnimationView.h

@@ -11,6 +11,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 @interface KSAudioAnimationView : UIView
 
+- (void)configWithImageWithUrl:(NSString *)imageUrl;
+
 @property (nonatomic, assign) BOOL isPlay;
 
 + (instancetype)shareInstance;

+ 8 - 1
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSAudioAnimationView.m

@@ -85,7 +85,14 @@
     [self.discView.layer removeAllAnimations];
 }
 
-
+- (void)configWithImageWithUrl:(NSString *)imageUrl {
+    if ([NSString isEmptyString:imageUrl]) {
+        [self.music_image setImage:[UIImage imageNamed:@"pub_music_placeholder"]];
+    }
+    else {
+        [self.music_image sd_setImageWithURL:[NSURL URLWithString:[imageUrl getUrlEndcodeString]]];
+    }
+}
 
 - (UIImageView *)stylusImage {
     if (!_stylusImage) {

+ 200 - 38
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMediaMergeView.m

@@ -19,8 +19,10 @@
 #import "KSNewAlertView.h"
 #import "MusicPublistAlert.h"
 #import "KSMediaManager.h"
+#import <RSKImageCropper/RSKImageCropper.h>
+#import "KSVideoCropViewController.h"
 
-@interface KSMediaMergeView ()<kSNewPlayerManagerDelegate,KSVideoPlayerViewDelegate>
+@interface KSMediaMergeView ()<kSNewPlayerManagerDelegate,KSVideoPlayerViewDelegate,RSKImageCropViewControllerDelegate,RSKImageCropViewControllerDataSource>
 
 @property (nonatomic, strong) KSAudioAnimationView *animationView;
 
@@ -99,6 +101,14 @@
 
 @property (nonatomic, assign) BOOL hasModify;
 
+@property (nonatomic, strong) UIImage *videoCoverImage;
+
+@property (nonatomic, assign) BOOL isChooseVideoCover;
+
+@property (nonatomic, strong) NSString *videoCoverUrl; // 视频封面
+
+@property (nonatomic, strong) dispatch_group_t uploadGroup;
+
 @end
 
 @implementation KSMediaMergeView
@@ -192,7 +202,6 @@
             self.videoUrl = fileUrl;
         } faliure:^(NSError * _Nonnull error) {
             dispatch_group_leave(self.requestGroup);
-
         }];
     }
 }
@@ -557,9 +566,8 @@
 
 - (void)showPublishAlert {
     self.publishAlert = [MusicPublistAlert shareInstance];
-    self.publishAlert.musicName.text = [NSString returnNoNullStringWithString:self.songName];
-    [self.publishAlert.musicImage sd_setImageWithURL:[NSURL URLWithString:[self.coverImage getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"music_placeholder"]];
-    self.publishAlert.userName.text = [NSString returnNoNullStringWithString:UserDefault(NicknameKey)];
+    [self.publishAlert configUI:self.isVideoPlay];
+    [self.publishAlert evaluateMusicName:self.songName userName:UserDefault(NicknameKey) musicImage:self.coverImage];
     MJWeakSelf;
     [self.publishAlert chooseAction:^(PUBLISH_ACTION type) {
         [weakSelf publishAction:type];
@@ -571,9 +579,9 @@
     switch (type) {
         case PUBLISH_ACTION_PUBLISH:
         {
-            self.desc = [NSString isEmptyString:self.publishAlert.textView.text] ? @"我发布了一首演奏作品,快来听听吧~" :self.publishAlert.textView.text;
-            if (self.settingImage) { // 上传图片
-                [self updateWithCoverImage:self.settingImage];
+            self.desc = [NSString isEmptyString:self.publishAlert.publishContainView.textView.text] ? @"我发布了一首演奏作品,快来听听吧~" :self.publishAlert.publishContainView.textView.text;
+            if (self.settingImage || self.videoCoverImage) { // 上传图片
+                [self updateWithCoverImage];
             }
             else { // 直接上传
                 [self publishMusic];
@@ -592,36 +600,123 @@
             MJWeakSelf;
             [self.mediaManager noAlertCallback:^(NSString * _Nullable videoUrl, NSMutableArray * _Nullable imageArray, NSMutableArray * _Nullable imageAsset) {
                 // 裁剪
-                [weakSelf refreshViewCoverImg:imageArray];
+                UIImage *sendImg = [imageArray lastObject];
+                // 跳转到裁剪功能
+                RSKImageCropViewController *imageCropVC = [[RSKImageCropViewController alloc] initWithImage:sendImg cropMode:RSKImageCropModeCustom];
+                imageCropVC.avoidEmptySpaceAroundImage = YES;
+                imageCropVC.rotationEnabled = YES;
+                imageCropVC.delegate = weakSelf;
+                imageCropVC.dataSource = weakSelf;
+                imageCropVC.modalPresentationStyle = UIModalPresentationFullScreen;
+                UIViewController *baseCtrl = [weakSelf findViewController];
+                [baseCtrl.navigationController presentViewController:imageCropVC animated:YES completion:nil];
+            }];
+            [self.mediaManager pushImagePickerController];
+        }
+            break;
+        case PUBLISH_ACTION_VIDEOCOVER: // 视频封面
+        {
+            self.isChooseVideoCover = YES;
+            // 调用相册
+            self.mediaManager = [[KSMediaManager alloc] init];
+            self.mediaManager.mediaType = MEDIATYPE_PHOTO;
+            self.mediaManager.maxPhotoNumber = 1;
+            self.mediaManager.baseCtrl = [self findViewController];
+
+            self.mediaManager.needCropImage = NO;
+            MJWeakSelf;
+            [self.mediaManager noAlertCallback:^(NSString * _Nullable videoUrl, NSMutableArray * _Nullable imageArray, NSMutableArray * _Nullable imageAsset) {
+                // 裁剪
+                UIImage *sendImg = [imageArray lastObject];
+                // 跳转到裁剪功能
+                RSKImageCropViewController *imageCropVC = [[RSKImageCropViewController alloc] initWithImage:sendImg cropMode:RSKImageCropModeCustom];
+                imageCropVC.avoidEmptySpaceAroundImage = YES;
+                imageCropVC.rotationEnabled = YES;
+                imageCropVC.delegate = weakSelf;
+                imageCropVC.dataSource = weakSelf;
+                imageCropVC.modalPresentationStyle = UIModalPresentationFullScreen;
+                UIViewController *baseCtrl = [weakSelf findViewController];
+                [baseCtrl.navigationController presentViewController:imageCropVC animated:YES completion:nil];
             }];
             [self.mediaManager pushImagePickerController];
         }
             break;
+        case PUBLISH_ACTION_VIDEOCROP:
+        {
+            KSVideoCropViewController *ctrl = [[KSVideoCropViewController alloc] init];
+            [ctrl configWithVideoPath:self.videoUrl];
+            UIViewController *baseCtrl = [self findViewController];
+            MJWeakSelf;
+            [ctrl chooseCropImageCallback:^(UIImage * _Nonnull cropImage) {
+                [weakSelf displayCoverImage:cropImage];
+            }];
+            [baseCtrl.navigationController presentViewController:ctrl animated:YES completion:nil];
+        }
+            break;
         default:
             break;
     }
 }
 
-- (void)updateWithCoverImage:(UIImage *)image {
-    NSData *imgData = [UIImage turnsImaegDataByImage:image];
+- (void)displayCoverImage:(UIImage *)image {
+    self.videoCoverImage = image;
+    [self.publishAlert.coverView.coverImage setImage:self.videoCoverImage];
+}
+
+- (void)updateWithCoverImage {
+    
+    if (self.settingImage) {
+        [self uploadMusicCover];
+    }
+    if (self.videoCoverImage) {
+        [self uploadVideoCover];
+    }
+    
+    dispatch_group_notify(self.uploadGroup, dispatch_get_main_queue(), ^{
+        [self publishMusic];
+    });
+}
+
+- (void)uploadMusicCover {
+    dispatch_group_enter(self.uploadGroup);
+
+    NSData *imgData = [UIImage turnsImaegDataByImage:self.settingImage];
     NSString *fileName = @"musicCoverImg";
     [[KSUploadManager shareInstance] configBucketName:@"klx"];
     [[KSUploadManager shareInstance] uploadImage:imgData fileName:fileName successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
         NSString *avatarUrl = [fileUrlArray lastObject];
         self.coverImage = avatarUrl;
-        [self publishMusic];
+        dispatch_group_leave(self.uploadGroup);
+    } faliure:^(NSError * _Nullable error, NSString *descMessaeg) {
+        if ([NSString isEmptyString:descMessaeg]) {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:descMessaeg];
+        }
+        dispatch_group_leave(self.uploadGroup);
+    }];
+}
+
+- (void)uploadVideoCover {
+    dispatch_group_enter(self.uploadGroup);
+    NSData *imgData = [UIImage turnsImaegDataByImage:self.videoCoverImage];
+    NSString *fileName = @"musicCoverImg";
+    [[KSUploadManager shareInstance] configBucketName:@"klx"];
+    [[KSUploadManager shareInstance] uploadImage:imgData fileName:fileName successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
+        NSString *avatarUrl = [fileUrlArray lastObject];
+        self.videoCoverUrl = avatarUrl;
+        dispatch_group_leave(self.uploadGroup);
     } faliure:^(NSError * _Nullable error, NSString *descMessaeg) {
         if ([NSString isEmptyString:descMessaeg]) {
             [LOADING_MANAGER MBShowAUTOHidingInWindow:descMessaeg];
         }
+        dispatch_group_leave(self.uploadGroup);
+
     }];
 }
 
 - (void)refreshViewCoverImg:(NSMutableArray *)imageArray {
     UIImage *img = [imageArray lastObject];
     self.settingImage = img;
-    [self.publishAlert.musicImage setImage:self.settingImage];
-    
+    [self.publishAlert.publishContainView.musicImage setImage:self.settingImage];
 }
 
 
@@ -634,7 +729,7 @@
                 self.filePath = outPath;
                 MJWeakSelf;
                 [self sendVideoActionWithUrl:outPath isFormal:YES success:^(NSString * _Nonnull uploadVideoUrl) {
-                    [weakSelf saveMusic:YES isFormal:YES fileUrl:uploadVideoUrl];
+                    [weakSelf saveMusic:YES isFormal:YES fileUrl:uploadVideoUrl progress:66];
 
                 } failure:^(NSString * _Nonnull desc) {
                     
@@ -654,7 +749,7 @@
                 self.filePath = outPath;
                 MJWeakSelf;
                 [self sendAudioWithPath:outPath isFormal:YES success:^(NSString *audioUrl) {
-                    [weakSelf saveMusic:NO isFormal:YES fileUrl:audioUrl];
+                    [weakSelf saveMusic:NO isFormal:YES fileUrl:audioUrl progress:66];
                 } failure:^(NSString *desc) {
                     [LOADING_MANAGER MBShowAUTOHidingInWindow:@"文件上传失败"];
                 }];
@@ -672,33 +767,36 @@
     if (self.isVideoPlay) {
         if (self.remoteVideoUrl) {
             // 保存草稿
-            [self saveMusic:YES isFormal:NO fileUrl:self.remoteVideoUrl needBack:needBack];
+            [self saveMusic:YES isFormal:NO fileUrl:self.remoteVideoUrl needBack:needBack progress:33];
         }
         else {
+            // 合成
+            [LOADING_MANAGER showProgressLoading:@"加载中..." progress:33];
             MJWeakSelf;
-            /*
-            [self saveVideoURLToAsset:self.videoUrl isFormal:NO callback:^(NSString *videoUrl) {
-                // 保存草稿
-                [weakSelf saveMusic:YES isFormal:NO fileUrl:videoUrl needBack:needBack];
-            }];
-             */
-            [self sendVideoActionWithUrlPath:self.videoUrl isFormal:NO success:^(NSString * _Nonnull uploadVideoUrl) {
-                // 保存草稿
-                [weakSelf saveMusic:YES isFormal:NO fileUrl:uploadVideoUrl needBack:needBack];
-            } failure:^(NSString * _Nonnull desc) {
-                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"上传失败"];
+            [KSMediaEditor mixRecordVideoWithAudio:self.recordUrl recordVolume:100 videoUrlStr:self.videoUrl completion:^(NSString * _Nonnull outPath, BOOL isSuccess, NSString * _Nonnull desc) {
+                if (isSuccess) {
+                    [self sendVideoActionWithUrl:outPath isFormal:NO success:^(NSString * _Nonnull uploadVideoUrl) {
+                        // 保存草稿
+                        [weakSelf saveMusic:YES isFormal:NO fileUrl:uploadVideoUrl needBack:needBack progress:66];
+                    } failure:^(NSString * _Nonnull desc) {
+                        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"上传失败"];
+                    }];
+                }
+                else {
+                    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"上传失败"];
+                }
             }];
         }
     }
     else {
         if (self.remoteRecrodUrl) {
-            [self saveMusic:NO isFormal:NO fileUrl:self.remoteRecrodUrl needBack:needBack];
+            [self saveMusic:NO isFormal:NO fileUrl:self.remoteRecrodUrl needBack:needBack progress:33];
         }
         else {
             MJWeakSelf;
             [self sendAudioWithURLPath:self.recordUrl isFormal:NO success:^(NSString *audioUrl) {
                 
-                [weakSelf saveMusic:NO isFormal:NO fileUrl:audioUrl needBack:needBack];
+                [weakSelf saveMusic:NO isFormal:NO fileUrl:audioUrl needBack:needBack progress:33];
             } failure:^(NSString *desc) {
                 [LOADING_MANAGER MBShowAUTOHidingInWindow:@"文件上传失败"];
             }];
@@ -757,7 +855,7 @@
         self.playControlView.playScheduleTime = (NSInteger)(playTime / 1000);
     }
     else {
-        NSLog(@"--- ---- bgPlayer   ----- %f", playTime);
+//        NSLog(@"--- ---- bgPlayer   ----- %f", playTime);
     }
 }
 
@@ -858,20 +956,20 @@
     }];
 }
 
-- (void)saveMusic:(BOOL)isVideo isFormal:(BOOL)isFormal fileUrl:(NSString *)fileUrl  {
+- (void)saveMusic:(BOOL)isVideo isFormal:(BOOL)isFormal fileUrl:(NSString *)fileUrl progress:(NSInteger)progress  {
     
-    [self saveMusic:isVideo isFormal:isFormal fileUrl:fileUrl needBack:NO];
+    [self saveMusic:isVideo isFormal:isFormal fileUrl:fileUrl needBack:NO progress:progress];
 }
 
-- (void)saveMusic:(BOOL)isVideo isFormal:(BOOL)isFormal fileUrl:(NSString *)fileUrl needBack:(BOOL)needBack {
+- (void)saveMusic:(BOOL)isVideo isFormal:(BOOL)isFormal fileUrl:(NSString *)fileUrl needBack:(BOOL)needBack progress:(NSInteger)progress {
     NSString *type = isFormal ? @"FORMAL" : @"DRAFT";
     NSMutableDictionary *parm = [NSMutableDictionary dictionary];
     [parm setValue:@(self.offsetTime) forKey:@"offset"];
     [parm setValue:@(self.originalVolume) forKey:@"originalVolume"];
     [parm setValue:@(self.accompanyVolume) forKey:@"accompanyVolume"];
     self.jsonConfig = [parm mj_JSONString];
-    [LOADING_MANAGER showProgressLoading:@"加载中..." progress:66];
-    [KSNetworkingManager saveMusicMessage:KS_POST jsonConfig:self.jsonConfig img:self.coverImage videoUrl:fileUrl accompanyUrl:self.remoteBgAudioUrl desc:self.desc type:type musicPracticeRecordId:self.recordId success:^(NSDictionary * _Nonnull dic) {
+    [LOADING_MANAGER showProgressLoading:@"加载中..." progress:progress];
+    [KSNetworkingManager saveMusicMessage:KS_POST jsonConfig:self.jsonConfig img:self.coverImage videoUrl:fileUrl accompanyUrl:self.remoteBgAudioUrl desc:self.desc type:type musicPracticeRecordId:self.recordId videoImg:self.videoCoverUrl success:^(NSDictionary * _Nonnull dic) {
         if ([dic ks_integerValueForKey:@"code"] == 200) {
             if (isFormal) {
                 [LOADING_MANAGER KSShowProgressMsg:@"发布成功" promptCompletion:^{
@@ -962,7 +1060,7 @@
     [LOADING_MANAGER showProgressLoading:tips progress:66];
     NSData *fileData = [NSData dataWithContentsOfURL:fileUrl];
     NSString *suffix = [NSString stringWithFormat:@".%@",[fileUrl pathExtension]];
-    [UPLOAD_MANAGER configBucketName:@"klx"];
+    [[KSUploadManager shareInstance] configBucketName:@"klx"];
     [UPLOAD_MANAGER uploadFile:fileData fileName:@"evaluateAudio" fileSuffix:suffix progress:^(int64_t bytesWritten, int64_t totalBytes) {
 
     } successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
@@ -1051,7 +1149,12 @@
     }
     return _requestGroup;
 }
-
+- (dispatch_group_t)uploadGroup {
+    if (!_uploadGroup) {
+        _uploadGroup = dispatch_group_create();
+    }
+    return _uploadGroup;
+}
 - (KSNewAlertView *)alertView {
     if (!_alertView) {
         _alertView = [KSNewAlertView shareInstance];
@@ -1070,6 +1173,65 @@
     return nil;
 }
 
+#pragma mark --- RSKImageCropViewControllerDelegate
+
+- (CGRect)imageCropViewControllerCustomMaskRect:(RSKImageCropViewController *)controller {
+    CGFloat height = KLandscapeHeight - 80;
+    
+    CGFloat width = height;
+    if (self.isChooseVideoCover) {
+        width = height / 9 * 16;
+
+    }
+    return CGRectMake((KLandscapeWidth - width) / 2.0f, (KLandscapeHeight - height) / 2.0f, width, height);
+}
+
+- (UIBezierPath *)imageCropViewControllerCustomMaskPath:(RSKImageCropViewController *)controller {
+    //返回裁剪框的位置
+    CGFloat height = KLandscapeHeight - 80;
+    CGFloat width = height;
+    if (self.isChooseVideoCover) {
+        width = height / 9 * 16;
+    }
+    UIBezierPath *path=[UIBezierPath bezierPathWithRoundedRect:CGRectMake((KLandscapeWidth - width) / 2.0f, (KLandscapeHeight - height) / 2.0f, width, height) cornerRadius:0];
+    return path;
+}
+/**
+返回一个图片可以移动的矩形区域
+仅在RSKImageCropModeCustom下有效
+如果你想支持图片旋转,则必须实现该方法
+ */
+- (CGRect)imageCropViewControllerCustomMovementRect:(RSKImageCropViewController *)controller
+{
+    return controller.maskRect;
+}
+
+/**
+ 通知 delegate 取消裁剪图像。
+ */
+- (void)imageCropViewControllerDidCancelCrop:(RSKImageCropViewController *)controller {
+    if (self.isChooseVideoCover) {
+        self.isChooseVideoCover = NO;
+    }
+    [controller dismissViewControllerAnimated:YES completion:nil];
+}
+
+/**
+ 通知 delegate 原始图像已经被裁剪。此外,还提供了一个裁剪矩形和用于生成图像的旋转角度。
+ */
+- (void)imageCropViewController:(RSKImageCropViewController *)controller didCropImage:(UIImage *)croppedImage usingCropRect:(CGRect)cropRect rotationAngle:(CGFloat)rotationAngle {
+//    croppedImage
+    if (self.isChooseVideoCover) {
+        self.isChooseVideoCover = NO;
+        [self displayCoverImage:croppedImage];
+    }
+    else {
+        self.settingImage = croppedImage;
+        [self.publishAlert.publishContainView.musicImage setImage:self.settingImage];
+    }
+    
+    [controller dismissViewControllerAnimated:YES completion:nil];
+}
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.

+ 4 - 4
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSMergeAudioControlView.xib

@@ -233,7 +233,7 @@
                             </connections>
                         </button>
                         <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nyI-H7-gwi">
-                            <rect key="frame" x="13" y="54" width="34" height="34"/>
+                            <rect key="frame" x="250" y="54" width="34" height="34"/>
                             <subviews>
                                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="slider_bubble" translatesAutoresizingMaskIntoConstraints="NO" id="ahK-NK-SMi">
                                     <rect key="frame" x="0.0" y="0.0" width="34" height="34"/>
@@ -256,7 +256,7 @@
                             </constraints>
                         </view>
                         <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Z4q-fo-efi">
-                            <rect key="frame" x="13" y="137" width="34" height="34"/>
+                            <rect key="frame" x="250" y="137" width="34" height="34"/>
                             <subviews>
                                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="slider_bubble" translatesAutoresizingMaskIntoConstraints="NO" id="qaQ-ih-J2u">
                                     <rect key="frame" x="0.0" y="0.0" width="34" height="34"/>
@@ -316,7 +316,7 @@
                         <constraint firstItem="if2-R5-Tul" firstAttribute="leading" secondItem="dNG-od-Opv" secondAttribute="leading" constant="26" id="Tbj-uW-5vm"/>
                         <constraint firstItem="if2-R5-Tul" firstAttribute="top" secondItem="pQK-tY-S1I" secondAttribute="bottom" constant="20" id="U6A-D9-FMf"/>
                         <constraint firstItem="MX8-jr-euo" firstAttribute="centerY" secondItem="gDH-uC-2DO" secondAttribute="centerY" id="W2M-EL-mO7"/>
-                        <constraint firstItem="Z4q-fo-efi" firstAttribute="centerX" secondItem="dNG-od-Opv" secondAttribute="leading" constant="30" id="WVs-oc-QrV"/>
+                        <constraint firstItem="Z4q-fo-efi" firstAttribute="centerX" secondItem="dNG-od-Opv" secondAttribute="leading" constant="267" id="WVs-oc-QrV"/>
                         <constraint firstItem="slK-h7-P25" firstAttribute="top" secondItem="XPO-nW-Uox" secondAttribute="bottom" constant="12" id="ZPv-OR-vc2"/>
                         <constraint firstItem="f5Q-wh-6l8" firstAttribute="centerX" secondItem="Jqd-bC-HWT" secondAttribute="centerX" id="aUL-2e-p91"/>
                         <constraint firstItem="ZEM-tW-WX9" firstAttribute="top" secondItem="dNG-od-Opv" secondAttribute="top" constant="14" id="ddY-o0-jeB"/>
@@ -332,7 +332,7 @@
                         <constraint firstItem="gDH-uC-2DO" firstAttribute="leading" secondItem="dNG-od-Opv" secondAttribute="leading" constant="8" id="hut-3H-gU3"/>
                         <constraint firstAttribute="bottom" secondItem="VTj-cX-p66" secondAttribute="bottom" constant="67" id="iPG-s9-hwk"/>
                         <constraint firstItem="imR-Qo-Jpf" firstAttribute="leading" secondItem="slK-h7-P25" secondAttribute="trailing" constant="6" id="iTt-Wy-aYO"/>
-                        <constraint firstItem="nyI-H7-gwi" firstAttribute="centerX" secondItem="dNG-od-Opv" secondAttribute="leading" constant="30" id="jdI-be-CFN"/>
+                        <constraint firstItem="nyI-H7-gwi" firstAttribute="centerX" secondItem="dNG-od-Opv" secondAttribute="leading" constant="267" id="jdI-be-CFN"/>
                         <constraint firstItem="DzT-go-dxS" firstAttribute="top" secondItem="pQK-tY-S1I" secondAttribute="top" constant="-5" id="kMt-a5-3io"/>
                         <constraint firstItem="Q7z-0G-roa" firstAttribute="top" secondItem="VTj-cX-p66" secondAttribute="bottom" constant="10" id="kNw-jw-Ek9"/>
                         <constraint firstItem="pQK-tY-S1I" firstAttribute="top" secondItem="oyf-C4-Pe3" secondAttribute="bottom" constant="16" id="lye-Zg-T75"/>

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/KSPlayerSliderView.m

@@ -52,7 +52,7 @@
         UIView *sliderImg = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 12, 12)];
         sliderImg.layer.cornerRadius = 6.0f;
         sliderImg.layer.masksToBounds = YES;
-        sliderImg.backgroundColor = HexRGB(0x269EFE);
+        sliderImg.backgroundColor = HexRGB(0x2DC7AA);
         UIImage *image = [UIView convertViewToImage:sliderImg];
         [self.progressSlider setThumbImage:image forState:UIControlStateNormal];
         [self.progressSlider setThumbImage:image forState:UIControlStateHighlighted];

+ 0 - 272
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MusicPublistAlert.xib

@@ -1,272 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" 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="22131"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MusicPublistAlert">
-            <rect key="frame" x="0.0" y="0.0" width="687" height="520"/>
-            <autoresizingMask key="autoresizingMask"/>
-            <subviews>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="crp-Dg-bEh">
-                    <rect key="frame" x="185.66666666666663" y="104.66666666666669" width="316" height="311"/>
-                    <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="作品详情" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="te4-O1-RAs">
-                            <rect key="frame" x="125.33333333333334" y="15" width="65.333333333333343" height="22"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="22" id="9P9-gf-TQs"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
-                            <color key="textColor" red="0.074509803921568626" green="0.078431372549019607" blue="0.082352941176470587" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="CTY-Fx-tzH">
-                            <rect key="frame" x="12" y="51.999999999999986" width="292" height="87.000000000000014"/>
-                            <subviews>
-                                <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WQ8-cQ-EDG">
-                                    <rect key="frame" x="12" y="0.0" width="268" height="87"/>
-                                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                                    <color key="textColor" red="0.2666666667" green="0.2666666667" blue="0.2666666667" alpha="1" colorSpace="calibratedRGB"/>
-                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                                    <textInputTraits key="textInputTraits" autocapitalizationType="sentences" enablesReturnKeyAutomatically="YES"/>
-                                </textView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我发布了一首演奏作品,快来听听吧~" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9AA-e2-K2q">
-                                    <rect key="frame" x="12" y="10" width="243" height="17"/>
-                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                                    <color key="textColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0/150" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="em6-7z-Xgu">
-                                    <rect key="frame" x="248" y="58" width="32" height="20"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="20" id="34t-Kc-j7t"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                    <color key="textColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                            </subviews>
-                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                            <constraints>
-                                <constraint firstAttribute="trailing" secondItem="em6-7z-Xgu" secondAttribute="trailing" constant="12" id="F5G-2F-xMS"/>
-                                <constraint firstAttribute="bottom" secondItem="em6-7z-Xgu" secondAttribute="bottom" constant="9" id="IiE-1G-erd"/>
-                                <constraint firstItem="WQ8-cQ-EDG" firstAttribute="leading" secondItem="CTY-Fx-tzH" secondAttribute="leading" constant="12" id="JOz-Zs-M9D"/>
-                                <constraint firstAttribute="trailing" secondItem="WQ8-cQ-EDG" secondAttribute="trailing" constant="12" id="Wfg-qP-9ez"/>
-                                <constraint firstItem="9AA-e2-K2q" firstAttribute="leading" secondItem="CTY-Fx-tzH" secondAttribute="leading" constant="12" id="XBD-OF-F8e"/>
-                                <constraint firstItem="9AA-e2-K2q" firstAttribute="top" secondItem="CTY-Fx-tzH" secondAttribute="top" constant="10" id="bSD-PX-0Jh"/>
-                                <constraint firstItem="WQ8-cQ-EDG" firstAttribute="top" secondItem="CTY-Fx-tzH" secondAttribute="top" id="lj6-bB-3sT"/>
-                                <constraint firstAttribute="height" constant="87" id="mHx-kV-2g8"/>
-                                <constraint firstAttribute="bottom" secondItem="WQ8-cQ-EDG" secondAttribute="bottom" id="mZ3-oV-sMo"/>
-                            </constraints>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="10"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                        </view>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="l5g-yG-AJ9">
-                            <rect key="frame" x="12" y="151" width="292" height="86"/>
-                            <subviews>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="music_coverBg" translatesAutoresizingMaskIntoConstraints="NO" id="EP2-DU-ddy">
-                                    <rect key="frame" x="19" y="12.333333333333343" width="61" height="61"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="61" id="DTT-42-ivC"/>
-                                        <constraint firstAttribute="width" constant="61" id="hgd-Hf-dTV"/>
-                                    </constraints>
-                                </imageView>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="pub_music_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="VVv-Nb-ldQ">
-                                    <rect key="frame" x="12" y="12.000000000000028" width="62" height="62"/>
-                                    <constraints>
-                                        <constraint firstAttribute="width" constant="62" id="LVE-t7-SCr"/>
-                                        <constraint firstAttribute="height" constant="62" id="pjr-Ke-g6S"/>
-                                    </constraints>
-                                    <userDefinedRuntimeAttributes>
-                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                            <real key="value" value="8"/>
-                                        </userDefinedRuntimeAttribute>
-                                    </userDefinedRuntimeAttributes>
-                                </imageView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ETV-b6-Fe7">
-                                    <rect key="frame" x="90.000000000000028" y="20.000000000000028" width="189.99999999999997" height="22"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="22" id="77r-wV-D6B"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
-                                    <color key="textColor" red="0.074509803920000006" green="0.078431372550000003" blue="0.08235294118" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9Ss-uK-g79">
-                                    <rect key="frame" x="90.000000000000028" y="46.000000000000028" width="189.99999999999997" height="20"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="20" id="eD2-NY-Z0M"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                                    <color key="textColor" red="0.46666666666666667" green="0.46666666666666667" blue="0.46666666666666667" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="unChoose_status" translatesAutoresizingMaskIntoConstraints="NO" id="eTy-AP-Nrh">
-                                    <rect key="frame" x="0.0" y="34.000000000000028" width="0.0" height="18"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="18" id="KB9-Tz-L8j"/>
-                                        <constraint firstAttribute="width" id="bSW-D2-mdn"/>
-                                    </constraints>
-                                </imageView>
-                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="34Q-Ap-BhT">
-                                    <rect key="frame" x="12" y="54.000000000000028" width="62" height="20"/>
-                                    <subviews>
-                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="选封面" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p3g-Ea-XCb">
-                                            <rect key="frame" x="11" y="0.0" width="40" height="18"/>
-                                            <constraints>
-                                                <constraint firstAttribute="height" constant="18" id="c6d-6u-Az0"/>
-                                            </constraints>
-                                            <fontDescription key="fontDescription" type="system" pointSize="13"/>
-                                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                                            <nil key="highlightedColor"/>
-                                        </label>
-                                    </subviews>
-                                    <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.37" colorSpace="custom" customColorSpace="calibratedRGB"/>
-                                    <constraints>
-                                        <constraint firstItem="p3g-Ea-XCb" firstAttribute="centerX" secondItem="34Q-Ap-BhT" secondAttribute="centerX" id="GHb-76-r1W"/>
-                                        <constraint firstAttribute="height" constant="20" id="Uih-s7-Z9a"/>
-                                        <constraint firstItem="p3g-Ea-XCb" firstAttribute="top" secondItem="34Q-Ap-BhT" secondAttribute="top" id="VSx-cs-Kk3"/>
-                                        <constraint firstAttribute="width" constant="62" id="vrS-NL-gdO"/>
-                                    </constraints>
-                                </view>
-                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Vxt-nB-ivY">
-                                    <rect key="frame" x="12" y="12.000000000000028" width="62" height="62"/>
-                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                                    <connections>
-                                        <action selector="chooseCover:" destination="iN0-l3-epB" eventType="touchUpInside" id="w2o-dJ-iQE"/>
-                                    </connections>
-                                </button>
-                            </subviews>
-                            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                            <constraints>
-                                <constraint firstItem="ETV-b6-Fe7" firstAttribute="top" secondItem="l5g-yG-AJ9" secondAttribute="top" constant="20" id="4Us-jY-xaa"/>
-                                <constraint firstItem="Vxt-nB-ivY" firstAttribute="bottom" secondItem="VVv-Nb-ldQ" secondAttribute="bottom" id="6An-Xx-CF5"/>
-                                <constraint firstItem="EP2-DU-ddy" firstAttribute="centerY" secondItem="l5g-yG-AJ9" secondAttribute="centerY" id="9gq-xr-2wm"/>
-                                <constraint firstAttribute="trailing" secondItem="ETV-b6-Fe7" secondAttribute="trailing" constant="12" id="E4Y-l1-IHm"/>
-                                <constraint firstAttribute="trailing" secondItem="9Ss-uK-g79" secondAttribute="trailing" constant="12" id="J9w-hP-R7d"/>
-                                <constraint firstItem="VVv-Nb-ldQ" firstAttribute="leading" secondItem="eTy-AP-Nrh" secondAttribute="trailing" constant="12" id="JjX-9P-cVY"/>
-                                <constraint firstItem="9Ss-uK-g79" firstAttribute="top" secondItem="ETV-b6-Fe7" secondAttribute="bottom" constant="4" id="KIe-Xd-GOo"/>
-                                <constraint firstItem="Vxt-nB-ivY" firstAttribute="trailing" secondItem="VVv-Nb-ldQ" secondAttribute="trailing" id="LAw-gk-MSD"/>
-                                <constraint firstItem="Vxt-nB-ivY" firstAttribute="leading" secondItem="VVv-Nb-ldQ" secondAttribute="leading" id="MYP-CH-MAK"/>
-                                <constraint firstItem="eTy-AP-Nrh" firstAttribute="leading" secondItem="l5g-yG-AJ9" secondAttribute="leading" id="NbV-dJ-UHV"/>
-                                <constraint firstItem="34Q-Ap-BhT" firstAttribute="trailing" secondItem="VVv-Nb-ldQ" secondAttribute="trailing" id="QWA-Ld-U5L"/>
-                                <constraint firstItem="VVv-Nb-ldQ" firstAttribute="trailing" secondItem="EP2-DU-ddy" secondAttribute="trailing" constant="-6" id="Ube-4B-zgW"/>
-                                <constraint firstItem="ETV-b6-Fe7" firstAttribute="leading" secondItem="EP2-DU-ddy" secondAttribute="trailing" constant="10" id="Vzb-js-zep"/>
-                                <constraint firstItem="eTy-AP-Nrh" firstAttribute="centerY" secondItem="l5g-yG-AJ9" secondAttribute="centerY" id="dpC-l5-Vmz"/>
-                                <constraint firstItem="34Q-Ap-BhT" firstAttribute="leading" secondItem="VVv-Nb-ldQ" secondAttribute="leading" id="g9W-eP-Dap"/>
-                                <constraint firstItem="9Ss-uK-g79" firstAttribute="leading" secondItem="ETV-b6-Fe7" secondAttribute="leading" id="i9d-wq-Qav"/>
-                                <constraint firstAttribute="height" constant="86" id="oDT-wq-TI3"/>
-                                <constraint firstItem="34Q-Ap-BhT" firstAttribute="bottom" secondItem="VVv-Nb-ldQ" secondAttribute="bottom" id="owr-L6-tci"/>
-                                <constraint firstItem="VVv-Nb-ldQ" firstAttribute="centerY" secondItem="l5g-yG-AJ9" secondAttribute="centerY" id="wAx-Fn-njL"/>
-                                <constraint firstItem="Vxt-nB-ivY" firstAttribute="top" secondItem="VVv-Nb-ldQ" secondAttribute="top" id="xuK-Jq-o5D"/>
-                            </constraints>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="10"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                        </view>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mxv-fX-f3j">
-                            <rect key="frame" x="48" y="255" width="220" height="38"/>
-                            <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="220" id="5fw-Lh-5Er"/>
-                                <constraint firstAttribute="height" constant="38" id="qZJ-YL-FtZ"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
-                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                            <state key="normal" title="发布作品"/>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="19"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="sureAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="AMG-ZX-bXR"/>
-                            </connections>
-                        </button>
-                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cancle_button" translatesAutoresizingMaskIntoConstraints="NO" id="uSL-RT-oX5">
-                            <rect key="frame" x="287" y="11" width="19" height="19"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="19" id="LRY-32-rBI"/>
-                                <constraint firstAttribute="height" constant="19" id="dWq-Go-3Vb"/>
-                            </constraints>
-                        </imageView>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8mM-Qw-PGH">
-                            <rect key="frame" x="276" y="0.0" width="40" height="40"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="40" id="SR0-Xr-LNe"/>
-                                <constraint firstAttribute="width" constant="40" id="zIs-lk-2mh"/>
-                            </constraints>
-                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                            <connections>
-                                <action selector="cancleAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="7JR-cS-Y5p"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="311" id="3bE-RT-gdX"/>
-                        <constraint firstAttribute="trailing" secondItem="CTY-Fx-tzH" secondAttribute="trailing" constant="12" id="3jK-yB-ifC"/>
-                        <constraint firstAttribute="width" constant="316" id="5Vp-Nm-Phf"/>
-                        <constraint firstItem="l5g-yG-AJ9" firstAttribute="leading" secondItem="crp-Dg-bEh" secondAttribute="leading" constant="12" id="GQX-dv-RhD"/>
-                        <constraint firstItem="CTY-Fx-tzH" firstAttribute="leading" secondItem="crp-Dg-bEh" secondAttribute="leading" constant="12" id="Iin-w2-S5a"/>
-                        <constraint firstItem="mxv-fX-f3j" firstAttribute="centerX" secondItem="crp-Dg-bEh" secondAttribute="centerX" id="J6H-Ym-4wW"/>
-                        <constraint firstAttribute="trailing" secondItem="uSL-RT-oX5" secondAttribute="trailing" constant="10" id="JvH-Ld-uxt"/>
-                        <constraint firstItem="8mM-Qw-PGH" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" id="P4Y-hH-uUz"/>
-                        <constraint firstItem="l5g-yG-AJ9" firstAttribute="top" secondItem="CTY-Fx-tzH" secondAttribute="bottom" constant="12" id="Wuw-qP-DaP"/>
-                        <constraint firstItem="te4-O1-RAs" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" constant="15" id="ci5-BA-awW"/>
-                        <constraint firstAttribute="trailing" secondItem="l5g-yG-AJ9" secondAttribute="trailing" constant="12" id="cye-KU-jSS"/>
-                        <constraint firstAttribute="trailing" secondItem="8mM-Qw-PGH" secondAttribute="trailing" id="ehJ-JA-HqW"/>
-                        <constraint firstItem="uSL-RT-oX5" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" constant="11" id="nwL-G4-dhm"/>
-                        <constraint firstItem="CTY-Fx-tzH" firstAttribute="top" secondItem="te4-O1-RAs" secondAttribute="bottom" constant="15" id="tfs-D8-BNT"/>
-                        <constraint firstAttribute="bottom" secondItem="mxv-fX-f3j" secondAttribute="bottom" constant="18" id="vf5-JM-3n3"/>
-                        <constraint firstItem="te4-O1-RAs" firstAttribute="centerX" secondItem="crp-Dg-bEh" secondAttribute="centerX" id="xB7-AF-HP0"/>
-                    </constraints>
-                    <userDefinedRuntimeAttributes>
-                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                            <real key="value" value="12"/>
-                        </userDefinedRuntimeAttribute>
-                    </userDefinedRuntimeAttributes>
-                </view>
-            </subviews>
-            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
-            <constraints>
-                <constraint firstItem="crp-Dg-bEh" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Q7S-rU-daX"/>
-                <constraint firstItem="crp-Dg-bEh" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="l1H-ZN-yAQ"/>
-            </constraints>
-            <nil key="simulatedTopBarMetrics"/>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="backView" destination="34Q-Ap-BhT" id="gb9-fd-tha"/>
-                <outlet property="countLabel" destination="em6-7z-Xgu" id="poA-O7-hZg"/>
-                <outlet property="musicImage" destination="VVv-Nb-ldQ" id="eG2-FL-W0e"/>
-                <outlet property="musicName" destination="ETV-b6-Fe7" id="Hsg-K4-GTb"/>
-                <outlet property="sureButton" destination="mxv-fX-f3j" id="vDY-eb-vr1"/>
-                <outlet property="textView" destination="WQ8-cQ-EDG" id="kSY-Qo-oPM"/>
-                <outlet property="tipsLabel" destination="9AA-e2-K2q" id="OB0-RH-UrS"/>
-                <outlet property="userName" destination="9Ss-uK-g79" id="9lr-IP-EcM"/>
-            </connections>
-            <point key="canvasLocation" x="121.37404580152672" y="-23.239436619718312"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="cancle_button" width="20" height="20"/>
-        <image name="music_coverBg" width="54" height="54"/>
-        <image name="pub_music_placeholder" width="205" height="205"/>
-        <image name="unChoose_status" width="18" height="18"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 4 - 5
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/MediaEditor/KSMediaEditor.m

@@ -244,7 +244,7 @@
 
    
     //导出
-    [self sessionExportAction:mixComposition outputPath:[self getVideoOutputPath] presetName:AVAssetExportPresetMediumQuality outputFileType:AVFileTypeQuickTimeMovie audioMix:audioMix completion:^(NSString *outPath, BOOL isSuccess, NSString *desc) {
+    [self sessionExportAction:mixComposition outputPath:[self getVideoOutputPath] presetName:AVAssetExportPreset1280x720 outputFileType:AVFileTypeQuickTimeMovie audioMix:audioMix completion:^(NSString *outPath, BOOL isSuccess, NSString *desc) {
         completionHandle(outPath, isSuccess, desc);
     }];
     
@@ -293,14 +293,13 @@
     
     // 合成
     AVAssetTrack *recordAssetTrack = [[recordAsset tracksWithMediaType:AVMediaTypeAudio] firstObject];
-    // 录音文件
-    [recordCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, recordAsset.duration) ofTrack:recordAssetTrack atTime:kCMTimeZero error:nil];
+
     // 如果时长超过视频的时长
     CMTime duration = recordDuration > videoDuration ? recordAsset.duration : videoAsset.duration;
     if (recordDuration > videoDuration) {
         duration = videoAsset.duration;
     }
-    
+    // 录音文件
     [recordCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, duration) ofTrack:recordAssetTrack atTime:kCMTimeZero error:nil];
     
     AVMutableAudioMixInputParameters *newRecordInputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:recordCompositionTrack];
@@ -308,7 +307,7 @@
     [newRecordInputParams setVolume:recordVolume atTime:kCMTimeZero];
     audioMix.inputParameters = [NSArray arrayWithObjects:newRecordInputParams,nil];
     //导出
-    [self sessionExportAction:mixComposition outputPath:[self getVideoOutputPath] presetName:AVAssetExportPresetMediumQuality outputFileType:AVFileTypeQuickTimeMovie audioMix:audioMix completion:^(NSString *outPath, BOOL isSuccess, NSString *desc) {
+    [self sessionExportAction:mixComposition outputPath:[self getVideoOutputPath] presetName:AVAssetExportPreset1280x720 outputFileType:AVFileTypeQuickTimeMovie audioMix:audioMix completion:^(NSString *outPath, BOOL isSuccess, NSString *desc) {
         completionHandle(outPath, isSuccess, desc);
     }];
 }

+ 7 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/Controller/InsititutionMineViewController.m

@@ -14,6 +14,7 @@
 #import "INSSettingViewController.h"
 #import "FeedbackViewController.h"
 #import "TenantNotiferCenterController.h"
+#import "MineWorksViewController.h"
 
 @interface InsititutionMineViewController ()<UIScrollViewDelegate>
 
@@ -215,6 +216,12 @@
             [self.navigationController pushViewController:ctrl animated:YES];
         }
             break;
+        case INSMINETYPE_WORKS: // 我的作品
+        {
+            MineWorksViewController *ctrl = [[MineWorksViewController alloc] init];
+            [self.navigationController pushViewController:ctrl animated:YES];
+        }
+            break;
         default:
             break;
     }

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineBodyView.h

@@ -21,7 +21,7 @@ typedef NS_ENUM(NSInteger, INSMINETYPE) {
     INSMINETYPE_USERAGREEMENT,
     INSMINETYPE_PRIVACY,
     INSMINETYPE_ABOUT,
-    
+    INSMINETYPE_WORKS, // 我的作品
 };
 
 typedef void(^INSMineViewCallback)(INSMINETYPE type);

+ 104 - 1
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineBodyView.m

@@ -7,8 +7,10 @@
 
 #import "InstitutionMineBodyView.h"
 #import "UIImageView+DisplayImage.h"
+#import "TYPageControl.h"
+#import "TenantMineFunctionView.h"
 
-@interface InstitutionMineBodyView ()
+@interface InstitutionMineBodyView ()<UIScrollViewDelegate>
 
 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *userNameTop;
 
@@ -27,10 +29,36 @@
 
 @property (weak, nonatomic) IBOutlet UILabel *tenantName;
 
+@property (weak, nonatomic) IBOutlet UIView *functionView;
+
+@property (nonatomic, strong) UIScrollView *functionScrollView;
+
+@property (nonatomic, strong) TYPageControl *pageControl;
+
+@property (nonatomic, strong) NSMutableArray *imageArray;
+
+@property (nonatomic, strong) NSMutableArray *titleArray;
+
+@property (nonatomic, strong) NSMutableArray *tagArray;
+
 @end
 
 @implementation InstitutionMineBodyView
 
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    [self.functionView addSubview:self.pageControl];
+    self.pageControl.currentPage = 0;
+    
+    [self.functionView addSubview:self.functionScrollView];
+    [self.functionScrollView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.functionView);
+    }];
+    self.functionScrollView.delegate = self;
+    self.functionScrollView.contentSize = CGSizeMake((KPortraitWidth - 26)*2, 74);
+    [self configFunctionView];
+}
+
 + (instancetype)shareInstance {
     InstitutionMineBodyView *view = [[[NSBundle mainBundle] loadNibNamed:@"InstitutionMineBodyView" owner:nil options:nil] firstObject];
     return view;
@@ -105,6 +133,7 @@
         self.tenantName.hidden = NO;
         self.tenantName.text = sourceModel.tenantGroupName;
     }
+    
 }
 
 - (IBAction)clickAction:(UITapGestureRecognizer *)sender {
@@ -115,6 +144,24 @@
     }
 }
 
+- (void)configFunctionView {
+    [self.functionScrollView removeAllSubViews];
+    CGFloat width = (KPortraitWidth - 26) / 4;
+    for (NSInteger index = 0; index < self.imageArray.count; index++) {
+        TenantMineFunctionView *functionButton = [TenantMineFunctionView shareInstance];
+        NSNumber *tagValue = self.tagArray[index];
+        NSInteger viewTag = [tagValue intValue];
+        MJWeakSelf;
+        [functionButton configWithSource:self.imageArray[index] title:self.titleArray[index] functionType:viewTag callback:^(NSInteger tagIndex) {
+            if (weakSelf.callback) {
+                weakSelf.callback(tagIndex);
+            }
+        }];
+        functionButton.frame = CGRectMake(width * index, 0, width, 74);
+        [self.functionScrollView addSubview:functionButton];
+    }
+}
+
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
@@ -127,4 +174,60 @@
     return 275 + 12 + 130 + 12 + 58 * 5;
 }
 
+- (TYPageControl *)pageControl {
+    if (!_pageControl) {
+        _pageControl = [[TYPageControl alloc] init];
+        _pageControl.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
+        _pageControl.pageIndicatorSpaing = 4.0f;
+        _pageControl.frame = CGRectMake(0, 60, (KPortraitWidth - 26), 12);
+        _pageControl.currentPageIndicatorTintColor = INS_THEMECOLOR;
+        _pageControl.pageIndicatorTintColor = HexRGB(0xd8d8d8);
+        _pageControl.pageIndicatorSize = CGSizeMake(4, 4);
+        _pageControl.currentPageIndicatorSize = CGSizeMake(12, 4);
+        _pageControl.numberOfPages = 2;
+    }
+    return _pageControl;
+}
+
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
+    if (scrollView == self.functionScrollView) {
+        NSInteger index = (NSInteger)(scrollView.contentOffset.x / (KPortraitWidth - 26));
+        
+        [UIView animateWithDuration:0.3f animations:^{
+            [self.pageControl setCurrentPage:index animate:YES];
+        }];
+    }
+}
+
+- (NSMutableArray *)imageArray {
+    if (!_imageArray) {
+        _imageArray = [NSMutableArray arrayWithArray:@[@"insititution_mine_music",@"insititution_mine_eveluate",@"insititution_mine_order",@"insititution_mine_rank",@"insititution_mine_code",@"tenant_mine_musicProduct"]];
+    }
+    return _imageArray;
+}
+
+- (NSMutableArray *)titleArray {
+    if (!_titleArray) {
+        _titleArray = [NSMutableArray arrayWithArray:@[@"我的曲库",@"练习统计",@"订单信息",@"排行榜",@"激活码",@"我的作品"]];
+    }
+    return _titleArray;
+}
+
+- (NSMutableArray *)tagArray {
+    if (!_tagArray) {
+        _tagArray = [NSMutableArray arrayWithArray:@[@(INSMINETYPE_MUSIC),@(INSMINETYPE_TRAIN),@(INSMINETYPE_ORDER),@(INSMINETYPE_RANK),@(INSMINETYPE_CODE),@(INSMINETYPE_WORKS)]];
+    }
+    return _tagArray;
+}
+- (UIScrollView *)functionScrollView {
+    if (!_functionScrollView) {
+        _functionScrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
+        _functionScrollView.backgroundColor = [UIColor clearColor];
+        _functionScrollView.pagingEnabled = YES;
+        _functionScrollView.showsHorizontalScrollIndicator = NO;
+        _functionScrollView.showsVerticalScrollIndicator = NO;
+        _functionScrollView.delegate = self;
+    }
+    return _functionScrollView;
+}
 @end

+ 10 - 187
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/InstitutionMineBodyView.xib

@@ -1,9 +1,9 @@
 <?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">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" 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"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -301,102 +301,9 @@
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iE8-e2-07v">
                     <rect key="frame" x="13" y="287" width="367" height="130"/>
                     <subviews>
-                        <view tag="1003" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Sny-pb-TWZ">
-                            <rect key="frame" x="0.0" y="51" width="73.333333333333329" height="74"/>
-                            <subviews>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="insititution_mine_music" translatesAutoresizingMaskIntoConstraints="NO" id="z6K-YU-QmJ">
-                                    <rect key="frame" x="20.666666666666664" y="2" width="32" height="32"/>
-                                    <gestureRecognizers/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="32" id="3nQ-Bb-ccy"/>
-                                        <constraint firstAttribute="width" constant="32" id="kmX-tB-rz0"/>
-                                    </constraints>
-                                </imageView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我的曲库" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="llV-N6-iUM">
-                                    <rect key="frame" x="12.000000000000004" y="38" width="49.333333333333343" height="16"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="16" id="EhM-4l-Q4H"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                    <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"/>
-                            <gestureRecognizers/>
-                            <constraints>
-                                <constraint firstItem="z6K-YU-QmJ" firstAttribute="top" secondItem="Sny-pb-TWZ" secondAttribute="top" constant="2" id="Eyg-6z-rnQ"/>
-                                <constraint firstItem="llV-N6-iUM" firstAttribute="top" secondItem="z6K-YU-QmJ" secondAttribute="bottom" constant="4" id="GgK-o3-OnV"/>
-                                <constraint firstItem="llV-N6-iUM" firstAttribute="centerX" secondItem="z6K-YU-QmJ" secondAttribute="centerX" id="Tl7-CN-zla"/>
-                                <constraint firstItem="z6K-YU-QmJ" firstAttribute="centerX" secondItem="Sny-pb-TWZ" secondAttribute="centerX" id="hNI-eo-HfF"/>
-                            </constraints>
-                            <connections>
-                                <outletCollection property="gestureRecognizers" destination="xCJ-Tc-iEY" appends="YES" id="5zR-pu-xql"/>
-                            </connections>
-                        </view>
-                        <view tag="1005" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9n9-51-GnM">
-                            <rect key="frame" x="146.66666666666666" y="51" width="73.666666666666657" height="74"/>
-                            <subviews>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="insititution_mine_order" translatesAutoresizingMaskIntoConstraints="NO" id="Dd1-kz-ACR">
-                                    <rect key="frame" x="21" y="2" width="32" height="32"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="32" id="QGk-JB-c5l"/>
-                                        <constraint firstAttribute="width" constant="32" id="uVK-ef-irC"/>
-                                    </constraints>
-                                </imageView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="订单信息" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CCv-8F-puO">
-                                    <rect key="frame" x="12.333333333333346" y="38" width="49.333333333333343" height="16"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="16" id="teG-Pd-LeH"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                    <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"/>
-                            <gestureRecognizers/>
-                            <constraints>
-                                <constraint firstItem="Dd1-kz-ACR" firstAttribute="centerX" secondItem="9n9-51-GnM" secondAttribute="centerX" id="3kU-J2-jIZ"/>
-                                <constraint firstItem="CCv-8F-puO" firstAttribute="centerX" secondItem="Dd1-kz-ACR" secondAttribute="centerX" id="FcT-JT-gwR"/>
-                                <constraint firstItem="Dd1-kz-ACR" firstAttribute="top" secondItem="9n9-51-GnM" secondAttribute="top" constant="2" id="Jd2-pU-WJ5"/>
-                                <constraint firstItem="CCv-8F-puO" firstAttribute="top" secondItem="Dd1-kz-ACR" secondAttribute="bottom" constant="4" id="U88-O8-Nhn"/>
-                            </constraints>
-                            <connections>
-                                <outletCollection property="gestureRecognizers" destination="vKx-8d-UTl" appends="YES" id="cu6-d5-Rgx"/>
-                            </connections>
-                        </view>
-                        <view tag="1006" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iBV-4n-9tN">
-                            <rect key="frame" x="220.33333333333334" y="51" width="73.333333333333343" height="74"/>
-                            <subviews>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="insititution_mine_rank" translatesAutoresizingMaskIntoConstraints="NO" id="6o5-QV-pgd">
-                                    <rect key="frame" x="20.666666666666657" y="2" width="32" height="32"/>
-                                    <constraints>
-                                        <constraint firstAttribute="width" constant="32" id="Jek-gw-t3C"/>
-                                        <constraint firstAttribute="height" constant="32" id="cg2-2G-gFg"/>
-                                    </constraints>
-                                </imageView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="排行榜" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dva-Em-ug7">
-                                    <rect key="frame" x="18" y="38" width="37" height="16"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="16" id="JKR-Wd-nWu"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                    <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"/>
-                            <gestureRecognizers/>
-                            <constraints>
-                                <constraint firstItem="Dva-Em-ug7" firstAttribute="centerX" secondItem="6o5-QV-pgd" secondAttribute="centerX" id="1sj-du-pWJ"/>
-                                <constraint firstItem="Dva-Em-ug7" firstAttribute="top" secondItem="6o5-QV-pgd" secondAttribute="bottom" constant="4" id="r2Y-yN-XbS"/>
-                                <constraint firstItem="6o5-QV-pgd" firstAttribute="top" secondItem="iBV-4n-9tN" secondAttribute="top" constant="2" id="x34-0c-dua"/>
-                                <constraint firstItem="6o5-QV-pgd" firstAttribute="centerX" secondItem="iBV-4n-9tN" secondAttribute="centerX" id="zwM-Ns-v9R"/>
-                            </constraints>
-                            <connections>
-                                <outletCollection property="gestureRecognizers" destination="5cM-13-0B5" appends="YES" id="X6T-5h-XcY"/>
-                            </connections>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Akl-gJ-5NJ">
+                            <rect key="frame" x="0.0" y="51" width="367" height="74"/>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                         </view>
                         <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="常用功能" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QIe-vg-wc9">
                             <rect key="frame" x="15.000000000000004" y="15" width="61.333333333333343" height="21"/>
@@ -407,96 +314,16 @@
                             <color key="textColor" red="0.074509803921568626" green="0.078431372549019607" blue="0.082352941176470587" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                             <nil key="highlightedColor"/>
                         </label>
-                        <view tag="1007" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JPB-oG-7OI">
-                            <rect key="frame" x="293.66666666666669" y="51" width="73.333333333333314" height="74"/>
-                            <subviews>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="insititution_mine_code" translatesAutoresizingMaskIntoConstraints="NO" id="fq9-6v-NL0">
-                                    <rect key="frame" x="20.666666666666629" y="2" width="32" height="32"/>
-                                    <constraints>
-                                        <constraint firstAttribute="width" constant="32" id="WSx-ZO-tIf"/>
-                                        <constraint firstAttribute="height" constant="32" id="e4d-3b-Gdb"/>
-                                    </constraints>
-                                </imageView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="激活码" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XRm-Fc-bnp">
-                                    <rect key="frame" x="18" y="38" width="37" height="16"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="16" id="mj3-pq-ivj"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                    <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"/>
-                            <gestureRecognizers/>
-                            <constraints>
-                                <constraint firstItem="fq9-6v-NL0" firstAttribute="top" secondItem="JPB-oG-7OI" secondAttribute="top" constant="2" id="3Ba-Hc-2g2"/>
-                                <constraint firstItem="XRm-Fc-bnp" firstAttribute="centerX" secondItem="fq9-6v-NL0" secondAttribute="centerX" id="4IJ-o8-sfw"/>
-                                <constraint firstItem="XRm-Fc-bnp" firstAttribute="top" secondItem="fq9-6v-NL0" secondAttribute="bottom" constant="4" id="MHf-qT-Fzl"/>
-                                <constraint firstItem="fq9-6v-NL0" firstAttribute="centerX" secondItem="JPB-oG-7OI" secondAttribute="centerX" id="VPs-WG-Ooh"/>
-                            </constraints>
-                            <connections>
-                                <outletCollection property="gestureRecognizers" destination="f2V-Zn-5hZ" appends="YES" id="Ubv-3d-jzI"/>
-                            </connections>
-                        </view>
-                        <view tag="1004" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XWh-l9-hOS">
-                            <rect key="frame" x="73.333333333333343" y="51" width="73.333333333333343" height="74"/>
-                            <subviews>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="insititution_mine_eveluate" translatesAutoresizingMaskIntoConstraints="NO" id="EEW-IB-hg7">
-                                    <rect key="frame" x="20.666666666666671" y="2" width="32" height="32"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="32" id="mbZ-LU-MyN"/>
-                                        <constraint firstAttribute="width" constant="32" id="rgr-gt-DRv"/>
-                                    </constraints>
-                                </imageView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="练习统计" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tKv-6K-2Lh">
-                                    <rect key="frame" x="12.000000000000004" y="38" width="49.333333333333343" height="16"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="16" id="4PT-bu-Tbp"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                    <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"/>
-                            <gestureRecognizers/>
-                            <constraints>
-                                <constraint firstItem="EEW-IB-hg7" firstAttribute="top" secondItem="XWh-l9-hOS" secondAttribute="top" constant="2" id="M4E-fM-bQj"/>
-                                <constraint firstItem="tKv-6K-2Lh" firstAttribute="top" secondItem="EEW-IB-hg7" secondAttribute="bottom" constant="4" id="P9I-8f-mp0"/>
-                                <constraint firstItem="EEW-IB-hg7" firstAttribute="centerX" secondItem="XWh-l9-hOS" secondAttribute="centerX" id="fJS-9g-8tg"/>
-                                <constraint firstItem="tKv-6K-2Lh" firstAttribute="centerX" secondItem="EEW-IB-hg7" secondAttribute="centerX" id="lsU-HV-gVb"/>
-                            </constraints>
-                            <connections>
-                                <outletCollection property="gestureRecognizers" destination="BYm-19-2ah" appends="YES" id="htz-UT-oWn"/>
-                            </connections>
-                        </view>
                     </subviews>
                     <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                     <constraints>
-                        <constraint firstItem="9n9-51-GnM" firstAttribute="top" secondItem="Sny-pb-TWZ" secondAttribute="top" id="1sE-so-FQ5"/>
-                        <constraint firstItem="iBV-4n-9tN" firstAttribute="bottom" secondItem="Sny-pb-TWZ" secondAttribute="bottom" id="2ie-Lh-j5e"/>
-                        <constraint firstAttribute="bottom" secondItem="Sny-pb-TWZ" secondAttribute="bottom" constant="5" id="2mJ-hl-NMX"/>
                         <constraint firstItem="QIe-vg-wc9" firstAttribute="leading" secondItem="iE8-e2-07v" secondAttribute="leading" constant="15" id="43f-iw-ckE"/>
-                        <constraint firstItem="Sny-pb-TWZ" firstAttribute="top" secondItem="QIe-vg-wc9" secondAttribute="bottom" constant="15" id="52f-wH-uDC"/>
-                        <constraint firstItem="9n9-51-GnM" firstAttribute="bottom" secondItem="Sny-pb-TWZ" secondAttribute="bottom" id="ABN-Ze-8fa"/>
-                        <constraint firstItem="9n9-51-GnM" firstAttribute="leading" secondItem="XWh-l9-hOS" secondAttribute="trailing" id="FRi-q4-0DZ"/>
-                        <constraint firstItem="XWh-l9-hOS" firstAttribute="bottom" secondItem="Sny-pb-TWZ" secondAttribute="bottom" id="Fuw-8r-pjH"/>
+                        <constraint firstItem="Akl-gJ-5NJ" firstAttribute="top" secondItem="QIe-vg-wc9" secondAttribute="bottom" constant="15" id="G96-fd-c4t"/>
                         <constraint firstItem="QIe-vg-wc9" firstAttribute="top" secondItem="iE8-e2-07v" secondAttribute="top" constant="15" id="M4I-eo-HK7"/>
-                        <constraint firstItem="9n9-51-GnM" firstAttribute="width" secondItem="Sny-pb-TWZ" secondAttribute="width" id="NSC-3b-BJN"/>
-                        <constraint firstItem="JPB-oG-7OI" firstAttribute="bottom" secondItem="iBV-4n-9tN" secondAttribute="bottom" id="OKn-6P-loW"/>
-                        <constraint firstItem="XWh-l9-hOS" firstAttribute="leading" secondItem="Sny-pb-TWZ" secondAttribute="trailing" id="SnR-aA-EIQ"/>
-                        <constraint firstItem="iBV-4n-9tN" firstAttribute="width" secondItem="JPB-oG-7OI" secondAttribute="width" id="WZA-hM-M1t"/>
-                        <constraint firstItem="iBV-4n-9tN" firstAttribute="top" secondItem="Sny-pb-TWZ" secondAttribute="top" id="Xl2-uN-x4K"/>
-                        <constraint firstItem="JPB-oG-7OI" firstAttribute="top" secondItem="iBV-4n-9tN" secondAttribute="top" id="YJA-mr-LYM"/>
+                        <constraint firstAttribute="bottom" secondItem="Akl-gJ-5NJ" secondAttribute="bottom" constant="5" id="WSt-xm-eWs"/>
                         <constraint firstAttribute="height" constant="130" id="ZcP-FC-3Pg"/>
-                        <constraint firstItem="JPB-oG-7OI" firstAttribute="leading" secondItem="iBV-4n-9tN" secondAttribute="trailing" id="fsd-xj-RxC"/>
-                        <constraint firstItem="XWh-l9-hOS" firstAttribute="top" secondItem="Sny-pb-TWZ" secondAttribute="top" id="kX2-B8-NZw"/>
-                        <constraint firstItem="JPB-oG-7OI" firstAttribute="width" secondItem="Sny-pb-TWZ" secondAttribute="width" id="q9G-2G-fdk"/>
-                        <constraint firstItem="Sny-pb-TWZ" firstAttribute="leading" secondItem="iE8-e2-07v" secondAttribute="leading" id="ve1-IS-9Ga"/>
-                        <constraint firstItem="iBV-4n-9tN" firstAttribute="leading" secondItem="9n9-51-GnM" secondAttribute="trailing" id="yhW-tY-WkR"/>
-                        <constraint firstItem="XWh-l9-hOS" firstAttribute="width" secondItem="Sny-pb-TWZ" secondAttribute="width" id="yiZ-Lc-Rrh"/>
-                        <constraint firstAttribute="trailing" secondItem="JPB-oG-7OI" secondAttribute="trailing" id="yp3-a3-L5A"/>
+                        <constraint firstItem="Akl-gJ-5NJ" firstAttribute="leading" secondItem="iE8-e2-07v" secondAttribute="leading" id="aJk-v7-dcP"/>
+                        <constraint firstAttribute="trailing" secondItem="Akl-gJ-5NJ" secondAttribute="trailing" id="hR7-e8-5vV"/>
                     </constraints>
                     <userDefinedRuntimeAttributes>
                         <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
@@ -767,6 +594,7 @@
             <nil key="simulatedBottomBarMetrics"/>
             <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
             <connections>
+                <outlet property="functionView" destination="Akl-gJ-5NJ" id="aPS-KN-edW"/>
                 <outlet property="memberDesc" destination="wqN-QT-Cza" id="V4p-qw-nCy"/>
                 <outlet property="memberImg" destination="j1E-FX-DSh" id="Qcd-Se-bsQ"/>
                 <outlet property="subjectLabel" destination="k3g-g1-liB" id="4om-GC-86Z"/>
@@ -845,12 +673,7 @@
         <image name="insititution_about" width="22" height="22"/>
         <image name="insititution_feedback" width="22" height="22"/>
         <image name="insititution_help" width="22" height="22"/>
-        <image name="insititution_mine_code" width="32" height="32"/>
-        <image name="insititution_mine_eveluate" width="32" height="32"/>
         <image name="insititution_mine_header" width="58" height="50"/>
-        <image name="insititution_mine_music" width="32" height="32"/>
-        <image name="insititution_mine_order" width="32" height="32"/>
-        <image name="insititution_mine_rank" width="32" height="32"/>
         <image name="insititution_mine_subject" width="13" height="13"/>
         <image name="insititution_mine_topLayer" width="129" height="114"/>
         <image name="insititution_privacy" width="22" height="22"/>

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

@@ -0,0 +1,22 @@
+//
+//  TenantMineFunctionView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2023/11/7.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^TenantMineViewCallback)(NSInteger tagIndex);
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TenantMineFunctionView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)configWithSource:(NSString *)imageName title:(NSString *)buttonTitle functionType:(NSInteger)tag callback:(TenantMineViewCallback)callback;
+@end
+
+NS_ASSUME_NONNULL_END

+ 51 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantMineFunctionView.m

@@ -0,0 +1,51 @@
+//
+//  TenantMineFunctionView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2023/11/7.
+//
+
+#import "TenantMineFunctionView.h"
+
+@interface TenantMineFunctionView ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *functionImageView;
+
+@property (weak, nonatomic) IBOutlet UILabel *functionTitle;
+
+@property (nonatomic, copy) TenantMineViewCallback callback;
+
+@property (nonatomic, assign) NSInteger viewTag;
+
+@end
+
+@implementation TenantMineFunctionView
+
++ (instancetype)shareInstance {
+    TenantMineFunctionView *view = [[[NSBundle mainBundle] loadNibNamed:@"TenantMineFunctionView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configWithSource:(NSString *)imageName title:(NSString *)buttonTitle functionType:(NSInteger)tag callback:(TenantMineViewCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+    [self.functionImageView setImage:[UIImage imageNamed:imageName]];
+    [self.functionTitle setText:buttonTitle];
+    self.viewTag = tag;
+}
+
+- (IBAction)functionAction:(id)sender {
+    if (self.callback) {
+        self.callback(self.viewTag);
+    }
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 78 - 0
KulexiuForStudent/KulexiuForStudent/InstitutionModule/Mine/View/TenantMineFunctionView.xib

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" 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="22131"/>
+        <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="TenantMineFunctionView">
+            <rect key="frame" x="0.0" y="0.0" width="74" height="74"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view tag="1003" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="beM-2v-ZF4">
+                    <rect key="frame" x="0.0" y="0.0" width="74" height="74"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="insititution_mine_music" translatesAutoresizingMaskIntoConstraints="NO" id="x7t-Bj-izm">
+                            <rect key="frame" x="21" y="2" width="32" height="32"/>
+                            <gestureRecognizers/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="32" id="T9a-T7-08r"/>
+                                <constraint firstAttribute="height" constant="32" id="Tkf-xL-8h9"/>
+                            </constraints>
+                        </imageView>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我的曲库" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZIb-hR-CNR">
+                            <rect key="frame" x="12.333333333333332" y="38" width="49.333333333333343" height="16"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="16" id="kiu-UH-7EV"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MrW-ZX-4wb">
+                            <rect key="frame" x="0.0" y="0.0" width="74" height="74"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="functionAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="WKI-Eg-pEq"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <gestureRecognizers/>
+                    <constraints>
+                        <constraint firstAttribute="trailing" secondItem="MrW-ZX-4wb" secondAttribute="trailing" id="0XZ-iU-iNp"/>
+                        <constraint firstAttribute="bottom" secondItem="MrW-ZX-4wb" secondAttribute="bottom" id="8iu-4y-CxS"/>
+                        <constraint firstItem="MrW-ZX-4wb" firstAttribute="top" secondItem="beM-2v-ZF4" secondAttribute="top" id="96u-jX-QFJ"/>
+                        <constraint firstItem="MrW-ZX-4wb" firstAttribute="leading" secondItem="beM-2v-ZF4" secondAttribute="leading" id="SbS-te-EiP"/>
+                        <constraint firstItem="x7t-Bj-izm" firstAttribute="centerX" secondItem="beM-2v-ZF4" secondAttribute="centerX" id="Sm3-hM-VP4"/>
+                        <constraint firstItem="ZIb-hR-CNR" firstAttribute="top" secondItem="x7t-Bj-izm" secondAttribute="bottom" constant="4" id="fZR-jW-YmQ"/>
+                        <constraint firstItem="ZIb-hR-CNR" firstAttribute="centerX" secondItem="x7t-Bj-izm" secondAttribute="centerX" id="goA-xu-oak"/>
+                        <constraint firstItem="x7t-Bj-izm" firstAttribute="top" secondItem="beM-2v-ZF4" secondAttribute="top" constant="2" id="k9j-Yk-iQD"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="beM-2v-ZF4" secondAttribute="trailing" id="Dbz-hi-Mu2"/>
+                <constraint firstAttribute="bottom" secondItem="beM-2v-ZF4" secondAttribute="bottom" id="I9h-Ta-vf8"/>
+                <constraint firstItem="beM-2v-ZF4" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="lri-Mb-IPd"/>
+                <constraint firstItem="beM-2v-ZF4" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="rr3-Ah-u1b"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="functionImageView" destination="x7t-Bj-izm" id="abv-Ag-pX5"/>
+                <outlet property="functionTitle" destination="ZIb-hR-CNR" id="yN1-P0-2o5"/>
+            </connections>
+            <point key="canvasLocation" x="15.267175572519083" y="-121.83098591549296"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="insititution_mine_music" width="32" height="32"/>
+    </resources>
+</document>

+ 10 - 4
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/Controller/KSDraftMergeViewController.m

@@ -15,6 +15,8 @@
 
 @property (nonatomic, copy) DraftEditCallback callback;
 
+@property (nonatomic, assign) BOOL hasInitUI;
+
 @end
 
 @implementation KSDraftMergeViewController
@@ -51,9 +53,11 @@
     [super viewDidLoad];
     // Do any additional setup after loading the view.
     self.ks_prefersNavigationBarHidden = YES;
+    self.hasInitUI = NO;
 }
 
 - (void)configUI {
+    self.hasInitUI = YES;
     [self.scrollView removeFromSuperview];
     KSMediaMergeView *mergeView = [[KSMediaMergeView alloc] init];
     mergeView.coverImage = self.sourceModel.img;
@@ -93,10 +97,12 @@
 - (void)viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
     [self changeOrientation:YES];
-    // 切换到横屏
-    dispatch_delay_block(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC), ^{
-        [self configUI];
-    });
+    if (self.hasInitUI == NO) {
+        // 切换到横屏
+        dispatch_delay_block(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC), ^{
+            [self configUI];
+        });
+    }
 }
 
 

+ 26 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/Controller/KSVideoCropViewController.h

@@ -0,0 +1,26 @@
+//
+//  KSVideoCropViewController.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "KSBaseViewController.h"
+
+typedef void(^VideoCropCallback)(UIImage * _Nonnull cropImage);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSVideoCropViewController : KSBaseViewController
+
+- (void)configWithVideoPath:(NSURL *)videoPathUrl;
+
+- (void)configWithVideoRemoteUrl:(NSString *)remoteUrl;
+
+- (void)chooseCropImageCallback:(VideoCropCallback)callback;
+
+- (void)changeLandScape;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 253 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/Controller/KSVideoCropViewController.m

@@ -0,0 +1,253 @@
+//
+//  KSVideoCropViewController.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "KSVideoCropViewController.h"
+#import <AVFoundation/AVFoundation.h>
+#import "KSCropImageNavView.h"
+#import "KSVideoImageSlider.h"
+#import "AppDelegate+AppService.h"
+#import "UIDevice+TFDevice.h"
+
+
+#define COVER_COUNT (10)
+
+@interface KSVideoCropViewController ()
+
+@property (nonatomic, strong) KSCropImageNavView *navView;
+
+@property (nonatomic, strong) UIImageView *displayImage;
+
+@property (strong,nonatomic)AVAssetImageGenerator * imageGenerator;
+
+@property (strong, nonatomic)NSMutableArray * imageArray;
+
+@property (nonatomic, strong) NSURL *videoUrl;
+
+@property (nonatomic, copy) VideoCropCallback callback;
+
+@property (nonatomic, strong) KSVideoImageSlider *imageSlider;
+
+@property (nonatomic, assign) BOOL needChangeOrigin;
+@end
+
+@implementation KSVideoCropViewController
+
+- (void)changeOrientation:(BOOL)isLandScape {
+    if (isLandScape) {
+        // 切换到横屏
+        AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
+        delegate.allowAutoRotate = YES;
+        [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeRight inController:self];
+    }
+    else {
+        
+        AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
+        delegate.allowAutoRotate = NO;
+        [UIDevice switchNewOrientation:UIInterfaceOrientationPortrait inController:self];
+    }
+}
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    [self configUI];
+}
+
+- (void)changeLandScape {
+    self.needChangeOrigin = YES;
+    [self changeOrientation:YES];
+}
+
+- (void)configUI {
+    self.ks_prefersNavigationBarHidden = YES;
+    [self.view addSubview:self.displayImage];
+    [self.displayImage mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.view);
+    }];
+    CGFloat height = 84.0f;
+    [self.view addSubview:self.imageSlider];
+    [self.imageSlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(self.view.mas_left).offset(iPhoneXSafeTopMargin);
+        make.right.mas_equalTo(self.view.mas_right).offset(-iPhoneXSafeBottomMargin);
+        make.bottom.mas_equalTo(self.view.mas_bottom).offset(-iPhoneXSafeBottomMargin);
+        make.height.mas_equalTo(height);
+    }];
+    
+    CGFloat navHeight = [KSCropImageNavView getViewHeight];
+    [self.view addSubview:self.navView];
+    [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.mas_equalTo(self.view);
+        make.height.mas_equalTo(navHeight);
+    }];
+}
+
+- (void)configWithVideoPath:(NSURL *)videoPathUrl {
+    [self configImageWallWithPath:videoPathUrl];
+}
+
+- (void)configImageWallWithPath:(NSURL *)fileUrl {
+    self.videoUrl = fileUrl;
+    AVAsset * asset =[AVAsset assetWithURL:fileUrl];
+    NSMutableArray * times = [NSMutableArray arrayWithCapacity:0];
+    CGFloat videoTime = CMTimeGetSeconds(asset.duration);
+
+    for (int i = 0; i < COVER_COUNT; i++) {
+        
+        CMTime time = [asset duration];
+        long long duration = time.value;
+        time.value = (i*1.0) / COVER_COUNT * duration;
+        NSValue * timeValue = [NSValue valueWithCMTime:time];
+        [times addObject:timeValue];
+    }
+    
+    if (_imageGenerator == nil) {
+        _imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset];
+        _imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
+        _imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
+        _imageGenerator.appliesPreferredTrackTransform = YES;
+    }
+    if (_imageArray == nil) {
+        _imageArray = [NSMutableArray arrayWithCapacity:0];
+    }
+
+    __block NSInteger count = 0;
+    AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){
+        if (result == AVAssetImageGeneratorSucceeded) {
+            UIImage *thumbnail = [UIImage imageWithCGImage:im];
+            [self.imageArray addObject:thumbnail];
+            count ++;
+        }
+        else if(result == AVAssetImageGeneratorFailed){
+            count ++;
+            NSLog(@">>>>>>>>>>>generate failed");
+        }
+        else if(result == AVAssetImageGeneratorCancelled){
+            count ++;
+            NSLog(@">>>>>>>>>>>generate cancelled");
+        }
+        if (count == times.count) {
+            [self performSelector:@selector(updateStatus:) onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO];
+        }
+    };
+    
+    _imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
+    _imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
+    [_imageGenerator generateCGImagesAsynchronouslyForTimes:times completionHandler:handler];
+}
+
+- (void)updateStatus:(id)sender {
+    self.imageSlider.maximumValue = _imageArray.count;
+    UIImage *firstImage = [self.imageArray firstObject];
+    self.imageSlider.imageArray = [self.imageArray copy];
+    [self.imageSlider createTheImageWall];
+    [self.imageSlider updateTheKnobImage:firstImage];
+    [self.displayImage setImage:firstImage];
+}
+
+- (void)configWithVideoRemoteUrl:(NSString *)remoteUrl {
+    [LOADING_MANAGER showCustomLoading:@"资源下载中..."];
+    [KSNetworkingManager downloadFileRequestWithFileUrl:remoteUrl progress:^(int64_t bytesRead, int64_t totalBytes) {
+
+    } success:^(NSURL * _Nonnull fileUrl) {
+        [LOADING_MANAGER removeCustomLoading];
+        [self configImageWallWithPath:fileUrl];
+        
+    } faliure:^(NSError * _Nonnull error) {
+        [LOADING_MANAGER removeCustomLoading];
+    }];
+}
+
+- (void)chooseCropImageCallback:(VideoCropCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+- (void)slideValueChanged:(id)control{
+    KSVideoImageSlider* slider = (KSVideoImageSlider*)control;
+    float scale = slider.knobValue/self.imageArray.count;
+    UIImage * image = [self generateThumbImageWithTime:scale];
+    [slider updateTheKnobImage:image];
+    [self.displayImage setImage:image];
+    NSLog(@">>>>>>>>>>>>%f ----- scale %f ",slider.knobValue,  scale);
+}
+
+
+- (UIImage *)generateThumbImageWithTime:(CGFloat)progress {
+    NSURL *url = self.videoUrl;
+    AVAsset *asset = [AVAsset assetWithURL:url];
+    if (_imageGenerator == nil) {
+        _imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset];
+        _imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
+        _imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
+        _imageGenerator.appliesPreferredTrackTransform = YES;
+    }
+    CMTime time = [asset duration];
+    long long duration = time.value;
+    time.value = progress*duration;
+    
+    CGImageRef imageRef = [_imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL];
+    UIImage *thumbnail = [UIImage imageWithCGImage:imageRef];
+    // CGImageRef won't be released by ARC, so you must release.
+    CGImageRelease(imageRef);
+    
+    return thumbnail;
+}
+#pragma mark ---- lazying
+- (UIImageView *)displayImage {
+    if (!_displayImage) {
+        _displayImage = [[UIImageView alloc] init];
+    }
+    return _displayImage;
+}
+
+- (KSVideoImageSlider *)imageSlider {
+    if (!_imageSlider) {
+        _imageSlider = [[KSVideoImageSlider alloc] initWithFrame:CGRectMake(0, 0, KLandscapeWidth - iPhoneXSafeTopMargin - iPhoneXSafeBottomMargin, 84)];
+        [_imageSlider addTarget:self
+                         action:@selector(slideValueChanged:)
+               forControlEvents:UIControlEventValueChanged];
+    }
+    return _imageSlider;
+}
+
+- (KSCropImageNavView *)navView {
+    if (!_navView) {
+        _navView = [KSCropImageNavView shareInstance];
+        MJWeakSelf;
+        [_navView navAction:^(BOOL isBack) {
+            if (isBack) {
+                [weakSelf backAction];
+            }
+            else {
+                if (weakSelf.needChangeOrigin) {
+                    [weakSelf changeOrientation:NO];
+                }
+                if (weakSelf.callback) {
+                    weakSelf.callback(weakSelf.displayImage.image);
+                }
+                [weakSelf backAction];
+            }
+        }];
+    }
+    return _navView;
+}
+
+
+- (void)backAction {
+    [self dismissViewControllerAnimated:YES completion:nil];
+}
+/*
+#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

+ 4 - 5
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/Controller/MineWorksViewController.m

@@ -67,11 +67,10 @@
     self.categoryView.titleColor = HexRGB(0x777777);
     self.categoryView.titleColorGradientEnabled = YES;
     
-    JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init];
-    lineView.indicatorColor = HexRGB(0x1CACF1);
-    lineView.indicatorWidth = 16;
-    lineView.height = 4;
-    lineView.verticalMargin = 5;
+    JXCategoryIndicatorImageView *lineView = [[JXCategoryIndicatorImageView alloc] init];
+    [lineView.indicatorImageView setImage:[UIImage imageNamed:@"minework_Line"]];
+    lineView.indicatorImageViewSize = CGSizeMake(16, 4);
+    lineView.verticalMargin = 10;
     self.categoryView.indicators = @[lineView];
     
     _pagerView = [self preferredPagingView];

+ 24 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/KSCropImageNavView.h

@@ -0,0 +1,24 @@
+//
+//  KSCropImageNavView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^CropNavCallback)(BOOL isBack);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSCropImageNavView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)navAction:(CropNavCallback)callback;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 60 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/KSCropImageNavView.m

@@ -0,0 +1,60 @@
+//
+//  KSCropImageNavView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "KSCropImageNavView.h"
+#import "UIView+KSLayer.h"
+
+@interface KSCropImageNavView ()
+
+@property (weak, nonatomic) IBOutlet UIView *layerView;
+
+@property (nonatomic, copy) CropNavCallback callback;
+
+@end
+
+@implementation KSCropImageNavView
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    CAGradientLayer *titleLayer = [UIView createGradientLayerFromColor:HexRGB(0x0D0D0D) startPoint:CGPointMake(0.5, 0) endColor:HexRGBAlpha(0x000000, 0) endPoint:CGPointMake(0.5, 1) bounds:CGRectMake(0, 0, KLandscapeWidth, [KSCropImageNavView getViewHeight])];
+    [self.layerView.layer addSublayer:titleLayer];
+}
++ (instancetype)shareInstance {
+    KSCropImageNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"KSCropImageNavView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)navAction:(CropNavCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)backAction:(id)sender {
+    if (self.callback) {
+        self.callback(YES);
+    }
+}
+
+- (IBAction)sureChoose:(id)sender {
+    if (self.callback) {
+        self.callback(NO);
+    }
+}
+
+
++ (CGFloat)getViewHeight {
+    return 59.0f;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 101 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/KSCropImageNavView.xib

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" 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="22131"/>
+        <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="KSCropImageNavView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="61"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view alpha="0.59999999999999998" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xeU-Tl-Xhh">
+                    <rect key="frame" x="0.0" y="0.0" width="393" height="61"/>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                </view>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HJB-he-mP1">
+                    <rect key="frame" x="0.0" y="0.0" width="393" height="61"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="back_button_white" translatesAutoresizingMaskIntoConstraints="NO" id="B8v-QN-Iho">
+                            <rect key="frame" x="20" y="20.666666666666668" width="12" height="20.000000000000004"/>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="401-bU-jDD">
+                            <rect key="frame" x="0.0" y="0.0" width="44" height="61"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="44" id="xF7-tP-bKn"/>
+                            </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="tti-8Q-1As"/>
+                            </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="GGz-C6-Tp4">
+                            <rect key="frame" x="163.66666666666666" y="20.666666666666668" width="66" height="20.000000000000004"/>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dGw-mB-Z1v">
+                            <rect key="frame" x="305" y="14.666666666666664" width="64" height="32"/>
+                            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="64" id="UdM-ZV-lN9"/>
+                                <constraint firstAttribute="height" constant="32" id="k09-mz-AeM"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" title="保存">
+                                <color key="titleColor" red="0.1764705882352941" green="0.7803921568627451" blue="0.66666666666666663" alpha="1" colorSpace="calibratedRGB"/>
+                            </state>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="16"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <connections>
+                                <action selector="sureChoose:" destination="iN0-l3-epB" eventType="touchUpInside" id="qFa-pj-gTm"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="GGz-C6-Tp4" firstAttribute="centerX" secondItem="HJB-he-mP1" secondAttribute="centerX" id="Ox9-3S-KJA"/>
+                        <constraint firstAttribute="trailing" secondItem="dGw-mB-Z1v" secondAttribute="trailing" constant="24" id="ZHA-ZL-TIB"/>
+                        <constraint firstItem="B8v-QN-Iho" firstAttribute="leading" secondItem="HJB-he-mP1" secondAttribute="leading" constant="20" id="ZYs-sQ-01o"/>
+                        <constraint firstItem="401-bU-jDD" firstAttribute="leading" secondItem="HJB-he-mP1" secondAttribute="leading" id="dQS-5Y-Zow"/>
+                        <constraint firstItem="GGz-C6-Tp4" firstAttribute="centerY" secondItem="HJB-he-mP1" secondAttribute="centerY" id="e94-GC-ZGQ"/>
+                        <constraint firstItem="401-bU-jDD" firstAttribute="top" secondItem="HJB-he-mP1" secondAttribute="top" id="hql-Xo-4On"/>
+                        <constraint firstItem="B8v-QN-Iho" firstAttribute="centerY" secondItem="HJB-he-mP1" secondAttribute="centerY" id="lOC-f2-ccQ"/>
+                        <constraint firstItem="dGw-mB-Z1v" firstAttribute="centerY" secondItem="HJB-he-mP1" secondAttribute="centerY" id="neX-1C-uUS"/>
+                        <constraint firstAttribute="bottom" secondItem="401-bU-jDD" secondAttribute="bottom" id="rkO-Q4-7Hf"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="HJB-he-mP1" secondAttribute="trailing" id="Awy-71-IeY"/>
+                <constraint firstItem="HJB-he-mP1" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Hye-1f-zjE"/>
+                <constraint firstItem="xeU-Tl-Xhh" firstAttribute="trailing" secondItem="HJB-he-mP1" secondAttribute="trailing" id="I9Q-Of-9yY"/>
+                <constraint firstItem="xeU-Tl-Xhh" firstAttribute="leading" secondItem="HJB-he-mP1" secondAttribute="leading" id="TCA-gz-2rL"/>
+                <constraint firstItem="HJB-he-mP1" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="cmv-a3-DOt"/>
+                <constraint firstAttribute="bottom" secondItem="HJB-he-mP1" secondAttribute="bottom" id="rJK-wt-q5F"/>
+                <constraint firstItem="xeU-Tl-Xhh" firstAttribute="bottom" secondItem="HJB-he-mP1" secondAttribute="bottom" id="saw-Qt-SH7"/>
+                <constraint firstItem="xeU-Tl-Xhh" firstAttribute="top" secondItem="HJB-he-mP1" secondAttribute="top" id="t5k-js-uGI"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="layerView" destination="xeU-Tl-Xhh" id="eLg-NR-BQt"/>
+            </connections>
+            <point key="canvasLocation" x="64.885496183206101" y="-129.22535211267606"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="back_button_white" width="12" height="20"/>
+    </resources>
+</document>

+ 25 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/KSVideoImageSlider.h

@@ -0,0 +1,25 @@
+//
+//  KSVideoImageSlider.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSVideoImageSlider : UIControl
+@property (nonatomic) float maximumValue;
+@property (nonatomic) float minimumValue;
+@property (nonatomic) float knobValue;
+@property (nonatomic,strong)NSMutableArray * imageArray;
+
+//Method
+-(void)createTheImageWall;
+-(void)updateTheKnobImage:(UIImage*)image;
+-(void)moveKnobWithSelectedValue:(float)value;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 133 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/KSVideoImageSlider.m

@@ -0,0 +1,133 @@
+//
+//  KSVideoImageSlider.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "KSVideoImageSlider.h"
+#define BOUND(VALUE, UPPER, LOWER)    MIN(MAX(VALUE, LOWER), UPPER)
+
+@interface KSVideoImageSlider ()
+{
+    UIImageView *_knobView;
+    float _knobWidth;
+    float _knobHeight;
+    float _useableTrackLength;
+    CGPoint _previousTouchPoint;
+}
+
+
+@end
+
+@implementation KSVideoImageSlider
+
+- (id)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    if (self) {
+        // Initialization code
+        _maximumValue = 10.0;
+        _minimumValue = 0.0;
+       // _knobValue = 0.0;
+        [self createLayerView:frame];
+        [self createTheknob];
+        [self setKnodFrames];
+    }
+    return self;
+}
+
+- (void)createLayerView:(CGRect)frame {
+    UIView *layerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
+    layerView.backgroundColor = [UIColor blackColor];
+    layerView.alpha = 0.32;
+    layerView.userInteractionEnabled = NO;
+    [self addSubview:layerView];
+}
+
+#pragma mark   --------PublicMethod
+-(void)createTheImageWall {
+    for (int i=0; i<self.maximumValue; i++) {
+        UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(i*(self.frame.size.width/self.maximumValue), 2, self.frame.size.width/self.maximumValue, self.frame.size.height-4)];
+        UIImage *image = self.imageArray[i];
+        [imageView setImage:image];
+        [self addSubview:imageView];
+        [self sendSubviewToBack:imageView];
+    }
+}
+
+- (void)updateTheKnobImage:(UIImage*)image{
+    [_knobView setImage:image];
+}
+
+- (void)moveKnobWithSelectedValue:(float)value{
+    [self setKnobValue:value];
+    [self setKnodFrames];
+}
+#pragma mark  --------PrivateMethod
+- (void)createTheknob{
+    if (_knobView == nil) {
+        _knobView = [[UIImageView alloc]init];
+        _knobView.layer.cornerRadius = 10.0f;
+        _knobView.layer.borderColor = HexRGB(0x279FFE).CGColor;
+        _knobView.layer.borderWidth = 4.0f;
+        _knobView.layer.masksToBounds = YES;
+        _knobView.contentMode = UIViewContentModeScaleAspectFill;
+        [self addSubview:_knobView];
+        [self bringSubviewToFront:_knobView];
+    }
+}
+
+- (void) setKnodFrames {
+    _knobWidth = 128;
+    _knobHeight = self.bounds.size.height;
+    _useableTrackLength = self.bounds.size.width - _knobWidth;
+    
+    float knobCentre = [self positionForValue:self.knobValue];
+    _knobView.frame = CGRectMake(knobCentre - _knobWidth / 2, 0, _knobWidth, _knobHeight);
+}
+
+- (float)positionForValue:(float)value
+{
+    return _useableTrackLength * (value - _minimumValue) /
+    (_maximumValue - _minimumValue) + (_knobWidth / 2);
+}
+#pragma mark -----------TouchHandle
+- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{
+    _previousTouchPoint = [touch locationInView:self];
+    
+    return YES;
+}
+- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{
+    CGPoint touchPoint = [touch locationInView:self];
+    
+    // 1. determine by how much the user has dragged
+    float delta = touchPoint.x - _previousTouchPoint.x;
+    float valueDelta = (_maximumValue - _minimumValue) * delta / _useableTrackLength;
+    
+    _previousTouchPoint = touchPoint;
+    
+    _knobValue  += valueDelta;
+    _knobValue  = BOUND(_knobValue, _maximumValue, _minimumValue);
+    [CATransaction begin];
+    [CATransaction setDisableActions:YES] ;
+    
+    [self setKnodFrames];
+    
+    [CATransaction commit];
+    [self sendActionsForControlEvents:UIControlEventValueChanged];
+    return YES;
+}
+
+- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{
+    
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 2 - 1
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MineWorksBodyView.m

@@ -48,6 +48,7 @@
         self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
         self.tableView.backgroundColor = [UIColor clearColor];
         self.tableView.showsVerticalScrollIndicator = NO;
+        self.tableView.showsHorizontalScrollIndicator = NO;
         self.tableView.rowHeight = 100.0f;
         self.tableView.dataSource = self;
         self.tableView.delegate = self;
@@ -238,7 +239,7 @@
     ctrl.sourceModel = model;
     MJWeakSelf;
     [ctrl editCallback:^{
-        [weakSelf refreshAndRequestData];
+//        [weakSelf refreshAndRequestData];
     }];
     [self.naviController pushViewController:ctrl animated:YES];
 }

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MineWorksNavView.m

@@ -24,7 +24,7 @@
     [super awakeFromNib];
     self.editView.hidden = YES;
     self.editButton.userInteractionEnabled = NO;
-    CAGradientLayer *titleLayer = [UIView createGradientLayerFromColor:HexRGBAlpha(0x77FFEF, 0.59) startPoint:CGPointMake(0.89, 1) endColor:HexRGB(0x42CDFF) endPoint:CGPointMake(0.19, 1) bounds:CGRectMake(0, 0, 48, 6)];
+    CAGradientLayer *titleLayer = [UIView createGradientLayerFromColor:HexRGBAlpha(0x77FFEF, 0.59) startPoint:CGPointMake(0.89, 1) endColor:HexRGB(0x2DC7AA) endPoint:CGPointMake(0.19, 1) bounds:CGRectMake(0, 0, 48, 6)];
     [self.titleView.layer addSublayer:titleLayer];
 }
 + (instancetype)shareInstance {

+ 11 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MineWorksNavView.xib

@@ -16,6 +16,14 @@
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YPw-d9-Fo2">
                     <rect key="frame" x="0.0" y="57" width="393" height="44"/>
                     <subviews>
+                        <view alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eYU-YQ-Vyp">
+                            <rect key="frame" x="51" y="30" width="48" height="6"/>
+                            <color key="backgroundColor" red="0.46666666670000001" green="1" blue="0.93725490199999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="6" id="U2q-rm-5Ie"/>
+                                <constraint firstAttribute="width" constant="48" id="hly-QV-vHm"/>
+                            </constraints>
+                        </view>
                         <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_worksTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Cum-va-YAQ">
                             <rect key="frame" x="50" y="12" width="78" height="20"/>
                         </imageView>
@@ -86,9 +94,11 @@
                         <constraint firstItem="Cum-va-YAQ" firstAttribute="centerY" secondItem="YPw-d9-Fo2" secondAttribute="centerY" id="5c0-EU-uVv"/>
                         <constraint firstItem="Cum-va-YAQ" firstAttribute="leading" secondItem="71W-r1-CNZ" secondAttribute="trailing" constant="20" id="6pF-6L-JHO"/>
                         <constraint firstItem="ENM-WF-Mzx" firstAttribute="bottom" secondItem="ts0-Ql-G2n" secondAttribute="bottom" id="J3e-3M-SLR"/>
+                        <constraint firstItem="eYU-YQ-Vyp" firstAttribute="leading" secondItem="Cum-va-YAQ" secondAttribute="leading" constant="1" id="TgC-dt-keb"/>
                         <constraint firstItem="bO5-ys-7vL" firstAttribute="leading" secondItem="YPw-d9-Fo2" secondAttribute="leading" id="YX4-Vs-gxk"/>
                         <constraint firstItem="71W-r1-CNZ" firstAttribute="leading" secondItem="YPw-d9-Fo2" secondAttribute="leading" constant="18" id="dEF-TC-40s"/>
                         <constraint firstItem="ts0-Ql-G2n" firstAttribute="centerY" secondItem="YPw-d9-Fo2" secondAttribute="centerY" id="dMe-bB-DKQ"/>
+                        <constraint firstItem="eYU-YQ-Vyp" firstAttribute="top" secondItem="Cum-va-YAQ" secondAttribute="bottom" constant="-2" id="fNi-0Y-aSy"/>
                         <constraint firstItem="ENM-WF-Mzx" firstAttribute="leading" secondItem="ts0-Ql-G2n" secondAttribute="leading" id="lDf-0q-Kz5"/>
                         <constraint firstAttribute="height" constant="44" id="lE6-HX-AdW"/>
                         <constraint firstAttribute="trailing" secondItem="ts0-Ql-G2n" secondAttribute="trailing" constant="12" id="qYW-3k-hpo"/>
@@ -111,6 +121,7 @@
                 <outlet property="editButton" destination="ENM-WF-Mzx" id="LPu-MD-8tm"/>
                 <outlet property="editLabel" destination="C2M-qv-DUp" id="Uc0-eX-7lP"/>
                 <outlet property="editView" destination="ts0-Ql-G2n" id="mAx-AK-7hI"/>
+                <outlet property="titleView" destination="eYU-YQ-Vyp" id="22s-Hh-6U5"/>
             </connections>
             <point key="canvasLocation" x="52.671755725190835" y="-5.2816901408450709"/>
         </view>

+ 21 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPubHeader.h

@@ -0,0 +1,21 @@
+//
+//  MusicPubHeader.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#ifndef MusicPubHeader_h
+#define MusicPubHeader_h
+
+typedef NS_ENUM(NSInteger, PUBLISH_ACTION) {
+    PUBLISH_ACTION_CHOOSEIMG,  // 选择作品封面
+    PUBLISH_ACTION_PUBLISH,    // 发布
+    PUBLISH_ACTION_VIDEOCOVER, // 选择视频封面
+    PUBLISH_ACTION_VIDEOCROP,  // 截取视频封面
+};
+
+typedef void(^MusicPublishCallback)(PUBLISH_ACTION type);
+
+
+#endif /* MusicPubHeader_h */

+ 7 - 12
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MusicPublistAlert.h → KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublicContentView.h

@@ -1,22 +1,16 @@
 //
-//  MusicPublistAlert.h
+//  MusicPublicContentView.h
 //  KulexiuSchoolStudent
 //
-//  Created by 王智 on 2023/11/1.
+//  Created by 王智 on 2023/11/8.
 //
 
 #import <UIKit/UIKit.h>
-
-typedef NS_ENUM(NSInteger, PUBLISH_ACTION) {
-    PUBLISH_ACTION_CHOOSEIMG,
-    PUBLISH_ACTION_PUBLISH,
-};
-
-typedef void(^MusicPublishCallback)(PUBLISH_ACTION type);
+#import "MusicPubHeader.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
-@interface MusicPublistAlert : UIView
+@interface MusicPublicContentView : UIView
 
 @property (weak, nonatomic) IBOutlet UITextView *textView;
 
@@ -28,9 +22,10 @@ NS_ASSUME_NONNULL_BEGIN
 
 + (instancetype)shareInstance;
 
-- (void)chooseAction:(MusicPublishCallback)callback;
+- (void)musicContentPubAction:(MusicPublishCallback)callback;
+
++ (CGFloat)getViewHeight;
 
-- (void)showAlert;
 @end
 
 NS_ASSUME_NONNULL_END

+ 14 - 26
KulexiuForStudent/KulexiuForStudent/Common/MediaMerge/AudioMerge/MusicPublistAlert.m → KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublicContentView.m

@@ -1,42 +1,42 @@
 //
-//  MusicPublistAlert.m
+//  MusicPublicContentView.m
 //  KulexiuSchoolStudent
 //
-//  Created by 王智 on 2023/11/1.
+//  Created by 王智 on 2023/11/8.
 //
 
-#import "MusicPublistAlert.h"
-#import "UIView+KSLayer.h"
+#import "MusicPublicContentView.h"
 
-@interface MusicPublistAlert ()<UITextViewDelegate>
+@interface MusicPublicContentView ()<UITextViewDelegate>
 
 @property (weak, nonatomic) IBOutlet UIButton *sureButton;
 
 @property (weak, nonatomic) IBOutlet UILabel *countLabel;
 
 @property (weak, nonatomic) IBOutlet UILabel *tipsLabel;
+
 @property (weak, nonatomic) IBOutlet UIView *backView;
 
 @property (nonatomic, copy) MusicPublishCallback callback;
 
 @end
 
-@implementation MusicPublistAlert
+@implementation MusicPublicContentView
+
 - (void)awakeFromNib {
     [super awakeFromNib];
     self.textView.delegate = self;
     
-//    CAGradientLayer *titleLayer = [UIView createGradientLayerFromColor:HexRGB(0x44C9FF) startPoint:CGPointMake(0, 0.5) endColor:HexRGB(0x259CFE) endPoint:CGPointMake(1, 0.5) bounds:CGRectMake(0, 0, 220, 38)];
-//    [self.sureButton.layer addSublayer:titleLayer];
     self.backView.layer.cornerRadius = 4;
     self.backView.layer.maskedCorners = kCALayerMinXMaxYCorner | kCALayerMaxXMaxYCorner;
 }
+
 + (instancetype)shareInstance {
-    MusicPublistAlert *view = [[[NSBundle mainBundle] loadNibNamed:@"MusicPublistAlert" owner:nil options:nil] firstObject];
+    MusicPublicContentView *view = [[[NSBundle mainBundle] loadNibNamed:@"MusicPublicContentView" owner:nil options:nil] firstObject];
     return view;
 }
 
-- (void)chooseAction:(MusicPublishCallback)callback {
+- (void)musicContentPubAction:(MusicPublishCallback)callback {
     if (callback) {
         self.callback = callback;
     }
@@ -46,30 +46,14 @@
     if (self.callback) {
         self.callback(PUBLISH_ACTION_PUBLISH);
     }
-    [self hideAlert];
 }
 
-- (IBAction)cancleAction:(id)sender {
-    [self hideAlert];
-}
 - (IBAction)chooseCover:(id)sender {
     if (self.callback) {
         self.callback(PUBLISH_ACTION_CHOOSEIMG);
     }
 }
 
-- (void)showAlert {
-    UIWindow *window = [NSObject getKeyWindow];
-    [window addSubview:self];
-    [self mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.left.right.top.bottom.mas_equalTo(window);
-    }];
-}
-
-- (void)hideAlert {
-    [self removeFromSuperview];
-}
-
 #pragma mark   ---- delegate
 
 - (void)textViewDidBeginEditing:(UITextView *)textView {
@@ -100,6 +84,10 @@
     self.countLabel.text = [NSString stringWithFormat:@"%zd/150",newString.length];
     return YES;
 }
+
++ (CGFloat)getViewHeight {
+    return 230.0f;
+}
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.

+ 222 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublicContentView.xib

@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" 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="22131"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MusicPublicContentView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="246"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ySm-Or-cry">
+                    <rect key="frame" x="12" y="99" width="369" height="73"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="music_coverBg" translatesAutoresizingMaskIntoConstraints="NO" id="vJP-em-vzJ">
+                            <rect key="frame" x="19" y="6" width="61" height="61"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="61" id="7rv-9b-MmO"/>
+                                <constraint firstAttribute="width" constant="61" id="DAq-YP-o88"/>
+                            </constraints>
+                        </imageView>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="pub_music_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="IbR-gO-EMr">
+                            <rect key="frame" x="12" y="5.6666666666666714" width="62" height="62"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="62" id="FyK-dq-xsq"/>
+                                <constraint firstAttribute="width" constant="62" id="v2f-ci-KsA"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="8"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lq4-ga-A7R">
+                            <rect key="frame" x="90" y="20" width="267" height="22"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="22" id="Q4v-O1-QEK"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                            <color key="textColor" red="0.074509803920000006" green="0.078431372550000003" blue="0.08235294118" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="I8N-pM-mro">
+                            <rect key="frame" x="90" y="46" width="267" height="20"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="20" id="NGk-7d-ARq"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="unChoose_status" translatesAutoresizingMaskIntoConstraints="NO" id="Z2c-Y5-JPA">
+                            <rect key="frame" x="0.0" y="27.666666666666671" width="0.0" height="18"/>
+                            <constraints>
+                                <constraint firstAttribute="width" id="Hkp-6N-xov"/>
+                                <constraint firstAttribute="height" constant="18" id="ihT-D0-sko"/>
+                            </constraints>
+                        </imageView>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xB0-uR-3Vs">
+                            <rect key="frame" x="12" y="47.666666666666657" width="62" height="20"/>
+                            <subviews>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="选封面" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dcs-Oi-GdD">
+                                    <rect key="frame" x="11" y="0.0" width="40" height="18"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="18" id="b6r-rS-afy"/>
+                                    </constraints>
+                                    <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                            </subviews>
+                            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.37" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstItem="Dcs-Oi-GdD" firstAttribute="centerX" secondItem="xB0-uR-3Vs" secondAttribute="centerX" id="0wX-YL-1c6"/>
+                                <constraint firstAttribute="height" constant="20" id="brl-Li-9m9"/>
+                                <constraint firstItem="Dcs-Oi-GdD" firstAttribute="top" secondItem="xB0-uR-3Vs" secondAttribute="top" id="e1c-2K-Qry"/>
+                                <constraint firstAttribute="width" constant="62" id="ls3-YT-lFD"/>
+                            </constraints>
+                        </view>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mGl-dI-rCl">
+                            <rect key="frame" x="12" y="5.6666666666666714" width="62" height="62"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="chooseCover:" destination="iN0-l3-epB" eventType="touchUpInside" id="5Fe-41-6ZC"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="IbR-gO-EMr" firstAttribute="centerY" secondItem="ySm-Or-cry" secondAttribute="centerY" id="2m2-TL-KDB"/>
+                        <constraint firstItem="IbR-gO-EMr" firstAttribute="trailing" secondItem="vJP-em-vzJ" secondAttribute="trailing" constant="-6" id="3Vr-NZ-5Yj"/>
+                        <constraint firstItem="vJP-em-vzJ" firstAttribute="centerY" secondItem="ySm-Or-cry" secondAttribute="centerY" id="4to-6o-TIt"/>
+                        <constraint firstItem="Z2c-Y5-JPA" firstAttribute="centerY" secondItem="ySm-Or-cry" secondAttribute="centerY" id="7ab-Ws-Xuo"/>
+                        <constraint firstAttribute="height" constant="73" id="87D-Tq-Ioq"/>
+                        <constraint firstItem="mGl-dI-rCl" firstAttribute="trailing" secondItem="IbR-gO-EMr" secondAttribute="trailing" id="8Ta-sM-fmj"/>
+                        <constraint firstAttribute="trailing" secondItem="I8N-pM-mro" secondAttribute="trailing" constant="12" id="AGz-Fb-LnU"/>
+                        <constraint firstItem="Lq4-ga-A7R" firstAttribute="leading" secondItem="vJP-em-vzJ" secondAttribute="trailing" constant="10" id="AHW-HU-zhs"/>
+                        <constraint firstItem="I8N-pM-mro" firstAttribute="leading" secondItem="Lq4-ga-A7R" secondAttribute="leading" id="FUA-xc-X82"/>
+                        <constraint firstItem="mGl-dI-rCl" firstAttribute="leading" secondItem="IbR-gO-EMr" secondAttribute="leading" id="FyH-Bg-WrU"/>
+                        <constraint firstItem="Lq4-ga-A7R" firstAttribute="top" secondItem="ySm-Or-cry" secondAttribute="top" constant="20" id="Mth-9R-s6K"/>
+                        <constraint firstItem="xB0-uR-3Vs" firstAttribute="leading" secondItem="IbR-gO-EMr" secondAttribute="leading" id="PGo-MX-r0D"/>
+                        <constraint firstItem="mGl-dI-rCl" firstAttribute="bottom" secondItem="IbR-gO-EMr" secondAttribute="bottom" id="UKV-dP-jb4"/>
+                        <constraint firstAttribute="trailing" secondItem="Lq4-ga-A7R" secondAttribute="trailing" constant="12" id="Wir-QO-mim"/>
+                        <constraint firstItem="I8N-pM-mro" firstAttribute="top" secondItem="Lq4-ga-A7R" secondAttribute="bottom" constant="4" id="XVM-Ko-OkK"/>
+                        <constraint firstItem="Z2c-Y5-JPA" firstAttribute="leading" secondItem="ySm-Or-cry" secondAttribute="leading" id="Xjv-we-kqb"/>
+                        <constraint firstItem="IbR-gO-EMr" firstAttribute="leading" secondItem="Z2c-Y5-JPA" secondAttribute="trailing" constant="12" id="cuD-f9-C1r"/>
+                        <constraint firstItem="mGl-dI-rCl" firstAttribute="top" secondItem="IbR-gO-EMr" secondAttribute="top" id="gfW-zB-wrB"/>
+                        <constraint firstItem="xB0-uR-3Vs" firstAttribute="trailing" secondItem="IbR-gO-EMr" secondAttribute="trailing" id="ikF-Uo-fWR"/>
+                        <constraint firstItem="xB0-uR-3Vs" firstAttribute="bottom" secondItem="IbR-gO-EMr" secondAttribute="bottom" id="qJA-gK-5iK"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="10"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0wJ-e7-ouI">
+                    <rect key="frame" x="86.666666666666686" y="190" width="220" height="38"/>
+                    <color key="backgroundColor" red="0.1764705882352941" green="0.7803921568627451" blue="0.66666666666666663" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="38" id="K9L-wd-aJd"/>
+                        <constraint firstAttribute="width" constant="220" id="WV4-5d-yoT"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" title="发布作品"/>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="19"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                    <connections>
+                        <action selector="sureAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="TwC-pw-oyY"/>
+                    </connections>
+                </button>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NpE-3V-eM1">
+                    <rect key="frame" x="12" y="0.0" width="369" height="87"/>
+                    <subviews>
+                        <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EYP-nq-h0J">
+                            <rect key="frame" x="12" y="0.0" width="345" height="87"/>
+                            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <color key="textColor" red="0.2666666667" green="0.2666666667" blue="0.2666666667" alpha="1" colorSpace="calibratedRGB"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <textInputTraits key="textInputTraits" autocapitalizationType="sentences" enablesReturnKeyAutomatically="YES"/>
+                        </textView>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我发布了一首演奏作品,快来听听吧~" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="glk-go-0oW">
+                            <rect key="frame" x="12" y="10" width="243" height="17"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0/150" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lro-Xx-AAz">
+                            <rect key="frame" x="325" y="58" width="32" height="20"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="20" id="83V-tz-Cpg"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                            <color key="textColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstItem="glk-go-0oW" firstAttribute="leading" secondItem="NpE-3V-eM1" secondAttribute="leading" constant="12" id="3kw-tz-XVV"/>
+                        <constraint firstItem="EYP-nq-h0J" firstAttribute="top" secondItem="NpE-3V-eM1" secondAttribute="top" id="GLb-KA-3Zz"/>
+                        <constraint firstAttribute="height" constant="87" id="MM1-lx-Cmu"/>
+                        <constraint firstAttribute="bottom" secondItem="lro-Xx-AAz" secondAttribute="bottom" constant="9" id="c5Y-ih-yEg"/>
+                        <constraint firstItem="EYP-nq-h0J" firstAttribute="leading" secondItem="NpE-3V-eM1" secondAttribute="leading" constant="12" id="erk-lD-qR7"/>
+                        <constraint firstItem="glk-go-0oW" firstAttribute="top" secondItem="NpE-3V-eM1" secondAttribute="top" constant="10" id="ncg-6K-1re"/>
+                        <constraint firstAttribute="trailing" secondItem="lro-Xx-AAz" secondAttribute="trailing" constant="12" id="sOe-Ih-nSR"/>
+                        <constraint firstAttribute="trailing" secondItem="EYP-nq-h0J" secondAttribute="trailing" constant="12" id="tXY-CK-lhd"/>
+                        <constraint firstAttribute="bottom" secondItem="EYP-nq-h0J" secondAttribute="bottom" id="vZM-tS-pb2"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="10"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="0wJ-e7-ouI" secondAttribute="bottom" constant="18" id="Ba7-0l-oGc"/>
+                <constraint firstAttribute="trailing" secondItem="NpE-3V-eM1" secondAttribute="trailing" constant="12" id="H3O-rj-Pdv"/>
+                <constraint firstAttribute="trailing" secondItem="ySm-Or-cry" secondAttribute="trailing" constant="12" id="Pqm-nZ-Nhi"/>
+                <constraint firstItem="0wJ-e7-ouI" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Qhu-ND-VFC"/>
+                <constraint firstItem="ySm-Or-cry" firstAttribute="top" secondItem="NpE-3V-eM1" secondAttribute="bottom" constant="12" id="RVK-fV-L77"/>
+                <constraint firstItem="NpE-3V-eM1" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="YZ5-PY-Ced"/>
+                <constraint firstItem="ySm-Or-cry" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="12" id="ev9-kC-cbD"/>
+                <constraint firstItem="NpE-3V-eM1" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="12" id="jir-QV-hWq"/>
+                <constraint firstItem="0wJ-e7-ouI" firstAttribute="top" secondItem="ySm-Or-cry" secondAttribute="bottom" constant="18" id="n6Y-mi-EJu"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="backView" destination="xB0-uR-3Vs" id="J3a-fb-kKX"/>
+                <outlet property="countLabel" destination="lro-Xx-AAz" id="hyn-Cm-7d9"/>
+                <outlet property="musicImage" destination="IbR-gO-EMr" id="GX0-pM-jOo"/>
+                <outlet property="musicName" destination="Lq4-ga-A7R" id="hLK-Cr-9Vv"/>
+                <outlet property="sureButton" destination="0wJ-e7-ouI" id="qo3-HE-Z5X"/>
+                <outlet property="textView" destination="EYP-nq-h0J" id="yCJ-fa-yQp"/>
+                <outlet property="tipsLabel" destination="glk-go-0oW" id="V2E-OK-68E"/>
+                <outlet property="userName" destination="I8N-pM-mro" id="zzf-Zy-vet"/>
+            </connections>
+            <point key="canvasLocation" x="58.778625954198468" y="-188.02816901408451"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="music_coverBg" width="54" height="54"/>
+        <image name="pub_music_placeholder" width="205" height="205"/>
+        <image name="unChoose_status" width="18" height="18"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 32 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublistAlert.h

@@ -0,0 +1,32 @@
+//
+//  MusicPublistAlert.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/1.
+//
+
+#import <UIKit/UIKit.h>
+#import "VideoCoverChooseView.h"
+#import "MusicPublicContentView.h"
+#import "MusicPubHeader.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MusicPublistAlert : UIView
+
+@property (nonatomic, strong) VideoCoverChooseView *coverView;
+
+@property (nonatomic, strong) MusicPublicContentView *publishContainView;
+
++ (instancetype)shareInstance;
+
+- (void)configUI:(BOOL)isVideoPublish;
+
+- (void)evaluateMusicName:(NSString *)musicName userName:(NSString *)userName musicImage:(NSString *)musicImage;
+
+- (void)chooseAction:(MusicPublishCallback)callback;
+
+- (void)showAlert;
+@end
+
+NS_ASSUME_NONNULL_END

+ 135 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublistAlert.m

@@ -0,0 +1,135 @@
+//
+//  MusicPublistAlert.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/1.
+//
+
+#import "MusicPublistAlert.h"
+
+
+@interface MusicPublistAlert ()
+
+@property (nonatomic, strong) UIScrollView *scrollView;
+
+@property (weak, nonatomic) IBOutlet UIView *containerView;
+
+
+@property (nonatomic, copy) MusicPublishCallback callback;
+
+@end
+
+@implementation MusicPublistAlert
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    [self.containerView addSubview:self.scrollView];
+    [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.containerView);
+    }];
+}
++ (instancetype)shareInstance {
+    MusicPublistAlert *view = [[[NSBundle mainBundle] loadNibNamed:@"MusicPublistAlert" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configUI:(BOOL)isVideoPublish {
+    MJWeakSelf;
+    if (isVideoPublish) {
+        self.coverView = [VideoCoverChooseView shareInstance];
+        [self.coverView chooseImageCallback:^(PUBLISH_ACTION type) {
+            [weakSelf endEditing:YES];
+            if (weakSelf.callback) {
+                weakSelf.callback(type);
+            }
+        }];
+        [self.scrollView addSubview:self.coverView];
+        CGFloat coverHeigt = [VideoCoverChooseView getViewHeight];
+        [self.coverView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.containerView);
+            make.top.mas_equalTo(self.scrollView.mas_top);
+            make.height.mas_equalTo(coverHeigt);
+        }];
+        // container
+        self.publishContainView = [MusicPublicContentView shareInstance];
+        [self.scrollView addSubview:self.publishContainView];
+        CGFloat height = [MusicPublicContentView getViewHeight];
+        [self.publishContainView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.containerView);
+            make.top.mas_equalTo(self.coverView.mas_bottom);
+            make.bottom.mas_equalTo(self.scrollView.mas_bottom);
+            make.height.mas_equalTo(height);
+        }];
+        [self.publishContainView musicContentPubAction:^(PUBLISH_ACTION type) {
+            [weakSelf endEditing:YES];
+            if (type == PUBLISH_ACTION_PUBLISH) {
+                [weakSelf hideAlert];
+            }
+            if (weakSelf.callback) {
+                weakSelf.callback(type);
+            }
+        }];
+    }
+    else {
+        // container
+        self.publishContainView = [MusicPublicContentView shareInstance];
+        [self addSubview:self.publishContainView];
+        CGFloat height = [MusicPublicContentView getViewHeight];
+        [self.publishContainView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.bottom.mas_equalTo(self.containerView);
+        }];
+        [self.publishContainView musicContentPubAction:^(PUBLISH_ACTION type) {
+            [weakSelf endEditing:YES];
+            if (weakSelf.callback) {
+                weakSelf.callback(type);
+            }
+        }];
+    }
+}
+
+- (void)evaluateMusicName:(NSString *)musicName userName:(NSString *)userName musicImage:(NSString *)musicImage {
+    self.publishContainView.musicName.text = [NSString returnNoNullStringWithString:musicName];
+    [self.publishContainView.musicImage sd_setImageWithURL:[NSURL URLWithString:[musicImage getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"music_placeholder"]];
+    self.publishContainView.userName.text = [NSString returnNoNullStringWithString:userName];
+}
+
+- (void)chooseAction:(MusicPublishCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+
+- (IBAction)cancleAction:(id)sender {
+    [self hideAlert];
+}
+
+- (void)showAlert {
+    UIWindow *window = [NSObject getKeyWindow];
+    [window addSubview:self];
+    [self mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(window);
+    }];
+}
+
+- (void)hideAlert {
+    [self removeFromSuperview];
+}
+
+- (UIScrollView *)scrollView {
+    if (!_scrollView) {
+        _scrollView = [[UIScrollView alloc] init];
+        _scrollView.showsVerticalScrollIndicator = NO;
+        _scrollView.showsHorizontalScrollIndicator = NO;
+        _scrollView.bounces = NO;
+    }
+    return _scrollView;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 90 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/MusicPublistAlert.xib

@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" 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="22131"/>
+        <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="MusicPublistAlert">
+            <rect key="frame" x="0.0" y="0.0" width="687" height="520"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="crp-Dg-bEh">
+                    <rect key="frame" x="185.66666666666663" y="104.66666666666669" width="316" height="311"/>
+                    <subviews>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="作品详情" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="te4-O1-RAs">
+                            <rect key="frame" x="125.33333333333334" y="15" width="65.333333333333343" height="22"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="22" id="9P9-gf-TQs"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                            <color key="textColor" red="0.074509803921568626" green="0.078431372549019607" blue="0.082352941176470587" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="VSu-Ld-Rbu">
+                            <rect key="frame" x="0.0" y="56" width="316" height="255"/>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        </view>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cancle_button" translatesAutoresizingMaskIntoConstraints="NO" id="uSL-RT-oX5">
+                            <rect key="frame" x="287" y="11" width="19" height="19"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="19" id="LRY-32-rBI"/>
+                                <constraint firstAttribute="height" constant="19" id="dWq-Go-3Vb"/>
+                            </constraints>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8mM-Qw-PGH">
+                            <rect key="frame" x="276" y="0.0" width="40" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="40" id="SR0-Xr-LNe"/>
+                                <constraint firstAttribute="width" constant="40" id="zIs-lk-2mh"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="cancleAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="7JR-cS-Y5p"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="311" id="3bE-RT-gdX"/>
+                        <constraint firstAttribute="width" constant="316" id="5Vp-Nm-Phf"/>
+                        <constraint firstItem="VSu-Ld-Rbu" firstAttribute="leading" secondItem="crp-Dg-bEh" secondAttribute="leading" id="Ar8-21-yBw"/>
+                        <constraint firstAttribute="trailing" secondItem="uSL-RT-oX5" secondAttribute="trailing" constant="10" id="JvH-Ld-uxt"/>
+                        <constraint firstItem="8mM-Qw-PGH" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" id="P4Y-hH-uUz"/>
+                        <constraint firstAttribute="bottom" secondItem="VSu-Ld-Rbu" secondAttribute="bottom" id="Qul-Iw-vdi"/>
+                        <constraint firstItem="te4-O1-RAs" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" constant="15" id="ci5-BA-awW"/>
+                        <constraint firstAttribute="trailing" secondItem="8mM-Qw-PGH" secondAttribute="trailing" id="ehJ-JA-HqW"/>
+                        <constraint firstItem="VSu-Ld-Rbu" firstAttribute="top" secondItem="te4-O1-RAs" secondAttribute="bottom" constant="19" id="ncm-iM-Is7"/>
+                        <constraint firstItem="uSL-RT-oX5" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" constant="11" id="nwL-G4-dhm"/>
+                        <constraint firstItem="te4-O1-RAs" firstAttribute="centerX" secondItem="crp-Dg-bEh" secondAttribute="centerX" id="xB7-AF-HP0"/>
+                        <constraint firstAttribute="trailing" secondItem="VSu-Ld-Rbu" secondAttribute="trailing" id="z0h-ml-YDQ"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="12"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
+            <constraints>
+                <constraint firstItem="crp-Dg-bEh" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Q7S-rU-daX"/>
+                <constraint firstItem="crp-Dg-bEh" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="l1H-ZN-yAQ"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="containerView" destination="VSu-Ld-Rbu" id="IVZ-aq-krM"/>
+            </connections>
+            <point key="canvasLocation" x="121.37404580152672" y="-23.239436619718312"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="cancle_button" width="20" height="20"/>
+    </resources>
+</document>

+ 27 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCoverChooseView.h

@@ -0,0 +1,27 @@
+//
+//  VideoCoverChooseView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import <UIKit/UIKit.h>
+#import "MusicPubHeader.h"
+
+typedef void(^VideoCoverChooseCallback)(PUBLISH_ACTION type);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface VideoCoverChooseView : UIView
+
+@property (weak, nonatomic) IBOutlet UIImageView *coverImage;
+
++ (instancetype)shareInstance;
+
+- (void)chooseImageCallback:(VideoCoverChooseCallback)callback;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 59 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCoverChooseView.m

@@ -0,0 +1,59 @@
+//
+//  VideoCoverChooseView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "VideoCoverChooseView.h"
+#import "UIView+KSLayer.h"
+
+@interface VideoCoverChooseView ()
+@property (weak, nonatomic) IBOutlet UIView *layerView;
+
+@property (nonatomic, copy) VideoCoverChooseCallback callback;
+
+@end
+
+@implementation VideoCoverChooseView
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    CAGradientLayer *viewLayer = [UIView createGradientLayerFromColor:HexRGB(0x80B1C8) startPoint:CGPointMake(0, 0.5) endColor:HexRGB(0x3A98A2) endPoint:CGPointMake(0.5, 1) bounds:CGRectMake(0, 0, 248, 30)];
+    [self.layerView.layer addSublayer:viewLayer];
+}
++ (instancetype)shareInstance {
+    VideoCoverChooseView *view = [[[NSBundle mainBundle] loadNibNamed:@"VideoCoverChooseView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (IBAction)albumChoose:(id)sender {
+    if (self.callback) {
+        self.callback(PUBLISH_ACTION_VIDEOCOVER);
+    }
+}
+
+- (IBAction)videoCrop:(id)sender {
+    if (self.callback) {
+        self.callback(PUBLISH_ACTION_VIDEOCROP);
+    }
+}
+
+- (void)chooseImageCallback:(VideoCoverChooseCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+
++ (CGFloat)getViewHeight {
+    return 163.0f;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 177 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCoverChooseView.xib

@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" 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="22131"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="VideoCoverChooseView">
+            <rect key="frame" x="0.0" y="0.0" width="316" height="163"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Rod-ju-kqd">
+                    <rect key="frame" x="13" y="0.0" width="290" height="136"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="videoMerge_cover" translatesAutoresizingMaskIntoConstraints="NO" id="Yfw-f3-ca2">
+                            <rect key="frame" x="0.0" y="0.0" width="290" height="136"/>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="10"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="trailing" secondItem="Yfw-f3-ca2" secondAttribute="trailing" id="2ZX-mF-kFV"/>
+                        <constraint firstAttribute="height" constant="136" id="C6o-HO-W1z"/>
+                        <constraint firstAttribute="bottom" secondItem="Yfw-f3-ca2" secondAttribute="bottom" id="GsL-sh-WZO"/>
+                        <constraint firstItem="Yfw-f3-ca2" firstAttribute="leading" secondItem="Rod-ju-kqd" secondAttribute="leading" id="I70-AY-OHA"/>
+                        <constraint firstItem="Yfw-f3-ca2" firstAttribute="top" secondItem="Rod-ju-kqd" secondAttribute="top" id="WVR-yM-gfe"/>
+                    </constraints>
+                </view>
+                <view alpha="0.58999999999999997" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Eoj-tF-ifL">
+                    <rect key="frame" x="34" y="121" width="248" height="30"/>
+                    <color key="backgroundColor" red="0.50196078431372548" green="0.61960784313725492" blue="0.78431372549019607" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="30" id="7rL-iS-MKS"/>
+                        <constraint firstAttribute="width" constant="248" id="hHH-4o-745"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="15"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TOX-dY-1lt">
+                    <rect key="frame" x="34" y="121" width="248" height="30"/>
+                    <subviews>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sPz-fl-Upn">
+                            <rect key="frame" x="0.0" y="0.0" width="123" height="30"/>
+                            <subviews>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cover_choose_image" translatesAutoresizingMaskIntoConstraints="NO" id="b49-x9-Ry1">
+                                    <rect key="frame" x="15" y="7" width="16" height="16"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="16" id="KTD-Sz-fLl"/>
+                                        <constraint firstAttribute="height" constant="16" id="tg3-wE-3tv"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="相册获取封面" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wD9-9N-1Ea">
+                                    <rect key="frame" x="35" y="7.6666666666666572" width="74" height="15"/>
+                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
+                                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rgT-xS-ewk">
+                                    <rect key="frame" x="0.0" y="0.0" width="123" height="30"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="albumChoose:" destination="iN0-l3-epB" eventType="touchUpInside" id="85f-AQ-i0Q"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstAttribute="bottom" secondItem="rgT-xS-ewk" secondAttribute="bottom" id="4ak-Zl-K0d"/>
+                                <constraint firstItem="wD9-9N-1Ea" firstAttribute="centerY" secondItem="sPz-fl-Upn" secondAttribute="centerY" id="MEU-Gc-U7P"/>
+                                <constraint firstItem="b49-x9-Ry1" firstAttribute="centerY" secondItem="sPz-fl-Upn" secondAttribute="centerY" id="O6C-6S-zD8"/>
+                                <constraint firstItem="rgT-xS-ewk" firstAttribute="top" secondItem="sPz-fl-Upn" secondAttribute="top" id="Oxs-x8-aFB"/>
+                                <constraint firstAttribute="trailing" secondItem="rgT-xS-ewk" secondAttribute="trailing" id="doi-yT-5Ol"/>
+                                <constraint firstItem="wD9-9N-1Ea" firstAttribute="leading" secondItem="b49-x9-Ry1" secondAttribute="trailing" constant="4" id="flu-1E-HCY"/>
+                                <constraint firstItem="b49-x9-Ry1" firstAttribute="centerY" secondItem="sPz-fl-Upn" secondAttribute="centerY" id="gVa-dp-wvO"/>
+                                <constraint firstItem="rgT-xS-ewk" firstAttribute="leading" secondItem="sPz-fl-Upn" secondAttribute="leading" id="lAt-dR-qYW"/>
+                                <constraint firstItem="b49-x9-Ry1" firstAttribute="leading" secondItem="sPz-fl-Upn" secondAttribute="leading" constant="15" id="leT-o0-A0I"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="s7h-QL-lWX">
+                            <rect key="frame" x="125" y="0.0" width="123" height="30"/>
+                            <subviews>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cover_crop_image" translatesAutoresizingMaskIntoConstraints="NO" id="uBM-vB-63W">
+                                    <rect key="frame" x="16" y="7" width="16" height="16"/>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="视频截取封面" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oaL-43-caz">
+                                    <rect key="frame" x="36.000000000000007" y="7.6666666666666572" width="73.666666666666686" height="15"/>
+                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
+                                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SaH-IM-rMB">
+                                    <rect key="frame" x="0.0" y="0.0" width="123" height="30"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="videoCrop:" destination="iN0-l3-epB" eventType="touchUpInside" id="5FD-qB-TSL"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstItem="SaH-IM-rMB" firstAttribute="leading" secondItem="s7h-QL-lWX" secondAttribute="leading" id="3Zh-Gm-rbl"/>
+                                <constraint firstItem="uBM-vB-63W" firstAttribute="leading" secondItem="s7h-QL-lWX" secondAttribute="leading" constant="16" id="Z5H-P0-WjL"/>
+                                <constraint firstItem="uBM-vB-63W" firstAttribute="centerY" secondItem="s7h-QL-lWX" secondAttribute="centerY" id="Zhw-8g-7Se"/>
+                                <constraint firstItem="oaL-43-caz" firstAttribute="leading" secondItem="uBM-vB-63W" secondAttribute="trailing" constant="4" id="cvs-aQ-AEq"/>
+                                <constraint firstItem="oaL-43-caz" firstAttribute="centerY" secondItem="s7h-QL-lWX" secondAttribute="centerY" id="lbV-BV-pMY"/>
+                                <constraint firstAttribute="bottom" secondItem="SaH-IM-rMB" secondAttribute="bottom" id="sFE-dh-XyI"/>
+                                <constraint firstAttribute="trailing" secondItem="SaH-IM-rMB" secondAttribute="trailing" id="wew-aj-C4r"/>
+                                <constraint firstItem="SaH-IM-rMB" firstAttribute="top" secondItem="s7h-QL-lWX" secondAttribute="top" id="wks-xS-Aep"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Wb-ep-CKI">
+                            <rect key="frame" x="123" y="9.6666666666666572" width="2" height="11"/>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="11" id="5Hu-Ha-fsy"/>
+                                <constraint firstAttribute="width" constant="2" id="AVF-5K-GM6"/>
+                            </constraints>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="s7h-QL-lWX" firstAttribute="leading" secondItem="7Wb-ep-CKI" secondAttribute="trailing" id="JBb-gc-R0a"/>
+                        <constraint firstItem="sPz-fl-Upn" firstAttribute="top" secondItem="TOX-dY-1lt" secondAttribute="top" id="Kzt-5A-QL4"/>
+                        <constraint firstItem="7Wb-ep-CKI" firstAttribute="leading" secondItem="sPz-fl-Upn" secondAttribute="trailing" id="LtK-QD-0HD"/>
+                        <constraint firstAttribute="trailing" secondItem="s7h-QL-lWX" secondAttribute="trailing" id="QaQ-NL-SBU"/>
+                        <constraint firstAttribute="bottom" secondItem="sPz-fl-Upn" secondAttribute="bottom" id="Wou-Go-wuB"/>
+                        <constraint firstItem="s7h-QL-lWX" firstAttribute="top" secondItem="TOX-dY-1lt" secondAttribute="top" id="hIs-Yy-9oC"/>
+                        <constraint firstAttribute="bottom" secondItem="s7h-QL-lWX" secondAttribute="bottom" id="jKS-O5-yhv"/>
+                        <constraint firstItem="7Wb-ep-CKI" firstAttribute="centerX" secondItem="TOX-dY-1lt" secondAttribute="centerX" id="kAH-ni-mQa"/>
+                        <constraint firstItem="sPz-fl-Upn" firstAttribute="leading" secondItem="TOX-dY-1lt" secondAttribute="leading" id="smL-ff-bFt"/>
+                        <constraint firstItem="7Wb-ep-CKI" firstAttribute="centerY" secondItem="TOX-dY-1lt" secondAttribute="centerY" id="zZR-0Y-xHY"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="trailing" secondItem="TOX-dY-1lt" secondAttribute="trailing" id="0LO-uR-sgt"/>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="bottom" secondItem="TOX-dY-1lt" secondAttribute="bottom" id="1sv-yO-kGe"/>
+                <constraint firstItem="Rod-ju-kqd" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="J0h-Tv-qF6"/>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="U1o-fC-wzj"/>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="leading" secondItem="TOX-dY-1lt" secondAttribute="leading" id="aJA-3E-8js"/>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="top" secondItem="TOX-dY-1lt" secondAttribute="top" id="aVH-Me-QLU"/>
+                <constraint firstItem="Rod-ju-kqd" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="plL-e8-8KF"/>
+                <constraint firstAttribute="trailing" secondItem="Rod-ju-kqd" secondAttribute="trailing" constant="13" id="rTU-2d-xDG"/>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="centerY" secondItem="Rod-ju-kqd" secondAttribute="bottom" id="uG3-w7-Tgg"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="coverImage" destination="Yfw-f3-ca2" id="Ejy-W6-GpP"/>
+                <outlet property="layerView" destination="Eoj-tF-ifL" id="qsd-FK-3bg"/>
+            </connections>
+            <point key="canvasLocation" x="58.015267175572518" y="-171.83098591549296"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="cover_choose_image" width="16" height="16"/>
+        <image name="cover_crop_image" width="16" height="16"/>
+        <image name="videoMerge_cover" width="291" height="136"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 18 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCropImageViewCell.h

@@ -0,0 +1,18 @@
+//
+//  VideoCropImageViewCell.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface VideoCropImageViewCell : UICollectionViewCell
+
+- (void)configWithSource:(UIImage *)image;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 28 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCropImageViewCell.m

@@ -0,0 +1,28 @@
+//
+//  VideoCropImageViewCell.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "VideoCropImageViewCell.h"
+
+@interface VideoCropImageViewCell ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *displayImage;
+
+
+@end
+
+@implementation VideoCropImageViewCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+}
+
+- (void)configWithSource:(UIImage *)image {
+    [self.displayImage setImage:image];
+}
+
+@end

+ 39 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Works/View/VideoCropImageViewCell.xib

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" 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="22131"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="VideoCropImageViewCell">
+            <rect key="frame" x="0.0" y="0.0" width="160" height="84"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                <rect key="frame" x="0.0" y="0.0" width="160" height="84"/>
+                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                <subviews>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="88X-kj-09O">
+                        <rect key="frame" x="0.0" y="0.0" width="160" height="84"/>
+                    </imageView>
+                </subviews>
+            </view>
+            <viewLayoutGuide key="safeArea" id="SEy-5g-ep8"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="88X-kj-09O" secondAttribute="trailing" id="6XL-qL-qhv"/>
+                <constraint firstItem="88X-kj-09O" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="PIL-Pu-U0P"/>
+                <constraint firstAttribute="bottom" secondItem="88X-kj-09O" secondAttribute="bottom" id="m2v-qv-cKE"/>
+                <constraint firstItem="88X-kj-09O" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="pI2-be-0rE"/>
+            </constraints>
+            <size key="customSize" width="160" height="84"/>
+            <connections>
+                <outlet property="displayImage" destination="88X-kj-09O" id="Xbc-hG-WBX"/>
+            </connections>
+            <point key="canvasLocation" x="296.18320610687022" y="-2.1126760563380285"/>
+        </collectionViewCell>
+    </objects>
+</document>