99 lines
3.9 KiB
Kotlin
99 lines
3.9 KiB
Kotlin
|
|
package com.pukka.mediaapp.viewmodel
|
|||
|
|
|
|||
|
|
import android.util.Log
|
|||
|
|
import androidx.lifecycle.ViewModel
|
|||
|
|
import androidx.lifecycle.viewModelScope
|
|||
|
|
import com.pukka.mediaapp.model.LayoutSection
|
|||
|
|
import com.pukka.mediaapp.model.NavItem
|
|||
|
|
import com.pukka.mediaapp.network.MediaRepository
|
|||
|
|
import com.pukka.mediaapp.utils.FileLogger
|
|||
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
|||
|
|
import kotlinx.coroutines.flow.StateFlow
|
|||
|
|
import kotlinx.coroutines.flow.asStateFlow
|
|||
|
|
import kotlinx.coroutines.launch
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 首页 ViewModel:负责导航栏数据与二级布局楼层数据。
|
|||
|
|
*/
|
|||
|
|
class HomeViewModel : ViewModel() {
|
|||
|
|
|
|||
|
|
private val repository = MediaRepository.getInstance()
|
|||
|
|
|
|||
|
|
private val _navItems = MutableStateFlow<List<NavItem>>(emptyList())
|
|||
|
|
val navItems: StateFlow<List<NavItem>> = _navItems.asStateFlow()
|
|||
|
|
|
|||
|
|
private val _sections = MutableStateFlow<List<LayoutSection>>(emptyList())
|
|||
|
|
val sections: StateFlow<List<LayoutSection>> = _sections.asStateFlow()
|
|||
|
|
|
|||
|
|
private val _loading = MutableStateFlow(false)
|
|||
|
|
val loading: StateFlow<Boolean> = _loading.asStateFlow()
|
|||
|
|
|
|||
|
|
private val _error = MutableStateFlow<String?>(null)
|
|||
|
|
val error: StateFlow<String?> = _error.asStateFlow()
|
|||
|
|
|
|||
|
|
/** 默认选中的导航项位置 */
|
|||
|
|
private val _selectedNavIndex = MutableStateFlow(0)
|
|||
|
|
val selectedNavIndex: StateFlow<Int> = _selectedNavIndex.asStateFlow()
|
|||
|
|
|
|||
|
|
private var hasLoadedNav = false
|
|||
|
|
|
|||
|
|
/** 加载首页导航,加载成功后默认请求 isFocus=1 的导航项对应的布局。 */
|
|||
|
|
fun loadNav() {
|
|||
|
|
if (hasLoadedNav) return
|
|||
|
|
viewModelScope.launch {
|
|||
|
|
_loading.value = true
|
|||
|
|
repository.getLayoutNav()
|
|||
|
|
.onSuccess { response ->
|
|||
|
|
val allItems = response.data
|
|||
|
|
?.flatMap { it.navList ?: emptyList() }
|
|||
|
|
?: emptyList()
|
|||
|
|
|
|||
|
|
// 只保留有布局数据的标签(type=1 为内容页)
|
|||
|
|
val contentItems = allItems.filter { it.type == 1 }
|
|||
|
|
_navItems.value = contentItems
|
|||
|
|
FileLogger.log("HomeVM", "导航加载: ${contentItems.size} 个标签, 默认选中=${contentItems.indexOfFirst { it.isFocus == "1" }}")
|
|||
|
|
hasLoadedNav = true
|
|||
|
|
if (contentItems.isNotEmpty()) {
|
|||
|
|
// 优先选 isFocus=="1" 的,否则选第一个
|
|||
|
|
val defaultIndex = contentItems.indexOfFirst { it.isFocus == "1" }
|
|||
|
|
val targetIndex = if (defaultIndex >= 0) defaultIndex else 0
|
|||
|
|
_selectedNavIndex.value = targetIndex
|
|||
|
|
loadLayout(contentItems[targetIndex].navid)
|
|||
|
|
} else {
|
|||
|
|
_loading.value = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
.onFailure {
|
|||
|
|
_error.value = it.message ?: "加载导航失败"
|
|||
|
|
_loading.value = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 根据 navid 加载二级页面布局(楼层列表)。 */
|
|||
|
|
fun loadLayout(navid: String) {
|
|||
|
|
if (navid.isEmpty()) return
|
|||
|
|
viewModelScope.launch {
|
|||
|
|
_loading.value = true
|
|||
|
|
repository.getLayout(navid)
|
|||
|
|
.onSuccess { response ->
|
|||
|
|
val sections = response.data ?: emptyList()
|
|||
|
|
Log.d("HomeViewModel", "loadLayout success: ${sections.size} sections")
|
|||
|
|
FileLogger.log("HomeVM", "布局加载: navid=$navid ${sections.size} 个楼层")
|
|||
|
|
_sections.value = sections
|
|||
|
|
}
|
|||
|
|
.onFailure {
|
|||
|
|
Log.e("HomeViewModel", "loadLayout failed", it)
|
|||
|
|
_error.value = it.message ?: "加载内容失败"
|
|||
|
|
_sections.value = emptyList()
|
|||
|
|
}
|
|||
|
|
_loading.value = false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/** 更新选中的导航索引 */
|
|||
|
|
fun selectNav(index: Int) {
|
|||
|
|
_selectedNavIndex.value = index
|
|||
|
|
}
|
|||
|
|
}
|