Browse Source

扫一扫+引导

Steven 2 years ago
parent
commit
206829e4b6
51 changed files with 1183 additions and 90 deletions
  1. 80 0
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. BIN
      KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate
  3. 2 2
      KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  4. 2 0
      KulexiuForStudent/KulexiuForStudent/AppDelegate.h
  5. 24 9
      KulexiuForStudent/KulexiuForStudent/AppDelegate.m
  6. 6 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/Contents.json
  7. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage1.imageset/Contents.json
  8. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage1.imageset/guidePage1@2x.png
  9. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage1.imageset/guidePage1@3x.png
  10. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage2.imageset/Contents.json
  11. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage2.imageset/guidePage2@2x.png
  12. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage2.imageset/guidePage2@3x.png
  13. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage3.imageset/Contents.json
  14. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage3.imageset/guidePage3@2x.png
  15. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage3.imageset/guidePage3@3x.png
  16. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_scan.imageset/Contents.json
  17. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_scan.imageset/home_scan@2x.png
  18. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_scan.imageset/home_scan@3x.png
  19. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Mine/ScanView.imageset/Contents.json
  20. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Mine/ScanView.imageset/ScanView@2x.png
  21. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Mine/ScanView.imageset/ScanView@3x.png
  22. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Mine/mine_scan.imageset/Contents.json
  23. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Mine/mine_scan.imageset/mine_scan@2x.png
  24. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Mine/mine_scan.imageset/mine_scan@3x.png
  25. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Mine/scan_photo.imageset/Contents.json
  26. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Mine/scan_photo.imageset/scan_photo@2x.png
  27. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Mine/scan_photo.imageset/scan_photo@3x.png
  28. 3 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/BaseViewController.h
  29. 19 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/BaseViewController.m
  30. 1 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.m
  31. 2 0
      KulexiuForStudent/KulexiuForStudent/Common/Define/PrefixHeader.pch
  32. 39 12
      KulexiuForStudent/KulexiuForStudent/Module/Home/Controller/HomeViewController.m
  33. 1 1
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeIntroduceView.m
  34. 1 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.h
  35. 5 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.m
  36. 15 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.xib
  37. 18 0
      KulexiuForStudent/KulexiuForStudent/Module/Login/Guide/Controller/GuideViewController.h
  38. 162 0
      KulexiuForStudent/KulexiuForStudent/Module/Login/Guide/Controller/GuideViewController.m
  39. 24 0
      KulexiuForStudent/KulexiuForStudent/Module/Login/Guide/View/GuideListView.h
  40. 75 0
      KulexiuForStudent/KulexiuForStudent/Module/Login/Guide/View/GuideListView.m
  41. 95 0
      KulexiuForStudent/KulexiuForStudent/Module/Login/Guide/View/GuideListView.xib
  42. 41 2
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Controller/MineViewController.m
  43. 16 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/Controller/KSScanViewController.h
  44. 213 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/Controller/KSScanViewController.m
  45. 27 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/View/ScanNavView.h
  46. 47 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/View/ScanNavView.m
  47. 82 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/View/ScanNavView.xib
  48. 6 1
      KulexiuForStudent/KulexiuForStudent/Module/Mine/View/MineNavView.h
  49. 8 1
      KulexiuForStudent/KulexiuForStudent/Module/Mine/View/MineNavView.m
  50. 15 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/View/MineNavView.xib
  51. 0 62
      KulexiuForStudent/Pods/Pods.xcodeproj/xcuserdata/wangzhi.xcuserdatad/xcschemes/xcschememanagement.plist

+ 80 - 0
KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj

@@ -691,6 +691,12 @@
 		BCB9091728530E9C00F5FF69 /* KSShopCardView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB9091628530E9C00F5FF69 /* KSShopCardView.m */; };
 		BCB9091928530EA500F5FF69 /* KSShopCardView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCB9091828530EA500F5FF69 /* KSShopCardView.xib */; };
 		BCB9FA16286C7F6C005D766B /* KSShareGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB9FA15286C7F6C005D766B /* KSShareGroupViewController.m */; };
+		BCB9FA27286D799B005D766B /* KSScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB9FA25286D799A005D766B /* KSScanViewController.m */; };
+		BCB9FA2B286D79A4005D766B /* ScanNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB9FA28286D79A4005D766B /* ScanNavView.m */; };
+		BCB9FA2C286D79A4005D766B /* ScanNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCB9FA29286D79A4005D766B /* ScanNavView.xib */; };
+		BCB9FA2F286D7B02005D766B /* GuideViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB9FA2E286D7B02005D766B /* GuideViewController.m */; };
+		BCB9FA35286D7C2F005D766B /* GuideListView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB9FA34286D7C2F005D766B /* GuideListView.m */; };
+		BCB9FA37286D7C38005D766B /* GuideListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCB9FA36286D7C38005D766B /* GuideListView.xib */; };
 		BCBFDF3728110C660052AFE5 /* HomeNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCBFDF3628110C660052AFE5 /* HomeNavView.m */; };
 		BCBFDF3928110C6F0052AFE5 /* HomeNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCBFDF3828110C6F0052AFE5 /* HomeNavView.xib */; };
 		BCBFDF3C281156430052AFE5 /* HomeBannerView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCBFDF3B281156430052AFE5 /* HomeBannerView.m */; };
@@ -1994,6 +2000,16 @@
 		BCB9091828530EA500F5FF69 /* KSShopCardView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KSShopCardView.xib; sourceTree = "<group>"; };
 		BCB9FA14286C7F6C005D766B /* KSShareGroupViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSShareGroupViewController.h; sourceTree = "<group>"; };
 		BCB9FA15286C7F6C005D766B /* KSShareGroupViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSShareGroupViewController.m; sourceTree = "<group>"; };
+		BCB9FA25286D799A005D766B /* KSScanViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSScanViewController.m; sourceTree = "<group>"; };
+		BCB9FA26286D799B005D766B /* KSScanViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSScanViewController.h; sourceTree = "<group>"; };
+		BCB9FA28286D79A4005D766B /* ScanNavView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScanNavView.m; sourceTree = "<group>"; };
+		BCB9FA29286D79A4005D766B /* ScanNavView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ScanNavView.xib; sourceTree = "<group>"; };
+		BCB9FA2A286D79A4005D766B /* ScanNavView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScanNavView.h; sourceTree = "<group>"; };
+		BCB9FA2D286D7B02005D766B /* GuideViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GuideViewController.h; sourceTree = "<group>"; };
+		BCB9FA2E286D7B02005D766B /* GuideViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GuideViewController.m; sourceTree = "<group>"; };
+		BCB9FA33286D7C2F005D766B /* GuideListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GuideListView.h; sourceTree = "<group>"; };
+		BCB9FA34286D7C2F005D766B /* GuideListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GuideListView.m; sourceTree = "<group>"; };
+		BCB9FA36286D7C38005D766B /* GuideListView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GuideListView.xib; sourceTree = "<group>"; };
 		BCBFDF3528110C660052AFE5 /* HomeNavView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeNavView.h; sourceTree = "<group>"; };
 		BCBFDF3628110C660052AFE5 /* HomeNavView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeNavView.m; sourceTree = "<group>"; };
 		BCBFDF3828110C6F0052AFE5 /* HomeNavView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeNavView.xib; sourceTree = "<group>"; };
@@ -2613,6 +2629,7 @@
 		275FA20327E7356B00CFEA2E /* Mine */ = {
 			isa = PBXGroup;
 			children = (
+				BCB9FA22286D7989005D766B /* Scan */,
 				BC8C2C412823F57100FBA5D5 /* AddressList */,
 				BC119248280EDD4600A716F7 /* Homework */,
 				BC1191F9280ED63C00A716F7 /* MineCourse */,
@@ -2695,6 +2712,7 @@
 		275FA20F27E7356B00CFEA2E /* Login */ = {
 			isa = PBXGroup;
 			children = (
+				BCB9FA30286D7C17005D766B /* Guide */,
 				275FA21027E7356B00CFEA2E /* Controller */,
 				275FA21927E7356B00CFEA2E /* Model */,
 				275FA21E27E7356B00CFEA2E /* View */,
@@ -4966,6 +4984,62 @@
 			path = DragWindow;
 			sourceTree = "<group>";
 		};
+		BCB9FA22286D7989005D766B /* Scan */ = {
+			isa = PBXGroup;
+			children = (
+				BCB9FA23286D7989005D766B /* Controller */,
+				BCB9FA24286D7989005D766B /* View */,
+			);
+			path = Scan;
+			sourceTree = "<group>";
+		};
+		BCB9FA23286D7989005D766B /* Controller */ = {
+			isa = PBXGroup;
+			children = (
+				BCB9FA26286D799B005D766B /* KSScanViewController.h */,
+				BCB9FA25286D799A005D766B /* KSScanViewController.m */,
+			);
+			path = Controller;
+			sourceTree = "<group>";
+		};
+		BCB9FA24286D7989005D766B /* View */ = {
+			isa = PBXGroup;
+			children = (
+				BCB9FA2A286D79A4005D766B /* ScanNavView.h */,
+				BCB9FA28286D79A4005D766B /* ScanNavView.m */,
+				BCB9FA29286D79A4005D766B /* ScanNavView.xib */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
+		BCB9FA30286D7C17005D766B /* Guide */ = {
+			isa = PBXGroup;
+			children = (
+				BCB9FA31286D7C17005D766B /* Controller */,
+				BCB9FA32286D7C17005D766B /* View */,
+			);
+			path = Guide;
+			sourceTree = "<group>";
+		};
+		BCB9FA31286D7C17005D766B /* Controller */ = {
+			isa = PBXGroup;
+			children = (
+				BCB9FA2D286D7B02005D766B /* GuideViewController.h */,
+				BCB9FA2E286D7B02005D766B /* GuideViewController.m */,
+			);
+			path = Controller;
+			sourceTree = "<group>";
+		};
+		BCB9FA32286D7C17005D766B /* View */ = {
+			isa = PBXGroup;
+			children = (
+				BCB9FA33286D7C2F005D766B /* GuideListView.h */,
+				BCB9FA34286D7C2F005D766B /* GuideListView.m */,
+				BCB9FA36286D7C38005D766B /* GuideListView.xib */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -5168,6 +5242,7 @@
 				BCBFDF3928110C6F0052AFE5 /* HomeNavView.xib in Resources */,
 				BC8B6DFD2856E06700866917 /* UMCommonLog.bundle in Resources */,
 				27F9033C27E87FE100C08A19 /* MineBodyView.xib in Resources */,
+				BCB9FA2C286D79A4005D766B /* ScanNavView.xib in Resources */,
 				27F9032B27E87C2E00C08A19 /* NetworkBodyView.xib in Resources */,
 				2779358F27E324A80010E277 /* WMPlayer.bundle in Resources */,
 				BC11926C280FAF5900A716F7 /* AccompanyAlertView.xib in Resources */,
@@ -5195,6 +5270,7 @@
 				BC542E40284079E300633781 /* UserAuthBodyView.xib in Resources */,
 				BC542E5528409EC900633781 /* InstrumentHeaderView.xib in Resources */,
 				BC119215280ED6A900A716F7 /* MyLiveCourseCell.xib in Resources */,
+				BCB9FA37286D7C38005D766B /* GuideListView.xib in Resources */,
 				BC50171727FC0D8E00F8BCBC /* SubjectChooseBodyView.xib in Resources */,
 				BCB6359D27F6D2AB00ACFDCF /* tock.wav in Resources */,
 				BC8A45C1283DDD7100094BBB /* synthgms.sf2 in Resources */,
@@ -5567,6 +5643,7 @@
 				BC542E5D2840A60100633781 /* UserSettingViewController.m in Sources */,
 				BC119213280ED6A900A716F7 /* MyLessonBodyView.m in Sources */,
 				BC02381F28685D6D005560CA /* RCChatroomLikeCount.m in Sources */,
+				BCB9FA35286D7C2F005D766B /* GuideListView.m in Sources */,
 				BC8A45A3283DC33400094BBB /* JudgePageView.m in Sources */,
 				BCB6354227F6D2A300ACFDCF /* VideoListView.m in Sources */,
 				2779359A27E324A80010E277 /* TZPhotoPreviewController.m in Sources */,
@@ -5601,6 +5678,7 @@
 				BCB9FA16286C7F6C005D766B /* KSShareGroupViewController.m in Sources */,
 				BC0212F727FC4A080040569F /* SubjectImageCell.m in Sources */,
 				277935D027E324A90010E277 /* ALCalendarDate.m in Sources */,
+				BCB9FA2F286D7B02005D766B /* GuideViewController.m in Sources */,
 				BCFE540328152A8500AD6786 /* KSOrderManager.m in Sources */,
 				2723B64427F15B5900E0B90B /* SCIndexViewConfiguration.m in Sources */,
 				2779358527E324A80010E277 /* LLFileManager.m in Sources */,
@@ -5653,6 +5731,7 @@
 				2779359127E324A80010E277 /* FastForwardView.m in Sources */,
 				BC119222280ED6F500A716F7 /* LiveLessonModel.m in Sources */,
 				2723B63C27F159BA00E0B90B /* KSBaseTableViewController.m in Sources */,
+				BCB9FA2B286D79A4005D766B /* ScanNavView.m in Sources */,
 				BC27A079280FFA2200F91E27 /* EvaluateDetailModel.m in Sources */,
 				2779358B27E324A80010E277 /* KLTNavigationController.m in Sources */,
 				27F9033127E87C2E00C08A19 /* DeviceCheckView.m in Sources */,
@@ -5910,6 +5989,7 @@
 				2723B66627F15CFC00E0B90B /* AboutUsBodyView.m in Sources */,
 				277935BC27E324A90010E277 /* FSCalendarExtensions.m in Sources */,
 				2779356227E324A70010E277 /* KSRecordPowerAnimationView.m in Sources */,
+				BCB9FA27286D799B005D766B /* KSScanViewController.m in Sources */,
 				BCFE53FA28129A5600AD6786 /* TeacherStyleModel.m in Sources */,
 				2779355527E324A70010E277 /* DiskFreeSpaceManager.m in Sources */,
 				2779352E27E324A60010E277 /* NSDictionary+Extension.m in Sources */,

BIN
KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate


+ 2 - 2
KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -62,8 +62,8 @@
             filePath = "KulexiuForStudent/Common/Base/KSNetworkingManager.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "1022"
-            endingLineNumber = "1022"
+            startingLineNumber = "1023"
+            endingLineNumber = "1023"
             landmarkName = "+homeworkListRequest:date:submit:page:rows:success:faliure:"
             landmarkType = "7">
          </BreakpointContent>

+ 2 - 0
KulexiuForStudent/KulexiuForStudent/AppDelegate.h

@@ -28,5 +28,7 @@
 - (void)requestRongCloudToken;
 - (void)appTrackActionAuth;
 
+- (void)initLoginView;
+
 @end
 

+ 24 - 9
KulexiuForStudent/KulexiuForStudent/AppDelegate.m

@@ -31,6 +31,7 @@
 #import "RCConnectionManager.h"
 #import "KSRCIMDataSource.h"
 #import "WXApi.h"
+#import "GuideViewController.h"
 
 @interface RCNaviDataInfo : NSObject
 
@@ -104,19 +105,27 @@
     [self configJPUSHWithLaunchOptions:launchOptions];
     // 融云相关配置
     [self configIM];
-    
-    NSString *token = UserDefault(TokenKey);
-    if ([NSString isEmptyString:token]) { // 未登录
-        LoginViewController *logonVC = [[LoginViewController alloc] init];
-        CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:logonVC];
+    BOOL hasLaunchGuide = UserDefaultBoolForKey(FIRST_LOGIN_KEY);
+    if (hasLaunchGuide == NO) {
+        GuideViewController *guideVC = [[GuideViewController alloc] init];
+        CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:guideVC];
         self.window.rootViewController = navCtrl;
     }
     else {
-        [KSNetworkingManager configRequestHeader];
-        [USER_MANAGER queryUserInfoConnectRongCloud:YES];
-        [self initTableBar];
-        self.window.rootViewController=_tabBarController;
+        NSString *token = UserDefault(TokenKey);
+        if ([NSString isEmptyString:token]) { // 未登录
+            LoginViewController *logonVC = [[LoginViewController alloc] init];
+            CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:logonVC];
+            self.window.rootViewController = navCtrl;
+        }
+        else {
+            [KSNetworkingManager configRequestHeader];
+            [USER_MANAGER queryUserInfoConnectRongCloud:YES];
+            [self initTableBar];
+            self.window.rootViewController=_tabBarController;
+        }
     }
+    
     [self.window makeKeyAndVisible];
     
     if (@available(iOS 15.0, *)) {
@@ -614,6 +623,12 @@ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
     [[UITabBar appearance] setShadowImage:[[UIImage alloc] init]];
 }
 
+- (void)initLoginView {
+    LoginViewController *logonVC = [[LoginViewController alloc] init];
+    CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:logonVC];
+    self.window.rootViewController = navCtrl;
+}
+
 - (void)applicationWillResignActive:(UIApplication *)application {
     // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.

+ 6 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/Contents.json

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

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage1.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage1.imageset/guidePage1@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage1.imageset/guidePage1@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage2.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage2.imageset/guidePage2@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage2.imageset/guidePage2@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage3.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage3.imageset/guidePage3@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Guide/guidePage3.imageset/guidePage3@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_scan.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_scan.imageset/home_scan@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_scan.imageset/home_scan@3x.png


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

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

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


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


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

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

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


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


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

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

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


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


+ 3 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/BaseViewController.h

@@ -20,6 +20,9 @@ NS_ASSUME_NONNULL_BEGIN
 - (void)removehub;
 - (void)MBPShow:(NSString*)str;
 
+// 提示后续操作
+- (void)KSShowMsg:(NSString *)message promptCompletion:(void(^)(void))promptCompletion;
+
 @end
 
 

+ 19 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/BaseViewController.m

@@ -8,6 +8,8 @@
 #import "BaseViewController.h"
 #import "UIView+Hints.h"
 
+#define PROMPT_TIME  1.5f
+
 @interface BaseViewController ()
 {
     MBProgressHUD *t_MBProgressHUD;
@@ -91,6 +93,23 @@
     [hud hideAnimated:YES afterDelay:hiddenTime];
 }
 
+- (void)KSShowMsg:(NSString *)message promptCompletion:(void (^)(void))promptCompletion {
+    [MBProgressHUD hideHUD];
+    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:[UIApplication sharedApplication].keyWindow animated:YES];
+    hud.removeFromSuperViewOnHide = YES;
+    hud.mode = MBProgressHUDModeText;
+    hud.label.text = message;
+    hud.label.numberOfLines = 0;
+    hud.label.textColor = [UIColor whiteColor];
+    hud.minSize = CGSizeMake(132.0f, 40.0f);
+    hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
+    hud.bezelView.backgroundColor = HexRGBAlpha(0x000000, 0.8);
+    [hud hideAnimated:YES afterDelay:PROMPT_TIME];
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(PROMPT_TIME * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+        promptCompletion();
+    });
+}
+
 /*
 #pragma mark - Navigation
 

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

@@ -667,6 +667,7 @@
     NSMutableDictionary *parm = [NSMutableDictionary dictionary];
     [parm setValue:@"2" forKey:@"catalogIds"];
     [parm setValue:@"STUDENT" forKey:@"catalogType"];
+    [parm setValue:@(1) forKey:@"status"];
     [parm setValue:@(1) forKey:@"page"];
     [parm setValue:@(5) forKey:@"rows"];
     [self request:post andWithUrl:url and:parm success:success faliure:faliure];

+ 2 - 0
KulexiuForStudent/KulexiuForStudent/Common/Define/PrefixHeader.pch

@@ -36,6 +36,8 @@
 #import "UIView+SubViewExtension.h"
 #import "NSObject+KSDateFormatter.h"
 
+#define FIRST_LOGIN_KEY (@"FirstLoginKey")
+
 #define DEALCALLBACKNOTICIFATION (@"DEALCALLBACKNOTICIFATION")
 
 // 加密使用 NSString+MD5

+ 39 - 12
KulexiuForStudent/KulexiuForStudent/Module/Home/Controller/HomeViewController.m

@@ -160,7 +160,7 @@
         [self requestTrackAuth];
     }
     else {
-        [self requestUserInfo:NO];
+        [self requestUserInfo:YES];
     }
     
     [self requestUnreadCount];
@@ -219,6 +219,10 @@
 
 
 - (void)configUI {
+    UIView *headBgView = [[UIView alloc] init];
+    headBgView.backgroundColor = [UIColor whiteColor];
+    [self.scrollView addSubview:headBgView];
+    
     [self.scrollView addSubview:self.bannerView];
     // banner
     self.bannerViewHeight = [HomeBannerView getViewHeight];
@@ -229,10 +233,23 @@
         make.height.mas_equalTo(self.bannerViewHeight);
     }];
     
+    [self.scrollView addSubview:self.buttonContainer];
+
+    self.buttonViewHeight = [HomeButtonView getViewHeight];
+    [self.buttonContainer mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(self.view);
+        make.top.mas_equalTo(self.bannerView.mas_bottom);
+        make.height.mas_equalTo(self.buttonViewHeight);
+    }];
+
+    [headBgView mas_makeConstraints:^(MASConstraintMaker *make) {
+        
+    }];
+    
     [self.scrollView addSubview:self.noticeView];
     [self.noticeView mas_makeConstraints:^(MASConstraintMaker *make) {
         make.left.right.mas_equalTo(self.view);
-        make.top.mas_equalTo(self.bannerView.mas_bottom);
+        make.top.mas_equalTo(self.buttonContainer.mas_bottom);
         make.height.mas_equalTo(CGFLOAT_MIN);
     }];
     [self.noticeView.adView addSubview:self.noticeScrollView];
@@ -241,22 +258,13 @@
     }];
     self.noticeView.hidden = YES;
     
-    [self.scrollView addSubview:self.buttonContainer];
-
-    self.buttonViewHeight = [HomeButtonView getViewHeight];
-    [self.buttonContainer mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.left.right.mas_equalTo(self.view);
-        make.top.mas_equalTo(self.noticeView.mas_bottom);
-        make.height.mas_equalTo(self.buttonViewHeight);
-    }];
-
     // 课程提醒
     [self.scrollView addSubview:self.tipsCourseView];
     self.tipsViewHeight = CGFLOAT_MIN;
     self.tipsCourseView.hidden = YES;
     [self.tipsCourseView mas_makeConstraints:^(MASConstraintMaker *make) {
         make.left.right.mas_equalTo(self.view);
-        make.top.mas_equalTo(self.buttonContainer.mas_bottom);
+        make.top.mas_equalTo(self.noticeView.mas_bottom);
         make.height.mas_equalTo(self.tipsViewHeight);
     }];
     // 专辑
@@ -1290,6 +1298,18 @@
     return _bannerScroll;
 }
 
+- (TYPageControl *)pageControl {
+    if (!_pageControl) {
+        _pageControl = [[TYPageControl alloc] init];
+        _pageControl.frame = CGRectMake(0, (kScreenWidth - 28) * 132 / 347 - 15, kScreenWidth-28, 10);
+        _pageControl.currentPageIndicatorTintColor = HexRGB(0xffffff);
+        _pageControl.pageIndicatorTintColor = HexRGBAlpha(0xffffff, 0.5);
+        _pageControl.pageIndicatorSize = CGSizeMake(10, 3);
+        _pageControl.currentPageIndicatorSize = CGSizeMake(10, 3);
+    }
+    return _pageControl;
+}
+
 #pragma mark ---- 更多资讯
 - (HotInformationHeadView *)informationHeadView {
     if (!_informationHeadView) {
@@ -1345,6 +1365,9 @@
     if (action == NAVACTION_USERCENTER) {
         [self displayUserCenter];
     }
+    else if (action == NAVACTION_SCAN) { // 扫一扫
+        [self showScanView];
+    }
     else { // 消息中心
         
         NotiferMessageViewController *ctrl = [[NotiferMessageViewController alloc] init];
@@ -1352,6 +1375,10 @@
     }
 }
 
+- (void)showScanView {
+    
+}
+
 - (void)showInstrumentView:(BOOL)hideBackButton {
     InstrumentChooseViewController *ctrl = [[InstrumentChooseViewController alloc] init];
     MJWeakSelf;

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeIntroduceView.m

@@ -29,7 +29,7 @@
 - (CGFloat)getViewHeightWithSourceCount:(NSInteger)count {
     
     NSInteger row = count / 2 + count % 2;
-    return 56 + row * 164 + (row - 1) * 12;
+    return 56 + row * 132 + (row - 1) * 12;
     
 }
 - (IBAction)moreAction:(id)sender {

+ 1 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.h

@@ -10,6 +10,7 @@
 typedef NS_ENUM(NSInteger, NAVACTION) {
     NAVACTION_USERCENTER,  // 用户
     NAVACTION_MESSAGE,     // 消息
+    NAVACTION_SCAN,        // 扫一扫
 };
 
 typedef void(^HomeNavCallback)(NAVACTION action);

+ 5 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.m

@@ -35,6 +35,11 @@
         self.calback(NAVACTION_MESSAGE);
     }
 }
+- (IBAction)scanAction:(id)sender {
+    if (self.calback) {
+        self.calback(NAVACTION_SCAN);
+    }
+}
 
 /*
 // Only override drawRect: if you perform custom drawing.

+ 15 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.xib

@@ -86,17 +86,31 @@
                         <action selector="toUseCenter:" destination="iN0-l3-epB" eventType="touchUpInside" id="x9k-on-BOB"/>
                     </connections>
                 </button>
+                <button hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ixd-fe-NI5">
+                    <rect key="frame" x="314" y="46" width="40" height="40"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="40" id="Ttb-Ur-o54"/>
+                        <constraint firstAttribute="height" constant="40" id="qe5-dD-blQ"/>
+                    </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" image="home_scan"/>
+                    <connections>
+                        <action selector="scanAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="T5f-o0-Vvc"/>
+                    </connections>
+                </button>
             </subviews>
             <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <constraints>
                 <constraint firstItem="omR-9c-WQ1" firstAttribute="top" secondItem="xYy-Ue-YZl" secondAttribute="top" constant="8" id="3LP-Cf-UOB"/>
                 <constraint firstAttribute="bottom" secondItem="xYy-Ue-YZl" secondAttribute="bottom" constant="5" id="GLZ-UC-GBm"/>
                 <constraint firstItem="V09-v5-ugm" firstAttribute="leading" secondItem="q8T-4X-XH1" secondAttribute="trailing" constant="5" id="HMR-Zb-eYg"/>
+                <constraint firstItem="xYy-Ue-YZl" firstAttribute="leading" secondItem="Ixd-fe-NI5" secondAttribute="trailing" constant="5" id="L9X-fi-71j"/>
                 <constraint firstAttribute="trailing" secondItem="omR-9c-WQ1" secondAttribute="trailing" constant="21" id="MxY-he-eWw"/>
                 <constraint firstAttribute="trailing" secondItem="xYy-Ue-YZl" secondAttribute="trailing" constant="15" id="NQ0-wf-rrB"/>
                 <constraint firstItem="9Ch-4E-l3g" firstAttribute="centerY" secondItem="q8T-4X-XH1" secondAttribute="centerY" id="TWf-lZ-rE9"/>
                 <constraint firstItem="q8T-4X-XH1" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="WOM-ee-yRZ"/>
                 <constraint firstItem="V09-v5-ugm" firstAttribute="centerY" secondItem="q8T-4X-XH1" secondAttribute="centerY" id="jWy-Il-BUG"/>
+                <constraint firstItem="xYy-Ue-YZl" firstAttribute="centerY" secondItem="Ixd-fe-NI5" secondAttribute="centerY" id="mCC-Ct-2in"/>
                 <constraint firstItem="xYy-Ue-YZl" firstAttribute="centerY" secondItem="q8T-4X-XH1" secondAttribute="centerY" id="n1m-Dh-PuS"/>
                 <constraint firstItem="q8T-4X-XH1" firstAttribute="centerX" secondItem="9Ch-4E-l3g" secondAttribute="centerX" id="pFZ-KT-emk"/>
             </constraints>
@@ -113,6 +127,7 @@
     </objects>
     <resources>
         <image name="home_message" width="23" height="23"/>
+        <image name="home_scan" width="22" height="22"/>
         <image name="user_default_avatal" width="52" height="52"/>
     </resources>
 </document>

+ 18 - 0
KulexiuForStudent/KulexiuForStudent/Module/Login/Guide/Controller/GuideViewController.h

@@ -0,0 +1,18 @@
+//
+//  GuideViewController.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/6/30.
+//
+
+#import "BaseViewController.h"
+
+NS_ASSUME_NONNULL_BEGIN
+// 初次登录引导
+@interface GuideViewController : BaseViewController
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 162 - 0
KulexiuForStudent/KulexiuForStudent/Module/Login/Guide/Controller/GuideViewController.m

@@ -0,0 +1,162 @@
+//
+//  GuideViewController.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/6/30.
+//
+
+#import "GuideViewController.h"
+#import "GuideListView.h"
+#import "TYPageControl.h"
+#import "AppDelegate.h"
+#import "UserInfoManager.h"
+
+@interface GuideViewController ()<UIScrollViewDelegate,CAAnimationDelegate>
+
+@property (nonatomic, strong) UIScrollView *scrollView;
+
+@property (nonatomic, strong) NSMutableArray *imgArray;
+
+@property (nonatomic, strong) NSMutableArray *titleArray;
+
+@property (nonatomic, strong) NSMutableArray *descArray;
+
+@property (nonatomic, strong) TYPageControl *pageControl;
+
+@end
+
+@implementation GuideViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    self.ks_prefersNavigationBarHidden = YES;
+    [self defaultSource];
+    [self configUI];
+}
+
+- (void)defaultSource {
+    self.imgArray = [NSMutableArray arrayWithArray:@[@"guidePage1",@"guidePage2",@"guidePage3"]];
+    self.titleArray = [NSMutableArray arrayWithArray:@[@"在家轻松学音乐",@"云教练实时反馈",@"多维沟通"]];
+    self.descArray = [NSMutableArray arrayWithArray:@[@"海量优质课程,名师讲解精学",@"24小时随时练,海量曲谱任您挑选",@"师生即时互动,经验交流分享"]];
+    
+}
+
+- (void)configUI {
+    [self.view addSubview:self.scrollView];
+    [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.view);
+    }];
+    if (@available(iOS 11.0, *)) {
+        self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
+    } else {
+        // Fallback on earlier versions
+        self.automaticallyAdjustsScrollViewInsets = NO;
+    }
+    
+    [self createListView];
+    [self.view addSubview:self.pageControl];
+    self.pageControl.numberOfPages = self.imgArray.count;
+    
+}
+
+- (void)createListView {
+    for (NSInteger i = 0; i < self.imgArray.count; i++) {
+        GuideListView *listView = [GuideListView shareInstance];
+        BOOL showButton = NO;
+        if (i == self.imgArray.count - 1) {
+            showButton = YES;
+            [listView enterCallback:^{
+                [self animationAcion];
+            }];
+        }
+        [listView configViewWithImageName:self.imgArray[i] topTitle:self.titleArray[i] desc:self.descArray[i] showButton:showButton];
+        [self.scrollView addSubview:listView];
+        [listView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.top.bottom.mas_equalTo(self.view);
+            make.left.mas_equalTo(self.scrollView.mas_left).offset(KPortraitWidth * i);
+            make.width.mas_equalTo(KPortraitWidth);
+            if (showButton) {
+                make.right.mas_equalTo(self.scrollView.mas_right);
+            }
+        }];
+    }
+}
+
+- (void)toNextPage {
+    
+    UserDefaultSetBoolForKey(YES, FIRST_LOGIN_KEY);
+    NSString *token = UserDefault(TokenKey);
+    if ([NSString isEmptyString:token]) { // 未登录
+        [self toLoginView];
+    }
+    else {
+        [self toHomeView];
+    }
+}
+
+- (void)animationAcion {
+    
+    [UIView animateWithDuration:1.5f delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
+        self.view.layer.opacity = 0.0f;
+    } completion:^(BOOL finished) {
+        [self toNextPage];
+    }];
+    
+}
+
+- (void)toLoginView {
+    AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
+    [appDelegate initLoginView];
+}
+- (void)toHomeView {
+    [KSNetworkingManager configRequestHeader];
+    [USER_MANAGER queryUserInfoConnectRongCloud:YES];
+    AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
+    [appDelegate initTableBar];
+    UITabBarController *tabBarController = appDelegate.tabBarController;
+    [tabBarController setSelectedIndex:0];
+}
+
+#pragma mark --- scroll view delegate
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
+    NSInteger index = (NSInteger)(scrollView.contentOffset.x / kScreenWidth);
+    [self.pageControl setCurrentPage:index animate:YES];
+}
+
+#pragma mark --- lazying
+- (UIScrollView *)scrollView {
+    if (!_scrollView) {
+        _scrollView = [[UIScrollView alloc] init];
+        _scrollView.delegate = self;
+        _scrollView.pagingEnabled = YES;
+        _scrollView.bounces = NO;
+        _scrollView.backgroundColor = HexRGB(0xf6f8f9);
+        _scrollView.showsHorizontalScrollIndicator = NO;
+        _scrollView.showsVerticalScrollIndicator = NO;
+    }
+    return _scrollView;
+}
+
+- (TYPageControl *)pageControl {
+    if (!_pageControl) {
+        _pageControl = [[TYPageControl alloc] init];
+        _pageControl.frame = CGRectMake(0, KPortraitHeight - iPhoneXSafeBottomMargin - 60, KPortraitWidth, 10);
+        _pageControl.currentPageIndicatorTintColor = HexRGB(0x2DC7AA);
+        _pageControl.pageIndicatorTintColor = HexRGB(0xD8EDE3);
+        _pageControl.pageIndicatorSize = CGSizeMake(7, 7);
+        _pageControl.currentPageIndicatorSize = CGSizeMake(14, 7);
+    }
+    return _pageControl;
+}
+/*
+#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

+ 24 - 0
KulexiuForStudent/KulexiuForStudent/Module/Login/Guide/View/GuideListView.h

@@ -0,0 +1,24 @@
+//
+//  GuideListView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/6/30.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef void(^GuideSureCallback)(void);
+
+@interface GuideListView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)configViewWithImageName:(NSString *)imageName topTitle:(NSString *)topTitle desc:(NSString *)descMsg showButton:(BOOL)showButton;
+
+- (void)enterCallback:(GuideSureCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 75 - 0
KulexiuForStudent/KulexiuForStudent/Module/Login/Guide/View/GuideListView.m

@@ -0,0 +1,75 @@
+//
+//  GuideListView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/6/30.
+//
+
+#import "GuideListView.h"
+
+@interface GuideListView ()
+
+@property (weak, nonatomic) IBOutlet UIView *colorView;
+
+@property (weak, nonatomic) IBOutlet UIImageView *imageView;
+@property (weak, nonatomic) IBOutlet UILabel *headTitle;
+@property (weak, nonatomic) IBOutlet UILabel *descLabel;
+
+@property (weak, nonatomic) IBOutlet UIButton *enterButton;
+
+@property (nonatomic, copy) GuideSureCallback callback;
+
+@end
+
+@implementation GuideListView
+
+- (void)enterCallback:(GuideSureCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
++ (instancetype)shareInstance {
+    GuideListView *view = [[[NSBundle mainBundle] loadNibNamed:@"GuideListView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    CAGradientLayer * gradientLayer = [CAGradientLayer layer];
+    gradientLayer.colors = @[(__bridge id)HexRGBAlpha(0xCEFBE3, 1.0f).CGColor,(__bridge id)HexRGBAlpha(0xffffff, 0.0f).CGColor];
+    gradientLayer.startPoint = CGPointMake(0.5, 0);
+    gradientLayer.endPoint = CGPointMake(0.5, 1);
+    gradientLayer.locations = @[@(0),@(1)];
+    gradientLayer.frame = CGRectMake(0, 0, KPortraitWidth, 360);
+    [self.colorView.layer addSublayer:gradientLayer];
+}
+
+- (void)configViewWithImageName:(NSString *)imageName topTitle:(NSString *)topTitle desc:(NSString *)descMsg showButton:(BOOL)showButton {
+    [self.imageView setImage:[UIImage imageNamed:imageName]];
+    [self.headTitle setText:topTitle];
+    self.descLabel.text = descMsg;
+    if (showButton) {
+        self.enterButton.hidden = NO;
+        self.enterButton.userInteractionEnabled = YES;
+    }
+    else {
+        self.enterButton.hidden = YES;
+        self.enterButton.userInteractionEnabled = NO;
+    }
+}
+
+- (IBAction)enterAction:(id)sender {
+    if (self.callback) {
+        self.callback();
+    }
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 95 - 0
KulexiuForStudent/KulexiuForStudent/Module/Login/Guide/View/GuideListView.xib

@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="GuideListView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="V0F-XR-LOW">
+                    <rect key="frame" x="0.0" y="0.0" width="414" height="360"/>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="360" id="lht-Xt-v17"/>
+                    </constraints>
+                </view>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="yUN-KZ-L1M">
+                    <rect key="frame" x="14" y="174" width="386" height="366"/>
+                    <constraints>
+                        <constraint firstAttribute="width" secondItem="yUN-KZ-L1M" secondAttribute="height" multiplier="348:330" id="orE-1k-zHV"/>
+                    </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="5BZ-aV-ZqC">
+                    <rect key="frame" x="158.5" y="564" width="97.5" height="33"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="33" id="ymd-fR-kou"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="24"/>
+                    <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="师生即时互动,经验交流分享" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="40p-7F-M6I">
+                    <rect key="frame" x="10" y="607" width="394" height="25"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="25" id="TEP-nB-4oq"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="light" pointSize="18"/>
+                    <color key="textColor" red="0.61960784313725492" green="0.61960784313725492" blue="0.61960784313725492" alpha="1" colorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ykp-ax-0bg">
+                    <rect key="frame" x="117" y="658" width="180" height="40"/>
+                    <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="180" id="aZb-Af-529"/>
+                        <constraint firstAttribute="height" constant="40" id="z9L-sA-42a"/>
+                    </constraints>
+                    <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="20"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                    <connections>
+                        <action selector="enterAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="INd-VF-rxd"/>
+                    </connections>
+                </button>
+            </subviews>
+            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="40p-7F-M6I" firstAttribute="top" secondItem="5BZ-aV-ZqC" secondAttribute="bottom" constant="10" id="2v3-3C-ylP"/>
+                <constraint firstItem="V0F-XR-LOW" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="EMN-a8-r6N"/>
+                <constraint firstAttribute="trailing" secondItem="yUN-KZ-L1M" secondAttribute="trailing" constant="14" id="Fzi-Wu-PNu"/>
+                <constraint firstAttribute="trailing" secondItem="V0F-XR-LOW" secondAttribute="trailing" id="OIe-Jn-wBV"/>
+                <constraint firstItem="yUN-KZ-L1M" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="174" id="Op6-Wp-jtd"/>
+                <constraint firstItem="yUN-KZ-L1M" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="XsY-jo-nmn"/>
+                <constraint firstItem="V0F-XR-LOW" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Xul-rB-VdW"/>
+                <constraint firstItem="5BZ-aV-ZqC" firstAttribute="top" secondItem="yUN-KZ-L1M" secondAttribute="bottom" constant="24" id="ZEA-Cz-g9B"/>
+                <constraint firstItem="40p-7F-M6I" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="bAT-LT-afE"/>
+                <constraint firstItem="5BZ-aV-ZqC" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="fBJ-c2-scA"/>
+                <constraint firstAttribute="trailing" secondItem="40p-7F-M6I" secondAttribute="trailing" constant="10" id="vgd-eT-UZy"/>
+                <constraint firstItem="ykp-ax-0bg" firstAttribute="top" secondItem="40p-7F-M6I" secondAttribute="bottom" constant="26" id="wLg-9o-nU5"/>
+                <constraint firstItem="ykp-ax-0bg" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="yvn-U5-zhs"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="colorView" destination="V0F-XR-LOW" id="Rkl-pw-kyS"/>
+                <outlet property="descLabel" destination="40p-7F-M6I" id="wCM-U9-TPH"/>
+                <outlet property="enterButton" destination="ykp-ax-0bg" id="zla-N1-sVW"/>
+                <outlet property="headTitle" destination="5BZ-aV-ZqC" id="83k-rz-XwT"/>
+                <outlet property="imageView" destination="yUN-KZ-L1M" id="Mpv-wD-FBe"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="79.6875"/>
+        </view>
+    </objects>
+</document>

+ 41 - 2
KulexiuForStudent/KulexiuForStudent/Module/Mine/Controller/MineViewController.m

@@ -18,6 +18,9 @@
 #import "MyCourseViewController.h"
 #import "HomeworkListViewController.h"
 #import "UserSettingViewController.h"
+#import "KSScanViewController.h"
+#import "KSPremissionAlert.h"
+#import "RecordCheckManager.h"
 
 @interface MineViewController ()
 
@@ -223,13 +226,49 @@
     if (!_navView) {
         _navView = [MineNavView shareInstance];
         MJWeakSelf;
-        [_navView mineNavAction:^{
-            [weakSelf settingAction];
+        [_navView mineNavAction:^(MINENAV_ACTION action) {
+            if (action == MINENAV_ACTION_SETTING) {
+                [weakSelf settingAction];
+            }
+            else {
+                [weakSelf scanAction];
+            }
         }];
     }
     return _navView;
 }
 
+- (void)scanAction {
+    // 判断是否有权限
+    PREMISSIONTYPE albumEnable = [RecordCheckManager checkCameraPremissionAvaiable:NO showInView:nil];
+    if (albumEnable == PREMISSIONTYPE_YES) { // 如果有权限
+        KSScanViewController *ctrl = [[KSScanViewController alloc] init];
+        [self.navigationController pushViewController:ctrl animated:YES];
+    }
+    else {
+        if (albumEnable == PREMISSIONTYPE_NO) {
+            [self showAlertWithMessage:@"请开启相机访问权限" type:CHECKDEVICETYPE_CAMREA];
+        }
+    }
+}
+
+- (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {
+    [KSPremissionAlert shareInstanceDisplayImage:deviceType message:message showInView:self.view cancel:^{
+        
+    } confirm:^{
+        [self openSettingView];
+    }];
+    
+}
+
+- (void)openSettingView {
+    if (@available(iOS 10, *)) {
+        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
+    } else {
+        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
+    }
+}
+
 - (DeviceCheckView *)checkView {
     if (!_checkView) {
         _checkView = [DeviceCheckView shareInstance];

+ 16 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/Controller/KSScanViewController.h

@@ -0,0 +1,16 @@
+//
+//  KSScanViewController.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2022/6/30.
+//
+
+#import "BaseViewController.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSScanViewController : BaseViewController
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 213 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/Controller/KSScanViewController.m

@@ -0,0 +1,213 @@
+//
+//  KSScanViewController.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2022/6/30.
+//
+
+#import "KSScanViewController.h"
+#import "GRScanManager.h"
+#import "ScanNavView.h"
+#import "KSBaseWKWebViewController.h"
+#import "KSMediaManager.h"
+#import "KSPremissionAlert.h"
+#import "RecordCheckManager.h"
+
+@interface KSScanViewController ()
+
+@property (nonatomic, strong) KSMediaManager *mediaManager;
+@property (nonatomic, strong) NSMutableArray *imageArray;    // 图片数组
+@property (nonatomic, strong) NSMutableArray *imageAsset;    // 图片 asset
+
+@property (nonatomic, strong) GRScanManager *scanManager;
+
+@property (nonatomic, strong) ScanNavView *navView;
+
+@property (nonatomic, strong) UIImageView *scanView;
+
+@property (nonatomic, strong) UIView *maskView;
+
+
+@end
+
+@implementation KSScanViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    self.ks_prefersNavigationBarHidden = YES;
+}
+
+- (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+    [self configUI];
+}
+
+- (void)configUI {
+    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake((KPortraitWidth - 255) / 2.0f, (KPortraitHeight - 255) / 2.0f, 255, 255)];
+    CGRect qrViweFrame = imageView.frame;
+    imageView.image = [UIImage imageNamed:@"ScanView"];
+    [self.view addSubview:imageView];
+    
+    self.scanView = imageView;
+    
+    CAShapeLayer *shperLayer = [[CAShapeLayer alloc]init];
+    
+    CGMutablePathRef path = CGPathCreateMutable();
+    // 保留顶部
+    CGPathAddRect(path, nil, CGRectMake(0, 0, KPortraitWidth, CGRectGetMinY(qrViweFrame)));
+    // 保留底部
+    CGPathAddRect(path, nil, CGRectMake(0,CGRectGetMaxY(qrViweFrame), KPortraitWidth,KPortraitHeight - CGRectGetMaxY(qrViweFrame)));
+    //保留左边
+    CGPathAddRect(path, nil, CGRectMake(0,CGRectGetMinY(qrViweFrame), CGRectGetMinX(qrViweFrame),300));
+    //保留右边
+    CGPathAddRect(path, nil, CGRectMake(CGRectGetMaxX(qrViweFrame),CGRectGetMinY(qrViweFrame),KPortraitWidth - CGRectGetMaxX(qrViweFrame),300));
+    shperLayer.path = path;
+    CGPathRelease(path);
+    
+    UIView *view = [[UIView alloc] initWithFrame:self.view.bounds];
+    view.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
+    [self.view addSubview:view];
+    self.maskView = view;
+    view.layer.mask = shperLayer;
+    
+    [self.view addSubview:self.navView];
+    [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.mas_equalTo(self.view);
+        make.height.mas_equalTo(kNaviBarHeight);
+    }];
+    
+    UILabel *msg = [[UILabel alloc] initWithFrame:CGRectMake(30, CGRectGetMaxY(imageView.frame) + 15, KPortraitWidth - 60, 22)];
+    msg.backgroundColor = [UIColor clearColor];
+    msg.textColor = HexRGB(0xffffff);
+    msg.textAlignment = NSTextAlignmentCenter;
+    msg.font = [UIFont systemFontOfSize:16];
+    msg.text = @"请对准需要识别的二维码。";
+    [self.view addSubview:msg];
+    MJWeakSelf;
+    [self.scanManager startScanningQRCodeWithInView:self.view scanView:self.scanView resultCallback:^(NSString *result) {
+        [weakSelf.scanManager stopScanning];
+        [weakSelf dealWithCheckSource:result];
+        NSLog(@"%@",result);
+    }];
+}
+
+- (void)dealWithCheckSource:(NSString *)result {
+    if (result) {
+        if ([result containsString:@"http://"] || [result containsString:@"https://"]) {
+            KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
+            webCtrl.url = result;
+            [self.navigationController pushViewController:webCtrl animated:YES];
+        }
+        else {
+            [self backPreView];
+        }
+    }
+}
+
+- (void)backPreView {
+    MJWeakSelf;
+    [self KSShowMsg:@"无法识别" promptCompletion:^{
+        [weakSelf.navigationController popViewControllerAnimated:YES];
+    }];
+}
+
+
+- (GRScanManager *)scanManager {
+    if (!_scanManager) {
+        _scanManager = [[GRScanManager alloc] init];
+        _scanManager.supportBarCode = YES;
+        _scanManager.supportQRCode  = YES;
+    }
+    return _scanManager;
+}
+
+- (ScanNavView *)navView {
+    if (!_navView) {
+        _navView = [ScanNavView shareInstance];
+        MJWeakSelf;
+        [_navView scanActionCallback:^(SCANNAV_ACTION action) {
+            [weakSelf topNavAction:action];
+        }];
+    }
+    return _navView;
+}
+
+- (void)topNavAction:(SCANNAV_ACTION)action {
+    if (action == SCANNAV_ACTION_BACK) {
+        [self.navigationController popViewControllerAnimated:YES];
+    }
+    else {  // 选择相册
+        // 判断是否有权限
+        PREMISSIONTYPE albumEnable = [RecordCheckManager checkPhotoLibraryPremissionAvaiable:NO showInView:nil];
+        if (albumEnable == PREMISSIONTYPE_YES) { // 如果有权限
+            [self choosePhoneScan];
+        }
+        else {
+            if (albumEnable == PREMISSIONTYPE_NO) {
+                [self showAlertWithMessage:@"请开启相册访问权限" type:CHECKDEVICETYPE_CAMREA];
+            }
+        }
+        
+    }
+}
+- (void)showAlertWithMessage:(NSString *)message type:(CHECKDEVICETYPE)deviceType {
+    [KSPremissionAlert shareInstanceDisplayImage:deviceType message:message showInView:self.view cancel:^{
+        
+    } confirm:^{
+        [self openSettingView];
+    }];
+    
+}
+
+- (void)openSettingView {
+    if (@available(iOS 10, *)) {
+        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:nil];
+    } else {
+        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
+    }
+}
+
+- (void)choosePhoneScan {
+    // 调用相册
+    self.mediaManager = [[KSMediaManager alloc] init];
+    self.mediaManager.mediaType = MEDIATYPE_PHOTO;
+    self.mediaManager.maxPhotoNumber = 1;
+    self.mediaManager.baseCtrl = self;
+    self.mediaManager.imageArray = [self.imageArray mutableCopy];
+    self.mediaManager.imageAsset = [self.imageAsset mutableCopy];
+    self.mediaManager.needCropImage = NO;
+    MJWeakSelf;
+    [self.mediaManager noAlertCallback:^(NSString * _Nullable videoUrl, NSMutableArray * _Nullable imageArray, NSMutableArray * _Nullable imageAsset) {
+        [weakSelf scanImage:[imageArray lastObject]];
+    }];
+    [self.mediaManager pushImagePickerController];
+}
+
+- (void)scanImage:(UIImage *)image {
+    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{ CIDetectorAccuracy : CIDetectorAccuracyHigh }];
+    
+    NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];
+    if (features.count > 0) {
+        CIQRCodeFeature *feature = [features objectAtIndex:0];
+        NSString *scannedResult = feature.messageString;
+        NSLog(@"result:%@",scannedResult);
+        [self dealWithCheckSource:scannedResult];
+    }
+    else {
+        [self MBPShow:@"无法识别"];
+    }
+
+}
+
+/*
+#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

+ 27 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/View/ScanNavView.h

@@ -0,0 +1,27 @@
+//
+//  ScanNavView.h
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2022/6/30.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, SCANNAV_ACTION) {
+    SCANNAV_ACTION_BACK,
+    SCANNAV_ACTION_IMAGE,
+};
+
+typedef void(^ScanCallback)(SCANNAV_ACTION action);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface ScanNavView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)scanActionCallback:(ScanCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 47 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/View/ScanNavView.m

@@ -0,0 +1,47 @@
+//
+//  ScanNavView.m
+//  KulexiuForTeacher
+//
+//  Created by 王智 on 2022/6/30.
+//
+
+#import "ScanNavView.h"
+
+@interface ScanNavView ()
+
+@property (nonatomic, copy) ScanCallback callback;
+
+@end
+
+@implementation ScanNavView
++ (instancetype)shareInstance {
+    ScanNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"ScanNavView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)scanActionCallback:(ScanCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)backAction:(id)sender {
+    if (self.callback) {
+        self.callback(SCANNAV_ACTION_BACK);
+    }
+}
+- (IBAction)chooseImage:(id)sender {
+    if (self.callback) {
+        self.callback(SCANNAV_ACTION_IMAGE);
+    }
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 82 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Scan/View/ScanNavView.xib

@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="ScanNavView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="88"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ko6-5H-Ofb">
+                    <rect key="frame" x="0.0" y="44" width="414" height="44"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="back_button_white" translatesAutoresizingMaskIntoConstraints="NO" id="3Mq-8O-oLD">
+                            <rect key="frame" x="15" y="12" width="12" height="20"/>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="nyu-Tz-I7I">
+                            <rect key="frame" x="0.0" y="2" width="40" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="40" id="XtN-Dg-FZW"/>
+                                <constraint firstAttribute="width" constant="40" id="Zhs-SB-Iw0"/>
+                            </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="Aeh-Ka-WRk"/>
+                            </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="owv-JM-vXm">
+                            <rect key="frame" x="170" y="11" width="74" height="22"/>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/>
+                            <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="pd2-Uc-9LK">
+                            <rect key="frame" x="364" y="2" width="40" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="40" id="JMN-iD-4wD"/>
+                                <constraint firstAttribute="height" constant="40" id="e5J-en-Kd1"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" image="scan_photo"/>
+                            <connections>
+                                <action selector="chooseImage:" destination="iN0-l3-epB" eventType="touchUpInside" id="gLY-4C-anz"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="trailing" secondItem="pd2-Uc-9LK" secondAttribute="trailing" constant="10" id="FWb-r0-tBQ"/>
+                        <constraint firstAttribute="height" constant="44" id="KvG-uI-yim"/>
+                        <constraint firstItem="pd2-Uc-9LK" firstAttribute="centerY" secondItem="ko6-5H-Ofb" secondAttribute="centerY" id="PZs-fa-oZW"/>
+                        <constraint firstItem="owv-JM-vXm" firstAttribute="centerX" secondItem="ko6-5H-Ofb" secondAttribute="centerX" id="QEs-lu-PjL"/>
+                        <constraint firstItem="nyu-Tz-I7I" firstAttribute="leading" secondItem="ko6-5H-Ofb" secondAttribute="leading" id="SKH-bi-ZqL"/>
+                        <constraint firstItem="nyu-Tz-I7I" firstAttribute="centerY" secondItem="ko6-5H-Ofb" secondAttribute="centerY" id="VUv-ce-tTf"/>
+                        <constraint firstItem="3Mq-8O-oLD" firstAttribute="leading" secondItem="ko6-5H-Ofb" secondAttribute="leading" constant="15" id="o3V-YQ-5DK"/>
+                        <constraint firstItem="owv-JM-vXm" firstAttribute="centerY" secondItem="ko6-5H-Ofb" secondAttribute="centerY" id="qGP-mp-Ae6"/>
+                        <constraint firstItem="nyu-Tz-I7I" firstAttribute="centerY" secondItem="3Mq-8O-oLD" secondAttribute="centerY" id="uHP-uX-P1e"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="ko6-5H-Ofb" secondAttribute="trailing" id="3oZ-gF-xsD"/>
+                <constraint firstItem="ko6-5H-Ofb" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="TaS-8Q-t87"/>
+                <constraint firstAttribute="bottom" secondItem="ko6-5H-Ofb" secondAttribute="bottom" id="fRC-g2-xug"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="131.8840579710145" y="45.535714285714285"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="back_button_white" width="12" height="20"/>
+        <image name="scan_photo" width="20" height="16"/>
+    </resources>
+</document>

+ 6 - 1
KulexiuForStudent/KulexiuForStudent/Module/Mine/View/MineNavView.h

@@ -7,7 +7,12 @@
 
 #import <UIKit/UIKit.h>
 
-typedef void(^MineNavAction)(void);
+typedef NS_ENUM(NSInteger, MINENAV_ACTION) {
+    MINENAV_ACTION_SETTING, // 设置
+    MINENAV_ACTION_SCAN,   // 扫一扫
+};
+
+typedef void(^MineNavAction)(MINENAV_ACTION action);
 
 NS_ASSUME_NONNULL_BEGIN
 

+ 8 - 1
KulexiuForStudent/KulexiuForStudent/Module/Mine/View/MineNavView.m

@@ -32,10 +32,17 @@
 
 - (IBAction)buttonAction:(id)sender {
     if (self.callback) {
-        self.callback();
+        self.callback(MINENAV_ACTION_SETTING);
     }
 }
 
+- (IBAction)scanAction:(id)sender {
+    if (self.callback) {
+        self.callback(MINENAV_ACTION_SCAN);
+    }
+}
+
+
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.

+ 15 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/View/MineNavView.xib

@@ -25,11 +25,25 @@
                         <action selector="buttonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="h9L-Z3-X9x"/>
                     </connections>
                 </button>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EJV-LH-t1s">
+                    <rect key="frame" x="319" y="47" width="40" height="40"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="40" id="deq-GW-hFW"/>
+                        <constraint firstAttribute="width" constant="40" id="hPx-qs-89D"/>
+                    </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" image="mine_scan"/>
+                    <connections>
+                        <action selector="scanAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="Ta1-5B-OCv"/>
+                    </connections>
+                </button>
             </subviews>
             <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <constraints>
                 <constraint firstAttribute="trailing" secondItem="o7c-br-wf5" secondAttribute="trailing" constant="10" id="Kng-m2-QZf"/>
+                <constraint firstItem="o7c-br-wf5" firstAttribute="centerY" secondItem="EJV-LH-t1s" secondAttribute="centerY" id="Oo2-s1-fZ6"/>
                 <constraint firstAttribute="bottom" secondItem="o7c-br-wf5" secondAttribute="bottom" id="UkV-jH-fS0"/>
+                <constraint firstItem="o7c-br-wf5" firstAttribute="leading" secondItem="EJV-LH-t1s" secondAttribute="trailing" constant="5" id="oxR-ny-WsN"/>
             </constraints>
             <nil key="simulatedTopBarMetrics"/>
             <nil key="simulatedBottomBarMetrics"/>
@@ -38,6 +52,7 @@
         </view>
     </objects>
     <resources>
+        <image name="mine_scan" width="21" height="21"/>
         <image name="mine_setting" width="21" height="20"/>
     </resources>
 </document>

+ 0 - 62
KulexiuForStudent/Pods/Pods.xcodeproj/xcuserdata/wangzhi.xcuserdatad/xcschemes/xcschememanagement.plist

@@ -8,218 +8,156 @@
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>0</integer>
 		</dict>
 		<key>AlipaySDK-iOS.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>1</integer>
 		</dict>
 		<key>Bugly.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>2</integer>
 		</dict>
 		<key>CHIPageControl.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>3</integer>
 		</dict>
 		<key>IQKeyboardManager.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>6</integer>
 		</dict>
 		<key>JCore.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>7</integer>
 		</dict>
 		<key>JPush.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>8</integer>
 		</dict>
 		<key>JXCategoryView.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>9</integer>
 		</dict>
 		<key>JXPagingView.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>10</integer>
 		</dict>
 		<key>MBProgressHUD.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>13</integer>
 		</dict>
 		<key>MJExtension.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>14</integer>
 		</dict>
 		<key>MJRefresh.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>15</integer>
 		</dict>
 		<key>Masonry.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>12</integer>
 		</dict>
 		<key>Pods-KulexiuForStudent-KulexiuForStudentUITests.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>17</integer>
 		</dict>
 		<key>Pods-KulexiuForStudent.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>16</integer>
 		</dict>
 		<key>Pods-KulexiuForStudentTests.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>18</integer>
 		</dict>
 		<key>RSKImageCropper.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>22</integer>
 		</dict>
 		<key>Reachability.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>19</integer>
 		</dict>
 		<key>RongCloudIM.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>20</integer>
 		</dict>
 		<key>RongCloudRTC.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>21</integer>
 		</dict>
 		<key>SDWebImage.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>23</integer>
 		</dict>
 		<key>SSZipArchive.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>25</integer>
 		</dict>
 		<key>SocketRocket.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>24</integer>
 		</dict>
 		<key>TYCyclePagerView.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>26</integer>
 		</dict>
 		<key>Whiteboard-Whiteboard.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>28</integer>
 		</dict>
 		<key>Whiteboard.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>27</integer>
 		</dict>
 		<key>YYModel.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>29</integer>
 		</dict>
 		<key>ZKCycleScrollView.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>30</integer>
 		</dict>
 		<key>dsBridge.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>4</integer>
 		</dict>
 		<key>iOS-KS3SDK.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>5</integer>
 		</dict>
 		<key>lottie-ios.xcscheme</key>
 		<dict>
 			<key>isShown</key>
 			<false/>
-			<key>orderHint</key>
-			<integer>11</integer>
 		</dict>
 	</dict>
 	<key>SuppressBuildableAutocreation</key>