登录模块手机号登录忘记密码完成

This commit is contained in:
fengshuo
2021-09-10 16:58:59 +08:00
parent 4d959bddd2
commit 64c43cb737
25 changed files with 1193 additions and 46 deletions

2
.gitignore vendored
View File

@@ -66,3 +66,5 @@ fastlane/test_output
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/
*/.DS_Store
.DS_Store

View File

@@ -57,6 +57,12 @@
18E7B29026EA0E6B0064BC9B /* FlutterBoost+Xplan.m in Sources */ = {isa = PBXBuildFile; fileRef = 18E7B28F26EA0E6B0064BC9B /* FlutterBoost+Xplan.m */; };
73FFADDC93E195344047A2EC /* Pods_xplan_ios.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CACF623970097D653132D69A /* Pods_xplan_ios.framework */; };
9B0E1C5926E77022005D4442 /* BaseNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0E1C5826E77022005D4442 /* BaseNavigationController.m */; };
E81C278C26EAFAF60031E639 /* Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = E81C278926EAFAF60031E639 /* Base64.m */; };
E81C278D26EAFAF60031E639 /* DESEncrypt.m in Sources */ = {isa = PBXBuildFile; fileRef = E81C278B26EAFAF60031E639 /* DESEncrypt.m */; };
E81C279026EB314D0031E639 /* LoginForgetEditView.m in Sources */ = {isa = PBXBuildFile; fileRef = E81C278F26EB314D0031E639 /* LoginForgetEditView.m */; };
E81C279326EB394D0031E639 /* LoginForgetPasswordViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E81C279226EB394D0031E639 /* LoginForgetPasswordViewController.m */; };
E81C279626EB39CC0031E639 /* LoginForgetPasswordPresent.m in Sources */ = {isa = PBXBuildFile; fileRef = E81C279526EB39CC0031E639 /* LoginForgetPasswordPresent.m */; };
E81C279826EB3AC40031E639 /* LoginForgetPasswordProtocol.h in Sources */ = {isa = PBXBuildFile; fileRef = E81C279726EB39E10031E639 /* LoginForgetPasswordProtocol.h */; };
E872308926E89BE000B90D4F /* LoginPhoneViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E872308826E89BE000B90D4F /* LoginPhoneViewController.m */; };
E872308D26E89DAA00B90D4F /* LoginInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = E872308C26E89DAA00B90D4F /* LoginInputView.m */; };
E872309326E8D31500B90D4F /* LoginVerifCodeView.m in Sources */ = {isa = PBXBuildFile; fileRef = E872309226E8D31500B90D4F /* LoginVerifCodeView.m */; };
@@ -66,6 +72,8 @@
E8B825C726EA0D9A009E8E9F /* LoginVerifCodeProtocol.h in Sources */ = {isa = PBXBuildFile; fileRef = E8B825C626EA0995009E8E9F /* LoginVerifCodeProtocol.h */; };
E8B825CA26EA1231009E8E9F /* LoginVerifCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E8B825C826EA1231009E8E9F /* LoginVerifCodeViewController.m */; };
E8B825CD26EA18C8009E8E9F /* ThemeColor.m in Sources */ = {isa = PBXBuildFile; fileRef = E8B825CC26EA18C8009E8E9F /* ThemeColor.m */; };
E8B825D026EA3825009E8E9F /* LoginPasswordViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E8B825CF26EA3825009E8E9F /* LoginPasswordViewController.m */; };
E8CEA03D26EA3DE500644B44 /* LoginPasswordPresent.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CEA03C26EA3DE500644B44 /* LoginPasswordPresent.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -169,6 +177,17 @@
9B0E1C5826E77022005D4442 /* BaseNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseNavigationController.m; sourceTree = "<group>"; };
B66633E061B1B34177CD011C /* Pods-xplan-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-xplan-ios.release.xcconfig"; path = "Target Support Files/Pods-xplan-ios/Pods-xplan-ios.release.xcconfig"; sourceTree = "<group>"; };
CACF623970097D653132D69A /* Pods_xplan_ios.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_xplan_ios.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E81C278826EAFAF60031E639 /* DESEncrypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DESEncrypt.h; sourceTree = "<group>"; };
E81C278926EAFAF60031E639 /* Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Base64.m; sourceTree = "<group>"; };
E81C278A26EAFAF60031E639 /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = "<group>"; };
E81C278B26EAFAF60031E639 /* DESEncrypt.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DESEncrypt.m; sourceTree = "<group>"; };
E81C278E26EB314D0031E639 /* LoginForgetEditView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginForgetEditView.h; sourceTree = "<group>"; };
E81C278F26EB314D0031E639 /* LoginForgetEditView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoginForgetEditView.m; sourceTree = "<group>"; };
E81C279126EB394D0031E639 /* LoginForgetPasswordViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginForgetPasswordViewController.h; sourceTree = "<group>"; };
E81C279226EB394D0031E639 /* LoginForgetPasswordViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoginForgetPasswordViewController.m; sourceTree = "<group>"; };
E81C279426EB39CC0031E639 /* LoginForgetPasswordPresent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginForgetPasswordPresent.h; sourceTree = "<group>"; };
E81C279526EB39CC0031E639 /* LoginForgetPasswordPresent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoginForgetPasswordPresent.m; sourceTree = "<group>"; };
E81C279726EB39E10031E639 /* LoginForgetPasswordProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginForgetPasswordProtocol.h; sourceTree = "<group>"; };
E872308726E89BE000B90D4F /* LoginPhoneViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginPhoneViewController.h; sourceTree = "<group>"; };
E872308826E89BE000B90D4F /* LoginPhoneViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoginPhoneViewController.m; sourceTree = "<group>"; };
E872308B26E89DAA00B90D4F /* LoginInputView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginInputView.h; sourceTree = "<group>"; };
@@ -186,6 +205,11 @@
E8B825C926EA1231009E8E9F /* LoginVerifCodeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoginVerifCodeViewController.h; sourceTree = "<group>"; };
E8B825CB26EA18C8009E8E9F /* ThemeColor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ThemeColor.h; sourceTree = "<group>"; };
E8B825CC26EA18C8009E8E9F /* ThemeColor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ThemeColor.m; sourceTree = "<group>"; };
E8B825CE26EA3825009E8E9F /* LoginPasswordViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginPasswordViewController.h; sourceTree = "<group>"; };
E8B825CF26EA3825009E8E9F /* LoginPasswordViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoginPasswordViewController.m; sourceTree = "<group>"; };
E8CEA03B26EA3DE500644B44 /* LoginPasswordPresent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginPasswordPresent.h; sourceTree = "<group>"; };
E8CEA03C26EA3DE500644B44 /* LoginPasswordPresent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LoginPasswordPresent.m; sourceTree = "<group>"; };
E8CEA03E26EA3E0200644B44 /* LoginPasswordProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LoginPasswordProtocol.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -367,6 +391,10 @@
E872308826E89BE000B90D4F /* LoginPhoneViewController.m */,
E8B825C926EA1231009E8E9F /* LoginVerifCodeViewController.h */,
E8B825C826EA1231009E8E9F /* LoginVerifCodeViewController.m */,
E8B825CE26EA3825009E8E9F /* LoginPasswordViewController.h */,
E8B825CF26EA3825009E8E9F /* LoginPasswordViewController.m */,
E81C279126EB394D0031E639 /* LoginForgetPasswordViewController.h */,
E81C279226EB394D0031E639 /* LoginForgetPasswordViewController.m */,
189DD56326DE465A00AB55B1 /* LoginViewController.h */,
189DD56426DE465A00AB55B1 /* LoginViewController.m */,
);
@@ -380,6 +408,10 @@
189DD58E26DF97E700AB55B1 /* LoginPresenter.m */,
E8B825C026EA00DF009E8E9F /* LoginVerifCodePresent.h */,
E8B825C126EA00DF009E8E9F /* LoginVerifCodePresent.m */,
E8CEA03B26EA3DE500644B44 /* LoginPasswordPresent.h */,
E8CEA03C26EA3DE500644B44 /* LoginPasswordPresent.m */,
E81C279426EB39CC0031E639 /* LoginForgetPasswordPresent.h */,
E81C279526EB39CC0031E639 /* LoginForgetPasswordPresent.m */,
);
path = Presenter;
sourceTree = "<group>";
@@ -389,6 +421,8 @@
children = (
189DD59426DF986300AB55B1 /* LoginProtocol.h */,
E8B825C626EA0995009E8E9F /* LoginVerifCodeProtocol.h */,
E8CEA03E26EA3E0200644B44 /* LoginPasswordProtocol.h */,
E81C279726EB39E10031E639 /* LoginForgetPasswordProtocol.h */,
);
path = Protocol;
sourceTree = "<group>";
@@ -396,6 +430,7 @@
189DD5A726DFA09700AB55B1 /* Tool */ = {
isa = PBXGroup;
children = (
E81C278726EAFABF0031E639 /* Security */,
189DD74D26E21D9000AB55B1 /* GCDHelper */,
189DD74726E21D8400AB55B1 /* KeyChain */,
189DD74226E21CCC00AB55B1 /* Reachability */,
@@ -523,6 +558,17 @@
path = Pods;
sourceTree = "<group>";
};
E81C278726EAFABF0031E639 /* Security */ = {
isa = PBXGroup;
children = (
E81C278A26EAFAF60031E639 /* Base64.h */,
E81C278926EAFAF60031E639 /* Base64.m */,
E81C278826EAFAF60031E639 /* DESEncrypt.h */,
E81C278B26EAFAF60031E639 /* DESEncrypt.m */,
);
path = Security;
sourceTree = "<group>";
};
E872308A26E89D5100B90D4F /* CustomView */ = {
isa = PBXGroup;
children = (
@@ -530,6 +576,8 @@
E872308C26E89DAA00B90D4F /* LoginInputView.m */,
E872309126E8D31500B90D4F /* LoginVerifCodeView.h */,
E872309226E8D31500B90D4F /* LoginVerifCodeView.m */,
E81C278E26EB314D0031E639 /* LoginForgetEditView.h */,
E81C278F26EB314D0031E639 /* LoginForgetEditView.m */,
);
path = CustomView;
sourceTree = "<group>";
@@ -674,32 +722,40 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E81C279826EB3AC40031E639 /* LoginForgetPasswordProtocol.h in Sources */,
E8B825C726EA0D9A009E8E9F /* LoginVerifCodeProtocol.h in Sources */,
E8B825CA26EA1231009E8E9F /* LoginVerifCodeViewController.m in Sources */,
189DD76226E60DDC00AB55B1 /* Api+Login.m in Sources */,
18E7B22626E8CDCF0064BC9B /* XplanFlutterBoostDelegate.m in Sources */,
189DD73E26E21C3F00AB55B1 /* YYUtility.m in Sources */,
E81C279626EB39CC0031E639 /* LoginForgetPasswordPresent.m in Sources */,
E8B825B726E9A7D8009E8E9F /* BaseObject.m in Sources */,
189DD53426DE255300AB55B1 /* TabbarViewController.m in Sources */,
187EEEFE26E8A82C002833B2 /* NSObject+AutoCoding.m in Sources */,
189DD55A26DE39D200AB55B1 /* BaseMvpPresenter.m in Sources */,
189DD6FF26E20E5900AB55B1 /* HttpRequestHelper.m in Sources */,
189DD74A26E21D8400AB55B1 /* SSKeychain.m in Sources */,
E8B825D026EA3825009E8E9F /* LoginPasswordViewController.m in Sources */,
189DD68426E1FDBB00AB55B1 /* XCHUDTool.m in Sources */,
189DD73F26E21C3F00AB55B1 /* YYUtility+Carrier.m in Sources */,
18E7B26926E8D5D60064BC9B /* XCCurrentVCStackManager.m in Sources */,
9B0E1C5926E77022005D4442 /* BaseNavigationController.m in Sources */,
189DD54B26DE338800AB55B1 /* BaseViewController.m in Sources */,
E81C279026EB314D0031E639 /* LoginForgetEditView.m in Sources */,
18E7B1B726E8B2D10064BC9B /* Api+Main.m in Sources */,
E8B825C226EA00DF009E8E9F /* LoginVerifCodePresent.m in Sources */,
18E7B1B226E8AF980064BC9B /* MainPresenter.m in Sources */,
189DD67E26E1FD8900AB55B1 /* UIImage+Utils.m in Sources */,
E8B825CD26EA18C8009E8E9F /* ThemeColor.m in Sources */,
E8CEA03D26EA3DE500644B44 /* LoginPasswordPresent.m in Sources */,
189DD52E26DE255300AB55B1 /* AppDelegate.m in Sources */,
E81C279326EB394D0031E639 /* LoginForgetPasswordViewController.m in Sources */,
E81C278D26EAFAF60031E639 /* DESEncrypt.m in Sources */,
189DD56526DE465A00AB55B1 /* LoginViewController.m in Sources */,
E8B825BF26E9E57D009E8E9F /* LoginTicketInfo.m in Sources */,
187EEEF026E89FE8002833B2 /* AccountInfoStorage.m in Sources */,
E872309326E8D31500B90D4F /* LoginVerifCodeView.m in Sources */,
E81C278C26EAFAF60031E639 /* Base64.m in Sources */,
189DD73D26E21C3F00AB55B1 /* YYUtility+Device.m in Sources */,
187EEEDC26E89B32002833B2 /* BaseModel.m in Sources */,
189DD74026E21C3F00AB55B1 /* YYUtility+App.m in Sources */,

View File

@@ -0,0 +1,16 @@
//
// Base64.h
// XChatFramework
//
// Created by chenran on 2017/5/4.
// Copyright © 2017年 chenran. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Base64 : NSObject
+(NSString *)encode:(NSData *)data;
+(NSData *)decode:(NSString *)dataString;
@end

View File

@@ -0,0 +1,133 @@
//
// Base64.m
// XChatFramework
//
// Created by chenran on 2017/5/4.
// Copyright © 2017 chenran. All rights reserved.
//
#import "Base64.h"
@interface Base64()
+(int)char2Int:(char)c;
@end
@implementation Base64
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+(NSString *)encode:(NSData *)data
{
if (data.length == 0)
return nil;
char *characters = malloc(data.length * 3 / 2);
if (characters == NULL)
return nil;
int end = data.length - 3;
int index = 0;
int charCount = 0;
int n = 0;
while (index <= end) {
int d = (((int)(((char *)[data bytes])[index]) & 0x0ff) << 16)
| (((int)(((char *)[data bytes])[index + 1]) & 0x0ff) << 8)
| ((int)(((char *)[data bytes])[index + 2]) & 0x0ff);
characters[charCount++] = encodingTable[(d >> 18) & 63];
characters[charCount++] = encodingTable[(d >> 12) & 63];
characters[charCount++] = encodingTable[(d >> 6) & 63];
characters[charCount++] = encodingTable[d & 63];
index += 3;
if(n++ >= 14)
{
n = 0;
characters[charCount++] = ' ';
}
}
if(index == data.length - 2)
{
int d = (((int)(((char *)[data bytes])[index]) & 0x0ff) << 16)
| (((int)(((char *)[data bytes])[index + 1]) & 255) << 8);
characters[charCount++] = encodingTable[(d >> 18) & 63];
characters[charCount++] = encodingTable[(d >> 12) & 63];
characters[charCount++] = encodingTable[(d >> 6) & 63];
characters[charCount++] = '=';
}
else if(index == data.length - 1)
{
int d = ((int)(((char *)[data bytes])[index]) & 0x0ff) << 16;
characters[charCount++] = encodingTable[(d >> 18) & 63];
characters[charCount++] = encodingTable[(d >> 12) & 63];
characters[charCount++] = '=';
characters[charCount++] = '=';
}
NSString * rtnStr = [[NSString alloc] initWithBytesNoCopy:characters length:charCount encoding:NSUTF8StringEncoding freeWhenDone:YES];
return rtnStr;
}
+(NSData *)decode:(NSString *)data
{
if(data == nil || data.length <= 0) {
return nil;
}
NSMutableData *rtnData = [[NSMutableData alloc]init];
int slen = data.length;
int index = 0;
while (true) {
while (index < slen && [data characterAtIndex:index] <= ' ') {
index++;
}
if (index >= slen || index + 3 >= slen) {
break;
}
int byte = ([self char2Int:[data characterAtIndex:index]] << 18) + ([self char2Int:[data characterAtIndex:index + 1]] << 12) + ([self char2Int:[data characterAtIndex:index + 2]] << 6) + [self char2Int:[data characterAtIndex:index + 3]];
Byte temp1 = (byte >> 16) & 255;
[rtnData appendBytes:&temp1 length:1];
if([data characterAtIndex:index + 2] == '=') {
break;
}
Byte temp2 = (byte >> 8) & 255;
[rtnData appendBytes:&temp2 length:1];
if([data characterAtIndex:index + 3] == '=') {
break;
}
Byte temp3 = byte & 255;
[rtnData appendBytes:&temp3 length:1];
index += 4;
}
return rtnData;
}
+(int)char2Int:(char)c
{
if (c >= 'A' && c <= 'Z') {
return c - 65;
} else if (c >= 'a' && c <= 'z') {
return c - 97 + 26;
} else if (c >= '0' && c <= '9') {
return c - 48 + 26 + 26;
} else {
switch(c) {
case '+':
return 62;
case '/':
return 63;
case '=':
return 0;
default:
return -1;
}
}
}
@end

View File

@@ -0,0 +1,16 @@
//
// DESEncrypt.h
// XChatFramework
//
// Created by chenran on 2017/5/4.
// Copyright © 2017年 chenran. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface DESEncrypt : NSObject
//加密方法
+(NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key;
//解密方法
+(NSString *) decryptUseDES:(NSString *)cipherText key:(NSString *)key;
@end

View File

@@ -0,0 +1,63 @@
//
// DESEncrypt.m
// XChatFramework
//
// Created by chenran on 2017/5/4.
// Copyright © 2017 chenran. All rights reserved.
//
#import "DESEncrypt.h"
#import <CommonCrypto/CommonCrypto.h>
#import "Base64.h"
@implementation DESEncrypt : NSObject
const Byte iv[] = {1,2,3,4,5,6,7,8};
#pragma mark-
+(NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key
{
NSString *ciphertext = nil;
NSData *textData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger dataLength = [textData length];
unsigned char buffer[200000];
memset(buffer, 0, sizeof(char));
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding|kCCOptionECBMode,
[key UTF8String], kCCKeySizeDES,
iv,
[textData bytes], dataLength,
buffer, 200000,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
ciphertext = [Base64 encode:data];
}
return ciphertext;
}
#pragma mark-
+(NSString *)decryptUseDES:(NSString *)cipherText key:(NSString *)key
{
NSString *plaintext = nil;
NSData *cipherdata = [Base64 decode:cipherText];
unsigned char buffer[200000];
memset(buffer, 0, sizeof(char));
size_t numBytesDecrypted = 0;
// kCCOptionPKCS7Padding|kCCOptionECBMode
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding|kCCOptionECBMode,
[key UTF8String], kCCKeySizeDES,
iv,
[cipherdata bytes], [cipherdata length],
buffer, 200000,
&numBytesDecrypted);
if(cryptStatus == kCCSuccess) {
NSData *plaindata = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
plaintext = [[NSString alloc]initWithData:plaindata encoding:NSUTF8StringEncoding];
}
return plaintext;
}
@end

View File

@@ -24,6 +24,19 @@ NS_ASSUME_NONNULL_BEGIN
/// @param phone 手机号
/// @param code 验证码
+ (void)loginWithCode:(HttpRequestHelperCompletion)completion phone:(NSString *)phone code:(NSString *)code client_secret:(NSString *)client_secret version:(NSString *)version client_id:(NSString *)client_id grant_type:(NSString *)grant_type;
/// 手机密码登录
/// @param completion 完成
/// @param phone 手机号
/// @param password 验证码
+ (void)loginWithPassword:(HttpRequestHelperCompletion)completion phone:(NSString *)phone password:(NSString *)password client_secret:(NSString *)client_secret version:(NSString *)version client_id:(NSString *)client_id grant_type:(NSString *)grant_type;
/// 充值密码 没有登录的时候
/// @param complction 完成
/// @param phone 手机号
/// @param newPwd 新的密码
/// @param smsCode 验证码
+ (void)resetPasswordWithPhone:(HttpRequestHelperCompletion)complction phone:(NSString *)phone newPwd:(NSString *)newPwd smsCode:(NSString *)smsCode;
@end
NS_ASSUME_NONNULL_END

View File

@@ -30,4 +30,21 @@
[self makeRequest:@"oauth/token" method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__,phone,code,client_secret,version, client_id, grant_type, nil];
}
///
/// @param completion
/// @param phone
/// @param password
+ (void)loginWithPassword:(HttpRequestHelperCompletion)completion phone:(NSString *)phone password:(NSString *)password client_secret:(NSString *)client_secret version:(NSString *)version client_id:(NSString *)client_id grant_type:(NSString *)grant_type {
[self makeRequest:@"oauth/token" method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__,phone,password,client_secret,version, client_id, grant_type, nil];
}
///
/// @param complction
/// @param phone
/// @param newPwd
/// @param smsCode
+ (void)resetPasswordWithPhone:(HttpRequestHelperCompletion)complction phone:(NSString *)phone newPwd:(NSString *)newPwd smsCode:(NSString *)smsCode {
[self makeRequest:@"acc/pwd/reset" method:HttpRequestHelperMethodPOST completion:complction, __FUNCTION__, phone, newPwd, smsCode, nil];
}
@end

View File

@@ -0,0 +1,25 @@
//
// LoginForgetPasswordPresent.h
// xplan-ios
//
// Created by 冯硕 on 2021/9/10.
//
#import "BaseMvpPresenter.h"
NS_ASSUME_NONNULL_BEGIN
@interface LoginForgetPasswordPresent : BaseMvpPresenter
/// 获取手机的验证码
/// @param phone 手机号
/// @param type 类型
- (void)phoneSmsCode:(NSString *)phone type:(int)type;
/// 没有登录的时候 重置密码
/// @param phone 手机号
/// @param newPwd 新的密码
/// @param smsCode 验证码
- (void)resetPassword:(NSString *)phone newPwd:(NSString *)newPwd smsCode:(NSString *)smsCode;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,70 @@
//
// LoginForgetPasswordPresent.m
// xplan-ios
//
// Created by on 2021/9/10.
//
#import "LoginForgetPasswordPresent.h"
///
#import <ReactiveObjC/ReactiveObjC.h>
///Tool
#import "AccountInfoStorage.h"
#import "DESEncrypt.h"
///Api
#import "Api+Login.h"
///Presenter
#import "LoginForgetPasswordPresent.h"
///Protocol
#import "LoginForgetPasswordProtocol.h"
@implementation LoginForgetPasswordPresent
- (id<LoginForgetPasswordProtocol>)getView {
return ((id<LoginForgetPasswordProtocol>) [super getView]);
}
///
/// @param phone
/// @param type
- (void)phoneSmsCode:(NSString *)phone type:(int)type {
[Api phoneSmsCode:[self createHttpCompletion:^(id _Nonnull data) {
[[self getView] phoneSmsCodeSuccess];
///60
[self openCutDownWithTotal:60];
} fail:^(NSInteger code, NSString * _Nullable msg) {
} showLoading:NO errorToast:YES] mobile:phone type:[NSString stringWithFormat:@"%d", type]];
}
///
/// @param phone
/// @param newPwd
/// @param smsCode
- (void)resetPassword:(NSString *)phone newPwd:(NSString *)newPwd smsCode:(NSString *)smsCode {
NSString * desPassword = [DESEncrypt encryptUseDES:newPwd key:@"1ea53d260ecf11e7b56e00163e046a26"];
[Api resetPasswordWithPhone:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
[[self getView] resetPasswrodSuccess];
} fail:^(NSInteger code, NSString * _Nullable msg) {
} showLoading:YES] phone:phone newPwd:desPassword smsCode:smsCode];
}
///
/// @param total
- (void)openCutDownWithTotal:(int)total {
__block int blockTotle = total;
__block RACDisposable * disposable;
disposable = [[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
blockTotle--;
[[self getView] countDownWithCurrent:blockTotle];
///
if (blockTotle == 0) {
[[self getView] countDownFinish];
[disposable dispose];
}
}];
}
@end

View File

@@ -0,0 +1,19 @@
//
// LoginPasswordPresent.h
// xplan-ios
//
// Created by 冯硕 on 2021/9/9.
//
#import "BaseMvpPresenter.h"
NS_ASSUME_NONNULL_BEGIN
@interface LoginPasswordPresent : BaseMvpPresenter
/// 使用手机号和密码登录
/// @param phone 手机号
/// @param password 验证码
- (void)loginWithPhone:(NSString *)phone password:(NSString *)password;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,36 @@
//
// LoginPasswordPresent.m
// xplan-ios
//
// Created by on 2021/9/9.
//
#import "LoginPasswordPresent.h"
///Http
#import "Api+Login.h"
///Tool
#import "AccountInfoStorage.h"
#import "DESEncrypt.h"
///Model
#import "AccountModel.h"
@implementation LoginPasswordPresent
/// 使
/// @param phone
/// @param password
- (void)loginWithPhone:(NSString *)phone password:(NSString *)password {
NSString * desPassword = [DESEncrypt encryptUseDES:password key:@"1ea53d260ecf11e7b56e00163e046a26"];
[Api loginWithPassword:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
AccountModel * accountModel = [AccountModel modelWithDictionary:data.data];
if (accountModel && accountModel.access_token.length > 0) {
[[AccountInfoStorage instance] saveAccountInfo:accountModel];
}
// [[self getView] loginSuccess];
} fail:^(NSInteger code, NSString * _Nullable msg) {
}] phone:phone password:desPassword client_secret:@"uyzjdhds" version:@"1" client_id:@"erban-client" grant_type:@"password"];
}
@end

View File

@@ -0,0 +1,23 @@
//
// LoginForgetPasswordProtocol.h
// xplan-ios
//
// Created by 冯硕 on 2021/9/10.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol LoginForgetPasswordProtocol <NSObject>
///请求手机号的验证码成功
- (void)phoneSmsCodeSuccess;
///倒计时进行中
- (void)countDownWithCurrent:(int)current;
///倒计时结束
- (void)countDownFinish;
///重置密码成功
- (void)resetPasswrodSuccess;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,17 @@
//
// LoginPasswordProtocol.h
// xplan-ios
//
// Created by 冯硕 on 2021/9/9.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol LoginPasswordProtocol <NSObject>
///手机号密码登录成功
- (void)phoneAndPasswordLoginSuccess;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,31 @@
//
// LoginForgetEditView.h
// xplan-ios
//
// Created by 冯硕 on 2021/9/10.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef enum : NSUInteger {
LoginForgetEditViewTypeNormal, // 普通类型
LoginForgetEditViewTypeSms, // 短信验证码类型
LoginForgetEditViewTypePassword, ///密码
} LoginForgetEditViewType;
@interface LoginForgetEditView : UIView
/** textField */
@property (nonatomic, strong, readonly) UITextField *textField;
/** rightButton */
@property (nonatomic, strong, readonly) UIButton *rightButton;
/** 验证码 */
@property (nonatomic, strong, readonly) UIButton *authCodeButton;
///类型
@property (nonatomic, assign) LoginForgetEditViewType type;
///展位图
@property (nonatomic,copy) NSString *placeholder;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,149 @@
//
// LoginForgetEditView.m
// xplan-ios
//
// Created by on 2021/9/10.
//
#import "LoginForgetEditView.h"
///
#import <Masonry/Masonry.h>
///Tool
#import "ThemeColor.h"
@interface LoginForgetEditView()
///
@property (nonatomic,strong) UIStackView *stackView;
/** textField */
@property (nonatomic, strong) UITextField *textField;
/** rightButton */
@property (nonatomic, strong) UIButton *rightButton;
/** bottomLineView */
@property (nonatomic, strong) UIView *bottomLineView;
/** */
@property (nonatomic, strong) UIButton *authCodeButton;
@end
@implementation LoginForgetEditView
#pragma mark - life cycle
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self initView];
[self initConstrations];
}
return self;
}
#pragma mark - private method
- (void)initView {
self.backgroundColor = [ThemeColor appCellBackgroundColor];
[self addSubview:self.stackView];
[self addSubview:self.bottomLineView];
[self.stackView addArrangedSubview:self.textField];
[self.stackView addArrangedSubview:self.rightButton];
[self.stackView addArrangedSubview:self.authCodeButton];
}
- (void)initConstrations {
[self.stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.authCodeButton);
make.left.right.mas_equalTo(self.bottomLineView);
make.top.bottom.mas_equalTo(self);
}];
[self.bottomLineView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self).inset(25);
make.bottom.mas_equalTo(0);
make.height.mas_equalTo(0.5);
}];
}
#pragma mark - getters and setters
- (void)setType:(LoginForgetEditViewType)type {
switch (type) {
case LoginForgetEditViewTypeNormal:
self.rightButton.hidden = YES;
self.authCodeButton.hidden = YES;
break;
case LoginForgetEditViewTypeSms:
self.authCodeButton.hidden = NO;
self.rightButton.hidden = YES;
break;
case LoginForgetEditViewTypePassword:
self.authCodeButton.hidden = YES;
self.rightButton.hidden = NO;
break;
default:
break;
}
}
- (void)setPlaceholder:(NSString *)placeholder {
_placeholder = placeholder;
if (_placeholder) {
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
style.alignment = NSTextAlignmentLeft;
NSDictionary *dic = @{
NSParagraphStyleAttributeName:style,
NSFontAttributeName:[UIFont systemFontOfSize:14],
NSForegroundColorAttributeName:[ThemeColor secondTextColor]};
if (placeholder == nil || placeholder.length == 0) {
placeholder = @"";
}
self.textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholder attributes:dic];
}
}
- (UITextField *)textField {
if (!_textField) {
_textField = [[UITextField alloc] init];
_textField.font = [UIFont systemFontOfSize:14];
_textField.textColor = [ThemeColor mainTextColor];
_textField.keyboardType = UIKeyboardTypeNumberPad;
_textField.tintColor = [ThemeColor appMainColor];
}
return _textField;
}
- (UIButton *)rightButton {
if (!_rightButton) {
_rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_rightButton setImage:[UIImage imageNamed:@"login_forget_password_hidden"] forState:UIControlStateNormal];
[_rightButton setImage:[UIImage imageNamed:@"login_forget_password_show"] forState:UIControlStateSelected];
}
return _rightButton;
}
- (UIView *)bottomLineView {
if (!_bottomLineView) {
_bottomLineView = [[UIView alloc] init];
_bottomLineView.backgroundColor = [ThemeColor partingLineColor];
}
return _bottomLineView;
}
- (UIButton *)authCodeButton {
if (!_authCodeButton) {
_authCodeButton = [UIButton buttonWithType:UIButtonTypeCustom];
_authCodeButton.titleLabel.font = [UIFont systemFontOfSize:14];
[_authCodeButton setTitle:@"获取验证码" forState:UIControlStateNormal];
[_authCodeButton setTitleColor:[ThemeColor secondTextColor] forState:UIControlStateDisabled];
[_authCodeButton setTitleColor:[ThemeColor appMainColor] forState:UIControlStateNormal];
}
return _authCodeButton;
}
- (UIStackView *)stackView {
if (!_stackView) {
_stackView = [[UIStackView alloc] init];
_stackView.axis = UILayoutConstraintAxisHorizontal;
_stackView.distribution = UIStackViewDistributionFill;
_stackView.alignment = UIStackViewAlignmentFill;
_stackView.spacing = 10;
}
return _stackView;
}
@end

View File

@@ -14,6 +14,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic,strong, readonly) UITextField *textField;
///占位的文字
@property (nonatomic,copy) NSString *placeHolder;
///显示前面的文字
@property (nonatomic,copy) NSString *title;
@end

View File

@@ -9,6 +9,7 @@
///
#import <Masonry/Masonry.h>
///
#import "ThemeColor.h"
@interface LoginInputView () <UITextFieldDelegate>
@@ -54,7 +55,14 @@
- (void)setPlaceHolder:(NSString *)placeHolder {
_placeHolder = placeHolder;
if (_placeHolder) {
self.textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:_placeHolder attributes:@{NSForegroundColorAttributeName: ThemeTextColor, NSFontAttributeName:[UIFont systemFontOfSize:14]}];
self.textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:_placeHolder attributes:@{NSForegroundColorAttributeName: [ThemeColor secondTextColor], NSFontAttributeName:[UIFont systemFontOfSize:14]}];
}
}
- (void)setTitle:(NSString *)title {
_title = title;
if (_title) {
self.titleLabel.text = _title;
}
}
@@ -73,7 +81,7 @@
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.font = [UIFont systemFontOfSize:18];
_titleLabel.textColor = [UIColor whiteColor];
_titleLabel.textColor = [ThemeColor mainTextColor];
_titleLabel.text = @"+86";
}
return _titleLabel;
@@ -83,11 +91,11 @@
- (UITextField *)textField {
if (!_textField) {
_textField = [[UITextField alloc] init];
_textField.textColor = [UIColor whiteColor];
_textField.textColor = [ThemeColor mainTextColor];
_textField.font = [UIFont systemFontOfSize:18.f];
_textField.borderStyle = UITextBorderStyleNone;
_textField.keyboardType = UIKeyboardTypeNumberPad;
_textField.tintColor = ThemeDefaultColor;
_textField.tintColor = [ThemeColor appMainColor];
_textField.backgroundColor = [UIColor clearColor];
_textField.delegate = self;
}

View File

@@ -9,6 +9,8 @@
///
#import <Masonry/Masonry.h>
#import <ReactiveObjC/ReactiveObjC.h>
///Tool
#import "ThemeColor.h"
@interface LoginVerifCodeView ()
///
@@ -54,7 +56,6 @@
if (textField.text.length > self.lableArray.count) {
textField.text = [textField.text substringToIndex:self.lableArray.count];
}
if (textField.text.length >= 5) {
[textField resignFirstResponder];
if (_textFieldChangeBlock) {
@@ -78,10 +79,10 @@
CGFloat itemSpace = 11;
for (int i = 0; i < _number; i++) {
UILabel * label = [[UILabel alloc] init];
label.textColor = [UIColor whiteColor];
label.font = [UIFont systemFontOfSize:18];
label.textColor = [ThemeColor mainTextColor];
label.font = [UIFont fontWithName:@"PingFang-SC-Medium" size:18];
label.textAlignment = NSTextAlignmentCenter;
label.backgroundColor = UIColorFromRGB(0x2A2A39);
label.backgroundColor = [ThemeColor appCellBackgroundColor];
label.layer.masksToBounds = YES;
label.layer.cornerRadius = 10;
label.tag = 100 + i;

View File

@@ -0,0 +1,16 @@
//
// LoginForgetPasswordViewController.h
// xplan-ios
//
// Created by 冯硕 on 2021/9/10.
//
#import "MvpViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface LoginForgetPasswordViewController : MvpViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,188 @@
//
// LoginForgetPasswordViewController.m
// xplan-ios
//
// Created by on 2021/9/10.
//
#import "LoginForgetPasswordViewController.h"
///
#import <Masonry/Masonry.h>
#import <ReactiveObjC/ReactiveObjC.h>
///Tool
#import "ThemeColor.h"
#import "XCHUDTool.h"
#import "UIImage+Utils.h"
///Presenter
#import "LoginForgetPasswordPresent.h"
#import "LoginForgetPasswordProtocol.h"
///View
#import "LoginForgetEditView.h"
@interface LoginForgetPasswordViewController ()<LoginForgetPasswordProtocol>
///
@property (nonatomic,strong) UIStackView *stackView;
///
@property (nonatomic,strong) LoginForgetEditView *phoneView;
///
@property (nonatomic,strong) LoginForgetEditView *codeView;
///
@property (nonatomic,strong) LoginForgetEditView *passwordView;
///
@property (nonatomic,strong) UIButton *finishButton;
@end
@implementation LoginForgetPasswordViewController
- (LoginForgetPasswordPresent *)createPresenter {
return [[LoginForgetPasswordPresent alloc] init];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self initSubViews];
[self initSubViewConstraints];
[self initEvents];
}
#pragma mark - Private Method
- (void)initSubViews {
self.title = @"忘记密码";
[self.view addSubview:self.stackView];
[self.view addSubview:self.finishButton];
[self.stackView addArrangedSubview:self.phoneView];
[self.stackView addArrangedSubview:self.codeView];
[self.stackView addArrangedSubview:self.passwordView];
}
- (void)initSubViewConstraints {
[self.stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.top.mas_equalTo(self.view);
}];
[self.finishButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self.view).inset(52);
make.height.mas_equalTo(45);
make.top.mas_equalTo(self.stackView.mas_bottom).offset(20);
}];
[self.phoneView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(45);
}];
[self.codeView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(self.phoneView);
}];
[self.passwordView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(self.phoneView);
}];
}
- (void)initEvents {
@weakify(self);
RAC(self.finishButton, enabled) = [RACSignal combineLatest:@[self.phoneView.textField.rac_textSignal, self.codeView.textField.rac_textSignal, self.passwordView.textField.rac_textSignal] reduce:^id _Nonnull(NSString *phone, NSString *code, NSString *password){
return @(phone.length == 11 && code.length > 0 && password.length >= 6 && password.length <= 16);
}];
///
[[self.codeView.authCodeButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
@strongify(self);
if (self.phoneView.textField.text.length != 11) {
[XCHUDTool showErrorWithMessage:@"请输入正确的手机号码"];
} else {
[self.presenter phoneSmsCode:self.phoneView.textField.text type:3];
}
}];
///
[[self.finishButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
[self.presenter resetPassword:self.phoneView.textField.text newPwd:self.passwordView.textField.text smsCode:self.codeView.textField.text];
}];
}
#pragma mark - LoginForgetPasswordProtocol
///
- (void)phoneSmsCodeSuccess {
self.codeView.authCodeButton.enabled= NO;
[XCHUDTool showSuccessWithMessage:@"验证码发送成功"];
}
///
- (void)countDownWithCurrent:(int)current {
[self.codeView.authCodeButton setTitle:[NSString stringWithFormat:@"%ds后重试", current] forState:UIControlStateDisabled];
}
///
- (void)countDownFinish {
self.codeView.authCodeButton.enabled= YES;
[self.codeView.authCodeButton setTitle:@"重新发送" forState:UIControlStateNormal];
}
///
- (void)resetPasswrodSuccess {
[XCHUDTool showSuccessWithMessage:@"重置密码成功"];
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - Getters And Setters
- (UIButton *)finishButton{
if (!_finishButton) {
_finishButton = [UIButton buttonWithType:UIButtonTypeCustom];
_finishButton.layer.masksToBounds = YES;
_finishButton.layer.cornerRadius = 45/2.f;
[_finishButton setTitle:@"提交" forState:UIControlStateNormal];
_finishButton.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium];
[_finishButton setTitleColor:[ThemeColor confirmButtonTextColor] forState:UIControlStateNormal];
_finishButton.enabled = NO;
UIImage *image = [UIImage gradientColorImageFromColors:@[[ThemeColor confirmButtonGradientStartColor], [ThemeColor confirmButtonGradientEndColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)];
[_finishButton setBackgroundImage:[UIImage gradientColorImageFromColors:@[[ThemeColor disableButtonBackColor], [ThemeColor disableButtonBackColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)] forState:UIControlStateDisabled];
[_finishButton setBackgroundImage:image forState:UIControlStateNormal];
}
return _finishButton;
}
- (UIStackView *)stackView {
if (!_stackView) {
_stackView = [[UIStackView alloc] init];
_stackView.axis = UILayoutConstraintAxisVertical;
_stackView.distribution = UIStackViewDistributionFill;
_stackView.alignment = UIStackViewAlignmentFill;
_stackView.spacing = 0;
}
return _stackView;
}
- (LoginForgetEditView *)phoneView {
if (!_phoneView) {
_phoneView = [[LoginForgetEditView alloc] init];
_phoneView.placeholder = @"请输入手机号";
_phoneView.type = LoginForgetEditViewTypeNormal;
}
return _phoneView;
}
- (LoginForgetEditView *)codeView {
if (!_codeView) {
_codeView = [[LoginForgetEditView alloc] init];
_codeView.placeholder = @"请输入验证码";
_codeView.type = LoginForgetEditViewTypeSms;
}
return _codeView;
}
- (LoginForgetEditView *)passwordView {
if (!_passwordView) {
_passwordView = [[LoginForgetEditView alloc] init];
_passwordView.placeholder = @"请输入密码6-16个字符";
_passwordView.type = LoginForgetEditViewTypePassword;
_passwordView.textField.keyboardType = UIKeyboardTypeASCIICapable;
_passwordView.textField.secureTextEntry = YES;
_passwordView.textField.clearButtonMode = UITextFieldViewModeAlways;
}
return _passwordView;
}
@end

View File

@@ -0,0 +1,16 @@
//
// LoginPasswordViewController.h
// xplan-ios
//
// Created by 冯硕 on 2021/9/9.
//
#import "MvpViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface LoginPasswordViewController : MvpViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,217 @@
//
// LoginPasswordViewController.m
// xplan-ios
//
// Created by on 2021/9/9.
//
#import "LoginPasswordViewController.h"
///
#import <Masonry/Masonry.h>
#import <ReactiveObjC/ReactiveObjC.h>
///Tool
#import "XCHUDTool.h"
#import "UIImage+Utils.h"
#import "ThemeColor.h"
///Presenter
#import "LoginPasswordPresent.h"
#import "LoginPasswordProtocol.h"
///View
#import "LoginInputView.h"
///VC
#import "LoginForgetPasswordViewController.h"
@interface LoginPasswordViewController ()<LoginPasswordProtocol>
///
@property (nonatomic,strong) UIButton *codeLoginButton;
///
@property (nonatomic,strong) UILabel *phoneLable;
///
@property (nonatomic,strong) LoginInputView *phoneView;
///
@property (nonatomic,strong) LoginInputView *codeView;
///
@property (nonatomic,strong) UIButton *forgetPasswordButton;
///
@property (nonatomic,strong) UIButton *nextButton;
@end
@implementation LoginPasswordViewController
- (void)dealloc {
NSLog(@"销毁了");
}
- (LoginPasswordPresent *)createPresenter {
return [[LoginPasswordPresent alloc] init];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self initSubViews];
[self initSubViewConstraints];
[self initEvents];
}
#pragma mark - Private Method
- (void)initSubViews {
[self.view addSubview:self.codeLoginButton];
[self.view addSubview:self.phoneLable];
[self.view addSubview:self.phoneView];
[self.view addSubview:self.codeView];
[self.view addSubview:self.forgetPasswordButton];
[self.view addSubview:self.nextButton];
}
- (void)initSubViewConstraints {
[self.codeLoginButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(self.view).offset(-15);
make.bottom.mas_equalTo(self.phoneLable.mas_top).offset(-30);
}];
[self.phoneLable mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.view);
make.top.mas_equalTo(self.view).offset(75);
}];
[self.phoneView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.phoneLable.mas_bottom).offset(50);
make.left.right.mas_equalTo(self.view).inset(47);
make.height.mas_equalTo(45);
}];
[self.codeView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.height.mas_equalTo(self.phoneView);
make.top.mas_equalTo(self.phoneView.mas_bottom).offset(15);
}];
[self.codeView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(self.phoneView);
}];
//
[self.nextButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.view);
make.top.mas_equalTo(self.forgetPasswordButton.mas_bottom).offset(30);
make.left.right.mas_equalTo(self.codeView);
make.height.mas_equalTo(45);
}];
[self.forgetPasswordButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.codeView.mas_bottom).offset(8);
make.right.mas_equalTo(self.codeView);
}];
}
- (void)initEvents {
@weakify(self);
RAC(self.nextButton, enabled) = [[RACSignal combineLatest:@[self.phoneView.textField.rac_textSignal, self.codeView.textField.rac_textSignal] reduce:^id _Nonnull(NSString *phone, NSString* password){
return @(phone.length ==11 && password.length >= 6);
}] takeUntil:self.rac_willDeallocSignal];
[[self.forgetPasswordButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
LoginForgetPasswordViewController * forgetPasswordVC = [[LoginForgetPasswordViewController alloc] init];
[self.navigationController pushViewController:forgetPasswordVC animated:YES];
}];
///
[[self.nextButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
@strongify(self);
[self.presenter loginWithPhone:self.phoneView.textField.text password:self.codeView.textField.text];
}];
///
[[self.codeLoginButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
[self.navigationController popViewControllerAnimated:YES];
}];
}
#pragma mark - LoginPasswordProtocol
- (void)phoneAndPasswordLoginSuccess {
[XCHUDTool showSuccessWithMessage:@"登录成功"];
[self.navigationController popToRootViewControllerAnimated:YES];
}
#pragma mark - Getters And Setters
- (UIButton *)nextButton {
if (!_nextButton) {
_nextButton = [UIButton buttonWithType:UIButtonTypeCustom];
_nextButton.layer.masksToBounds = YES;
_nextButton.layer.cornerRadius = 45/2.f;
[_nextButton setTitle:@"下一步" forState:UIControlStateNormal];
_nextButton.titleLabel.font = [UIFont fontWithName:@"" size:18];
_nextButton.enabled = NO;
UIImage *disableImage = [UIImage gradientColorImageFromColors:@[[ThemeColor disableButtonBackColor],[ThemeColor disableButtonBackColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)];
[_nextButton setBackgroundImage:disableImage forState:UIControlStateDisabled];
[_nextButton setTitleColor:[ThemeColor disableButtonTextColor] forState:UIControlStateDisabled];
UIImage *image = [UIImage gradientColorImageFromColors:@[[ThemeColor confirmButtonGradientStartColor],[ThemeColor confirmButtonGradientEndColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)];
[_nextButton setBackgroundImage:image forState:UIControlStateNormal];
[_nextButton setTitleColor:[ThemeColor confirmButtonTextColor] forState:UIControlStateDisabled];
}
return _nextButton;
}
- (UIButton *)codeLoginButton {
if (!_codeLoginButton) {
_codeLoginButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_codeLoginButton setTitle:@"验证码登录" forState:UIControlStateNormal];
[_codeLoginButton setTitleColor:[ThemeColor mainTextColor] forState:UIControlStateNormal];
_codeLoginButton.titleLabel.font = [UIFont fontWithName:@"PingFang-SC-Bold" size:15];;
}
return _codeLoginButton;
}
- (UIButton *)forgetPasswordButton {
if (!_forgetPasswordButton) {
_forgetPasswordButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_forgetPasswordButton setTitle:@"忘记密码?" forState:UIControlStateNormal];
[_forgetPasswordButton setTitleColor:[ThemeColor mainTextColor] forState:UIControlStateNormal];
_forgetPasswordButton.titleLabel.font = [UIFont fontWithName:@"PingFang-SC-Regular" size:11];;
}
return _forgetPasswordButton;
}
- (UILabel *)phoneLable{
if (!_phoneLable) {
_phoneLable = [[UILabel alloc] init];
_phoneLable.font = [UIFont fontWithName:@"PingFang-SC-Medium" size:18];
_phoneLable.text = @"你的手机号是多少";
_phoneLable.textColor = [ThemeColor mainTextColor];
}
return _phoneLable;
}
- (LoginInputView *)phoneView {
if (!_phoneView) {
_phoneView = [[LoginInputView alloc] init];
_phoneView.backgroundColor = [ThemeColor appCellBackgroundColor];
_phoneView.layer.masksToBounds = YES;
_phoneView.layer.cornerRadius = 45/2;
_phoneView.title = @"+86";
if (@available(iOS 10.0, *)) {
_phoneView.textField.keyboardType = UIKeyboardTypeASCIICapableNumberPad;
} else {
// Fallback on earlier versions
_phoneView.textField.keyboardType = UIKeyboardTypePhonePad;
}
}
return _phoneView;
}
- (LoginInputView *)codeView {
if (!_codeView) {
_codeView = [[LoginInputView alloc] init];
_codeView.backgroundColor = [ThemeColor appCellBackgroundColor];
_codeView.layer.masksToBounds = YES;
_codeView.layer.cornerRadius = 45/2;
_codeView.title = @"密码";
_codeView.textField.keyboardType = UIKeyboardTypeASCIICapable;
_codeView.textField.secureTextEntry = YES;
_codeView.textField.clearButtonMode = UITextFieldViewModeAlways;
}
return _codeView;
}
@end

View File

@@ -11,10 +11,12 @@
#import <ReactiveObjC/ReactiveObjC.h>
///Tool
#import "UIImage+Utils.h"
#import "ThemeColor.h"
///View
#import "LoginInputView.h"
///ViewController
#import "LoginVerifCodeViewController.h"
#import "LoginPasswordViewController.h"
@interface LoginPhoneViewController ()
///
@@ -38,7 +40,6 @@
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"手机号码登录";
[self initSubViews];
[self initSubViewConstraints];
[self initEevents];
@@ -58,12 +59,12 @@
- (void)initSubViewConstraints {
[self.passwordLoginButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(self.view).offset(-15);
make.top.mas_equalTo(self.view).offset(79 + kSafeAreaTopHeight);
make.bottom.mas_equalTo(self.titleStackView.mas_top).offset(-30);
}];
[self.titleStackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.view);
make.top.mas_equalTo(self.view).offset(140 + kSafeAreaTopHeight);
make.top.mas_equalTo(self.view).offset(75);
}];
[self.phoneView mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -82,7 +83,9 @@
@weakify(self);
///
[[self.passwordLoginButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
@strongify(self);
LoginPasswordViewController * passwordVC = [[LoginPasswordViewController alloc] init];
[self.navigationController pushViewController:passwordVC animated:YES];
}];
[[self.nextButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
@@ -105,10 +108,8 @@
if (!_passwordLoginButton) {
_passwordLoginButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_passwordLoginButton setTitle:@"密码登录" forState:UIControlStateNormal];
[_passwordLoginButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_passwordLoginButton.titleLabel.font = [UIFont systemFontOfSize:15];
_passwordLoginButton.layer.masksToBounds = YES;
_passwordLoginButton.layer.cornerRadius = 10;
[_passwordLoginButton setTitleColor:[ThemeColor mainTextColor] forState:UIControlStateNormal];
_passwordLoginButton.titleLabel.font = [UIFont fontWithName:@"PingFang-SC-Bold" size:15];
}
return _passwordLoginButton;
}
@@ -130,7 +131,7 @@
_autoLoginLabel.text = @"未注册的手机号自动登录";
_autoLoginLabel.textAlignment = NSTextAlignmentCenter;
_autoLoginLabel.font = [UIFont systemFontOfSize:11];
_autoLoginLabel.textColor = [UIColor whiteColor];
_autoLoginLabel.textColor = [ThemeColor secondTextColor];
}
return _autoLoginLabel;
}
@@ -140,7 +141,7 @@
_titleLabel = [[UILabel alloc] init];
_titleLabel.font = [UIFont boldSystemFontOfSize:18];
_titleLabel.text = @"你的手机号是多少";
_titleLabel.textColor = [UIColor whiteColor];
_titleLabel.textColor = [ThemeColor mainTextColor];
}
return _titleLabel;
}
@@ -148,7 +149,7 @@
- (LoginInputView *)phoneView {
if (!_phoneView) {
_phoneView = [[LoginInputView alloc] init];
_phoneView.backgroundColor = UIColorFromRGB(0x2A2A39);
_phoneView.backgroundColor = [ThemeColor appCellBackgroundColor];
_phoneView.layer.masksToBounds = YES;
_phoneView.layer.cornerRadius = 45/2;
}
@@ -162,10 +163,10 @@
_nextButton.layer.cornerRadius = 45/2.f;
[_nextButton setTitle:@"下一步" forState:UIControlStateNormal];
_nextButton.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium];
[_nextButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
[_nextButton setTitleColor:[ThemeColor confirmButtonTextColor] forState:UIControlStateNormal];
_nextButton.enabled = NO;
UIImage *image = [UIImage gradientColorImageFromColors:@[ThemeButtonGradientStartColor,ThemeButtonGradientEndColor] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)];
[_nextButton setBackgroundImage:[UIImage gradientColorImageFromColors:@[ThemeTabbarNormalColor, ThemeTabbarNormalColor] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)] forState:UIControlStateDisabled];
UIImage *image = [UIImage gradientColorImageFromColors:@[[ThemeColor confirmButtonGradientStartColor], [ThemeColor confirmButtonGradientEndColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)];
[_nextButton setBackgroundImage:[UIImage gradientColorImageFromColors:@[[ThemeColor disableButtonBackColor], [ThemeColor disableButtonBackColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)] forState:UIControlStateDisabled];
[_nextButton setBackgroundImage:image forState:UIControlStateNormal];
}
return _nextButton;

View File

@@ -11,6 +11,7 @@
#import <ReactiveObjC/ReactiveObjC.h>
///Tool
#import "XCHUDTool.h"
#import "ThemeColor.h"
///Presenter
#import "LoginVerifCodePresent.h"
///Protocole
@@ -45,9 +46,8 @@
[super viewDidLoad];
[self initSubViews];
[self initSubViewConstraints];
[self initEvents];
[self httpRequestPhoneSmsCode];
[self initEvents];
}
#pragma mark - Private Method
@@ -66,7 +66,7 @@
- (void)initSubViewConstraints {
[self.titleStackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.view);
make.top.mas_equalTo(self.view).offset(140 + kSafeAreaTopHeight);
make.top.mas_equalTo(self.view).offset(75);
}];
[self.codeView mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -77,46 +77,57 @@
[self.retryStackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.codeView.mas_bottom).offset(16);
make.centerX.mas_equalTo(self.view);
make.centerX.mas_equalTo(self.view);
}];
}
- (void)initEvents {
@weakify(self);
[[[self rac_signalForSelector:@selector(phoneSmsCodeSuccess)] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(RACTuple * _Nullable x) {
@strongify(self);
self.codeSendLabel.text = [NSString stringWithFormat:@"验证码已发送至:%@", self.phone];
}];
self.codeView.textFieldChangeBlock = ^(NSString * _Nonnull smsCode) {
if (self.phone.length > 0 && smsCode.length == 5) {
@strongify(self);
[self.presenter loginWithPhone:self.phone code:smsCode];
}
};
}
- (void)httpRequestPhoneSmsCode {
[self.presenter phoneSmsCode:self.phone type:1];
}
- (void)initEvents {
@weakify(self);
self.codeView.textFieldChangeBlock = ^(NSString * _Nonnull code) {
@strongify(self);
if (self.phone.length > 0 && code.length == 5) {
[self.presenter loginWithPhone:self.phone code:code];
}
};
}
- (NSAttributedString *)createRetrySendCodeWithTime:(int)time {
NSMutableAttributedString * attribute = [[NSMutableAttributedString alloc] init];
NSString * timeString = [NSString stringWithFormat:@"%ds ", time];
NSString * anewString = @"后可重新获取验证码";
NSAttributedString * timeAttribute = [[NSAttributedString alloc] initWithString:timeString attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15], NSForegroundColorAttributeName:[ThemeColor appMainColor]}];
NSAttributedString * anewAttribute = [[NSAttributedString alloc] initWithString:anewString attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15], NSForegroundColorAttributeName:[ThemeColor secondTextColor]}];
[attribute appendAttributedString:timeAttribute];
[attribute appendAttributedString:anewAttribute];
return attribute;
}
#pragma mark - LoginProtocol
- (void)phoneSmsCodeSuccess {
[XCHUDTool showSuccessWithMessage:@"发送成功"];
self.codeSendLabel.hidden = NO;
self.codeSendLabel.text = [NSString stringWithFormat:@"验证码已发送至:%@", self.phone];
}
- (void)countDownFinish {
self.retryCodeButton.hidden = NO;
self.cutdownLabel.hidden = YES;
self.codeSendLabel.hidden = YES;
}
- (void)countDownWithCurrent:(int)current {
self.cutdownLabel.text = [NSString stringWithFormat:@"%ds 后重新获取验证码", current];
self.cutdownLabel.attributedText = [self createRetrySendCodeWithTime:current];
self.retryCodeButton.hidden = YES;
self.cutdownLabel.hidden = NO;
}
- (void)loginSuccess {
[self.navigationController popToRootViewControllerAnimated:NO];
[XCHUDTool showSuccessWithMessage:@"登录成功"];
[self.navigationController popToRootViewControllerAnimated:YES];
}
#pragma mark - Getters And Setters
@@ -136,7 +147,8 @@
_codeSendLabel = [[UILabel alloc] init];
_codeSendLabel.textAlignment = NSTextAlignmentCenter;
_codeSendLabel.font = [UIFont systemFontOfSize:11];
_codeSendLabel.textColor = [UIColor whiteColor];
_codeSendLabel.textColor = [ThemeColor secondTextColor];
_codeSendLabel.hidden = YES;
}
return _codeSendLabel;
}
@@ -144,9 +156,9 @@
- (UILabel *)titleLabel{
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.font = [UIFont boldSystemFontOfSize:18];
_titleLabel.font = [UIFont fontWithName:@"PingFang-SC-Medium" size:18];
_titleLabel.text = @"填写验证码";
_titleLabel.textColor = [UIColor whiteColor];
_titleLabel.textColor = [ThemeColor mainTextColor];
}
return _titleLabel;
}
@@ -185,7 +197,7 @@
if (!_retryCodeButton) {
_retryCodeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_retryCodeButton setTitle:@"重新获取验证码" forState:UIControlStateNormal];
[_retryCodeButton setTitleColor:ThemeDefaultColor forState:UIControlStateNormal];
[_retryCodeButton setTitleColor:[ThemeColor appMainColor] forState:UIControlStateNormal];
_retryCodeButton.titleLabel.font = [UIFont systemFontOfSize:11];
_retryCodeButton.hidden = YES;
}