From e8244c0fad43e9c1afe68b31ff2d3a3209b4667c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E9=AA=90=E7=91=9E?= <3349293156@qq.com> Date: Sat, 18 Oct 2025 18:50:38 +0800 Subject: [PATCH 1/2] add --- .../.idea/deploymentTargetSelector.xml | 10 +- LLRiseTabBarDemo/app/build.gradle | 5 + .../app/src/main/AndroidManifest.xml | 2 + .../activity/ForgotPasswordActivity.java | 168 +++++++++++++++--- .../activity/LoginActivity.java | 101 ++++++++++- .../activity/RegisterActivity.java | 122 +++++++++++-- .../fragment/PersonFragment.java | 56 +++++- .../fragment/PublishFragment.java | 2 +- .../app/src/main/java/model/Item.java | 2 +- .../res/layout/activity_forgot_password.xml | 2 +- .../src/main/res/layout/fragment_person.xml | 31 +++- 11 files changed, 430 insertions(+), 71 deletions(-) diff --git a/LLRiseTabBarDemo/.idea/deploymentTargetSelector.xml b/LLRiseTabBarDemo/.idea/deploymentTargetSelector.xml index 3deff32..ebe5a47 100644 --- a/LLRiseTabBarDemo/.idea/deploymentTargetSelector.xml +++ b/LLRiseTabBarDemo/.idea/deploymentTargetSelector.xml @@ -2,16 +2,8 @@ - + diff --git a/LLRiseTabBarDemo/app/build.gradle b/LLRiseTabBarDemo/app/build.gradle index b27a390..6dc064d 100644 --- a/LLRiseTabBarDemo/app/build.gradle +++ b/LLRiseTabBarDemo/app/build.gradle @@ -54,6 +54,11 @@ dependencies { // 项目模块 implementation project(':mainnavigatetabbar') + // 网络请求库 + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0' + // 如果有其他依赖冲突,可以排除旧版本 configurations { all { diff --git a/LLRiseTabBarDemo/app/src/main/AndroidManifest.xml b/LLRiseTabBarDemo/app/src/main/AndroidManifest.xml index 6907bda..7a8e02c 100644 --- a/LLRiseTabBarDemo/app/src/main/AndroidManifest.xml +++ b/LLRiseTabBarDemo/app/src/main/AndroidManifest.xml @@ -4,6 +4,8 @@ package="com.startsmake.llrisetabbardemo"> + + attemptResetPassword()); // 返回登录 - tvLogin.setOnClickListener(v -> { - Intent intent = new Intent(ForgotPasswordActivity.this, LoginActivity.class); - startActivity(intent); - finish(); - }); + tvLogin.setOnClickListener(v -> navigateToLogin()); + } + + private void handleIntentExtras() { + Intent intent = getIntent(); + if (intent != null) { + String phone = intent.getStringExtra("phone"); + if (phone != null && !phone.isEmpty()) { + etPhone.setText(phone); + etVerificationCode.requestFocus(); + } + } } private void sendVerificationCode() { String phone = etPhone.getText().toString().trim(); - if (phone.isEmpty()) { - etPhone.setError("请输入手机号"); + if (!validatePhone(phone)) { return; } - if (phone.length() != 11) { - etPhone.setError("手机号格式不正确"); + // 检查用户是否存在 + if (!userManager.isUserExists(phone)) { + etPhone.setError("该手机号未注册"); + etPhone.requestFocus(); return; } if (!isCounting) { startCountDown(); - Toast.makeText(this, "验证码已发送", Toast.LENGTH_SHORT).show(); - // 这里应该调用后端API发送验证码 + + // 使用短信服务发送验证码 + smsManager.sendVerificationCode(phone, new SmsManager.SmsSendCallback() { + @Override + public void onSuccess(String code) { + verificationCode = code; + Toast.makeText(ForgotPasswordActivity.this, + "验证码已发送到手机尾号" + phone.substring(7), + Toast.LENGTH_SHORT).show(); + } + + @Override + public void onFailure(String error) { + Toast.makeText(ForgotPasswordActivity.this, + "验证码发送失败: " + error, + Toast.LENGTH_SHORT).show(); + resetCountDown(); + } + }); + } + } + + private boolean validatePhone(String phone) { + if (phone.isEmpty()) { + etPhone.setError("请输入手机号"); + etPhone.requestFocus(); + return false; + } + + if (phone.length() != 11) { + etPhone.setError("手机号格式不正确"); + etPhone.requestFocus(); + return false; } + + if (!phone.startsWith("1")) { + etPhone.setError("手机号格式不正确"); + etPhone.requestFocus(); + return false; + } + + return true; } private void startCountDown() { @@ -99,43 +157,111 @@ public class ForgotPasswordActivity extends AppCompatActivity { }.start(); } + private void resetCountDown() { + if (countDownTimer != null) { + countDownTimer.cancel(); + } + isCounting = false; + btnSendCode.setEnabled(true); + btnSendCode.setText("发送验证码"); + } + private void attemptResetPassword() { String phone = etPhone.getText().toString().trim(); String code = etVerificationCode.getText().toString().trim(); String newPassword = etNewPassword.getText().toString().trim(); + if (!validateResetInput(phone, code, newPassword)) { + return; + } + + // 验证验证码 + if (!code.equals(verificationCode)) { + etVerificationCode.setError("验证码错误"); + etVerificationCode.requestFocus(); + return; + } + + // 重置密码 + if (userManager.updatePassword(phone, newPassword)) { + performResetSuccess(phone); + } else { + Toast.makeText(this, "重置密码失败,请检查手机号是否正确", Toast.LENGTH_SHORT).show(); + } + } + + private boolean validateResetInput(String phone, String code, String newPassword) { if (phone.isEmpty()) { etPhone.setError("请输入手机号"); - return; + etPhone.requestFocus(); + return false; } if (code.isEmpty()) { etVerificationCode.setError("请输入验证码"); - return; + etVerificationCode.requestFocus(); + return false; } if (newPassword.isEmpty()) { etNewPassword.setError("请输入新密码"); - return; + etNewPassword.requestFocus(); + return false; } if (phone.length() != 11) { etPhone.setError("手机号格式不正确"); - return; + etPhone.requestFocus(); + return false; } if (newPassword.length() < 6) { etNewPassword.setError("密码至少6位"); - return; + etNewPassword.requestFocus(); + return false; + } + + // 检查密码强度(可选) + if (!isPasswordStrong(newPassword)) { + etNewPassword.setError("密码过于简单,建议包含字母和数字"); + etNewPassword.requestFocus(); + return false; + } + + return true; + } + + private boolean isPasswordStrong(String password) { + // 简单的密码强度检查:至少包含字母和数字 + boolean hasLetter = false; + boolean hasDigit = false; + + for (char c : password.toCharArray()) { + if (Character.isLetter(c)) { + hasLetter = true; + } else if (Character.isDigit(c)) { + hasDigit = true; + } } - // 模拟重置密码成功 - performResetPassword(); + return hasLetter && hasDigit; } - private void performResetPassword() { + private void performResetSuccess(String phone) { Toast.makeText(this, "密码重置成功!", Toast.LENGTH_SHORT).show(); - // 重置成功后跳转到登录页面 + + // 重置成功后跳转到登录页面,并传递手机号 + navigateToLoginWithPhone(phone); + } + + private void navigateToLoginWithPhone(String phone) { + Intent intent = new Intent(ForgotPasswordActivity.this, LoginActivity.class); + intent.putExtra("phone", phone); + startActivity(intent); + finish(); + } + + private void navigateToLogin() { Intent intent = new Intent(ForgotPasswordActivity.this, LoginActivity.class); startActivity(intent); finish(); @@ -148,4 +274,4 @@ public class ForgotPasswordActivity extends AppCompatActivity { countDownTimer.cancel(); } } -} +} \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/LoginActivity.java b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/LoginActivity.java index ef5b6a6..b387ac7 100644 --- a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/LoginActivity.java +++ b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/LoginActivity.java @@ -10,20 +10,43 @@ import androidx.appcompat.app.AppCompatActivity; import com.google.android.material.textfield.TextInputEditText; import com.startsmake.llrisetabbardemo.R; +import com.startsmake.llrisetabbardemo.manager.UserManager; +import com.startsmake.llrisetabbardemo.model.User; public class LoginActivity extends AppCompatActivity { private TextInputEditText etPhone, etPassword; private Button btnLogin, btnSkipLogin; private TextView tvForgotPassword, tvRegister; + private UserManager userManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); + // 初始化用户管理器 + userManager = UserManager.getInstance(this); + + // 临时注释掉自动跳转,便于测试登录流程 + + if (userManager.isLoggedIn()) { + navigateToMain(); + return; + } + + initViews(); setupClickListeners(); + setupDemoUsers(); + handleIntentExtras(); + + // 显示当前登录状态 + if (userManager.isLoggedIn()) { + User currentUser = userManager.getCurrentUser(); + etPhone.setText(currentUser.getPhone()); + Toast.makeText(this, "已登录用户: " + currentUser.getPhone(), Toast.LENGTH_LONG).show(); + } } private void initViews() { @@ -55,36 +78,84 @@ public class LoginActivity extends AppCompatActivity { }); } + // 处理从其他页面传递过来的数据 + private void handleIntentExtras() { + Intent intent = getIntent(); + if (intent != null) { + String phone = intent.getStringExtra("phone"); + if (phone != null && !phone.isEmpty()) { + etPhone.setText(phone); + etPassword.requestFocus(); // 自动聚焦到密码输入框 + } + } + } + private void attemptLogin() { String phone = etPhone.getText().toString().trim(); String password = etPassword.getText().toString().trim(); + if (!validateInput(phone, password)) { + return; + } + + // 验证用户登录 + if (userManager.validateLogin(phone, password)) { + // 登录成功 + userManager.saveUserLogin(phone, password); + performLoginSuccess(); + } else { + // 登录失败 + showLoginError(); + } + } + + private boolean validateInput(String phone, String password) { if (phone.isEmpty()) { etPhone.setError("请输入手机号"); - return; + etPhone.requestFocus(); + return false; } if (password.isEmpty()) { etPassword.setError("请输入密码"); - return; + etPassword.requestFocus(); + return false; } if (phone.length() != 11) { etPhone.setError("手机号格式不正确"); - return; + etPhone.requestFocus(); + return false; + } + + if (!phone.startsWith("1")) { + etPhone.setError("手机号格式不正确"); + etPhone.requestFocus(); + return false; + } + + if (password.length() < 6) { + etPassword.setError("密码至少6位"); + etPassword.requestFocus(); + return false; } - // 模拟登录成功(因为没有后端) - performLogin(); + return true; } - private void performLogin() { + private void performLoginSuccess() { Toast.makeText(this, "登录成功!", Toast.LENGTH_SHORT).show(); navigateToMain(); } + private void showLoginError() { + Toast.makeText(this, "手机号或密码错误", Toast.LENGTH_SHORT).show(); + etPassword.setError("密码错误"); + etPassword.requestFocus(); + } + private void skipToMain() { - Toast.makeText(this, "跳过登录,进入主界面", Toast.LENGTH_SHORT).show(); + Toast.makeText(this, "游客模式进入", Toast.LENGTH_SHORT).show(); navigateToMain(); } @@ -93,4 +164,18 @@ public class LoginActivity extends AppCompatActivity { startActivity(intent); finish(); } -} + + // 设置演示用户,便于测试 + private void setupDemoUsers() { + // 注册几个演示用户 + userManager.registerUser("13800138000", "123456"); + userManager.registerUser("13900139000", "123456"); + userManager.registerUser("15000150000", "123456"); + + // 可选:在控制台输出演示用户信息,便于测试 + System.out.println("演示用户已创建:"); + System.out.println("手机号:13800138000,密码:123456"); + System.out.println("手机号:13900139000,密码:123456"); + System.out.println("手机号:15000150000,密码:123456"); + } +} \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/RegisterActivity.java b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/RegisterActivity.java index b962695..810958d 100644 --- a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/RegisterActivity.java +++ b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/activity/RegisterActivity.java @@ -12,6 +12,10 @@ import androidx.appcompat.app.AppCompatActivity; import com.google.android.material.textfield.TextInputEditText; import com.startsmake.llrisetabbardemo.R; +import com.startsmake.llrisetabbardemo.manager.SmsManager; +import com.startsmake.llrisetabbardemo.manager.UserManager; + +import java.util.Random; public class RegisterActivity extends AppCompatActivity { @@ -22,12 +26,18 @@ public class RegisterActivity extends AppCompatActivity { private CountDownTimer countDownTimer; private boolean isCounting = false; + private String verificationCode = ""; + private UserManager userManager; + private SmsManager smsManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); + userManager = UserManager.getInstance(this); + smsManager = SmsManager.getInstance(this); // 初始化 SmsManager + initViews(); setupClickListeners(); } @@ -63,21 +73,62 @@ public class RegisterActivity extends AppCompatActivity { private void sendVerificationCode() { String phone = etPhone.getText().toString().trim(); - if (phone.isEmpty()) { - etPhone.setError("请输入手机号"); + if (!validatePhone(phone)) { return; } - if (phone.length() != 11) { - etPhone.setError("手机号格式不正确"); + // 检查用户是否已存在 + if (userManager.isUserExists(phone)) { + etPhone.setError("该手机号已注册"); + etPhone.requestFocus(); return; } if (!isCounting) { startCountDown(); - Toast.makeText(this, "验证码已发送", Toast.LENGTH_SHORT).show(); - // 这里应该调用后端API发送验证码 + + // 使用短信服务发送验证码 + smsManager.sendVerificationCode(phone, new SmsManager.SmsSendCallback() { + @Override + public void onSuccess(String code) { + verificationCode = code; + Toast.makeText(RegisterActivity.this, + "验证码已发送到手机尾号" + phone.substring(7), + Toast.LENGTH_SHORT).show(); + } + + @Override + public void onFailure(String error) { + Toast.makeText(RegisterActivity.this, + "验证码发送失败: " + error, + Toast.LENGTH_SHORT).show(); + // 重置倒计时 + resetCountDown(); + } + }); + } + } + + private boolean validatePhone(String phone) { + if (phone.isEmpty()) { + etPhone.setError("请输入手机号"); + etPhone.requestFocus(); + return false; + } + + if (phone.length() != 11) { + etPhone.setError("手机号格式不正确"); + etPhone.requestFocus(); + return false; } + + if (!phone.startsWith("1")) { + etPhone.setError("手机号格式不正确"); + etPhone.requestFocus(); + return false; + } + + return true; } private void startCountDown() { @@ -99,44 +150,83 @@ public class RegisterActivity extends AppCompatActivity { }.start(); } + private void resetCountDown() { + if (countDownTimer != null) { + countDownTimer.cancel(); + } + isCounting = false; + btnSendCode.setEnabled(true); + btnSendCode.setText("发送验证码"); + } + private void attemptRegister() { String phone = etPhone.getText().toString().trim(); String code = etVerificationCode.getText().toString().trim(); String password = etPassword.getText().toString().trim(); + if (!validateRegisterInput(phone, code, password)) { + return; + } + + // 验证验证码 + if (!code.equals(verificationCode)) { + etVerificationCode.setError("验证码错误"); + etVerificationCode.requestFocus(); + return; + } + + // 注册用户 + if (userManager.registerUser(phone, password)) { + performRegisterSuccess(); + } else { + Toast.makeText(this, "注册失败,用户已存在", Toast.LENGTH_SHORT).show(); + } + } + + private boolean validateRegisterInput(String phone, String code, String password) { if (phone.isEmpty()) { etPhone.setError("请输入手机号"); - return; + etPhone.requestFocus(); + return false; } if (code.isEmpty()) { etVerificationCode.setError("请输入验证码"); - return; + etVerificationCode.requestFocus(); + return false; } if (password.isEmpty()) { etPassword.setError("请输入密码"); - return; + etPassword.requestFocus(); + return false; } if (phone.length() != 11) { etPhone.setError("手机号格式不正确"); - return; + etPhone.requestFocus(); + return false; } if (password.length() < 6) { etPassword.setError("密码至少6位"); - return; + etPassword.requestFocus(); + return false; } - // 模拟注册成功 - performRegister(); + return true; } - private void performRegister() { + private void performRegisterSuccess() { Toast.makeText(this, "注册成功!", Toast.LENGTH_SHORT).show(); - // 注册成功后跳转到登录页面 - Intent intent = new Intent(RegisterActivity.this, LoginActivity.class); + + // 自动登录 + String phone = etPhone.getText().toString().trim(); + String password = etPassword.getText().toString().trim(); + userManager.saveUserLogin(phone, password); + + // 跳转到主页面 + Intent intent = new Intent(RegisterActivity.this, MainActivity.class); startActivity(intent); finish(); } diff --git a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PersonFragment.java b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PersonFragment.java index fc8327b..181b128 100644 --- a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PersonFragment.java +++ b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PersonFragment.java @@ -1,26 +1,68 @@ package com.startsmake.llrisetabbardemo.fragment; +import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; -// 改为 AndroidX import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import com.startsmake.llrisetabbardemo.R; +import com.startsmake.llrisetabbardemo.activity.LoginActivity; +import com.startsmake.llrisetabbardemo.manager.UserManager; +import com.startsmake.llrisetabbardemo.model.User; -/** - * User:Shine - * Date:2015-10-20 - * Description: - */ public class PersonFragment extends Fragment { + private TextView tvUserInfo; + private Button btnLogout; + private UserManager userManager; + @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_person, container, false); + View view = inflater.inflate(R.layout.fragment_person, container, false); + + userManager = UserManager.getInstance(requireContext()); + initViews(view); + setupUserInfo(); + setupClickListeners(); + + return view; + } + + private void initViews(View view) { + tvUserInfo = view.findViewById(R.id.tv_user_info); + btnLogout = view.findViewById(R.id.btn_logout); + } + + private void setupUserInfo() { + if (userManager.isLoggedIn()) { + User user = userManager.getCurrentUser(); + tvUserInfo.setText("欢迎," + user.getNickname() + "\n手机号: " + user.getPhone()); + btnLogout.setVisibility(View.VISIBLE); + } else { + tvUserInfo.setText("游客模式"); + btnLogout.setVisibility(View.GONE); + } + } + + private void setupClickListeners() { + btnLogout.setOnClickListener(v -> logout()); + } + + private void logout() { + userManager.logout(); + Toast.makeText(getContext(), "已登出", Toast.LENGTH_SHORT).show(); + + // 跳转回登录页面 + Intent intent = new Intent(getActivity(), LoginActivity.class); + startActivity(intent); + getActivity().finish(); } } \ No newline at end of file diff --git a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PublishFragment.java b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PublishFragment.java index c6152c8..983fcd2 100644 --- a/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PublishFragment.java +++ b/LLRiseTabBarDemo/app/src/main/java/com/startsmake/llrisetabbardemo/fragment/PublishFragment.java @@ -22,7 +22,7 @@ import com.startsmake.llrisetabbardemo.R; import com.startsmake.llrisetabbardemo.activity.MainActivity; import com.startsmake.llrisetabbardemo.adapter.ImageAdapter; -import com.startsmake.llrisetabbardemo.model.Item; +import model.Item; import java.util.ArrayList; import java.util.List; diff --git a/LLRiseTabBarDemo/app/src/main/java/model/Item.java b/LLRiseTabBarDemo/app/src/main/java/model/Item.java index d5e58bf..2e6697e 100644 --- a/LLRiseTabBarDemo/app/src/main/java/model/Item.java +++ b/LLRiseTabBarDemo/app/src/main/java/model/Item.java @@ -1,4 +1,4 @@ -package com.startsmake.llrisetabbardemo.model; +package model; import java.io.Serializable; import java.util.ArrayList; diff --git a/LLRiseTabBarDemo/app/src/main/res/layout/activity_forgot_password.xml b/LLRiseTabBarDemo/app/src/main/res/layout/activity_forgot_password.xml index 6888595..17b4125 100644 --- a/LLRiseTabBarDemo/app/src/main/res/layout/activity_forgot_password.xml +++ b/LLRiseTabBarDemo/app/src/main/res/layout/activity_forgot_password.xml @@ -49,7 +49,7 @@ android:id="@+id/et_phone" android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="手机号" + android:hint="注册手机号" android:inputType="phone" android:maxLines="1" android:padding="16dp" diff --git a/LLRiseTabBarDemo/app/src/main/res/layout/fragment_person.xml b/LLRiseTabBarDemo/app/src/main/res/layout/fragment_person.xml index 9151ffd..1e80014 100644 --- a/LLRiseTabBarDemo/app/src/main/res/layout/fragment_person.xml +++ b/LLRiseTabBarDemo/app/src/main/res/layout/fragment_person.xml @@ -1,14 +1,31 @@ - + android:orientation="vertical" + android:padding="16dp"> + android:layout_marginTop="50dp" + android:gravity="center" + android:text="用户信息" + android:textColor="#333333" + android:textSize="18sp" + android:textStyle="bold" /> - \ No newline at end of file +