瀏覽代碼

Merge branch 'v1.0.5' into dev

# Conflicts:
#	MusicVideoPlus.xcodeproj/project.pbxproj
#	MusicVideoPlus/Classes/Modules/Home/Controllers/MVHomeController.swift
#	Podfile

合并v1.0,5分支代码
jsonwang 3 年之前
父節點
當前提交
9b2eaa0e07
共有 25 個文件被更改,包括 1405 次插入59 次删除
  1. 64 23
      MusicVideoPlus.xcodeproj/project.pbxproj
  2. 78 0
      MusicVideoPlus.xcodeproj/xcshareddata/xcschemes/MusicVideoPlus.xcscheme
  3. 22 0
      MusicVideoPlus/Assets.xcassets/Home/empty_mine_product.imageset/Contents.json
  4. 二進制
      MusicVideoPlus/Assets.xcassets/Home/empty_mine_product.imageset/empty_mine_product@2x.png
  5. 二進制
      MusicVideoPlus/Assets.xcassets/Home/empty_mine_product.imageset/empty_mine_product@3x.png
  6. 22 0
      MusicVideoPlus/Assets.xcassets/Login/mi_upload_share_timeline.imageset/Contents.json
  7. 二進制
      MusicVideoPlus/Assets.xcassets/Login/mi_upload_share_timeline.imageset/mi_upload_share_timeline@2x.png
  8. 二進制
      MusicVideoPlus/Assets.xcassets/Login/mi_upload_share_timeline.imageset/mi_upload_share_timeline@3x.png
  9. 6 0
      MusicVideoPlus/Assets.xcassets/Mine/Contents.json
  10. 22 0
      MusicVideoPlus/Assets.xcassets/Mine/icon_video_point.imageset/Contents.json
  11. 二進制
      MusicVideoPlus/Assets.xcassets/Mine/icon_video_point.imageset/icon_video_point@2x.png
  12. 二進制
      MusicVideoPlus/Assets.xcassets/Mine/icon_video_point.imageset/icon_video_point@3x.png
  13. 20 10
      MusicVideoPlus/Classes/Modules/Home/Controllers/MVHomeController.swift
  14. 0 1
      MusicVideoPlus/Classes/Modules/Home/Views/MVBannerCell.swift
  15. 319 0
      MusicVideoPlus/Classes/Modules/Home/Views/MVPlayControlViewCell.swift
  16. 0 22
      MusicVideoPlus/Classes/Modules/Mine/Controllers/MVMineController.swift
  17. 191 0
      MusicVideoPlus/Classes/Modules/Mine/Controllers/MVMineProductController.swift
  18. 211 0
      MusicVideoPlus/Classes/Modules/Mine/Controllers/MVPlayViewController.swift
  19. 106 0
      MusicVideoPlus/Classes/Modules/Mine/Controllers/PQCollectionViewFlowlayout.swift
  20. 52 0
      MusicVideoPlus/Classes/Modules/Mine/ViewModel/MVMineViewModel.swift
  21. 86 0
      MusicVideoPlus/Classes/Modules/Mine/Views/MVMineHeadInfoView.swift
  22. 111 0
      MusicVideoPlus/Classes/Modules/Mine/Views/MVMineProductCell.swift
  23. 78 0
      MusicVideoPlus/Classes/Modules/Mine/Views/MVProductEmptyView.swift
  24. 13 0
      MusicVideoPlus/Classes/Modules/Utils/MVRequestURLUtil.swift
  25. 4 3
      Podfile

+ 64 - 23
MusicVideoPlus.xcodeproj/project.pbxproj

@@ -10,6 +10,15 @@
 		2D076756266DF8E300E64472 /* PQServerProtocalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D076755266DF8E300E64472 /* PQServerProtocalView.swift */; };
 		2D076758266E08E700E64472 /* MVHomeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D076757266E08E700E64472 /* MVHomeController.swift */; };
 		2D1EC138266B4F4900CBACE4 /* MVThirdApiUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D1EC137266B4F4900CBACE4 /* MVThirdApiUtil.swift */; };
+		2D9630D3268186A500AE6FFE /* MVPlayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9630D2268186A500AE6FFE /* MVPlayViewController.swift */; };
+		2D9630D52681874D00AE6FFE /* MVPlayControlViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9630D42681874D00AE6FFE /* MVPlayControlViewCell.swift */; };
+		2D9630D92681947300AE6FFE /* MVRequestURLUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9630D82681947300AE6FFE /* MVRequestURLUtil.swift */; };
+		2D9630DC2681C8AB00AE6FFE /* MVMineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9630DB2681C8AB00AE6FFE /* MVMineViewModel.swift */; };
+		2D9630DE268206F300AE6FFE /* MVMineProductController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9630DD268206F300AE6FFE /* MVMineProductController.swift */; };
+		2D9630E12682096900AE6FFE /* PQCollectionViewFlowlayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9630E02682096900AE6FFE /* PQCollectionViewFlowlayout.swift */; };
+		2D9630E326820B1900AE6FFE /* MVMineProductCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9630E226820B1900AE6FFE /* MVMineProductCell.swift */; };
+		2D9630E52682D14500AE6FFE /* MVMineHeadInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9630E42682D14500AE6FFE /* MVMineHeadInfoView.swift */; };
+		2D9630E72683534B00AE6FFE /* MVProductEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D9630E62683534B00AE6FFE /* MVProductEmptyView.swift */; };
 		4112DD832669BFA600A5AFD9 /* MVBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4112DD822669BFA600A5AFD9 /* MVBanner.swift */; };
 		4112DD862669BFFA00A5AFD9 /* MVBannerFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4112DD852669BFFA00A5AFD9 /* MVBannerFlowLayout.swift */; };
 		4112DD912669C11C00A5AFD9 /* MVBannerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4112DD902669C11C00A5AFD9 /* MVBannerCell.swift */; };
@@ -21,7 +30,6 @@
 		418532302665342100DCA2C1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4185322F2665342100DCA2C1 /* AppDelegate.swift */; };
 		418532392665342200DCA2C1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 418532382665342200DCA2C1 /* Assets.xcassets */; };
 		41CA6E5E266782EC00874B19 /* MVBaseController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41CA6E5D266782EC00874B19 /* MVBaseController.swift */; };
-		41CA6E662667887C00874B19 /* MVMineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41CA6E652667887C00874B19 /* MVMineController.swift */; };
 		41CA6E69266788C000874B19 /* MVLoginController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41CA6E68266788C000874B19 /* MVLoginController.swift */; };
 		41CA6E6C266788F700874B19 /* MVPlayerConntroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41CA6E6B266788F700874B19 /* MVPlayerConntroller.swift */; };
 		41CA6E702667953700874B19 /* MVSettingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41CA6E6F2667953700874B19 /* MVSettingController.swift */; };
@@ -34,6 +42,15 @@
 		2D076755266DF8E300E64472 /* PQServerProtocalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PQServerProtocalView.swift; sourceTree = "<group>"; };
 		2D076757266E08E700E64472 /* MVHomeController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MVHomeController.swift; sourceTree = "<group>"; };
 		2D1EC137266B4F4900CBACE4 /* MVThirdApiUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVThirdApiUtil.swift; sourceTree = "<group>"; };
+		2D9630D2268186A500AE6FFE /* MVPlayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVPlayViewController.swift; sourceTree = "<group>"; };
+		2D9630D42681874D00AE6FFE /* MVPlayControlViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVPlayControlViewCell.swift; sourceTree = "<group>"; };
+		2D9630D82681947300AE6FFE /* MVRequestURLUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVRequestURLUtil.swift; sourceTree = "<group>"; };
+		2D9630DB2681C8AB00AE6FFE /* MVMineViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MVMineViewModel.swift; sourceTree = "<group>"; };
+		2D9630DD268206F300AE6FFE /* MVMineProductController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMineProductController.swift; sourceTree = "<group>"; };
+		2D9630E02682096900AE6FFE /* PQCollectionViewFlowlayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PQCollectionViewFlowlayout.swift; sourceTree = "<group>"; };
+		2D9630E226820B1900AE6FFE /* MVMineProductCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMineProductCell.swift; sourceTree = "<group>"; };
+		2D9630E42682D14500AE6FFE /* MVMineHeadInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMineHeadInfoView.swift; sourceTree = "<group>"; };
+		2D9630E62683534B00AE6FFE /* MVProductEmptyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVProductEmptyView.swift; sourceTree = "<group>"; };
 		3FA19A38D145C54301B3CD85 /* Pods_MusicVideoPlus.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MusicVideoPlus.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		4112DCF02668C45B00A5AFD9 /* MusicVideoPlus.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MusicVideoPlus.entitlements; sourceTree = "<group>"; };
 		4112DD492668D6A600A5AFD9 /* MusicVideoPlus-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MusicVideoPlus-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -50,7 +67,6 @@
 		418532382665342200DCA2C1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		4185323D2665342200DCA2C1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		41CA6E5D266782EC00874B19 /* MVBaseController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVBaseController.swift; sourceTree = "<group>"; };
-		41CA6E652667887C00874B19 /* MVMineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMineController.swift; sourceTree = "<group>"; };
 		41CA6E68266788C000874B19 /* MVLoginController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVLoginController.swift; sourceTree = "<group>"; };
 		41CA6E6B266788F700874B19 /* MVPlayerConntroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVPlayerConntroller.swift; sourceTree = "<group>"; };
 		41CA6E6F2667953700874B19 /* MVSettingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVSettingController.swift; sourceTree = "<group>"; };
@@ -84,11 +100,30 @@
 			isa = PBXGroup;
 			children = (
 				2D1EC137266B4F4900CBACE4 /* MVThirdApiUtil.swift */,
+				2D9630D82681947300AE6FFE /* MVRequestURLUtil.swift */,
 			);
 			name = Utils;
 			path = Modules/Utils;
 			sourceTree = "<group>";
 		};
+		2D9630DA2681C8AB00AE6FFE /* ViewModel */ = {
+			isa = PBXGroup;
+			children = (
+				2D9630DB2681C8AB00AE6FFE /* MVMineViewModel.swift */,
+			);
+			path = ViewModel;
+			sourceTree = "<group>";
+		};
+		2D9630DF2682080100AE6FFE /* Views */ = {
+			isa = PBXGroup;
+			children = (
+				2D9630E226820B1900AE6FFE /* MVMineProductCell.swift */,
+				2D9630E42682D14500AE6FFE /* MVMineHeadInfoView.swift */,
+				2D9630E62683534B00AE6FFE /* MVProductEmptyView.swift */,
+			);
+			path = Views;
+			sourceTree = "<group>";
+		};
 		4112DD812669BF8900A5AFD9 /* Banner */ = {
 			isa = PBXGroup;
 			children = (
@@ -210,6 +245,7 @@
 				4112DD812669BF8900A5AFD9 /* Banner */,
 				4112DD902669C11C00A5AFD9 /* MVBannerCell.swift */,
 				4149C8922669FE6F0055CAA2 /* MVTagsCell.swift */,
+				2D9630D42681874D00AE6FFE /* MVPlayControlViewCell.swift */,
 			);
 			path = Views;
 			sourceTree = "<group>";
@@ -217,21 +253,14 @@
 		41CA6E43266782C900874B19 /* Mine */ = {
 			isa = PBXGroup;
 			children = (
-				41CA6E44266782C900874B19 /* ViewModels */,
-				41CA6E45266782C900874B19 /* Models */,
+				2D9630DF2682080100AE6FFE /* Views */,
 				41CA6E46266782C900874B19 /* Controllers */,
-				41CA6E47266782C900874B19 /* Views */,
+				2D9630DA2681C8AB00AE6FFE /* ViewModel */,
+				41CA6E45266782C900874B19 /* Models */,
 			);
 			path = Mine;
 			sourceTree = "<group>";
 		};
-		41CA6E44266782C900874B19 /* ViewModels */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = ViewModels;
-			sourceTree = "<group>";
-		};
 		41CA6E45266782C900874B19 /* Models */ = {
 			isa = PBXGroup;
 			children = (
@@ -242,18 +271,13 @@
 		41CA6E46266782C900874B19 /* Controllers */ = {
 			isa = PBXGroup;
 			children = (
-				41CA6E652667887C00874B19 /* MVMineController.swift */,
+				2D9630E02682096900AE6FFE /* PQCollectionViewFlowlayout.swift */,
+				2D9630D2268186A500AE6FFE /* MVPlayViewController.swift */,
+				2D9630DD268206F300AE6FFE /* MVMineProductController.swift */,
 			);
 			path = Controllers;
 			sourceTree = "<group>";
 		};
-		41CA6E47266782C900874B19 /* Views */ = {
-			isa = PBXGroup;
-			children = (
-			);
-			path = Views;
-			sourceTree = "<group>";
-		};
 		41CA6E48266782C900874B19 /* Setting */ = {
 			isa = PBXGroup;
 			children = (
@@ -446,7 +470,9 @@
 				418532292665342100DCA2C1 /* Frameworks */,
 				4185322A2665342100DCA2C1 /* Resources */,
 				3115904EEDD5A7932018A62B /* [CP] Embed Pods Frameworks */,
+ 
 				F8C0D8A7D78D2E760511A0B1 /* [CP] Copy Pods Resources */,
+ 
 			);
 			buildRules = (
 			);
@@ -463,6 +489,7 @@
 		418532242665342100DCA2C1 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
+				CLASSPREFIX = MV;
 				LastSwiftUpdateCheck = 1230;
 				LastUpgradeCheck = 1230;
 				TargetAttributes = {
@@ -542,7 +569,9 @@
 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MusicVideoPlus/Pods-MusicVideoPlus-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
+ 
 		F8C0D8A7D78D2E760511A0B1 /* [CP] Copy Pods Resources */ = {
+ 
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
@@ -572,16 +601,24 @@
 				4112DD912669C11C00A5AFD9 /* MVBannerCell.swift in Sources */,
 				41CA6E6C266788F700874B19 /* MVPlayerConntroller.swift in Sources */,
 				41CA6E5E266782EC00874B19 /* MVBaseController.swift in Sources */,
+				2D9630D92681947300AE6FFE /* MVRequestURLUtil.swift in Sources */,
+				2D9630E326820B1900AE6FFE /* MVMineProductCell.swift in Sources */,
 				417D86A7266A3CC900DA2444 /* MVHotVideoModel.swift in Sources */,
+				2D9630E72683534B00AE6FFE /* MVProductEmptyView.swift in Sources */,
+				2D9630D52681874D00AE6FFE /* MVPlayControlViewCell.swift in Sources */,
+				2D9630DE268206F300AE6FFE /* MVMineProductController.swift in Sources */,
 				4149C8932669FE6F0055CAA2 /* MVTagsCell.swift in Sources */,
 				4112DD832669BFA600A5AFD9 /* MVBanner.swift in Sources */,
 				2D1EC138266B4F4900CBACE4 /* MVThirdApiUtil.swift in Sources */,
+				2D9630D3268186A500AE6FFE /* MVPlayViewController.swift in Sources */,
 				2D076756266DF8E300E64472 /* PQServerProtocalView.swift in Sources */,
 				4144BE31266F128E00ABBDFA /* PQBandingPhoneController.swift in Sources */,
 				41CA6E69266788C000874B19 /* MVLoginController.swift in Sources */,
-				41CA6E662667887C00874B19 /* MVMineController.swift in Sources */,
+				2D9630E52682D14500AE6FFE /* MVMineHeadInfoView.swift in Sources */,
+				2D9630DC2681C8AB00AE6FFE /* MVMineViewModel.swift in Sources */,
 				41CA6F4B26689F4400874B19 /* PQMineViewModel.swift in Sources */,
 				417D868C266A2E8400DA2444 /* MVHomeViewModel.swift in Sources */,
+				2D9630E12682096900AE6FFE /* PQCollectionViewFlowlayout.swift in Sources */,
 				41CA6F782668B80D00874B19 /* PQPhoneLoginController.swift in Sources */,
 				418532302665342100DCA2C1 /* AppDelegate.swift in Sources */,
 			);
@@ -724,7 +761,9 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 1.0.3;
+ 
+				MARKETING_VERSION = 1.1.0;
+ 
 				PRODUCT_BUNDLE_IDENTIFIER = com.piaoquan.shanyin;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "MusicVideoPlus/MusicVideoPlus-Bridging-Header.h";
@@ -751,7 +790,9 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 1.0.3;
+ 
+				MARKETING_VERSION = 1.1.0;
+ 
 				PRODUCT_BUNDLE_IDENTIFIER = com.piaoquan.shanyin;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "MusicVideoPlus/MusicVideoPlus-Bridging-Header.h";

+ 78 - 0
MusicVideoPlus.xcodeproj/xcshareddata/xcschemes/MusicVideoPlus.xcscheme

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1230"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "4185322B2665342100DCA2C1"
+               BuildableName = "MusicVideoPlus.app"
+               BlueprintName = "MusicVideoPlus"
+               ReferencedContainer = "container:MusicVideoPlus.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "4185322B2665342100DCA2C1"
+            BuildableName = "MusicVideoPlus.app"
+            BlueprintName = "MusicVideoPlus"
+            ReferencedContainer = "container:MusicVideoPlus.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "4185322B2665342100DCA2C1"
+            BuildableName = "MusicVideoPlus.app"
+            BlueprintName = "MusicVideoPlus"
+            ReferencedContainer = "container:MusicVideoPlus.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 22 - 0
MusicVideoPlus/Assets.xcassets/Home/empty_mine_product.imageset/Contents.json

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

二進制
MusicVideoPlus/Assets.xcassets/Home/empty_mine_product.imageset/empty_mine_product@2x.png


二進制
MusicVideoPlus/Assets.xcassets/Home/empty_mine_product.imageset/empty_mine_product@3x.png


+ 22 - 0
MusicVideoPlus/Assets.xcassets/Login/mi_upload_share_timeline.imageset/Contents.json

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

二進制
MusicVideoPlus/Assets.xcassets/Login/mi_upload_share_timeline.imageset/mi_upload_share_timeline@2x.png


二進制
MusicVideoPlus/Assets.xcassets/Login/mi_upload_share_timeline.imageset/mi_upload_share_timeline@3x.png


+ 6 - 0
MusicVideoPlus/Assets.xcassets/Mine/Contents.json

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

+ 22 - 0
MusicVideoPlus/Assets.xcassets/Mine/icon_video_point.imageset/Contents.json

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

二進制
MusicVideoPlus/Assets.xcassets/Mine/icon_video_point.imageset/icon_video_point@2x.png


二進制
MusicVideoPlus/Assets.xcassets/Mine/icon_video_point.imageset/icon_video_point@3x.png


+ 20 - 10
MusicVideoPlus/Classes/Modules/Home/Controllers/MVHomeController.swift

@@ -37,8 +37,10 @@ class MVHomeController: MVBaseController {
         let mineBtn = UIButton(type: .custom)
         mineBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
         mineBtn.setBackgroundImage(UIImage(named: "wode"), for: .normal)
+        mineBtn.setImage(UIImage(named: "wode"), for: .normal)
         mineBtn.adjustsImageWhenHighlighted = false
         mineBtn.tag = 1000
+        mineBtn.addCorner(corner: cDefaultMargin * 3)
         return mineBtn
     }()
 
@@ -202,7 +204,7 @@ class MVHomeController: MVBaseController {
         addNotification(self, selector: #selector(loginSuccesss), name: cBandingPhoneSuccessKey, object: nil)
         addNotification(self, selector: #selector(stuckPointDismiss), name: cFinishedPublishedNotiKey, object: nil)
 
-//        view.addSubview(mineBtn)
+        view.addSubview(mineBtn)
         view.addSubview(stuckPointBtn)
         view.addSubview(settingBtn)
         view.addSubview(viewListView)
@@ -281,12 +283,6 @@ class MVHomeController: MVBaseController {
     }
 
     func addLayout() {
-//        mineBtn.snp.remakeConstraints { make in
-//            make.width.equalTo(60)
-//            make.height.equalTo(60)
-//            make.left.equalToSuperview().offset(16)
-//            make.bottom.equalToSuperview().offset(-50)
-//        }
         categoryCollectionView.snp.remakeConstraints { make in
             make.width.equalTo(cScreenWidth)
             make.height.equalTo(45)
@@ -297,7 +293,13 @@ class MVHomeController: MVBaseController {
         stuckPointBtn.snp.remakeConstraints { make in
             make.width.height.equalTo(60)
             make.centerX.equalToSuperview()
-            make.bottom.equalToSuperview().offset(-(cDefaultMargin +  cAKSafeAreaHeight))
+            make.bottom.equalToSuperview().offset(-(cDefaultMargin + cAKSafeAreaHeight))
+        }
+
+        mineBtn.snp.remakeConstraints { make in
+            make.width.height.equalTo(60)
+            make.left.equalToSuperview().offset(cDefaultMargin * 3)
+            make.centerY.equalTo(stuckPointBtn)
         }
 
         settingBtn.snp.remakeConstraints { make in
@@ -316,8 +318,12 @@ class MVHomeController: MVBaseController {
     @objc func btnClick(sender: UIButton) {
         switch sender.tag {
         case 1000: // 个人中心
+            PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_clickButton_mineTab, pageSource: .sp_shanyinApp_main, extParams: nil, remindmsg: "")
+            
             jumpToDetailVc(type: 1)
         case 2000: // 系统相册
+            PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_clickButton_syncedUpMusic, pageSource: .sp_shanyinApp_main, extParams: nil, remindmsg: "")
+            
             jumpToDetailVc(type: 3)
         case 3000: // 设置
             navigationController?.pushViewController(MVSettingController(), animated: true)
@@ -383,9 +389,8 @@ class MVHomeController: MVBaseController {
         // 条件都满足转换到对就界面
         switch type {
         case 1:
-            navigationController?.pushViewController(MVMineController(), animated: true)
+            navigationController?.pushViewController(MVMineProductController(), animated: true)
         case 2:
-
             PQStuckPointViewModel.stuckPointProjectMusicInfo(projectId: videoData?.reCreateVideoData?.projectId ?? "") { [weak self] musicData, _ in
                 if musicData != nil {
                     let vc = PQStuckPointMaterialController()
@@ -412,6 +417,9 @@ class MVHomeController: MVBaseController {
         if mAllVideos.count > indexPath.row {
             isCreateVideo = true
             let videoListModel = mAllVideos[indexPath.row]
+            
+            PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_clickButton_syncedUpMusicRecreate, pageSource: .sp_shanyinApp_main, extParams: ["videoId":videoListModel.videoId], remindmsg: "")
+            
             jumpToDetailVc(type: 2, videoData: videoListModel)
         } else {
             BFLog(message: "数据出错越界!!! mAllVideos.count: \(mAllVideos.count) indexPath.row: \(indexPath.row)")
@@ -439,6 +447,7 @@ extension MVHomeController {
     /// 播放指定位置的视频
     /// - Parameter page: 视频数据位置
     func playVideo(page: Int) {
+ 
         DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.05) {
             if !(UIViewController.getCurrentViewController()?.isMember(of: MVHomeController.self))! {
                 BFLog(message: "当前显示的界面不是在首界面,不进行播放")
@@ -479,6 +488,7 @@ extension MVHomeController {
 
                 } else {
                     BFLog(message: "播放不成功: cell:\(String(describing: cell)) mVideos:\(self.mVideos.count) showProtocal: is \(String(describing: showProtocal))")
+ 
                 }
             }
         }

+ 0 - 1
MusicVideoPlus/Classes/Modules/Home/Views/MVBannerCell.swift

@@ -26,7 +26,6 @@ class MVBannerCell: UICollectionViewCell {
         let progressView = UIProgressView(progressViewStyle: .default)
         progressView.progressTintColor = .white
         return progressView
-
     }()
 
 //    lazy var backShadowView: UIView = {

+ 319 - 0
MusicVideoPlus/Classes/Modules/Home/Views/MVPlayControlViewCell.swift

@@ -0,0 +1,319 @@
+//
+//  MVPlayControlViewCell.swift
+//  MusicVideoPlus
+//
+//  Created by SanW on 2021/6/22.
+//
+
+import BFFramework
+import UIKit
+
+class MVPlayControlViewCell: UICollectionViewCell {
+    let musicWidth: CGFloat = cScreenWidth - 12 - (16 + cDefaultMargin) * 2 - (12 + cDefaultMargin * 7 + 12)
+    var btnClickHandle: ((_ sender: UIButton, _ videoData: PQVideoListModel?) -> Void)?
+    lazy var coverImageView: UIImageView = {
+        let coverImageView = UIImageView()
+        coverImageView.contentMode = .scaleAspectFill
+        coverImageView.isUserInteractionEnabled = true
+        coverImageView.tag = cCellTag
+        coverImageView.backgroundColor = UIColor.white
+        let ges = UITapGestureRecognizer(target: self, action: #selector(tagClick))
+        coverImageView.addGestureRecognizer(ges)
+        return coverImageView
+    }()
+
+    lazy var pauseBtn: UIButton = {
+        let pauseBtn = UIButton(type: .custom)
+        pauseBtn.setImage(UIImage(named: "video_pause"), for: .selected)
+        pauseBtn.setImage(nil, for: .normal)
+        pauseBtn.tag = 1
+        pauseBtn.isUserInteractionEnabled = false
+//        pauseBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
+        return pauseBtn
+    }()
+
+    lazy var watchCountLab: UILabel = {
+        let watchCountLab = UILabel()
+        watchCountLab.addShadow()
+        watchCountLab.textColor = UIColor.white
+        watchCountLab.font = UIFont.systemFont(ofSize: 11)
+        return watchCountLab
+    }()
+
+    lazy var nickNameBtn: UIButton = {
+        let nickNameBtn = UIButton(type: .custom)
+        nickNameBtn.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
+        nickNameBtn.setTitleColor(UIColor.white, for: .normal)
+        nickNameBtn.tag = 2
+        nickNameBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
+        return nickNameBtn
+    }()
+
+    lazy var musicContenView: UIView = {
+        let musicContenView = UIView()
+        return musicContenView
+    }()
+
+    lazy var musicImageView: UIImageView = {
+        let musicImageView = UIImageView(image: UIImage(named: "musicName_icon"))
+        musicImageView.showLoadingAnimation(duration: 3)
+        return musicImageView
+    }()
+
+    lazy var musicBgView: UIImageView = {
+        let musicBgView = UIImageView(image: UIImage(named: "musicName_bg"))
+        return musicBgView
+    }()
+
+    lazy var titleLabel: UILabel = {
+        let titleLabel = UILabel()
+        titleLabel.textAlignment = .left
+        titleLabel.textColor = .white
+        titleLabel.numberOfLines = 5
+        titleLabel.lineBreakMode = .byCharWrapping
+        titleLabel.font = UIFont.systemFont(ofSize: 16, weight: .bold)
+        return titleLabel
+    }()
+
+    /// 音乐歌曲名称
+    lazy var musicNameLab: LMJHorizontalScrollText = {
+        let musicNameLab = LMJHorizontalScrollText(frame: CGRect(x: 12 + cDefaultMargin, y: 0, width: musicWidth, height: 32))
+        musicNameLab.textColor = UIColor.white
+        musicNameLab.textFont = UIFont.systemFont(ofSize: 15, weight: .semibold)
+        musicNameLab.speed = 0.03
+        musicNameLab.moveDirection = LMJTextScrollMoveLeft
+        musicNameLab.moveMode = LMJTextScrollContinuous
+        musicNameLab.stop()
+        return musicNameLab
+    }()
+
+    lazy var reCreateBtn: UIButton = {
+        let reCreateBtn = UIButton(type: .custom)
+        reCreateBtn.setTitle(" 用此音乐做视频", for: .normal)
+        reCreateBtn.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
+        reCreateBtn.setTitleColor(UIColor.white, for: .normal)
+        reCreateBtn.addCorner(corner: 8)
+        reCreateBtn.setImage(UIImage(named: "reCreate"), for: .normal)
+        reCreateBtn.tag = 3
+        reCreateBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
+        reCreateBtn.backgroundColor = UIColor(red: 61.0 / 255.0, green: 193.0 / 255.0, blue: 193.0 / 255.0, alpha: 0.8)
+        return reCreateBtn
+    }()
+
+    lazy var wechatImage: UIButton = {
+        let wechatImage = UIButton(type: .custom)
+        wechatImage.setImage(UIImage(named: "mi_upload_share_friend"), for: .normal)
+        wechatImage.tag = 4
+        wechatImage.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
+        wechatImage.layer.shadowColor = UIColor(white: 0, alpha: 0.5).cgColor
+        wechatImage.layer.shadowOffset = CGSize(width: 2, height: 2)
+        return wechatImage
+    }()
+
+    lazy var wechatLab: UILabel = {
+        let wechatLab = UILabel()
+        wechatLab.textAlignment = .center
+        wechatLab.textColor = UIColor.white
+        wechatLab.font = UIFont.systemFont(ofSize: 13, weight: .medium)
+        wechatLab.text = "分享好友"
+        wechatLab.addShadow()
+        wechatLab.layer.shadowColor = UIColor(white: 0, alpha: 0.5).cgColor
+        wechatLab.layer.shadowOffset = CGSize(width: 2, height: 2)
+        return wechatLab
+    }()
+
+    lazy var wechatFriImage: UIButton = {
+        let wechatFriImage = UIButton(type: .custom)
+        wechatFriImage.setImage(UIImage(named: "mi_upload_share_timeline"), for: .normal)
+        wechatFriImage.tag = 5
+        wechatFriImage.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
+        wechatFriImage.layer.shadowColor = UIColor(white: 0, alpha: 0.5).cgColor
+        wechatFriImage.layer.shadowOffset = CGSize(width: 2, height: 2)
+        return wechatFriImage
+    }()
+
+    lazy var wechatFriLab: UILabel = {
+        let wechatFriLab = UILabel()
+        wechatFriLab.textAlignment = .center
+        wechatFriLab.textColor = UIColor.white
+        wechatFriLab.font = UIFont.systemFont(ofSize: 13, weight: .medium)
+        wechatFriLab.text = "分享朋友圈"
+        wechatFriLab.addShadow()
+        wechatFriLab.layer.shadowColor = UIColor(white: 0, alpha: 0.5).cgColor
+        wechatFriLab.layer.shadowOffset = CGSize(width: 2, height: 2)
+        return wechatFriLab
+    }()
+
+    lazy var progressView: UIProgressView = {
+        let progressView = UIProgressView(progressViewStyle: .default)
+        progressView.progressTintColor = .white
+        return progressView
+    }()
+
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        contentView.addSubview(coverImageView)
+        contentView.addSubview(pauseBtn)
+        contentView.addSubview(watchCountLab)
+        contentView.addSubview(nickNameBtn)
+        contentView.addSubview(titleLabel)
+        contentView.addSubview(musicContenView)
+        musicContenView.addSubview(musicBgView)
+        musicContenView.addSubview(musicImageView)
+        musicBgView.addSubview(musicNameLab)
+        contentView.addSubview(reCreateBtn)
+        contentView.addSubview(wechatImage)
+        contentView.addSubview(wechatLab)
+        contentView.addSubview(wechatFriImage)
+        contentView.addSubview(wechatFriLab)
+        contentView.addSubview(progressView)
+    }
+
+    required init?(coder _: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    @objc class func playControlCell(collectionView: UICollectionView, indexPath: IndexPath) -> MVPlayControlViewCell {
+        let cell: MVPlayControlViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: MVPlayControlViewCell.self), for: indexPath) as! MVPlayControlViewCell
+        return cell
+    }
+
+    override func prepareForReuse() {
+        super.prepareForReuse()
+        pauseBtn.isSelected = false
+        progressView.progress = 0
+    }
+
+    var videoData: PQVideoListModel? {
+        didSet {
+            addData()
+            addLayout()
+        }
+    }
+
+    func addData() {
+        pauseBtn.isSelected = false
+        progressView.progress = 0
+        let coverImg = (videoData?.videoCoverSnapshotPath != nil && (videoData?.videoCoverSnapshotPath?.count ?? 0) > 0) ? videoData?.videoCoverSnapshotPath ?? "" : videoData?.coverImg?["coverImgPath"] as! String
+        coverImageView.setNetImage(url: coverImg)
+        if videoData?.shareCountFriend != nil, videoData?.shareCountFriend ?? 0 > 0 {
+            wechatLab.text = (videoData?.shareCountFriend ?? 0).changeUnit()
+        } else {
+            wechatLab.text = "分享好友"
+        }
+        if videoData?.shareCount != nil, videoData?.shareCount ?? 0 > 0 {
+            wechatFriLab.text = (videoData?.shareCount ?? 0).changeUnit()
+        } else {
+            wechatFriLab.text = "分享朋友圈"
+        }
+        watchCountLab.text = "\(videoData?.playCountFormatStr ?? "0")次观看"
+        nickNameBtn.setTitle("@\(videoData?.userInfo?.nickName ?? "")", for: .normal)
+        titleLabel.text = videoData?.title ?? ""
+        let nameWidth: CGFloat = sizeWithText(text: "\(videoData?.reCreateVideoData?.rhythmMusicName ?? "")  ", font: UIFont.systemFont(ofSize: 15, weight: .semibold), size: CGSize(width: cScreenWidth, height: 32)).width
+        musicNameLab.stop()
+        if nameWidth > musicWidth {
+            musicNameLab.move()
+            musicNameLab.text = "\(videoData?.reCreateVideoData?.rhythmMusicName ?? "")  "
+        } else {
+            musicNameLab.stop()
+            musicNameLab.text = "\(videoData?.reCreateVideoData?.rhythmMusicName ?? "")                                                                    "
+        }
+    }
+
+    func updateProgress(progress: Float) {
+        progressView.setProgress(progress, animated: false)
+    }
+
+    func addLayout() {
+        let shareW: CGFloat = cDefaultMargin * 7
+        let margin: CGFloat = 12
+        let musicH: CGFloat = 32
+        coverImageView.snp.remakeConstraints { make in
+            make.size.equalToSuperview()
+        }
+
+        pauseBtn.snp.remakeConstraints { make in
+            make.width.height.equalTo(shareW)
+            make.centerX.equalToSuperview()
+            make.centerY.equalToSuperview().offset(-cDefaultMargin * 5)
+        }
+
+        reCreateBtn.snp.makeConstraints { make in
+            make.left.equalToSuperview().offset(margin)
+            make.right.equalToSuperview().offset(-margin)
+            make.height.equalTo(margin * 4)
+            make.bottom.equalToSuperview().offset(-(cSafeAreaHeight + margin * 4))
+        }
+
+        wechatFriLab.snp.remakeConstraints { make in
+            make.bottom.equalTo(reCreateBtn.snp_top).offset(-cDefaultMargin * 2)
+            make.right.equalTo(reCreateBtn)
+            make.width.equalTo(shareW)
+        }
+
+        wechatFriImage.snp.remakeConstraints { make in
+            make.bottom.equalTo(wechatFriLab.snp_top)
+            make.width.height.equalTo(shareW)
+            make.right.equalTo(wechatFriLab)
+        }
+
+        wechatLab.snp.remakeConstraints { make in
+            make.bottom.equalTo(wechatFriImage.snp_top).offset(-margin)
+            make.width.height.right.equalTo(wechatFriLab)
+        }
+        wechatImage.snp.remakeConstraints { make in
+            make.bottom.equalTo(wechatLab.snp_top)
+            make.width.height.equalTo(shareW)
+            make.right.equalTo(wechatFriLab)
+        }
+
+        musicContenView.snp.remakeConstraints { make in
+            make.height.equalTo(musicH)
+            make.right.equalTo(wechatFriLab.snp_left).offset(-margin)
+            make.left.equalTo(reCreateBtn)
+            make.bottom.equalTo(reCreateBtn.snp_top).offset(-cDefaultMargin * 2)
+        }
+
+        musicImageView.snp.makeConstraints { make in
+            make.top.left.equalToSuperview()
+            make.width.height.equalTo(musicContenView.snp_height)
+        }
+
+        musicBgView.snp.makeConstraints { make in
+            make.left.equalTo(musicImageView.snp_centerX)
+            make.right.top.height.equalToSuperview()
+        }
+
+        titleLabel.snp.remakeConstraints { make in
+            make.bottom.equalTo(musicContenView.snp_top).offset(-margin)
+            make.left.equalTo(reCreateBtn)
+            make.right.equalTo(musicContenView)
+        }
+
+        nickNameBtn.snp.remakeConstraints { make in
+            make.left.equalTo(reCreateBtn)
+            make.bottom.equalTo(titleLabel.snp_top).offset(-margin / 2)
+        }
+
+        watchCountLab.snp.remakeConstraints { make in
+            make.left.equalTo(reCreateBtn)
+            make.right.equalTo(musicContenView)
+            make.bottom.equalTo(nickNameBtn.snp_top).offset(-margin / 2)
+        }
+
+        progressView.snp.remakeConstraints { make in
+            make.left.right.bottom.equalToSuperview()
+        }
+    }
+
+    @objc func tagClick() {
+        pauseBtn.isSelected = !pauseBtn.isSelected
+        btnClick(sender: pauseBtn)
+    }
+
+    @objc func btnClick(sender: UIButton) {
+        if btnClickHandle != nil {
+            btnClickHandle!(sender, videoData)
+        }
+    }
+}

+ 0 - 22
MusicVideoPlus/Classes/Modules/Mine/Controllers/MVMineController.swift

@@ -1,22 +0,0 @@
-//
-//  MVMineController.swift
-//  MusicVideoPlus
-//
-//  Created by ak on 2021/6/2.
-//
-
-import Foundation
-
-class MVMineController: MVBaseController{
-
-    override func viewWillAppear(_: Bool) {
-        super.viewWillAppear(true)
-
-        showNavigation()
-        leftButton(image: "back_black")
- 
-    }
-    
-    
-
-}

+ 191 - 0
MusicVideoPlus/Classes/Modules/Mine/Controllers/MVMineProductController.swift

@@ -0,0 +1,191 @@
+//
+//  MVMineProductController.swift
+//  MusicVideoPlus
+//
+//  Created by SanW on 2021/6/22.
+//
+
+import BFFramework
+import UIKit
+
+class MVMineProductController: PQBaseViewController {
+    var itemsList: [PQVideoListModel] = Array<PQVideoListModel>.init()
+    var pageNum: Int = 1
+    let margin: CGFloat = 14
+    let headH: CGFloat = cDefaultMargin * 9
+
+    lazy var headInfoView: MVMineHeadInfoView = {
+        let headInfoView = MVMineHeadInfoView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: headH), margin: 0)
+        return headInfoView
+    }()
+
+    lazy var flowLayout: PQCollectionViewFlowlayout = {
+        let flowLayout = PQCollectionViewFlowlayout()
+        flowLayout.columnCount = 2
+        flowLayout.sectionInset = .zero
+        flowLayout.minimumLineSpacing = cDefaultMargin / 2
+        flowLayout.minimumInteritemSpacing = cDefaultMargin / 2
+        flowLayout.headerH = headH
+        return flowLayout
+    }()
+
+    lazy var collectionView: UICollectionView = {
+        let width = (cScreenWidth - 30) / 2
+        let proCollectView = UICollectionView(frame: CGRect(x: margin, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth - margin * 2, height: view.frame.height - cDevice_iPhoneNavBarAndStatusBarHei - cSafeAreaHeight), collectionViewLayout: flowLayout)
+        proCollectView.register(MVMineProductCell.self, forCellWithReuseIdentifier: String(describing: MVMineProductCell.self))
+        proCollectView.showsVerticalScrollIndicator = false
+        proCollectView.delegate = self
+        proCollectView.dataSource = self
+        proCollectView.backgroundColor = UIColor.white
+        proCollectView.addRefreshView { [weak self] isRefresh in
+            self?.loadRequestData(isRefresh: isRefresh)
+        }
+        return proCollectView
+    }()
+
+    lazy var emptyView: MVProductEmptyView = {
+        let emptyView = MVProductEmptyView.init(frame: CGRect.init(x: 0, y: headH, width: collectionView.frame.width, height: collectionView.frame.height - headH))
+        emptyView.btnClickHandle = {[weak self] sender in
+            let vc = PQStuckPointMaterialController()
+            self?.navigationController?.pushViewController(vc, animated: true)
+        }
+        emptyView.isHidden = true
+        return emptyView
+    }()
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        view.addSubview(collectionView)
+        collectionView.addSubview(emptyView)
+        collectionView.addSubview(headInfoView)
+        leftBackButton()
+        loadRequestData()
+        setTitle(title: BFLoginUserInfo.shared.nickName, color: UIColor(white: 0, alpha: 0))
+        MVMineViewModel.userInfoData { [weak self] count, _ in
+            if count != nil {
+                BFLoginUserInfo.shared.videos = "\(count ?? 0)"
+                self?.headInfoView.updateProducts()
+            }
+        }
+        
+        PQEventTrackViewModel.baseReportUpload(businessType: .bt_pageView, objectType: .ot_shanyinApp_viewPage_mineTab, pageSource: .sp_shanyinApp_mine, extParams: nil, remindmsg: "")
+    }
+
+    /// 请求网络数据
+    /// - Parameter isRefresh: <#isRefresh description#>
+    /// - Returns: <#description#>
+    func loadRequestData(isRefresh: Bool = true) {
+        if isRefresh {
+            pageNum = 1
+        } else {
+            pageNum = pageNum + 1
+        }
+        MVMineViewModel.userVideoListData(pageNum: pageNum) { [weak self] videoList, _ in
+            if videoList != nil {
+                if (videoList?.count ?? 0) > 0 {
+                    if isRefresh {
+                        self?.itemsList = videoList!
+                    } else {
+                        self?.itemsList = self!.itemsList + videoList!
+                    }
+                    self?.flowLayout.findList = self?.itemsList as! [PQVideoListModel]
+                    self?.collectionView.reloadData()
+                    self?.emptyView.isHidden = true
+                } else {
+                    self?.emptyView.isHidden = false
+                }
+            } else {
+                cShowHUB(superView: nil, msg: "没有网络连接")
+                self?.pageNum = (self?.pageNum ?? 1) - 1
+            }
+            if isRefresh {
+                self?.collectionView.mj_header?.endRefreshing()
+                self?.collectionView.mj_footer?.resetNoMoreData()
+            } else {
+                self?.collectionView.mj_footer?.endRefreshing()
+            }
+            if (videoList?.count ?? 0) < 20 {
+                self?.collectionView.mj_footer?.endRefreshingWithNoMoreData()
+            }
+        }
+    }
+}
+
+extension MVMineProductController: UICollectionViewDelegate, UICollectionViewDataSource, UIScrollViewDelegate {
+    func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int {
+        return itemsList.count
+    }
+
+    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        let itemData = itemsList[indexPath.item]
+        let cell = MVMineProductCell.productCell(collectionView: collectionView, indexPath: indexPath)
+        cell.videoData = itemData
+        cell.btnClickHandle = { [weak self] sender, videoData in
+            self?.btnClickHandle(sender: sender, videoData: videoData)
+        }
+        return cell
+    }
+
+    func collectionView(_: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        if itemsList[indexPath.item].auditStatus != 5 || itemsList[indexPath.item].transcodeStatus != 3 {
+            return
+        }
+        let playVC = MVPlayViewController()
+        playVC.itemsList = itemsList
+        playVC.currentIndex = indexPath
+        playVC.pageNum = pageNum
+        navigationController?.pushViewController(playVC, animated: true)
+    }
+
+    func scrollViewDidScroll(_ scrollView: UIScrollView) {
+        BFLog(message: "scrollView.contentOffset.y = \(scrollView.contentOffset.y)")
+        if scrollView.contentOffset.y <= 0 {
+            navTitleLabel?.textColor = UIColor(white: 0, alpha: 0)
+        } else if scrollView.contentOffset.y >= headH {
+            navTitleLabel?.textColor = UIColor(white: 0, alpha: 1)
+        } else {
+            var alpha: CGFloat = (scrollView.contentOffset.y / headH)
+            if alpha < 0 {
+                alpha = 0
+            }
+            if alpha > 1 {
+                alpha = 1
+            }
+            navTitleLabel?.textColor = UIColor(white: 0, alpha: alpha)
+        }
+    }
+
+    /// 处理按钮点击事件
+    /// - Parameters:
+    ///   - sender: <#sender description#>
+    ///   - videoData: <#videoData description#>
+    func btnClickHandle(sender _: UIButton, videoData: PQVideoListModel?) {
+        let seleView = PQSelectedOprationView.showSelectedOprationView(itemList: ["删除视频"]) { sender in
+            if sender.tag == 1 {
+                PQBaseViewModel.deleteVideo(videoId: Int(videoData?.uniqueId ?? "0") ?? 0) { [weak self] isSuccess, videoId, _ in
+                    if isSuccess {
+                        self?.itemsList.removeAll(where: { tempVideo in
+                            tempVideo.uniqueId == "\(videoId)"
+                        })
+                        self?.flowLayout.findList = self?.itemsList as! [PQVideoListModel]
+                        self?.collectionView.reloadData()
+                        cShowHUB(superView: nil, msg: "删除成功")
+                        if (self?.itemsList.count ?? 0) <= 0 {
+                            self?.loadRequestData()
+                        }
+                    }
+                }
+            }
+        }
+        seleView.contentView.backgroundColor = UIColor.hexColor(hexadecimal: "#F2F2F2")
+        seleView.cancelBtn.backgroundColor = UIColor.white
+        seleView.cancelBtn.setTitleColor(UIColor.black, for: .normal)
+        seleView.cancelBtn.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
+        let firstBtn: UIButton? = seleView.contentView.subviews[1] as? UIButton
+        firstBtn?.backgroundColor = UIColor.white
+        firstBtn?.setTitleColor(UIColor.hexColor(hexadecimal: "#FF0000"), for: .normal)
+        firstBtn?.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
+        seleView.contentView.subviews[2].backgroundColor = UIColor.hexColor(hexadecimal: "#F2F2F2")
+    }
+
+    @objc func btnClick(sender _: UIButton) {}
+}

+ 211 - 0
MusicVideoPlus/Classes/Modules/Mine/Controllers/MVPlayViewController.swift

@@ -0,0 +1,211 @@
+//
+//  MVPlayViewController.swift
+//  MusicVideoPlus
+//
+//  Created by SanW on 2021/6/22.
+//
+
+import BFFramework
+import UIKit
+import WechatOpenSDK
+
+class MVPlayViewController: PQBaseViewController {
+    var itemsList: [PQVideoListModel] = Array<PQVideoListModel>.init()
+    var pageNum: Int = 1
+    var currentIndex: IndexPath?
+    lazy var leftBtn: UIButton = {
+        let leftBtn = UIButton(type: .custom)
+        leftBtn.frame = CGRect(x: 0, y: cDevice_iPhoneStatusBarHei, width: cDefaultMargin * 4, height: cDefaultMargin * 4)
+        leftBtn.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: -5, right: 0)
+        leftBtn.setImage(UIImage().BF_Image(named: "icon_detail_back"), for: .normal)
+        leftBtn.addTarget(self, action: #selector(backBtnClick), for: .touchUpInside)
+        return leftBtn
+    }()
+
+    lazy var collectionView: UICollectionView = {
+        let layout = UICollectionViewFlowLayout()
+        layout.minimumLineSpacing = 0
+        layout.sectionInset = UIEdgeInsets.zero
+        layout.minimumInteritemSpacing = 0
+        layout.itemSize = view.frame.size
+        let collectionView = UICollectionView(frame: view.frame, collectionViewLayout: layout)
+        collectionView.scrollsToTop = false
+        collectionView.isPagingEnabled = true
+        collectionView.showsVerticalScrollIndicator = false
+        collectionView.register(MVPlayControlViewCell.self, forCellWithReuseIdentifier: String(describing: MVPlayControlViewCell.self))
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        if #available(iOS 11.0, *) {
+            collectionView.contentInsetAdjustmentBehavior = .never
+        } else {
+            automaticallyAdjustsScrollViewInsets = false
+        }
+        collectionView.addRefreshView { [weak self] isRefresh in
+            self?.loadRequestData(isRefresh: isRefresh)
+        }
+        return collectionView
+    }()
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        view.addSubview(collectionView)
+        view.addSubview(leftBtn)
+        if itemsList.count <= 0 {
+            loadRequestData()
+        }
+        if currentIndex != nil, itemsList.count > (currentIndex?.item ?? 0) {
+            collectionView.contentOffset = CGPoint(x: 0, y: CGFloat(currentIndex?.item ?? 0) * view.frame.size.height)
+            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) { [weak self] in
+                self?.scrollViewDidEndDecelerating(self!.collectionView)
+            }
+        }
+
+        PQSingletoVideoPlayer.shared.playStatusBloc = { [weak self] status in
+            if status == .PQVIDEO_PLAY_STATUS_END {
+                if ((self?.currentIndex?.item ?? 0) + 1) < (self?.itemsList.count ?? 0) {
+                    //                self?.collectionView.scrollToItem(at: IndexPath(item: (self?.currentIndex?.item ?? 0) + 1, section: 0), at: .top, animated: false)
+                    self?.collectionView.contentOffset = CGPoint(x: 0, y: CGFloat((self?.currentIndex?.item ?? 0) + 1) * (self!.collectionView.frame.height))
+                    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) { [weak self] in
+                        self?.scrollViewDidEndDecelerating(self!.collectionView)
+                    }
+                } else {
+                    (self?.collectionView.visibleCell() as? MVPlayControlViewCell)?.tagClick()
+                }
+            }
+        }
+
+        PQSingletoVideoPlayer.shared.progressBloc = { [weak self] _, playProgress, duration in
+            (self?.collectionView.visibleCell() as? MVPlayControlViewCell)?.updateProgress(progress: playProgress / duration)
+        }
+    }
+
+    override func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
+        PQSingletoVideoPlayer.shared.resumePlayer()
+    }
+
+    override func viewDidDisappear(_ animated: Bool) {
+        super.viewDidDisappear(animated)
+        PQSingletoVideoPlayer.shared.pausePlayer()
+    }
+
+    /// 请求网络数据
+    /// - Parameter isRefresh: <#isRefresh description#>
+    /// - Returns: <#description#>
+    func loadRequestData(isRefresh: Bool = true) {
+        if isRefresh {
+            pageNum = 1
+        } else {
+            pageNum = pageNum + 1
+        }
+        MVMineViewModel.userVideoListData(pageNum: pageNum) { [weak self] videoList, _ in
+            if videoList != nil, (videoList?.count ?? 0) > 0 {
+                if isRefresh {
+                    self?.itemsList = videoList!
+                } else {
+                    self?.itemsList = self!.itemsList + videoList!
+                }
+                self?.collectionView.reloadData()
+                self?.scrollViewDidEndDecelerating(self!.collectionView)
+            } else {
+                self?.pageNum = (self?.pageNum ?? 1) - 1
+            }
+            self?.collectionView.mj_header?.endRefreshing()
+            self?.collectionView.mj_footer?.endRefreshing()
+        }
+    }
+}
+
+extension MVPlayViewController: UICollectionViewDelegate, UICollectionViewDataSource, UIScrollViewDelegate {
+    func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int {
+        return itemsList.count
+    }
+
+    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        let itemData = itemsList[indexPath.item]
+        let cell = MVPlayControlViewCell.playControlCell(collectionView: collectionView, indexPath: indexPath)
+        cell.videoData = itemData
+        cell.btnClickHandle = { [weak self] sender, videoData in
+            self?.btnClickHandle(sender: sender, videoData: videoData)
+        }
+        return cell
+    }
+
+    func collectionView(_: UICollectionView, didSelectItemAt _: IndexPath) {}
+
+    func scrollViewDidEndDecelerating(_: UIScrollView) {
+        if itemsList.count <= 0 {
+            PQSingletoVideoPlayer.shared.stopPlayer()
+            return
+        }
+        let cell: MVPlayControlViewCell? = collectionView.visibleCell() as? MVPlayControlViewCell
+        if cell == nil {
+            return
+        }
+        let indexPath = collectionView.indexPath(for: cell!)
+        if currentIndex != nil, currentIndex?.item == indexPath?.item {
+            PQSingletoVideoPlayer.shared.resumePlayer()
+            return
+        }
+        currentIndex = indexPath
+        var itemData = itemsList[indexPath?.item ?? 0]
+        itemData.playProgress = 0
+        PQSingletoVideoPlayer.shared.configPlyer(videoData: itemData, controllerView: cell!.coverImageView)
+        PQSingletoVideoPlayer.shared.resetPlayer()
+    }
+
+    /// 按钮点击处理
+    /// - Parameters:
+    ///   - sender: <#sender description#>
+    ///   - videoData: <#videoData description#>
+    /// - Returns: <#description#>
+    func btnClickHandle(sender: UIButton, videoData: PQVideoListModel?) {
+        switch sender.tag {
+        case 1: // 暂停/播放
+            if sender.isSelected {
+                PQSingletoVideoPlayer.shared.pausePlayer()
+            } else {
+                PQSingletoVideoPlayer.shared.resumePlayer()
+            }
+        case 2: // 昵称
+
+            break
+        case 3: // 做同款
+            let navVc: UINavigationController? = (UIApplication.shared.keyWindow?.rootViewController) as? UINavigationController
+            (navVc?.viewControllers.first as? MVHomeController)?.jumpToDetailVc(type: 2, videoData: videoData)
+        case 4: // 分享好友
+            if !PQSingletoWXApiUtil.shared.isInstallWX() {
+                cShowHUB(superView: nil, msg: "您还未安装微信客户端!")
+                return
+            }
+            cShowHUB(superView: nil, msg: nil)
+            let shareId = getUniqueId(desc: "\(videoData?.uniqueId ?? "")shareId")
+            PQBaseViewModel.wxFriendShareInfo(videoId: (videoData?.uniqueId)!) { [weak self] imagePath, title, shareWeappRawId, msg in
+                if msg != nil {
+                    cShowHUB(superView: nil, msg: "网络不佳哦")
+                    return
+                }
+                PQSingletoWXApiUtil.shared.share(type: 3, scene: Int32(WXSceneSession.rawValue), shareWeappRawId: shareWeappRawId, title: title, description: title, imageUrl: imagePath, path: videoData?.videoPath, videoId: (videoData?.uniqueId)!, pageSource: videoData?.pageSource ?? .sp_category, shareId: shareId).wxApiUtilHander = { _, _ in
+                }
+                cHiddenHUB(superView: nil)
+            }
+        case 5: // 分享朋友圈
+            if !PQSingletoWXApiUtil.shared.isInstallWX() {
+                cShowHUB(superView: nil, msg: "您还未安装微信客户端!")
+                return
+            }
+            let shareId = getUniqueId(desc: "\(videoData?.uniqueId ?? "")shareId")
+            PQBaseViewModel.h5ShareLinkInfo(videoId: videoData?.uniqueId ?? "", pageSource: videoData?.pageSource ?? .sp_category) { [weak self] path, _ in
+                cHiddenHUB(superView: nil)
+                if path != nil {
+                    PQSingletoWXApiUtil.shared.share(type: 1, scene: Int32(WXSceneTimeline.rawValue), title: BFLoginUserInfo.shared.isLogin() ? "\(BFLoginUserInfo.shared.nickName)made a music video for you" : "Music Video for U", description: "", imageUrl: videoData?.shareImgPath, path: path, videoId: (videoData?.uniqueId)!, pageSource: videoData?.pageSource ?? .sp_category, shareId: shareId).wxApiUtilHander = { _, _ in
+                    }
+                } else {
+                    cShowHUB(superView: nil, msg: "网络不佳哦")
+                }
+            }
+        default:
+            break
+        }
+    }
+}

+ 106 - 0
MusicVideoPlus/Classes/Modules/Mine/Controllers/PQCollectionViewFlowlayout.swift

@@ -0,0 +1,106 @@
+//
+//  PQCollectionViewFlowlayout.swift
+//  PQSpeed
+//
+//  Created by SanW on 2020/5/26.
+//  Copyright © 2020 BytesFlow. All rights reserved.
+//
+
+import BFFramework
+import Photos
+import UIKit
+
+class PQCollectionViewFlowlayout: UICollectionViewFlowLayout {
+    // 总列数
+    var columnCount: Int = 0
+    // 数据数组
+    var findList = [Any]()
+    // 整个高度
+    private var maxH: Int?
+    // 头部高度
+    var headerH: CGFloat = 100
+    // 所有item的属性
+    fileprivate var layoutAttributesArray = [UICollectionViewLayoutAttributes]()
+
+    override func prepare() {
+        let contentWidth: CGFloat = (collectionView?.bounds.size.width)! - sectionInset.left - sectionInset.right
+        let marginX = minimumInteritemSpacing
+        let itemWidth = (contentWidth - marginX * CGFloat(columnCount - 1)) / CGFloat(columnCount)
+        computeAttributesWithItemWidth(CGFloat(itemWidth))
+    }
+
+    /// 根据itemWidth计算布局属性
+    func computeAttributesWithItemWidth(_ itemWidth: CGFloat) {
+        // 定义一个列高数组 记录每一列的总高度
+        var columnHeight = [Int](repeating: Int(sectionInset.top + headerH), count: columnCount)
+        // 定义一个记录每一列的总item个数的数组
+        var columnItemCount = [Int](repeating: 0, count: columnCount)
+        var attributesArray = [UICollectionViewLayoutAttributes]()
+
+        // 添加头部属性
+        let headerAttr: UICollectionViewLayoutAttributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, with: IndexPath(item: 0, section: 0))
+        headerAttr.frame = CGRect(x: 0, y: CGFloat(0), width: collectionView!.bounds.size.width, height: headerH)
+        attributesArray.append(headerAttr)
+        // 给属性数组设置数值
+        // self.layoutAttributesArray = attributesArray
+
+        // 遍历数据计算每个item的属性并布局
+        var index = 0
+        for data in findList {
+            var itemHeight: CGFloat = 0
+            if data is PQVideoListModel {
+                itemHeight = (data as! PQVideoListModel).itemHeight
+            } else if data is PQEditVisionTrackMaterialsModel {
+                itemHeight = CGFloat((data as! PQEditVisionTrackMaterialsModel).itemHeight)
+            } else {
+                itemHeight = 0
+            }
+            let indexPath = IndexPath(item: index, section: 0)
+            let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
+            // 找出最短列号
+            let minHeight: Int = columnHeight.sorted().first!
+            let column = columnHeight.firstIndex(of: minHeight)
+            // 数据追加在最短列
+            columnItemCount[column!] += 1
+            let itemX = (itemWidth + minimumInteritemSpacing) * CGFloat(column!) + sectionInset.left
+            let itemY = minHeight
+            // 等比例缩放 计算item的高度
+            let itemH = itemHeight.isNaN ? 0 : Int(itemHeight)
+            // 设置frame
+            attributes.frame = CGRect(x: itemX, y: CGFloat(itemY), width: itemWidth, height: CGFloat(itemH))
+
+            attributesArray.append(attributes)
+            // 累加列高
+            columnHeight[column!] += itemH + Int(minimumLineSpacing)
+            index += 1
+        }
+
+        // 找出最高列列号
+        let maxHeight: Int = columnHeight.sorted().last!
+        let column = columnHeight.index(of: maxHeight)
+        // 根据最高列设置itemSize 使用总高度的平均值
+        var itemH = 0
+
+        if findList.count > 0 {
+            itemH = (maxHeight - Int(minimumLineSpacing) * (columnItemCount[column!] + 1)) / columnItemCount[column!]
+        }
+        itemSize = CGSize(width: itemWidth, height: CGFloat(itemH))
+        // 给属性数组设置数值
+        layoutAttributesArray = attributesArray
+        maxH = maxHeight + 30
+    }
+
+    override func layoutAttributesForElements(in _: CGRect) -> [UICollectionViewLayoutAttributes]? {
+        return layoutAttributesArray
+    }
+
+    /// 重写设置contentSize
+    override var collectionViewContentSize: CGSize {
+        get {
+            return CGSize(width: (collectionView?.bounds.width)!, height: CGFloat(maxH!))
+        }
+        set {
+            self.collectionViewContentSize = newValue
+        }
+    }
+}

+ 52 - 0
MusicVideoPlus/Classes/Modules/Mine/ViewModel/MVMineViewModel.swift

@@ -0,0 +1,52 @@
+//
+//  MVMineViewModel.swift
+//  MusicVideoPlus
+//
+//  Created by SanW on 2021/6/22.
+//
+
+import BFFramework
+import UIKit
+
+class MVMineViewModel: NSObject {
+    /// 分页获取我的视频
+    /// - Parameters:
+    ///   - pageNum: 第几页
+    ///   - pageSize: 一页多少
+    ///   - completeHander: <#completeHander description#>
+    class func userVideoListData(pageNum: Int = 1, pageSize: Int = 20, completeHander: @escaping (_ videoLists: [PQVideoListModel]?, _ msg: String?) -> Void) {
+        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + userVideoListUrl, parames: ["pageNum": pageNum, "pageSize": pageSize]) { response, _, error, _ in
+            if response is NSNull || response == nil {
+                completeHander(nil, error?.msg)
+            } else {
+                let temResponseArr: [[String: Any]]? = response as? [[String: Any]]
+                if temResponseArr != nil {
+                    var videoLists = Array<PQVideoListModel>.init()
+                    temResponseArr?.forEach { dic in
+                        let tempModel = PQVideoListModel(jsonDict: dic)
+                        let userInfo = PQUserInfoModel()
+                        userInfo.nickName = BFLoginUserInfo.shared.nickName
+                        tempModel.userInfo = userInfo
+                        videoLists.append(tempModel)
+                    }
+                    completeHander(videoLists, error?.msg)
+                } else {
+                    completeHander(nil, error?.msg)
+                }
+            }
+        }
+    }
+
+    /// 获取用户信息
+    /// - Parameter completeHander: <#completeHander description#>
+    class func userInfoData(completeHander: @escaping (_ videoCount: Int?, _ msg: String?) -> Void) {
+        SWNetRequest.postRequestData(url: PQENVUtil.shared.clipapiapi + userInfoUrl, parames: nil) { response, _, error, _ in
+            if response is NSNull || response == nil {
+                completeHander(nil, error?.msg)
+            } else {
+                let videoCount: Int? = Int("\((response as? [String: Any])?["videoCount"] ?? "0")")
+                completeHander(videoCount, error?.msg)
+            }
+        }
+    }
+}

+ 86 - 0
MusicVideoPlus/Classes/Modules/Mine/Views/MVMineHeadInfoView.swift

@@ -0,0 +1,86 @@
+//
+//  MVMineHeadInfoView.swift
+//  MusicVideoPlus
+//
+//  Created by SanW on 2021/6/23.
+//
+
+import BFFramework
+import UIKit
+
+class MVMineHeadInfoView: UIView {
+    private var leftMargin: CGFloat = 0
+    lazy var iconImageView: UIImageView = {
+        let iconImageView = UIImageView()
+        iconImageView.contentMode = .scaleAspectFill
+        iconImageView.clipsToBounds = true
+        iconImageView.backgroundColor = UIColor.white
+        return iconImageView
+    }()
+
+    lazy var nickNameLab: UILabel = {
+        let nickNameLab = UILabel()
+        nickNameLab.textColor = .black
+        nickNameLab.numberOfLines = 1
+        nickNameLab.lineBreakMode = .byCharWrapping
+        nickNameLab.font = UIFont.systemFont(ofSize: 24, weight: .bold)
+        return nickNameLab
+    }()
+
+    lazy var productsLabel: UILabel = {
+        let productsLabel = UILabel()
+        productsLabel.textColor = UIColor(white: 0, alpha: 0.5)
+        productsLabel.numberOfLines = 1
+        productsLabel.lineBreakMode = .byCharWrapping
+        productsLabel.font = UIFont.systemFont(ofSize: 14, weight: .semibold)
+        return productsLabel
+    }()
+
+    init(frame: CGRect, margin: CGFloat = 16) {
+        super.init(frame: frame)
+        leftMargin = margin
+        addSubview(iconImageView)
+        addSubview(nickNameLab)
+        addSubview(productsLabel)
+    }
+
+    required init?(coder _: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    override func layoutSubviews() {
+        super.layoutSubviews()
+        addData()
+        addLayout()
+    }
+
+    func addData() {
+        iconImageView.setNetImage(url: BFLoginUserInfo.shared.avatarUrl, placeholder: UIImage(named: "wode")!)
+        nickNameLab.text = BFLoginUserInfo.shared.nickName
+        updateProducts()
+    }
+
+    func updateProducts() -> Void {
+        productsLabel.text = "\(Int(BFLoginUserInfo.shared.videos)?.changeUnit() ?? "0") 作品"
+    }
+    
+    func addLayout() {
+        let iconH: CGFloat = cDefaultMargin * 7
+        let margin: CGFloat = 12
+        iconImageView.addCorner(corner: iconH / 2)
+        iconImageView.snp.makeConstraints { make in
+            make.width.height.equalTo(iconH)
+            make.top.equalToSuperview().offset(cDefaultMargin / 2)
+            make.left.equalToSuperview().offset(leftMargin)
+        }
+        nickNameLab.snp.makeConstraints { make in
+            make.left.equalTo(iconImageView.snp_right).offset(margin)
+            make.right.equalToSuperview().offset(-leftMargin)
+            make.centerY.equalTo(iconImageView).offset(-margin)
+        }
+        productsLabel.snp.makeConstraints { make in
+            make.left.right.equalTo(nickNameLab)
+            make.centerY.equalTo(iconImageView).offset(margin)
+        }
+    }
+}

+ 111 - 0
MusicVideoPlus/Classes/Modules/Mine/Views/MVMineProductCell.swift

@@ -0,0 +1,111 @@
+//
+//  MVMineProductCell.swift
+//  MusicVideoPlus
+//
+//  Created by SanW on 2021/6/22.
+//
+
+import BFFramework
+import UIKit
+
+class MVMineProductCell: UICollectionViewCell {
+    var btnClickHandle: ((_ sender: UIButton, _ videoData: PQVideoListModel?) -> Void)?
+
+    lazy var coverImageView: UIImageView = {
+        let coverImageView = UIImageView()
+//        coverImageView.contentMode = .scaleAspectFill
+//        coverImageView.clipsToBounds = true
+        coverImageView.isUserInteractionEnabled = false
+//        coverImageView.tag = cCellTag
+        coverImageView.backgroundColor = UIColor.white
+        coverImageView.addCorner(corner: 6)
+        return coverImageView
+    }()
+
+    lazy var marksView: UIImageView = {
+        let marksView = UIImageView(image: UIImage(named: "home_marks"))
+//        marksView.contentMode = .scaleAspectFill
+//        marksView.clipsToBounds = true
+        marksView.isUserInteractionEnabled = false
+        return marksView
+    }()
+
+    lazy var moreBtn: UIButton = {
+        let moreBtn = UIButton(type: .custom)
+        let image: UIImage = UIImage(named: "icon_video_point")!
+        moreBtn.setImage(UIImage(cgImage: image.cgImage!, scale: image.scale, orientation: .left), for: .normal)
+        moreBtn.tag = 1
+        moreBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
+        return moreBtn
+    }()
+
+    lazy var titleLabel: UILabel = {
+        let titleLabel = UILabel()
+        titleLabel.textAlignment = .left
+        titleLabel.textColor = .white
+        titleLabel.numberOfLines = 1
+        titleLabel.lineBreakMode = .byCharWrapping
+        titleLabel.font = UIFont.systemFont(ofSize: 16, weight: .bold)
+        return titleLabel
+    }()
+
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        contentView.addSubview(coverImageView)
+        coverImageView.addSubview(marksView)
+        contentView.addSubview(moreBtn)
+        contentView.addSubview(titleLabel)
+    }
+
+    required init?(coder _: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    @objc class func productCell(collectionView: UICollectionView, indexPath: IndexPath) -> MVMineProductCell {
+        let cell: MVMineProductCell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: MVMineProductCell.self), for: indexPath) as! MVMineProductCell
+        return cell
+    }
+
+    var videoData: PQVideoListModel? {
+        didSet {
+            addData()
+            addLayout()
+        }
+    }
+
+    func addData() {
+        let coverImg = (videoData?.videoCoverSnapshotPath != nil && (videoData?.videoCoverSnapshotPath?.count ?? 0) > 0) ? videoData?.videoCoverSnapshotPath ?? "" : videoData?.coverImg?["coverImgPath"] as! String
+        coverImageView.setNetImage(url: coverImg)
+        titleLabel.text = videoData?.title ?? ""
+    }
+
+    func addLayout() {
+        let margin: CGFloat = 12
+        let moreH: CGFloat = 40
+
+        coverImageView.snp.remakeConstraints { make in
+            make.size.equalToSuperview()
+        }
+
+        marksView.snp.remakeConstraints { make in
+            make.width.left.bottom.equalToSuperview()
+        }
+
+        moreBtn.snp.remakeConstraints { make in
+            make.width.height.equalTo(moreH)
+            make.bottom.right.equalToSuperview()
+        }
+
+        titleLabel.snp.remakeConstraints { make in
+            make.centerY.equalTo(moreBtn)
+            make.left.equalToSuperview().offset(margin)
+            make.right.equalTo(moreBtn.snp_left)
+        }
+    }
+
+    @objc func btnClick(sender: UIButton) {
+        if btnClickHandle != nil {
+            btnClickHandle!(sender, videoData)
+        }
+    }
+}

+ 78 - 0
MusicVideoPlus/Classes/Modules/Mine/Views/MVProductEmptyView.swift

@@ -0,0 +1,78 @@
+//
+//  MVProductEmptyView.swift
+//  MusicVideoPlus
+//
+//  Created by SanW on 2021/6/23.
+//
+
+import BFFramework
+import UIKit
+
+class MVProductEmptyView: UIView {
+    var btnClickHandle: ((_ sender: UIButton) -> Void)?
+    lazy var reCreateBtn: UIButton = {
+        let reCreateBtn = UIButton(type: .custom)
+        reCreateBtn.setTitle("制作卡点视频", for: .normal)
+        reCreateBtn.titleLabel?.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
+        reCreateBtn.setTitleColor(UIColor.white, for: .normal)
+        reCreateBtn.addCorner(corner: 8)
+        reCreateBtn.tag = 1
+        reCreateBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
+        reCreateBtn.backgroundColor = UIColor(red: 61.0 / 255.0, green: 193.0 / 255.0, blue: 193.0 / 255.0, alpha: 0.8)
+        return reCreateBtn
+    }()
+
+    let emptyImageView: UIImageView = {
+        let emptyImageView = UIImageView(image: UIImage(named: "empty_mine_product"))
+        return emptyImageView
+    }()
+
+    lazy var titleLabel: UILabel = {
+        let titleLabel = UILabel()
+        titleLabel.textColor = UIColor.hexColor(hexadecimal: "#E0E0E0")
+        titleLabel.text = "暂无作品"
+        titleLabel.numberOfLines = 1
+        titleLabel.textAlignment = .center
+        titleLabel.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
+        return titleLabel
+    }()
+
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        addSubview(emptyImageView)
+        addSubview(titleLabel)
+        addSubview(reCreateBtn)
+    }
+
+    required init?(coder _: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    override func layoutSubviews() {
+        super.layoutSubviews()
+        let margin: CGFloat = cDefaultMargin * 2
+        let btnH: CGFloat = cDefaultMargin * 5
+        reCreateBtn.snp.makeConstraints { make in
+            make.left.equalToSuperview().offset(margin)
+            make.right.equalToSuperview().offset(-margin)
+            make.bottom.equalToSuperview().offset(-(btnH + cSafeAreaHeight))
+            make.height.equalTo(btnH)
+        }
+        emptyImageView.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.centerY.equalToSuperview().offset(-btnH * 2)
+            make.width.equalTo(margin * 5)
+            make.height.equalTo(margin * 3)
+        }
+        titleLabel.snp.makeConstraints { make in
+            make.left.right.equalToSuperview()
+            make.top.equalTo(emptyImageView.snp_bottom).offset(cDefaultMargin)
+        }
+    }
+
+    @objc func btnClick(sender: UIButton) {
+        if btnClickHandle != nil {
+            btnClickHandle!(sender)
+        }
+    }
+}

+ 13 - 0
MusicVideoPlus/Classes/Modules/Utils/MVRequestURLUtil.swift

@@ -0,0 +1,13 @@
+//
+//  MVRequestURLUtil.swift
+//  MusicVideoPlus
+//
+//  Created by SanW on 2021/6/22.
+//
+
+import UIKit
+
+/** 个人主页-用户视频列表 */
+public let userVideoListUrl = "rhythmapp/user/listUserVideos"
+/** 个人主页-用户信息 */
+public let userInfoUrl = "/rhythmapp/user/getMypageUserInfo"

+ 4 - 3
Podfile

@@ -4,9 +4,10 @@ target 'MusicVideoPlus' do
   # Comment the next line if you don't want to use dynamic frameworks
   use_frameworks!
   source 'https://github.com/CocoaPods/Specs.git'
-  pod "BFFramework" ,:git => 'https://git.yishihui.com/iOS/BFFramework.git'
-  
-#   pod "BFFramework" ,:git => 'https://git.yishihui.com/iOS/BFFramework.git'
+ 
+  #pod "BFFramework" ,:git => 'https://git.yishihui.com/iOS/BFFramework.git' , :tag => '0.1.1'
+   pod "BFFramework" ,:git => 'https://git.yishihui.com/iOS/BFFramework.git'
+ 
   # 使用本地路径
 #  pod 'BFFramework', :path => '/Users/ak/Desktop/BFFramework/'
   #pod 'BFFramework', :path => '/Users/sanw/Desktop/BytesFlow/Projects/BFFramework/'