zhujie
10 天以前 88b00f3fc74446a1727c93722c7b64179b45a9db
app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt
@@ -14,32 +14,45 @@
import com.example.firstapp.model.ExpressPackage
import com.example.firstapp.model.FinanceGroup
import com.example.firstapp.model.FinancePackage
import com.example.firstapp.model.IncomeGroup
import com.example.firstapp.model.IncomePackage
import com.example.firstapp.util.SecureStorage
import com.example.firstapp.utils.PreferencesManager
import kotlinx.coroutines.launch
import com.example.firstapp.database.repository.ReminderRecordRepository
import com.example.firstapp.database.entity.ReminderRecord
import com.example.firstapp.model.TrainGroup
import com.example.firstapp.model.TrainPackage
import com.example.firstapp.model.FlightGroup
import com.example.firstapp.model.FlightPackage
class HomeViewModel : ViewModel() {
    private val _expressItems = MutableLiveData<List<ExpressGroup>>()
    private val _financeItems = MutableLiveData<List<FinanceGroup>>()
    private val _incomeItems = MutableLiveData<List<FinanceGroup>>()
    private val _flightItems = MutableLiveData<List<FinanceGroup>>()
    private val _trainItems = MutableLiveData<List<FinanceGroup>>()
    private val _incomeItems = MutableLiveData<List<IncomeGroup>>()
    private val _flightItems = MutableLiveData<List<FlightGroup>>()
    private val _trainItems = MutableLiveData<List<TrainGroup>>()
    
    val expressItems: LiveData<List<ExpressGroup>> = _expressItems
    val financeItems: LiveData<List<FinanceGroup>> = _financeItems
    val incomeItems: LiveData<List<FinanceGroup>> = _incomeItems
    val flightItems: LiveData<List<FinanceGroup>> = _flightItems
    val trainItems: LiveData<List<FinanceGroup>> = _trainItems
    val incomeItems: LiveData<List<IncomeGroup>> = _incomeItems
    val flightItems: LiveData<List<FlightGroup>> = _flightItems
    val trainItems: LiveData<List<TrainGroup>> = _trainItems
    private val _categories = MutableLiveData<List<CategoryConfig>>()
    val categories: LiveData<List<CategoryConfig>> = _categories
    // 添加可见分类的 LiveData
    private val _visibleCategories = MutableLiveData<List<String>>()
    val visibleCategories: LiveData<List<String>> = _visibleCategories
    private val _visibleCategories = MutableLiveData<List<CategoryConfig>>()
    val visibleCategories: LiveData<List<CategoryConfig>> = _visibleCategories
    private val _unreadReminderCount = MutableLiveData<Int>()
    val unreadReminderCount: LiveData<Int> = _unreadReminderCount
    private lateinit var secureStorage: SecureStorage
    private lateinit var currentUserId: String
    private var currentUserId: String = ""
    private lateinit var reminderRecordRepository: ReminderRecordRepository
    private var categoriesLoaded = false
    init {
        // 初始化时加载包裹列表数据
@@ -51,180 +64,287 @@
    fun initialize(context: Context, userId: String) {
        secureStorage = SecureStorage(context)
        currentUserId = userId
        loadCategories()
        reminderRecordRepository = ReminderRecordRepository(context)
        // 只在首次加载或者用户修改分类后加载分类数据
        if (!categoriesLoaded) {
            loadCategories()
            categoriesLoaded = true
        }
        // 初始化时更新可见分类
        _categories.value?.let { updateVisibleCategories(it) }
        // 加载未读提醒数量
        checkUnreadReminders()
    }
    fun loadExpressData() {
        viewModelScope.launch {
            // 1. 获取所有驿站类型的提醒设置
            val stations = Core.reminder.getByType("快递")
            // 2. 按驿站分组获取包裹信息
            val groups = stations.map { station ->
                val packages = Core.code.getByKeyword(station.nickname).map { code ->
                    ExpressPackage(
                        id = code.id, //ID
                        company = code.secondLevel, //快递公司
                        trackingNumber = code.code, // 取件码
                        createTime = code.createTime  //快递时间
                    )
                }
                ExpressGroup(
                    stationName = station.nickname, packages = packages
                )
            }
            _expressItems.postValue(groups)
        }
    }
    fun loadFinanceData() {
        viewModelScope.launch {
            // 1. 获取所有驿站类型的提醒设置
            val stations = Core.reminder.getByType("还款")
            // 2. 按驿站分组获取包裹信息
            val groups = stations.map { station ->
                val packages = Core.code.getByKeyword(station.nickname).map { code ->
                    FinancePackage(
                        id = code.id, //ID
                        company = code.secondLevel, //快递公司
                        trackingNumber = code.code, // 取件码
                        createTime = code.createTime  //快递时间
                    )
                }
                FinanceGroup(
                    stationName = station.nickname, packages = packages
                )
            }
            _financeItems.postValue(groups)
        }
    }
    fun loadIncomeData() {
        viewModelScope.launch {
            val stations = Core.reminder.getByType("收入")
            val groups = stations.map { station ->
                val packages = Core.code.getByKeyword(station.nickname).map { code ->
                    FinancePackage(
                        id = code.id,
                        company = code.secondLevel,
                        trackingNumber = code.code,
                        createTime = code.createTime
                    )
                }
                FinanceGroup(stationName = station.nickname, packages = packages)
            }
            _incomeItems.postValue(groups)
        }
    }
    fun loadFlightData() {
        viewModelScope.launch {
            val stations = Core.reminder.getByType("航班")
            val groups = stations.map { station ->
                val packages = Core.code.getByKeyword(station.nickname).map { code ->
                    FinancePackage(
                        id = code.id,
                        company = code.secondLevel,
                        trackingNumber = code.code,
                        createTime = code.createTime
                    )
                }
                FinanceGroup(stationName = station.nickname, packages = packages)
            }
            _flightItems.postValue(groups)
        }
    }
    fun loadTrainData() {
        viewModelScope.launch {
            val stations = Core.reminder.getByType("火车票")
            val groups = stations.map { station ->
                val packages = Core.code.getByKeyword(station.nickname).map { code ->
                    FinancePackage(
                        id = code.id,
                        company = code.secondLevel,
                        trackingNumber = code.code,
                        createTime = code.createTime
                    )
                }
                FinanceGroup(stationName = station.nickname, packages = packages)
            }
            _trainItems.postValue(groups)
        }
    }
    fun loadCategories() {
    private fun loadDataByType(type: String) {
        viewModelScope.launch {
            try {
                // 先尝试从服务器获取配置
                val serverCategories = RetrofitClient.apiService.getUserCategories(currentUserId)
                if (serverCategories.isNotEmpty()) {
                    _categories.value = serverCategories
                    secureStorage.saveCategories(currentUserId, serverCategories)
                } else {
                    // 如果服务器没有配置,尝试获取本地配置
                    val localCategories = secureStorage.getCategories(currentUserId)
                    if (localCategories.isEmpty()) {
                        // 如果本地也没有配置,使用默认配置
                        val defaultCategories = listOf(
                            CategoryConfig(1, "快递", 0),
                            CategoryConfig(2, "还款", 1),
                            CategoryConfig(3, "收入", 2),
                            CategoryConfig(4, "航班", 3),
                            CategoryConfig(5, "火车票", 4)
                        )
                        _categories.value = defaultCategories
                        syncCategoriesToServer(defaultCategories)
                    } else {
                        _categories.value = localCategories
                        syncCategoriesToServer(localCategories)
                // 获取该类型下的所有站点分组
                val stations = Core.code.getStationsByType(type)
                when (type) {
                    "快递" -> {
                        // 处理快递类型
                        val groups = stations.map { station ->
                            val packages = Core.code.getPackagesByTypeAndStation(type, station.stationName).map { code ->
                                ExpressPackage(
                                    id = code.id,
                                    company = code.secondLevel,
                                    trackingNumber = code.code,
                                    createTime = code.createTime
                                )
                            }
                            ExpressGroup(stationName = station.stationName, packages = packages)
                        }
                        _expressItems.postValue(groups)
                    }
                    "收入" -> {
                        // 特殊处理收入类型
                        val groups = stations.map { station ->
                            val packages = Core.code.getPackagesByTypeAndStation(type, station.stationName).map { code ->
                                IncomePackage(
                                    id = code.id,
                                    company = code.secondLevel,  // 交易对方
                                    trackingNumber = code.code,  // 金额
                                    createTime = code.createTime,
                                    balance = code.remarks.replace("余额", "") // 去掉"余额"前缀
                                )
                            }
                            IncomeGroup(stationName = station.stationName, packages = packages)
                        }
                        _incomeItems.postValue(groups)
                    }
                    "火车票" -> {
                        // 处理火车票类型
                        val groups = stations.map { station ->
                            val packages = Core.code.getPackagesByTypeAndStation(type, station.stationName).map { code ->
                                TrainPackage(
                                    id = code.id,
                                    company = code.secondLevel,
                                    trackingNumber = code.code,
                                    createTime = code.createTime
                                )
                            }
                            TrainGroup(stationName = station.stationName, packages = packages)
                        }
                        _trainItems.postValue(groups)
                    }
                    "航班" -> {
                        // 处理航班类型
                        val groups = stations.map { station ->
                            val packages = Core.code.getPackagesByTypeAndStation(type, station.stationName).map { code ->
                                FlightPackage(
                                    id = code.id,
                                    company = code.secondLevel,
                                    trackingNumber = code.code,
                                    createTime = code.createTime
                                )
                            }
                            FlightGroup(stationName = station.stationName, packages = packages)
                        }
                        _flightItems.postValue(groups)
                    }
                    else -> {
                        // 处理其他类型(还款)
                        val groups = stations.map { station ->
                            val packages = Core.code.getPackagesByTypeAndStation(type, station.stationName).map { code ->
                                FinancePackage(
                                    id = code.id,
                                    company = code.secondLevel,
                                    trackingNumber = code.code,
                                    createTime = code.createTime
                                )
                            }
                            FinanceGroup(stationName = station.stationName, packages = packages)
                        }
                        // 根据类型更新对应的 LiveData
                        when (type) {
                            "还款" -> _financeItems.postValue(groups)
                        }
                    }
                }
            } catch (e: Exception) {
                // 如果网络请求失败,使用本地数据
                val localCategories = secureStorage.getCategories(currentUserId)
                _categories.value = localCategories.ifEmpty {
                    listOf(
                        CategoryConfig(1, "快递", 0),
                        CategoryConfig(2, "还款", 1),
                        CategoryConfig(3, "收入", 2),
                        CategoryConfig(4, "航班", 3),
                        CategoryConfig(5, "火车票", 4)
                    )
                }
                Log.e("HomeViewModel", "Failed to load $type data: ${e.message}")
            }
        }
    }
    private fun syncCategoriesToServer(categories: List<CategoryConfig>) {
    fun loadExpressData() {
        loadDataByType("快递")
    }
    fun loadFinanceData() {
        loadDataByType("还款")
    }
    fun loadIncomeData() {
        loadDataByType("收入")
    }
    fun loadFlightData() {
        loadDataByType("航班")
    }
    fun loadTrainData() {
        loadDataByType("火车票")
    }
    fun loadAllCategoryData() {
        getFullCategories().forEach { category ->
            loadDataByType(category.name)
        }
    }
    fun getFullCategories(): List<CategoryConfig> {
        return listOf(
            CategoryConfig(1, "快递", 0, true),
            CategoryConfig(2, "还款", 1, true),
            CategoryConfig(3, "收入", 2, true),
            CategoryConfig(4, "航班", 3, true),
            CategoryConfig(5, "火车票", 4, true)
        )
    }
    private fun loadCategories() {
        viewModelScope.launch {
            try {
                RetrofitClient.apiService.saveUserCategories(
                    CategoryConfigSync(currentUserId, categories)
                // 默认完整分类列表
//                val fullCategories = listOf(
//                    CategoryConfig(1, "快递", 0, true),
//                    CategoryConfig(2, "还款", 1, true),
//                    CategoryConfig(3, "收入", 2, true),
//                    CategoryConfig(4, "航班", 3, true),
//                    CategoryConfig(5, "火车票", 4, true)
//                )
                val fullCategories=getFullCategories()
                // 基础分类(非会员可见)
                val basicCategories = listOf(
                    CategoryConfig(1, "快递", 0, true),
                    CategoryConfig(2, "还款", 1, true)
                )
                try {
                    // 获取会员状态
                    val savedPhone = PreferencesManager.getPhone()
                    val userResponse = RetrofitClient.apiService.getUserInfo(savedPhone ?: "")
                    val isMember = userResponse.code == "0" && userResponse.data?.isMember == true
                    // 从用户信息中获取正确的userId
                    if (userResponse.code == "0" && userResponse.data != null) {
                        currentUserId = userResponse.data?.id.toString()
                    }
                    // 首先检查本地是否有缓存的分类配置
                    val localCategories = secureStorage.getCategories(currentUserId)
                    if (localCategories.isNotEmpty()) {
                        // 使用本地缓存的配置
                        _categories.value = localCategories
                    } else {
                        // 本地无缓存,尝试从服务器获取
                        try {
                            val serverCategories = RetrofitClient.apiService.getUserCategories(currentUserId)
                            if (serverCategories.isNotEmpty()) {
                                // 服务器有配置,使用服务器配置
                                // 如果不是会员,需要过滤掉会员专属分类
                                val filteredCategories = if (isMember) {
                                    serverCategories
                                } else {
                                    serverCategories.filter { it.name == "快递" || it.name == "还款" }
                                }
                                _categories.value = filteredCategories
                                // 同时更新本地缓存
                                secureStorage.saveCategories(currentUserId, filteredCategories)
                                // 同步回服务器(如果有变化)
                                if (filteredCategories.size != serverCategories.size) {
                                    syncCategoriesToServer(filteredCategories)
                                }
                            } else {
                                // 服务器返回空,根据会员状态设置默认分类
                                val defaultCategories = if (isMember) fullCategories else basicCategories
                                _categories.value = defaultCategories
                                // 更新本地缓存
                                secureStorage.saveCategories(currentUserId, defaultCategories)
                                // 同步到服务器
                                syncCategoriesToServer(defaultCategories)
                            }
                        } catch (e: Exception) {
                            // 服务器获取失败,使用默认分类
                            Log.e("HomeViewModel", "Failed to get categories from server: ${e.message}")
                            val defaultCategories = if (isMember) fullCategories else basicCategories
                            _categories.value = defaultCategories
                            secureStorage.saveCategories(currentUserId, defaultCategories)
                        }
                    }
                } catch (e: Exception) {
                    // 网络连接失败,尝试从本地获取配置
                    Log.e("HomeViewModel", "Failed to get user info: ${e.message}")
                    val localCategories = secureStorage.getCategories(currentUserId)
                    if (localCategories.isNotEmpty()) {
                        // 使用本地缓存的配置
                        _categories.value = localCategories
                    } else {
                        // 本地也没有配置,使用基础分类
                        _categories.value = basicCategories
                        // 更新本地缓存
                        secureStorage.saveCategories(currentUserId, basicCategories)
                    }
                }
                // 更新可见分类
                _categories.value?.let { updateVisibleCategories(it) }
            } catch (e: Exception) {
                // 同步失败,可以稍后重试或者显示提示
                Log.e("CategorySync", "Failed to sync categories: ${e.message}")
                Log.e("HomeViewModel", "Failed to load categories: ${e.message}")
                // 出现异常时,使用基础分类
                val basicCategories = listOf(
                    CategoryConfig(1, "快递", 0, true),
                    CategoryConfig(2, "还款", 1, true)
                )
                _categories.value = basicCategories
                // 更新可见分类
                updateVisibleCategories(basicCategories)
            }
        }
    }
    private suspend fun syncCategoriesToServer(categories: List<CategoryConfig>) {
        try {
            RetrofitClient.apiService.saveUserCategories(
                CategoryConfigSync(currentUserId, categories)
            )
        } catch (e: Exception) {
            // 同步失败,可以稍后重试或者显示提示
            Log.e("CategorySync", "Failed to sync categories: ${e.message}")
        }
    }
    fun saveCategories(categories: List<CategoryConfig>) {
        _categories.value = categories
        // 保存到本地存储
        secureStorage.saveCategories(currentUserId, categories)
        // 同步到服务器
        viewModelScope.launch {
            // 保存到本地
            secureStorage.saveCategories(currentUserId, categories)
            // 同步到服务器
            syncCategoriesToServer(categories)
            _categories.value = categories
            // 更新可见分类
            updateVisibleCategories(categories)
            try {
                syncCategoriesToServer(categories)
            } catch (e: Exception) {
                Log.e("HomeViewModel", "Failed to sync categories: ${e.message}")
            }
        }
        // 更新可见分类
        updateVisibleCategories(categories)
        // 标记分类已被修改
        categoriesLoaded = true
    }
    private fun updateVisibleCategories(categories: List<CategoryConfig>) {
@@ -233,13 +353,32 @@
            .sortedBy { it.order }
            .map { it.name }
        
        _visibleCategories.value = visibleNames
        _visibleCategories.value = categories.filter { it.isEnabled }
    }
    // 添加检查未读提醒数量的方法
    fun checkUnreadReminders() {
        viewModelScope.launch {
            try {
                val unreadCount = reminderRecordRepository.getUnreadCount(ReminderRecord.STATUS_UNREAD)
                _unreadReminderCount.postValue(unreadCount)
            } catch (e: Exception) {
                Log.e("HomeViewModel", "Failed to get unread reminder count: ${e.message}")
            }
        }
    }
    // 添加方法以强制刷新分类
    fun refreshCategories() {
        categoriesLoaded = false
        loadCategories()
    }
    // 登出时不再清除本地数据
    fun logout() {
        // 只清除内存中的数据
        _categories.value = emptyList()
        categoriesLoaded = false
    }
}