// // YMRetrievePasswordView.m // MSYOUPAI // // Created by YoMi on 2024/2/6. // Copyright © 2024 MS. All rights reserved. // #import "YMRetrievePasswordView.h" #import "YMRetrievePasswordViewModel.h" #import "YMCaptchaPopupView.h" #import "CaptchaCenter.h" @interface YMRetrievePasswordView () /// 找回密码VM @property (nonatomic, strong) YMRetrievePasswordViewModel *viewModel; /// 手机视图 @property (nonatomic, strong) UIView *mobileView; /// 手机号标签 @property (nonatomic, strong) UILabel *mobileLb; /// 手机号输入框 @property (nonatomic, strong) UITextField *mobileInputBox; /// 验证码视图 @property (nonatomic, strong) UIView *verifyCodeView; /// 验证码标签 @property (nonatomic, strong) UILabel *verifyCodeLb; /// 验证码输入框 @property (nonatomic, strong) UITextField *verifyCodeInputBox; /// 获取验证码 @property (nonatomic, strong) YMCaptchaCountdownButton *getVerifyCodeBtn; /// 密码视图 @property (nonatomic, strong) UIView *passwordView; /// 密码标签 @property (nonatomic, strong) UILabel *passwordLb; /// 密码输入框 @property (nonatomic, strong) UITextField *passwordInputBox; /// 协议视图 @property (nonatomic, strong) UIView *agreementView; /// 单选按钮 @property (nonatomic, strong) UIButton *radioBtn; /// 协议标签 @property (nonatomic, strong) YYLabel *agreementLb; /// 确定按钮 @property (nonatomic, strong) UIButton *confirmBtn; @end @implementation YMRetrievePasswordView - (void)ym_setupViews{ [self addSubview:self.mobileView]; [self.mobileView addSubview:self.mobileLb]; [self.mobileView addSubview:self.mobileInputBox]; [self addSubview:self.verifyCodeView]; [self.verifyCodeView addSubview:self.verifyCodeLb]; [self.verifyCodeView addSubview:self.verifyCodeInputBox]; [self.verifyCodeView addSubview:self.getVerifyCodeBtn]; [self addSubview:self.passwordView]; [self.passwordView addSubview:self.passwordLb]; [self.passwordView addSubview:self.passwordInputBox]; [self addSubview:self.agreementView]; [self.agreementView addSubview:self.radioBtn]; [self.agreementView addSubview:self.agreementLb]; [self addSubview:self.confirmBtn]; [self setNeedsUpdateConstraints]; [self updateConstraintsIfNeeded]; } - (void)updateConstraints{ [self.mobileView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self).offset(adapt(24)); make.left.equalTo(self).offset(adapt(28)); make.right.equalTo(self).offset(adapt(-28)); }]; [self.mobileLb mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mobileView); make.left.equalTo(self.mobileView); }]; [self.mobileInputBox mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mobileLb.mas_bottom).offset(adapt(10)); make.left.equalTo(self.mobileView); make.right.equalTo(self.mobileView); make.bottom.equalTo(self.mobileView); make.height.mas_equalTo(adapt(30)); }]; [self.verifyCodeView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.mobileView.mas_bottom).offset(adapt(24)); make.left.equalTo(self.mobileView.mas_left); make.right.equalTo(self.mobileView.mas_right); }]; [self.verifyCodeLb mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.verifyCodeView); make.left.equalTo(self.verifyCodeView); }]; [self.verifyCodeInputBox mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.verifyCodeLb.mas_bottom).offset(adapt(10)); make.left.equalTo(self.verifyCodeView); make.bottom.equalTo(self.verifyCodeView); make.height.mas_equalTo(adapt(30)); }]; [self.getVerifyCodeBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.verifyCodeLb.mas_bottom).offset(adapt(10)); make.left.equalTo(self.verifyCodeInputBox.mas_right).offset(adapt(5)); make.right.equalTo(self.verifyCodeView); make.bottom.equalTo(self.verifyCodeView); make.width.mas_equalTo(adapt(100)); }]; [self.passwordView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.verifyCodeView.mas_bottom).offset(adapt(24)); make.left.equalTo(self.mobileView.mas_left); make.right.equalTo(self.mobileView.mas_right); }]; [self.passwordLb mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.passwordView); make.left.equalTo(self.passwordView); }]; [self.passwordInputBox mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.passwordLb.mas_bottom).offset(adapt(10)); make.left.equalTo(self.passwordView); make.right.equalTo(self.passwordView); make.bottom.equalTo(self.passwordView); make.height.mas_equalTo(adapt(30)); }]; [self.confirmBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.passwordView.mas_bottom).offset(adapt(24)); make.left.equalTo(self.mobileView.mas_left); make.right.equalTo(self.mobileView.mas_right); make.height.mas_equalTo(adapt(40)); }]; [self.agreementView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self.mas_centerX); make.bottom.equalTo(self).offset(Is_iPhoneX ? adapt(-32) : adapt(-12)); }]; [self.radioBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(self.agreementLb.mas_centerY); make.left.equalTo(self.agreementView).offset(adapt(5)); make.width.height.mas_equalTo(adapt(12)); }]; [self.agreementLb mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.agreementView).offset(adapt(10)); make.left.equalTo(self.radioBtn.mas_right).offset(adapt(5)); make.right.equalTo(self.agreementView).offset(adapt(-5)); make.bottom.equalTo(self.agreementView).offset(adapt(-10)); }]; [super updateConstraints]; } - (void)ym_bindViewModel:(YMRetrievePasswordViewModel *)viewModel{ if (!viewModel) { return; } _viewModel = viewModel; RAC(self.viewModel , mobile) = [[RACSignal merge:@[RACObserve(self.mobileInputBox, text),self.mobileInputBox.rac_textSignal]] takeUntil:self.rac_willDeallocSignal]; RAC(self.viewModel , verifyCode) = [[RACSignal merge:@[RACObserve(self.verifyCodeInputBox, text),self.verifyCodeInputBox.rac_textSignal]]takeUntil:self.rac_willDeallocSignal]; RAC(self.viewModel , password) = [[RACSignal merge:@[RACObserve(self.passwordInputBox, text),self.passwordInputBox.rac_textSignal]]takeUntil:self.rac_willDeallocSignal]; [self.viewModel.validRetrievePasswordSignal subscribeNext:^(id _Nullable value) { self.confirmBtn.enabled = [value boolValue]; if ([value boolValue]) { self.confirmBtn.alpha = 1; } else { self.confirmBtn.alpha = 0.5; } }]; } - (UIView *)mobileView{ if (!_mobileView) { _mobileView = [[UIView alloc]init]; } return _mobileView; } - (UILabel *)mobileLb{ if (!_mobileLb) { _mobileLb = [[UILabel alloc]init]; _mobileLb.font = LCBoldFont(17); _mobileLb.textColor = HexColorFromRGB(0x1B2739); _mobileLb.textAlignment = NSTextAlignmentLeft; _mobileLb.text = @"手机号"; } return _mobileLb; } - (UITextField *)mobileInputBox{ if (!_mobileInputBox) { NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init]; style.minimumLineHeight = 0; NSMutableAttributedString *placeholderAttributed = [[NSMutableAttributedString alloc]initWithString:@"请输入手机号"]; placeholderAttributed.yy_paragraphStyle = style; placeholderAttributed.yy_font = LCFont(14); placeholderAttributed.yy_color = HexColorFromRGB(0xADB0BC); _mobileInputBox = [[UITextField alloc]init]; _mobileInputBox.attributedPlaceholder = placeholderAttributed; _mobileInputBox.clearButtonMode = UITextFieldViewModeWhileEditing; _mobileInputBox.autocorrectionType = UITextAutocorrectionTypeDefault; _mobileInputBox.autocapitalizationType = UITextAutocapitalizationTypeNone; _mobileInputBox.keyboardType = UIKeyboardTypePhonePad; _mobileInputBox.ba_maxLength = 11; //@weakify(self) [[[_mobileInputBox rac_textSignal] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) { //@strongify(self) }]; } return _mobileInputBox; } - (UIView *)verifyCodeView{ if (!_verifyCodeView) { _verifyCodeView = [[UIView alloc]init]; } return _verifyCodeView; } - (UILabel *)verifyCodeLb{ if (!_verifyCodeLb) { _verifyCodeLb = [[UILabel alloc]init]; _verifyCodeLb.font = LCBoldFont(17); _verifyCodeLb.textColor = HexColorFromRGB(0x1B2739); _verifyCodeLb.textAlignment = NSTextAlignmentLeft; _verifyCodeLb.text = @"短信验证码"; } return _verifyCodeLb; } - (UITextField *)verifyCodeInputBox{ if (!_verifyCodeInputBox) { NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init]; style.minimumLineHeight = 0; NSMutableAttributedString *placeholderAttributed = [[NSMutableAttributedString alloc]initWithString:@"请输入验证码"]; placeholderAttributed.yy_paragraphStyle = style; placeholderAttributed.yy_font = LCFont(14); placeholderAttributed.yy_color = HexColorFromRGB(0xADB0BC); _verifyCodeInputBox = [[UITextField alloc]init]; _verifyCodeInputBox.attributedPlaceholder = placeholderAttributed; _verifyCodeInputBox.clearButtonMode = UITextFieldViewModeWhileEditing; _verifyCodeInputBox.autocorrectionType = UITextAutocorrectionTypeDefault; _verifyCodeInputBox.autocapitalizationType = UITextAutocapitalizationTypeNone; _verifyCodeInputBox.keyboardType = UIKeyboardTypeDecimalPad; //@weakify(self) [[[_verifyCodeInputBox rac_textSignal] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) { // @strongify(self) }]; } return _verifyCodeInputBox; } - (YMCaptchaCountdownButton *)getVerifyCodeBtn{ if (!_getVerifyCodeBtn) { _getVerifyCodeBtn = [YMCaptchaCountdownButton buttonWithType:UIButtonTypeCustom]; _getVerifyCodeBtn.titleLabel.font = LCFont(14); [_getVerifyCodeBtn setTitleColor:HexColorFromRGB(0x6D82FD) forState:UIControlStateNormal]; [_getVerifyCodeBtn setTitle:@"获取验证码" forState:UIControlStateNormal]; @weakify(self) [_getVerifyCodeBtn countDownButtonHandler:^(YMCaptchaCountdownButton *sender, NSInteger tag) { @strongify(self) if (OCStringIsEmpty(self.mobileInputBox.text)) { [ZCHUDHelper showTitle:@"请输入手机号"]; return; } [self.mobileInputBox resignFirstResponder]; [self.verifyCodeInputBox resignFirstResponder]; [self.passwordInputBox resignFirstResponder]; [CaptchaCenter.defaultCenter getCaptchaType:^(NSNumber * _Nullable type, NSError * _Nullable error) { if (error) { [ZCHUDHelper showTitle:@"获取验证码失败"]; return; } if ([type isEqualToNumber:@1]) { // 原生 YMCaptchaPopupView *view = [[YMCaptchaPopupView alloc] init]; view.cancelButtonTappedBlock = ^{}; @weakify(self) view.confirmButtonTappedBlock = ^(NSString * _Nonnull input) { @strongify(self) [self getVerifyCodeWithCapthca:input sender:sender]; }; UIView *currentVCView = [LCTools getCurrentVC].view; if (currentVCView != nil && ![currentVCView isEqual:NSNull.null]) { [view showInView:currentVCView]; } } else { // 阿里 @weakify(self) [CaptchaCenter.defaultCenter verifyCompletion:^(NSString * _Nonnull status, NSDictionary * _Nonnull result) { @strongify(self) [self getVerifyCodeWithCapthca:result sender:sender]; }]; } }]; }]; } return _getVerifyCodeBtn; } - (void)getVerifyCodeWithCapthca:(id)captcha sender:(YMCaptchaCountdownButton *)sender { @weakify(self) [self.viewModel getVerifyCodeWithCapthca:captcha Handler:^(NSDictionary * _Nonnull dic, NSError * _Nullable error) { @strongify(self) sender.enabled = NO; [sender startCountDownWithSecond:59]; [sender countDownChanging:^NSString *(YMCaptchaCountdownButton *countDownButton, NSUInteger second) { NSString *title = [NSString stringWithFormat:@"重新发送(%zds)",second]; return title; }]; [sender countDownFinished:^NSString *(YMCaptchaCountdownButton *countDownButton, NSUInteger second) { countDownButton.enabled = YES; return @"重新发送"; }]; }]; } - (UIView *)passwordView{ if (!_passwordView) { _passwordView = [[UIView alloc]init]; } return _passwordView; } - (UILabel *)passwordLb{ if (!_passwordLb) { _passwordLb = [[UILabel alloc]init]; _passwordLb.font = LCBoldFont(17); _passwordLb.textColor = HexColorFromRGB(0x1B2739); _passwordLb.textAlignment = NSTextAlignmentLeft; _passwordLb.text = @"密码"; } return _passwordLb; } - (UITextField *)passwordInputBox{ if (!_passwordInputBox) { NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc]init]; style.minimumLineHeight = 0; NSMutableAttributedString *placeholderAttributed = [[NSMutableAttributedString alloc]initWithString:@"请输入密码"]; placeholderAttributed.yy_paragraphStyle = style; placeholderAttributed.yy_font = LCFont(14); placeholderAttributed.yy_color = HexColorFromRGB(0xADB0BC); _passwordInputBox = [[UITextField alloc]init]; _passwordInputBox.attributedPlaceholder = placeholderAttributed; _passwordInputBox.clearButtonMode = UITextFieldViewModeWhileEditing; _passwordInputBox.autocorrectionType = UITextAutocorrectionTypeDefault; _passwordInputBox.autocapitalizationType = UITextAutocapitalizationTypeNone; _passwordInputBox.keyboardType = UIKeyboardTypeDefault; _passwordInputBox.secureTextEntry = YES; //@weakify(self) [[[_passwordInputBox rac_textSignal] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(id x) { //@strongify(self) }]; } return _passwordInputBox; } - (UIView *)agreementView{ if (!_agreementView) { _agreementView = [[UIView alloc]init]; } return _agreementView; } - (UIButton *)radioBtn{ if (!_radioBtn) { _radioBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_radioBtn setBackgroundImage:ImageByName(@"ym_login_auth_normal_icon") forState:UIControlStateNormal]; [_radioBtn setBackgroundImage:ImageByName(@"ym_login_auth_selected_icon") forState:UIControlStateSelected]; // WS(weakSelf) [[[_radioBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(__kindof UIButton * _Nullable sender) { sender.selected = !sender.selected; }]; } return _radioBtn; } - (YYLabel *)agreementLb{ if (!_agreementLb) { _agreementLb = [[YYLabel alloc] init]; _agreementLb.numberOfLines = 0; _agreementLb.preferredMaxLayoutWidth = kFrameWidth - 55; NSString *agreementText = @"同意《用户协议》与《隐私政策》"; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init]; paragraphStyle.alignment = NSTextAlignmentLeft; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]initWithString:agreementText]; attributedString.yy_font = LCFont(12); attributedString.yy_color = HexColorFromRGBA(0x000000,0.65); attributedString.yy_paragraphStyle = paragraphStyle; //设置高亮色和点击事件 [attributedString yy_setTextHighlightRange:[agreementText rangeOfString:@"《用户协议》"] color:AGREEMENTColor backgroundColor:[UIColor clearColor] tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) { YMWebArticleViewModel *webArticleVM = [[YMWebArticleViewModel alloc]initWithParams:@{ ParamsUrl:[NSString stringWithFormat:@"%@%@",[LCSaveData getBaseURL]?[LCSaveData getBaseURL]:BaseURL,UserProtocolH5] }]; [YMRouter openURL:stringFormat(@"%@%@", YM_ROUTER_URL_PREFIX, YM_ROUTER_WEB_ARTICLE) withUserInfo:@{ RouterViewModel:webArticleVM } completion:nil]; }]; //设置高亮色和点击事件 [attributedString yy_setTextHighlightRange:[[attributedString string] rangeOfString:@"《隐私政策》"] color:AGREEMENTColor backgroundColor:[UIColor clearColor] tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) { YMWebArticleViewModel *webArticleVM = [[YMWebArticleViewModel alloc]initWithParams:@{ ParamsUrl:[NSString stringWithFormat:@"%@%@",[LCSaveData getBaseURL]?[LCSaveData getBaseURL]:BaseURL,UserPrivacyH5] }]; [YMRouter openURL:stringFormat(@"%@%@", YM_ROUTER_URL_PREFIX, YM_ROUTER_WEB_ARTICLE) withUserInfo:@{ RouterViewModel:webArticleVM } completion:nil]; }]; _agreementLb.attributedText = attributedString; } return _agreementLb; } - (UIButton *)confirmBtn{ if (!_confirmBtn) { _confirmBtn = [UIButton buttonWithType:UIButtonTypeCustom]; _confirmBtn.titleLabel.font = LCBoldFont(15); [_confirmBtn setTitle:@"确定" forState:UIControlStateNormal]; [_confirmBtn setTitleColor:MAINGRIDTitleC forState:UIControlStateNormal]; [_confirmBtn ym_setGradientBackgroundWithColors:kMainGradColors locations:kMainGradLocation startPoint:kMainGradStartP endPoint:kMainGradEndP]; _confirmBtn.layer.cornerRadius = adapt(40)/2; WS(weakSelf) [[[_confirmBtn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(__kindof UIButton * _Nullable sender) { if (OCStringIsEmpty(weakSelf.mobileInputBox.text)) { [ZCHUDHelper showTitle:@"请输入手机号"]; return; } if (OCStringIsEmpty(weakSelf.verifyCodeInputBox.text)) { [ZCHUDHelper showTitle:@"请输入短信验证码"]; return; } if (OCStringIsEmpty(weakSelf.passwordInputBox.text)) { [ZCHUDHelper showTitle:@"请输入密码"]; return; } if (!weakSelf.radioBtn.selected) { YMLoginRegistrAgreementPopupView *customView = [[YMLoginRegistrAgreementPopupView alloc]init]; YMPopupView *popupView = [YMPopupView initWithCustomView:customView parentView:nil popStyle:YMPopupStyleFade dismissStyle:YMDismissStyleFade]; popupView.priority = 999; popupView.cornerRadius = adapt(10); popupView.rectCorners = UIRectCornerAllCorners; popupView.positionStyle = YMPositionStyleCenter; popupView.isHideBg = NO; popupView.bgAlpha = 0.3; [popupView pop]; @weakify(popupView) customView.buttonBlock = ^(BOOL isConfirm) { @strongify(popupView) if (isConfirm) { weakSelf.radioBtn.selected = YES; [weakSelf.viewModel retrievePasswordRequest]; } [popupView dismissWithStyle:YMDismissStyleFade duration:2.0]; }; customView.dismissBlock = ^{ @strongify(popupView) [popupView dismissWithStyle:YMDismissStyleFade duration:2.0]; }; return; } [weakSelf.viewModel retrievePasswordRequest]; }]; } return _confirmBtn; } @end