增加重置密码的界面及配套的MVP代码

This commit is contained in:
free will committed 2021-08-23 17:03:29 +08:00
1 parent dbbfb69470
commit 97387511b5
7 files changed
+521 -9

No files matched your search

+3
View File
@@ -36,6 +36,9 @@
<activity
android:name=".activity.main.MainActivity"
android:launchMode="singleTask" />
<activity
android:name=".activity.reset.ResetActivity"
android:launchMode="singleTask" />
<service
android:name=".services.MINVpnService"
android:permission="android.permission.BIND_VPN_SERVICE">
@@ -20,6 +20,7 @@ import com.pkusz.min_vpn_client.activity.base.MINVpnBaseActivity;
import com.pkusz.min_vpn_client.activity.loginSMS.LoginSMSActivity;
import com.pkusz.min_vpn_client.activity.main.MainActivity;
import com.pkusz.min_vpn_client.activity.register.RegisterActivity;
import com.pkusz.min_vpn_client.activity.reset.ResetActivity;
import com.pkusz.min_vpn_client.activity.setting.SettingActivity;
import com.pkusz.min_vpn_client.model.MINVpnSettingAPI;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalGetVpnInfoRequest;
@@ -110,7 +111,7 @@ public class LoginActivity extends MINVpnBaseActivity<LoginActivityPresenter>
// 监听是否新设备登录
tvLoginWithSMS.setOnClickListener(v -> {
System.out.println("跳转到新设备登录界面ing");
System.out.println("即将跳转到新设备登录界面");
ContextExtensionKt.jumpTo(this, LoginSMSActivity.class);
});
@@ -122,8 +123,8 @@ public class LoginActivity extends MINVpnBaseActivity<LoginActivityPresenter>
// 监听重置密码按钮
tvResetNow.setOnClickListener(v -> {
System.out.println("假装跳转到重置界面");
// ContextExtensionKt.jumpTo(this, LoginSMSActivity.class);
System.out.println("即将跳转到重置界面");
ContextExtensionKt.jumpTo(this, ResetActivity.class);
});
// 显示账号
@@ -0,0 +1,257 @@
package com.pkusz.min_vpn_client.activity.reset;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 19:45 2021/6/25
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.jkb.vcedittext.VerificationCodeEditText;
import com.pkusz.min_vpn_client.R;
import com.pkusz.min_vpn_client.activity.base.MINVpnBaseActivity;
import com.pkusz.min_vpn_client.model.MINVpnSettingAPI;
import com.pkusz.min_vpn_client.utils.AccountValidatorRegexUtil;
import com.pkusz.min_vpn_client.utils.DigestUtilKt;
import com.pkusz.min_vpn_client.utils.KeyManager;
import com.white.countdownbutton.CountDownButton;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import br.com.simplepass.loadingbutton.customViews.CircularProgressButton;
import cn.qjm253.min_vpn.extensions.ActivityExtensionsKt;
import cn.qjm253.quick_android_base.GlideApp;
import cn.qjm253.quick_android_base.extensions.ContextExtensionKt;
import cn.qjm253.quick_android_base.extensions.ViewExtensionKt;
import cn.qjm253.quick_android_base.util.DisplayUtils;
import cn.qjm253.quick_android_custom_view.other.ClearAbleEditText;
import cn.qjm253.quick_android_easy_bar.EasyBar;
import cn.qjm253.quick_android_easy_bar.EasyBarExtensionsKt;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
public class ResetActivity extends MINVpnBaseActivity<ResetActivityPresenter>
implements ResetActivityContract.View{
// 常规变量区
private String rawUsername ="";
private String oldPassword ="";
private String newPassword ="";
private String newPassword2="";
private String phoneNumber="";
private String verifyNumber="";
// 界面变量区
private EasyBar easyBar;
private ImageView imageView_imgLogo;
private ClearAbleEditText etUsername;
private ClearAbleEditText etOldPassword;
private ClearAbleEditText etPassword;
private ClearAbleEditText etPassword2;
private ClearAbleEditText Reset_SMSPhoneNumber;
private ConstraintLayout Reset_SMSRegion;
private VerificationCodeEditText Reset_etSMSNumber;
private CountDownButton Reset_getSMScode;
private CircularProgressButton btnReset;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reset);
// 初始化各个组件
easyBar=findViewById(R.id.easyBar);
imageView_imgLogo=findViewById(R.id.imgLogo);
etUsername=findViewById(R.id.etusername);
etOldPassword=findViewById(R.id.etOldPassword);
etPassword=findViewById(R.id.etPassword);
etPassword2=findViewById(R.id.etPassword2);
Reset_SMSPhoneNumber=findViewById(R.id.Reset_SMSPhoneNumber);
Reset_SMSRegion=findViewById(R.id.Reset_SMSRegion);
Reset_etSMSNumber=findViewById(R.id.Reset_etSMSNumber);
Reset_getSMScode=findViewById(R.id.Reset_getSMScode);
btnReset=findViewById(R.id.btnReset);
initView();
}
private void initView(){
// 初始化bar
EasyBarExtensionsKt.init(easyBar, EasyBar.Mode.ICON, "",
(Function1<View, Unit>) view -> {
System.out.println("跳回到上一界面");
onBackPressed();
return null;
},
(Function1<View, Unit>) view -> {
System.out.println("empty right");
return null;
},
R.drawable.back, 0, "", "", R.string.reset,
true, R.color.white);
// glideapp
GlideApp.with(this)
.load(R.drawable.logo)
.circleCrop()
.into(imageView_imgLogo);
// 获取验证码操作的监听器
Reset_getSMScode.setOnClickListener(v -> {
// todo 执行获取验证码的逻辑
System.out.println("执行获取验证码的逻辑");
});
// 显示账号
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
etUsername.setText(MINVpnSettingAPI.INSTANCE.getUsername());
}else{
System.out.println("Base64Util.Base64PlusDecode error");
}
// 修改密码按钮
btnReset.setBackgroundResource(R.drawable.button_shape_default);
btnReset.setOnClickListener(v->{
ContextExtensionKt.hideSoftKeyboard(this, btnReset);
btnReset.startAnimation();
this.rawUsername = Objects.requireNonNull(etUsername.getText()).toString();
this.oldPassword = Objects.requireNonNull(etOldPassword.getText()).toString();
this.newPassword = Objects.requireNonNull(etPassword.getText()).toString();
this.newPassword2 = Objects.requireNonNull(etPassword2.getText()).toString();
this.phoneNumber = Objects.requireNonNull(Reset_SMSPhoneNumber.getText()).toString();
this.verifyNumber = Objects.requireNonNull(Reset_etSMSNumber.getText()).toString();
// 登录前判断本地是否有身份信息,如果无,则提醒使用新设备登录界面
boolean isHaveIdentity= KeyManager.INSTANCE.isInKeyChain("/"+this.rawUsername);
if(!isHaveIdentity){
showWarning("本地无此用户身份("+this.rawUsername+"),请检查您输入的用户名。");
btnReset.revertAnimation();
return;
}
if (rawUsername.isEmpty() || oldPassword.isEmpty()
|| newPassword.isEmpty() || newPassword2.isEmpty()
|| phoneNumber.isEmpty() || verifyNumber.isEmpty()) {
showWarning("请将信息填写完整");
btnReset.revertAnimation();
return;
}
if (!AccountValidatorRegexUtil.INSTANCE.isUsername(rawUsername)) {
showWarning("请输入有效的用户名,用户名为3-20位,包含字母、数字、下划线,且以字母开头");
btnReset.revertAnimation();
return;
}
if (!AccountValidatorRegexUtil.INSTANCE.isPassword(oldPassword)) {
showWarning("请输入有效的旧密码,密码为8-16位,必须同时包含字母、数字和特殊符号");
btnReset.revertAnimation();
return;
}
if (!AccountValidatorRegexUtil.INSTANCE.isPassword(newPassword)) {
showWarning("请输入有效的新密码,密码为8-16位,必须同时包含字母、数字和特殊符号");
btnReset.revertAnimation();
return;
}
if (!newPassword.equals(newPassword2)) {
showWarning("两次输入的密码不一致,请检查。");
btnReset.revertAnimation();
return;
}
// 密码经md5哈希
String oldpassword =DigestUtilKt.encodeToMD5(oldPassword);
String newpassword =DigestUtilKt.encodeToMD5(newPassword);
// todo: 传递修改密码请求信息,执行登录网络请求
});
// 监听键盘是否弹起
ActivityExtensionsKt.listenKeyboardVisible(this,(isOpen)->{
if(isOpen){
ViewExtensionKt.animer200(imageView_imgLogo,
ViewExtensionKt.scaleXAnimation(imageView_imgLogo,1f, 0.5f),
ViewExtensionKt.scaleYAnimation(imageView_imgLogo,1f, 0.5f),
ViewExtensionKt.transYAnimation(imageView_imgLogo,
0f, -DisplayUtils.dp2px(this, 40)),
ViewExtensionKt.transYAnimation(etUsername,
0f, -DisplayUtils.dp2px(this, 90)),
ViewExtensionKt.transYAnimation(etOldPassword,
0f, -DisplayUtils.dp2px(this, 90)),
ViewExtensionKt.transYAnimation(etPassword,
0f, -DisplayUtils.dp2px(this, 90)),
ViewExtensionKt.transYAnimation(etPassword2,
0f, -DisplayUtils.dp2px(this, 90)),
ViewExtensionKt.transYAnimation(Reset_SMSPhoneNumber,
0f, -DisplayUtils.dp2px(this, 90)),
ViewExtensionKt.transYAnimation(Reset_SMSRegion,
0f, -DisplayUtils.dp2px(this, 90)),
ViewExtensionKt.transYAnimation(btnReset,
0f, -DisplayUtils.dp2px(this, 90)));
}else{
ViewExtensionKt.animer200(imageView_imgLogo,
ViewExtensionKt.scaleXAnimation(imageView_imgLogo,0.5f, 1f),
ViewExtensionKt.scaleYAnimation(imageView_imgLogo,0.5f, 1f),
ViewExtensionKt.transYAnimation(imageView_imgLogo,
0f, -DisplayUtils.dp2px(this, 40),0f),
ViewExtensionKt.transYAnimation(etUsername,
0f, -DisplayUtils.dp2px(this, 90),0f),
ViewExtensionKt.transYAnimation(etOldPassword,
0f, -DisplayUtils.dp2px(this, 90),0f),
ViewExtensionKt.transYAnimation(etPassword,
0f, -DisplayUtils.dp2px(this, 90),0f),
ViewExtensionKt.transYAnimation(etPassword2,
0f, -DisplayUtils.dp2px(this, 90),0f),
ViewExtensionKt.transYAnimation(Reset_SMSPhoneNumber,
0f, -DisplayUtils.dp2px(this, 90),0f),
ViewExtensionKt.transYAnimation(Reset_SMSRegion,
0f, -DisplayUtils.dp2px(this, 90),0f),
ViewExtensionKt.transYAnimation(btnReset,
0f, -DisplayUtils.dp2px(this, 90),0f));
}
return null;
});
}
@NotNull
@Override
public ResetActivityPresenter onCreatePresenter() {
return new ResetActivityPresenter(this);
}
@Override
public void loginSuccess() {
loginSuccess("登录成功");
}
@Override
public void loginSuccess(String successMsg) {
// 关闭activity
finish();
}
@Override
public void loginFailed(String errMsg) {
showWarning("登录失败: "+errMsg);
btnReset.revertAnimation();
}
@Override
public void syncVpnInfoSuccess() {
showSuccess("从VMS同步VPN服务器信息成功");
}
@Override
public void syncVpnInfoFailed() {
showWarning("从VMS同步VPN服务器信息失败");
}
}
@@ -0,0 +1,47 @@
package com.pkusz.min_vpn_client.activity.reset;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 16:28 2021/6/28
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
import android.content.Context;
import com.pkusz.min_vpn_client.activity.base.MINVpnBaseView;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalGetVpnInfoRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalLoginRequest;
import cn.qjm253.quick_android_mvp.base.mvp.BaseModel;
import cn.qjm253.quick_android_mvp.base.mvp.BasePresenter;
public interface ResetActivityContract {
interface View extends MINVpnBaseView {
void loginSuccess();
void loginSuccess(String successMsg);
void loginFailed(String errMsg);
void syncVpnInfoSuccess();
void syncVpnInfoFailed();
}
interface Model extends BaseModel {
void login(OriginalLoginRequest loginRequest);
void loginWithSafetyInfo(OriginalLoginRequest loginRequest, Context context);
void downloadRegisterFacePicture(String username, OriginalLoginRequest loginRequest, Context context);
void syncVpnServersInfo(OriginalGetVpnInfoRequest serverRequest);
}
abstract class Presenter extends BasePresenter<ResetActivityContract.View, ResetActivityContract.Model> {
void loginSuccess(){}
void loginSuccess(String successMsg){}
void loginFailed(String errMsg){}
void syncVpnInfoSuccess(){}
void syncVpnInfoFailed(){}
void login(OriginalLoginRequest loginRequest){}
void loginWithSafetyInfo(OriginalLoginRequest loginRequest, Context context){}
void downloadRegisterFacePicture(String username, OriginalLoginRequest loginRequest, Context context){}
void syncVpnServersInfo(OriginalGetVpnInfoRequest serverRequest){}
}
}
@@ -0,0 +1,69 @@
package com.pkusz.min_vpn_client.activity.reset;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 16:37 2021/6/28
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
import android.content.Context;
import com.pkusz.min_vpn_client.activity.login.LoginActivityContract;
import com.pkusz.min_vpn_client.activity.login.LoginActivityPresenter;
import com.pkusz.min_vpn_client.model.MINVpnSettingAPI;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalGetVpnInfoRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalLoginRequest;
import com.pkusz.min_vpn_client.model.Response.VpnServerInfoList;
import com.pkusz.min_vpn_client.model.VMSRequestAPI;
import common.LoggerHelper;
public class ResetActivityModel implements ResetActivityContract.Model{
private ResetActivityPresenter mPresenter;
public ResetActivityModel(ResetActivityPresenter presenter){
this.mPresenter=presenter;
}
@Override
public void login(OriginalLoginRequest loginRequest) {
Integer resCode = VMSRequestAPI.INSTANCE.login(loginRequest);
if(resCode==null) {
mPresenter.loginFailed("登录失败,未成功收到VMS的合法应答");
}else if(resCode==200) {
mPresenter.loginSuccess();
}else{
mPresenter.loginFailed("登录失败,VMS应答码为"+resCode);
}
}
@Override
public void loginWithSafetyInfo(OriginalLoginRequest loginRequest, Context context) {
// 废弃接口
LoggerHelper.warning("model.loginWithSafetyInfo: 暂停使用含有mac地址等安全信息的登录功能");
}
@Override
public void downloadRegisterFacePicture(String username, OriginalLoginRequest loginRequest, Context context) {
// 废弃接口
LoggerHelper.warning("model.downloadRegisterFacePicture: 暂停人脸识别登录功能");
}
/**
* 从VMS中获取VPNServer的最新信息。同步到客户端
* @param serverRequest
*/
@Override
public void syncVpnServersInfo(OriginalGetVpnInfoRequest serverRequest) {
VpnServerInfoList infoList = VMSRequestAPI.INSTANCE.getVPNServerInfoList(serverRequest);
if(infoList==null){
mPresenter.syncVpnInfoFailed();
}else{
// 将信息同步到MINVpnSettingAPI
MINVpnSettingAPI.INSTANCE.updateVpnServerInfoList(infoList);
// 通知界面
mPresenter.syncVpnInfoSuccess();
}
}
}
@@ -0,0 +1,68 @@
package com.pkusz.min_vpn_client.activity.reset;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 16:35 2021/6/28
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
import android.content.Context;
import com.pkusz.min_vpn_client.activity.login.LoginActivity;
import com.pkusz.min_vpn_client.activity.login.LoginActivityContract;
import com.pkusz.min_vpn_client.activity.login.LoginActivityModel;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalGetVpnInfoRequest;
import com.pkusz.min_vpn_client.model.OriginalRequest.OriginalLoginRequest;
public class ResetActivityPresenter extends ResetActivityContract.Presenter{
public ResetActivityPresenter(ResetActivity resetActivity){
mView=resetActivity;
mModel=new ResetActivityModel(this);
}
@Override
void loginSuccess() {
mView.loginSuccess();
}
@Override
void loginSuccess(String successMsg) {
mView.loginSuccess(successMsg);
}
@Override
void loginFailed(String errMsg) {
mView.loginFailed(errMsg);
}
@Override
void syncVpnInfoSuccess() {
mView.syncVpnInfoSuccess();
}
@Override
void syncVpnInfoFailed() {
mView.syncVpnInfoFailed();
}
@Override
void login(OriginalLoginRequest loginRequest) {
mModel.login(loginRequest);
}
@Override
void loginWithSafetyInfo(OriginalLoginRequest loginRequest, Context context) {
mModel.loginWithSafetyInfo(loginRequest, context);
}
@Override
void downloadRegisterFacePicture(String username, OriginalLoginRequest loginRequest, Context context) {
mModel.downloadRegisterFacePicture(username, loginRequest, context);
}
@Override
void syncVpnServersInfo(OriginalGetVpnInfoRequest serverRequest) {
mModel.syncVpnServersInfo(serverRequest);
}
}
+73 -6
View File
@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="cn.qjm253.min_vpn.activity.login.LoginActivity">
tools:context="com.pkusz.min_vpn_client.activity.reset.ResetActivity">
<include
android:id="@+id/include"
layout="@layout/bar_item" />
@@ -52,7 +52,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/etusername"
app:left_drawable="@drawable/mine"
app:left_drawable="@drawable/password"
app:right_drawable="@drawable/delete"
app:tinColor="@color/light_grey" />
@@ -92,9 +92,76 @@
app:right_drawable="@drawable/delete"
app:tinColor="@color/light_grey" />
<cn.qjm253.quick_android_custom_view.other.ClearAbleEditText
android:id="@+id/Reset_SMSPhoneNumber"
style="@style/login_et_style"
android:layout_marginStart="40dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="40dp"
android:hint="@string/phone_number"
android:inputType="number"
app:drawable_height="20dp"
app:drawable_width="20dp"
app:focusedTinColor="@color/colorPrimary"
app:layout_constraintEnd_toEndOf="@+id/etPassword2"
app:layout_constraintStart_toStartOf="@+id/etPassword2"
app:layout_constraintTop_toBottomOf="@+id/etPassword2"
app:left_drawable="@drawable/phone"
app:right_drawable="@drawable/delete"
app:tinColor="@color/light_grey" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/Reset_SMSRegion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="@dimen/dp_10"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/Reset_SMSPhoneNumber"
>
<com.jkb.vcedittext.VerificationCodeEditText
android:id="@+id/Reset_etSMSNumber"
android:layout_width="0dp"
android:layout_height="@dimen/dp_40"
android:inputType="number"
android:textColor="@color/black"
android:textSize="20sp"
android:layout_marginStart="40dp"
android:layout_marginEnd="10dp"
app:bottomLineHeight="2dp"
app:bottomLineNormalColor="@color/grey"
app:bottomLineSelectedColor="@color/grey"
app:figures="6"
app:selectedBackgroundColor="@color/transparent"
app:verCodeMargin="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="@id/Reset_getSMScode"
/>
<com.white.countdownbutton.CountDownButton
android:id="@+id/Reset_getSMScode"
android:layout_width="@dimen/dp_100"
android:layout_height="42dp"
android:text="获取验证码"
android:textSize="17.5dp"
android:gravity="center"
android:textColor="@drawable/countdownbutton_text"
android:background="@color/transparent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="40dp"
app:countDownFormat="%dS后重试"
app:countDown="60000"
app:countDownInterval="1000"
app:enableCountDown="true"
app:cdFinishText="重新获取"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<br.com.simplepass.loadingbutton.customViews.CircularProgressButton
android:id="@+id/btnLogin"
android:id="@+id/btnReset"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginStart="40dp"
@@ -105,9 +172,9 @@
android:textColor="@color/white"
app:finalCornerAngle="40dp"
app:initialCornerAngle="0dp"
app:layout_constraintLeft_toLeftOf="@id/etOldPassword"
app:layout_constraintRight_toRightOf="@id/etOldPassword"
app:layout_constraintTop_toBottomOf="@id/etPassword2"
app:layout_constraintLeft_toLeftOf="@id/Reset_SMSRegion"
app:layout_constraintRight_toRightOf="@id/Reset_SMSRegion"
app:layout_constraintTop_toBottomOf="@id/Reset_SMSRegion"
app:spinning_bar_color="#FFFFFF"
app:spinning_bar_padding="4dp"
app:spinning_bar_width="3dp" />