From 81f6c5e759afb637df981b3faf7e8e0bcaa2b6ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=9C=A8=E5=9D=A4?= Date: Wed, 21 Jan 2026 18:18:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=92=8C=E4=B8=AA=E4=BA=BA=E8=B5=84=E6=96=99ViewModel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增PaymentViewModel处理支付和订单逻辑 - 新增ProfileViewModel处理用户资料逻辑 - 更新ViewModelFactory支持新的ViewModel --- .../ui/viewmodel/PaymentViewModel.kt | 98 +++++++++++++++++++ .../ui/viewmodel/ProfileViewModel.kt | 74 ++++++++++++++ .../ui/viewmodel/ViewModelFactory.kt | 24 ++++- 3 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/PaymentViewModel.kt create mode 100644 app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/ProfileViewModel.kt diff --git a/app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/PaymentViewModel.kt b/app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/PaymentViewModel.kt new file mode 100644 index 0000000..bec8363 --- /dev/null +++ b/app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/PaymentViewModel.kt @@ -0,0 +1,98 @@ +package com.huaga.life_echo.ui.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.huaga.life_echo.data.repository.PaymentRepository +import com.huaga.life_echo.network.models.OrderDto +import com.huaga.life_echo.network.models.PlanDto +import com.huaga.life_echo.network.models.QuotaCheckDto +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch + +class PaymentViewModel( + private val paymentRepository: PaymentRepository +) : ViewModel() { + + private val _plans = MutableStateFlow>(emptyList()) + val plans: StateFlow> = _plans + + private val _currentPlan = MutableStateFlow(null) + val currentPlan: StateFlow = _currentPlan + + private val _quota = MutableStateFlow(null) + val quota: StateFlow = _quota + + private val _orders = MutableStateFlow>(emptyList()) + val orders: StateFlow> = _orders + + private val _isLoading = MutableStateFlow(false) + val isLoading: StateFlow = _isLoading + + private val _error = MutableStateFlow(null) + val error: StateFlow = _error + + init { + loadPlans() + loadCurrentPlan() + checkQuota() + loadOrders() + } + + fun loadPlans() { + viewModelScope.launch { + _isLoading.value = true + _error.value = null + paymentRepository.getPlans().fold( + onSuccess = { _plans.value = it }, + onFailure = { _error.value = it.message } + ) + _isLoading.value = false + } + } + + fun loadCurrentPlan() { + viewModelScope.launch { + paymentRepository.getCurrentPlan().fold( + onSuccess = { _currentPlan.value = it }, + onFailure = { } + ) + } + } + + fun checkQuota() { + viewModelScope.launch { + paymentRepository.checkQuota().fold( + onSuccess = { _quota.value = it }, + onFailure = { } + ) + } + } + + fun createOrder(planId: String, onSuccess: (OrderDto) -> Unit, onError: (String) -> Unit) { + viewModelScope.launch { + _isLoading.value = true + _error.value = null + paymentRepository.createOrder(planId).fold( + onSuccess = { + _isLoading.value = false + onSuccess(it) + }, + onFailure = { + _isLoading.value = false + _error.value = it.message + onError(it.message ?: "创建订单失败") + } + ) + } + } + + fun loadOrders() { + viewModelScope.launch { + paymentRepository.getOrders().fold( + onSuccess = { _orders.value = it }, + onFailure = { } + ) + } + } +} diff --git a/app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/ProfileViewModel.kt b/app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/ProfileViewModel.kt new file mode 100644 index 0000000..7d1ef7f --- /dev/null +++ b/app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/ProfileViewModel.kt @@ -0,0 +1,74 @@ +package com.huaga.life_echo.ui.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.huaga.life_echo.data.repository.ProfileRepository +import com.huaga.life_echo.network.models.FAQDto +import com.huaga.life_echo.network.models.UserProfileDto +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch + +class ProfileViewModel( + private val profileRepository: ProfileRepository +) : ViewModel() { + + private val _userProfile = MutableStateFlow(null) + val userProfile: StateFlow = _userProfile + + private val _faqs = MutableStateFlow>(emptyList()) + val faqs: StateFlow> = _faqs + + private val _isLoading = MutableStateFlow(false) + val isLoading: StateFlow = _isLoading + + private val _error = MutableStateFlow(null) + val error: StateFlow = _error + + init { + loadUserProfile() + loadFAQs() + } + + fun loadUserProfile() { + viewModelScope.launch { + _isLoading.value = true + profileRepository.getUserProfile().fold( + onSuccess = { + _userProfile.value = it + _isLoading.value = false + }, + onFailure = { + _error.value = it.message + _isLoading.value = false + } + ) + } + } + + fun loadFAQs() { + viewModelScope.launch { + profileRepository.getFAQs().fold( + onSuccess = { _faqs.value = it }, + onFailure = { } + ) + } + } + + fun submitFeedback(content: String, contact: String?, onSuccess: () -> Unit, onError: (String) -> Unit) { + viewModelScope.launch { + _isLoading.value = true + profileRepository.submitFeedback(content, contact).fold( + onSuccess = { + _isLoading.value = false + onSuccess() + }, + onFailure = { + _isLoading.value = false + _error.value = it.message + onError(it.message ?: "提交失败") + } + ) + } + } +} diff --git a/app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/ViewModelFactory.kt b/app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/ViewModelFactory.kt index 3d7a294..c1d4d05 100644 --- a/app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/ViewModelFactory.kt +++ b/app-android/app/src/main/java/com/huaga/life_echo/ui/viewmodel/ViewModelFactory.kt @@ -4,8 +4,7 @@ import android.content.Context import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import com.huaga.life_echo.data.database.AppDatabase -import com.huaga.life_echo.data.repository.ChapterRepository -import com.huaga.life_echo.data.repository.ConversationRepository +import com.huaga.life_echo.data.repository.* import com.huaga.life_echo.network.ApiService class ViewModelFactory(private val context: Context) : ViewModelProvider.Factory { @@ -14,7 +13,8 @@ class ViewModelFactory(private val context: Context) : ViewModelProvider.Factory private val conversationRepository by lazy { ConversationRepository( conversationDao = database.conversationDao(), - segmentDao = database.conversationSegmentDao() + segmentDao = database.conversationSegmentDao(), + apiService = apiService ) } private val chapterRepository by lazy { @@ -24,6 +24,14 @@ class ViewModelFactory(private val context: Context) : ViewModelProvider.Factory } private val apiService by lazy { ApiService() } + private val paymentRepository by lazy { + PaymentRepository(apiService = apiService) + } + + private val profileRepository by lazy { + ProfileRepository(apiService = apiService) + } + @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { return when { @@ -48,6 +56,16 @@ class ViewModelFactory(private val context: Context) : ViewModelProvider.Factory modelClass.isAssignableFrom(AuthViewModel::class.java) -> { AuthViewModel(context = context) as T } + modelClass.isAssignableFrom(PaymentViewModel::class.java) -> { + PaymentViewModel( + paymentRepository = paymentRepository + ) as T + } + modelClass.isAssignableFrom(ProfileViewModel::class.java) -> { + ProfileViewModel( + profileRepository = profileRepository + ) as T + } else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}") } }