From 9048f0067ca220fe90ee41bb9a05b125119b4cb3 Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期五, 14 三月 2025 10:58:14 +0800
Subject: [PATCH] add: 验证码接口
---
app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt | 58 +++++++++++++++++-----------
app/src/main/java/com/example/firstapp/database/service/ApiService.kt | 8 ++++
app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt | 20 +++++++++
app/src/main/java/com/example/firstapp/database/response/LoginResponse.kt | 7 +++
4 files changed, 69 insertions(+), 24 deletions(-)
diff --git a/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt b/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt
index eb53f35..457e213 100644
--- a/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt
+++ b/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt
@@ -38,7 +38,6 @@
if (phone.length == 11) {
viewModel.sendVerificationCode(phone)
startCountDown()
-// 17625318565 111111
} else {
Toast.makeText(this@PhoneLoginActivity,
"请输入正确的手机号", Toast.LENGTH_SHORT).show()
@@ -59,12 +58,31 @@
}
private fun observeViewModel() {
+ // 观察登录状态
viewModel.loginState.observe(this) { isLoggedIn ->
if (isLoggedIn) {
startActivity(Intent(this, MainActivity::class.java))
finishAffinity() // 结束所有之前的Activity
}
}
+ // 观察消息提示
+ viewModel.loginMessage.observe(this) { message ->
+ Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
+ if (message == "验证码已发送") {
+ startCountDown()
+ }
+ }
+
+ // 观察加载状态
+ viewModel.isLoading.observe(this) { isLoading ->
+ binding.btnLogin.isEnabled = !isLoading
+ if (isLoading) {
+ binding.btnLogin.text = "登录中..."
+ } else {
+ binding.btnLogin.text = "登录"
+ }
+ }
+
}
private fun startCountDown() {
diff --git a/app/src/main/java/com/example/firstapp/database/response/LoginResponse.kt b/app/src/main/java/com/example/firstapp/database/response/LoginResponse.kt
new file mode 100644
index 0000000..8823c85
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/database/response/LoginResponse.kt
@@ -0,0 +1,7 @@
+package com.example.firstapp.database.response
+
+data class LoginResponse(
+ val code: Int,
+ val msg: String,
+ val data: Boolean
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/service/ApiService.kt b/app/src/main/java/com/example/firstapp/database/service/ApiService.kt
index f88e5ec..68be728 100644
--- a/app/src/main/java/com/example/firstapp/database/service/ApiService.kt
+++ b/app/src/main/java/com/example/firstapp/database/service/ApiService.kt
@@ -4,9 +4,11 @@
import com.example.firstapp.database.entity.KeywordConfig
import com.example.firstapp.database.response.ContentResponse
import com.example.firstapp.database.response.DictResponse
+import com.example.firstapp.database.response.LoginResponse
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
+import retrofit2.http.POST
import retrofit2.http.Query
/**
@@ -22,6 +24,12 @@
@GET("sysDict/getByDictCodeAndItemText")
suspend fun getDictValue(@Query("dictCode") dictCode: String, @Query("itemText") itemText: String): DictResponse
+
+ @POST("sms/send-code")
+ suspend fun sendVerificationCode(@Query("phone") phone: String): LoginResponse
+
+ @POST("sms/login")
+ suspend fun verifyCode(@Query("phone") phone: String, @Query("code") code: String): LoginResponse
}
// 创建Retrofit实例(单例)
diff --git a/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt b/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt
index 6d102f4..1526f66 100644
--- a/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt
+++ b/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt
@@ -1,45 +1,57 @@
package com.example.firstapp.ui.login
-import android.app.Application
-import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
-import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
-import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.ViewModel
+import com.example.firstapp.database.service.RetrofitClient
-class LoginViewModel(application: Application) : AndroidViewModel(application) {
+class LoginViewModel : ViewModel() {
private val _loginState = MutableLiveData<Boolean>()
val loginState: LiveData<Boolean> = _loginState
+ private val _loginMessage = MutableLiveData<String>()
+ val loginMessage: LiveData<String> = _loginMessage
+
+ private val _isLoading = MutableLiveData<Boolean>()
+ val isLoading: LiveData<Boolean> = _isLoading
+
fun sendVerificationCode(phone: String) {
viewModelScope.launch {
- // 这里实现发送验证码的逻辑
- // 模拟网络请求
- delay(1000)
- // 实际应用中需要调用后端API
+ _isLoading.value = true
+ try {
+ val response = RetrofitClient.apiService.sendVerificationCode(phone)
+ if (response.code == 200) {
+ _loginMessage.value = "验证码已发送"
+ } else {
+ _loginMessage.value = response.msg.ifEmpty { "发送验证码失败" }
+ }
+ } catch (e: Exception) {
+ _loginMessage.value = "网络错误,请稍后重试"
+ } finally {
+ _isLoading.value = false
+ }
}
}
fun login(phone: String, code: String) {
viewModelScope.launch {
- // 模拟登录请求
- delay(1000)
- // 保存登录状态和手机号
- saveLoginInfo(phone)
- _loginState.value = true
+ _isLoading.value = true
+ try {
+ val response = RetrofitClient.apiService.verifyCode(phone, code)
+ if (response.code == 200 && response.data) {
+ _loginState.value = true
+ } else {
+ _loginMessage.value = response.msg.ifEmpty { "登录失败" }
+ }
+ } catch (e: Exception) {
+ _loginMessage.value = "网络错误,请稍后重试"
+ } finally {
+ _isLoading.value = false
+ }
}
}
- private fun saveLoginInfo(phone: String) {
- getApplication<Application>().getSharedPreferences(
- "user_info", Context.MODE_PRIVATE
- ).edit().apply {
- putBoolean("is_logged_in", true)
- putString("phone", phone)
- apply()
- }
- }
}
\ No newline at end of file
--
Gitblit v1.9.3