1.1
tj
2025-04-09 2b446a5fd5d8f9b8c0f1e3acef1eef7ad9adb6f9
app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt
@@ -1,45 +1,98 @@
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.request.SmsLoginRequest
import com.example.firstapp.database.request.SmsSendRequest
import com.example.firstapp.database.service.RetrofitClient
import com.example.firstapp.utils.Log
import com.example.firstapp.ui.home.HomeViewModel
import com.example.firstapp.utils.PreferencesManager
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
    private lateinit var homeViewModel: HomeViewModel
    fun sendVerificationCode(phone: String) {
        viewModelScope.launch {
            // 这里实现发送验证码的逻辑
            // 模拟网络请求
            delay(1000)
            // 实际应用中需要调用后端API
            _isLoading.value = true
            try {
                // 创建 SmsSendRequest 对象
                val request = SmsSendRequest(
                    tel = phone,
                    userType = "customer"
                )
                //Retrofit 进行网络请求时,类名不需要完全一致,只要保证类的属性名称和类型与后端 DTO 对象的属性一致即可。
                //Retrofit + Gson 在序列化时会将对象转换为 JSON,后端 Spring 框架会将 JSON 反序列化为 SmsSendDTO 对象
                //HTTP 请求实际传输的是 JSON 格式的数据,而不是 Java/Kotlin 对象。
                val response = RetrofitClient.apiService.sendVerificationCode(request)
                if (response.code == 0) {
                    _loginMessage.value = "验证码已发送"
                } else {
                    _loginMessage.value = response.msg.ifEmpty { "发送验证码失败" }
                }
            } catch (e: Exception) {
                Log.e("LoginError", "Login failed: ${e.message}", e)
                _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 request = SmsLoginRequest(
                    username = phone,
                    smsCode = code,
                    userType = "customer"
                )
                //HttpServletRequest request这是后端 Spring 框架中的一个特殊参数,
                //用于获取 HTTP 请求的相关信息(如请求头、Cookie 等),它会由 Spring 框架自动注入,不需要客户端显式传递。
                val response = RetrofitClient.apiService.verifyCode(request)
                if (response.code == "0" && response.data != null) {
                    saveToken(response.data.value,phone)  // 这里获取的是 access_token
                    _loginState.value = true
                } else {
                    _loginMessage.value = response.msg.ifEmpty { "登录失败" }
                }
            } catch (e: Exception) {
                Log.e("LoginError", "Login failed: ${e.message}", e)
                _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()
    fun logout() {
        viewModelScope.launch {
            // 不再清除用户数据,只执行登出操作
            homeViewModel.logout()
            // 其他登出操作...
        }
    }
    private fun saveToken(token: String,phone:String) {
        // TODO: 实现token存储逻辑
        // 可能还需要存储 refresh_token
        PreferencesManager.saveToken(token)
        // 保存登录的手机号
        PreferencesManager.savePhone(phone)
    }
}