From 2309f454c0e1df3c43fde66002a1d009c0b8f479 Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期二, 01 四月 2025 11:34:35 +0800
Subject: [PATCH] add : 收入逻辑
---
app/src/main/java/com/example/firstapp/activity/PickupActivity.kt | 55 ++++
app/src/main/res/layout/activity_phone_login.xml | 2
app/src/main/java/com/example/firstapp/model/StationGroup.kt | 6
app/src/main/java/com/example/firstapp/adapter/IncomeAdapter.kt | 111 +++++++++++
app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt | 11 +
app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt | 116 ++++++++---
app/src/main/res/layout/item_income_package_home.xml | 47 ++++
app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt | 18 +
app/src/main/res/layout/item_income_group.xml | 56 +++++
app/src/main/res/layout/fragment_home.xml | 3
app/src/main/java/com/example/firstapp/model/IncomeGroup.kt | 14 +
app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt | 158 +++++++--------
12 files changed, 466 insertions(+), 131 deletions(-)
diff --git a/app/src/main/java/com/example/firstapp/activity/PickupActivity.kt b/app/src/main/java/com/example/firstapp/activity/PickupActivity.kt
index d7dda6d..48a6dc1 100644
--- a/app/src/main/java/com/example/firstapp/activity/PickupActivity.kt
+++ b/app/src/main/java/com/example/firstapp/activity/PickupActivity.kt
@@ -14,11 +14,23 @@
class PickupActivity : AppCompatActivity() {
private lateinit var binding: ActivityPickupBinding
private lateinit var expressAdapter: ExpressPackageAdapter
+
+ // 添加类型常量
+ companion object {
+ const val TYPE_EXPRESS = "express"
+ const val TYPE_REPAYMENT = "repayment"
+ const val TYPE_INCOME = "income"
+ }
+
+ private var pageType = TYPE_EXPRESS
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityPickupBinding.inflate(layoutInflater)
setContentView(binding.root)
+
+ // 获取页面类型
+ pageType = intent.getStringExtra("page_type") ?: TYPE_EXPRESS
initViews()
loadData()
@@ -39,17 +51,37 @@
finish()
}
- // 修改底部按钮点击事件
- binding.btnPickupAll.setOnClickListener {
- showPickupConfirmDialog()
+ // 设置底部按钮文本并添加点击事件
+ binding.btnPickupAll.apply {
+ text = getButtonText()
+ setOnClickListener {
+ showPickupConfirmDialog()
+ }
}
+ }
+ private fun getConfirmMessage(): String {
+ return when (pageType) {
+ TYPE_EXPRESS -> "是否确认取出所有包裹?"
+ TYPE_REPAYMENT -> "是否确认处理所有还款?"
+ TYPE_INCOME -> "是否确认处理所有收入?"
+ else -> "是否确认处理所有项目?"
+ }
+ }
+
+ private fun getButtonText(): String {
+ return when (pageType) {
+ TYPE_EXPRESS -> "全部取件"
+ TYPE_REPAYMENT -> "全部还款"
+ TYPE_INCOME -> "全部收款"
+ else -> "全部处理"
+ }
}
private fun showPickupConfirmDialog() {
AlertDialog.Builder(this)
- .setTitle("确认取件")
- .setMessage("是否确认取出所有包裹?")
+ .setTitle(getButtonText())
+ .setMessage(getConfirmMessage())
.setPositiveButton("确认") { _, _ ->
handlePickupAll()
}
@@ -84,7 +116,7 @@
// 清空列表
expressAdapter.submitList(emptyList())
// 更新包裹数量显示
- binding.tvPackageCount.text = "共0个包裹"
+ binding.tvPackageCount.text = getCountText(0)
// 通知MainActivity刷新
setResult(RESULT_OK)
} catch (e: Exception) {
@@ -92,6 +124,15 @@
// 如果出错则重新加载数据
loadData()
}
+ }
+ }
+
+ private fun getCountText(count: Int): String {
+ return when (pageType) {
+ TYPE_EXPRESS -> "共${count}个包裹"
+ TYPE_REPAYMENT -> "共${count}笔还款"
+ TYPE_INCOME -> "共${count}笔收入"
+ else -> "共${count}个"
}
}
@@ -112,7 +153,7 @@
expressAdapter.submitList(packages)
binding.tvStationName.text = stationName
- binding.tvPackageCount.text = "共${packages.size}个包裹"
+ binding.tvPackageCount.text = getCountText(packages.size)
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/adapter/IncomeAdapter.kt b/app/src/main/java/com/example/firstapp/adapter/IncomeAdapter.kt
new file mode 100644
index 0000000..856ba45
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/adapter/IncomeAdapter.kt
@@ -0,0 +1,111 @@
+package com.example.firstapp.adapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import com.example.firstapp.databinding.ItemIncomeGroupBinding
+import com.example.firstapp.databinding.ItemIncomePackageHomeBinding
+import com.example.firstapp.model.IncomeGroup
+import com.example.firstapp.model.IncomePackage
+
+class IncomeAdapter : ListAdapter<IncomeGroup, IncomeAdapter.ViewHolder>(IncomeGroupDiffCallback()) {
+
+ private var onPackageClickListener: (IncomeGroup, IncomePackage) -> Unit = { _, _ -> }
+
+ fun setOnPackageClickListener(listener: (IncomeGroup, IncomePackage) -> Unit) {
+ onPackageClickListener = listener
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = ItemIncomeGroupBinding.inflate(
+ LayoutInflater.from(parent.context), parent, false
+ )
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val group = getItem(position)
+ holder.bind(group)
+ }
+
+ inner class ViewHolder(private val binding: ItemIncomeGroupBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ private val packagesAdapter = IncomePackageHomeAdapter { pack ->
+ currentGroup?.let { group ->
+ onPackageClickListener(group, pack)
+ }
+ }
+ private var currentGroup: IncomeGroup? = null
+
+ init {
+ binding.rvPackages.apply {
+ layoutManager = LinearLayoutManager(context)
+ adapter = packagesAdapter
+ }
+ }
+
+ fun bind(group: IncomeGroup) {
+ currentGroup = group
+ binding.tvStationName.text = group.stationName
+ binding.tvPackageCount.text = "共${group.packages.size}笔收入"
+ packagesAdapter.submitList(group.packages)
+ }
+ }
+}
+
+class IncomePackageHomeAdapter(private val onPackageClick: (IncomePackage) -> Unit) :
+ ListAdapter<IncomePackage, IncomePackageHomeAdapter.ViewHolder>(IncomePackageDiffCallback()) {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = ItemIncomePackageHomeBinding.inflate(
+ LayoutInflater.from(parent.context), parent, false
+ )
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val pack = getItem(position)
+ holder.bind(pack)
+ }
+
+ inner class ViewHolder(private val binding: ItemIncomePackageHomeBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ init {
+ binding.root.setOnClickListener {
+ val pack = getItem(adapterPosition)
+ onPackageClick(pack)
+ }
+ }
+
+ fun bind(pack: IncomePackage) {
+ binding.tvCompany.text = pack.company
+ binding.tvCreateTime.text = pack.createTime
+ binding.tvTrackingNumber.text = "¥${pack.trackingNumber}"
+// binding.tvBalance.text = "余额: ¥${pack.balance}"
+ }
+ }
+}
+
+private class IncomeGroupDiffCallback : DiffUtil.ItemCallback<IncomeGroup>() {
+ override fun areItemsTheSame(oldItem: IncomeGroup, newItem: IncomeGroup): Boolean {
+ return oldItem.stationName == newItem.stationName
+ }
+
+ override fun areContentsTheSame(oldItem: IncomeGroup, newItem: IncomeGroup): Boolean {
+ return oldItem == newItem
+ }
+}
+
+private class IncomePackageDiffCallback : DiffUtil.ItemCallback<IncomePackage>() {
+ override fun areItemsTheSame(oldItem: IncomePackage, newItem: IncomePackage): Boolean {
+ return oldItem.id == newItem.id
+ }
+
+ override fun areContentsTheSame(oldItem: IncomePackage, newItem: IncomePackage): Boolean {
+ return oldItem == newItem
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt b/app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt
index f79e67a..c494471 100644
--- a/app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt
+++ b/app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt
@@ -10,6 +10,7 @@
import com.example.firstapp.model.CourierStat
import com.example.firstapp.model.DailyStat
import com.example.firstapp.model.HeatmapStat
+import com.example.firstapp.model.StationGroup
import io.reactivex.Completable
import kotlinx.coroutines.flow.Flow
@@ -261,4 +262,21 @@
WHERE strftime('%Y', createTime) = strftime('%Y', datetime(:date/1000, 'unixepoch', 'localtime'))
""")
fun getCurrentYearStats(date: Long): Flow<List<DailyStat>>
+
+ @Query("""
+ SELECT oneLevel as stationName, COUNT(*) as count
+ FROM Code
+ WHERE category = :type AND pickup = '0'
+ GROUP BY oneLevel
+ ORDER BY createTime DESC
+ """)
+ fun getStationsByType(type: String): List<StationGroup>
+
+ @Query("""
+ SELECT * FROM Code
+ WHERE category = :type AND pickup = '0'
+ AND oneLevel = :stationName
+ ORDER BY createTime DESC
+ """)
+ fun getPackagesByTypeAndStation(type: String, stationName: String): List<Code>
}
diff --git a/app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt b/app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt
index a9352e2..c7ccd88 100644
--- a/app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt
+++ b/app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt
@@ -3,6 +3,7 @@
import androidx.annotation.WorkerThread
import com.example.firstapp.database.dao.CodeDao
import com.example.firstapp.database.entity.Code
+import com.example.firstapp.model.StationGroup
import kotlinx.coroutines.flow.Flow
@@ -75,4 +76,14 @@
fun getCurrentYearStats(date: Long) = codeDao.getCurrentYearStats(date)
+ @WorkerThread
+ fun getStationsByType(type: String): List<StationGroup> {
+ return codeDao.getStationsByType(type)
+ }
+
+ @WorkerThread
+ fun getPackagesByTypeAndStation(type: String, stationName: String): List<Code> {
+ return codeDao.getPackagesByTypeAndStation(type, stationName)
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/model/IncomeGroup.kt b/app/src/main/java/com/example/firstapp/model/IncomeGroup.kt
new file mode 100644
index 0000000..d76f9f7
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/model/IncomeGroup.kt
@@ -0,0 +1,14 @@
+package com.example.firstapp.model
+
+data class IncomeGroup(
+ val stationName: String, // 银行名称
+ val packages: List<IncomePackage>
+)
+
+data class IncomePackage(
+ var id: Long,
+ val company: String, // 交易对方
+ val trackingNumber: String, // 金额
+ val createTime: String, // 交易时间
+ val balance: String // 账户余额
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/model/StationGroup.kt b/app/src/main/java/com/example/firstapp/model/StationGroup.kt
new file mode 100644
index 0000000..c37e008
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/model/StationGroup.kt
@@ -0,0 +1,6 @@
+package com.example.firstapp.model
+
+data class StationGroup(
+ val stationName: String,
+ val count: Int
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt b/app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt
index 72b4b45..0841d30 100644
--- a/app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt
+++ b/app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt
@@ -17,13 +17,17 @@
import androidx.recyclerview.widget.LinearLayoutManager
import com.bumptech.glide.Glide
import com.example.firstapp.R
+import com.example.firstapp.activity.ContentDetailActivity
import com.example.firstapp.activity.PickupActivity
import com.example.firstapp.adapter.ExpressAdapter
import com.example.firstapp.adapter.FinanceAdapter
import com.example.firstapp.adapter.CategorySelectorAdapter
+import com.example.firstapp.adapter.IncomeAdapter
import com.example.firstapp.database.service.RetrofitClient
import com.example.firstapp.databinding.FragmentHomeBinding
import com.example.firstapp.databinding.DialogCategorySelectorBinding
+import com.example.firstapp.model.IncomeGroup
+import com.example.firstapp.model.IncomePackage
import com.example.firstapp.utils.PreferencesManager
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.coroutines.launch
@@ -39,7 +43,7 @@
private lateinit var homeViewModel: HomeViewModel
private lateinit var expressAdapter: ExpressAdapter
private lateinit var financeAdapter: FinanceAdapter
- private lateinit var incomeAdapter: FinanceAdapter
+ private lateinit var incomeAdapter: IncomeAdapter
private lateinit var flightAdapter: FinanceAdapter
private lateinit var trainAdapter: FinanceAdapter
private lateinit var dataUpdateReceiver: BroadcastReceiver
@@ -62,12 +66,11 @@
// val userId = getUserId() // 需要实现这个方法
val userId ="123456"
homeViewModel.initialize(requireContext(), userId)
-
- //调用这个方法来设置 RecyclerView用于设置 RecyclerView 的布局和适配器。
- setupRecyclerViews()
+
+ // 设置点击监听事件
+ setupAdapters()
setupTabSwitching()
- //调用这个方法来观察 ViewModel 中的数据变化
- observeViewModelData()
+ setupObservers()
setupCategorySelector()
}
@@ -85,7 +88,7 @@
}
}
- private fun setupRecyclerViews() {
+ private fun setupAdapters() {
binding.expressRecycler.apply {
layoutManager = LinearLayoutManager(context)
expressAdapter = ExpressAdapter()
@@ -97,6 +100,7 @@
val intent = Intent(requireContext(), PickupActivity::class.java).apply {
putExtra("station_name", group.stationName)
putExtra("company", pack.company)
+ putExtra("page_type", PickupActivity.TYPE_EXPRESS)
}
startActivity(intent)
}
@@ -117,6 +121,8 @@
val intent = Intent(requireContext(), PickupActivity::class.java).apply {
putExtra("station_name", group.stationName)
putExtra("company", pack.company)
+ putExtra("page_type", PickupActivity.TYPE_REPAYMENT)
+
}
startActivity(intent)
}
@@ -125,9 +131,22 @@
// 添加新的 RecyclerView
binding.incomeRecycler.apply {
layoutManager = LinearLayoutManager(context)
- incomeAdapter = FinanceAdapter()
+ incomeAdapter = IncomeAdapter()
adapter = incomeAdapter
- visibility = View.GONE
+
+ // 设置初始状态 - 添加这行
+ binding.incomeRecycler.visibility = View.GONE
+
+ // 设置点击监听
+ incomeAdapter.setOnPackageClickListener { group, pack ->
+ // 跳转到取件页面
+ val intent = Intent(requireContext(), PickupActivity::class.java).apply {
+ putExtra("station_name", group.stationName)
+ putExtra("company", pack.company)
+ putExtra("page_type", PickupActivity.TYPE_INCOME)
+ }
+ startActivity(intent)
+ }
}
binding.flightRecycler.apply {
@@ -151,7 +170,7 @@
tabExpress.setTextColor(ContextCompat.getColor(requireContext(), R.color.tab_selected))
tabFinance.setTextColor(ContextCompat.getColor(requireContext(), R.color.gray))
- // 快递标签点击事件
+ // 快递标签点击事件 - 快递功能所有用户都可以使用
tabExpress.setOnClickListener {
hideAllRecyclers()
expressRecycler.visibility = View.VISIBLE
@@ -159,33 +178,60 @@
homeViewModel.loadExpressData()
}
- // 财务标签点击事件
- tabFinance.setOnClickListener {
- hideAllRecyclers()
- financeRecycler.visibility = View.VISIBLE
- updateTabStyles(tabFinance)
- homeViewModel.loadFinanceData()
- }
+ // 其他标签点击事件需要检查会员状态
+ val memberOnlyTabs = mapOf(
+ tabFinance to { homeViewModel.loadFinanceData() },
+ tabIncome to { homeViewModel.loadIncomeData() },
+ tabFlight to { homeViewModel.loadFlightData() },
+ tabTrain to { homeViewModel.loadTrainData() }
+ )
- tabIncome.setOnClickListener {
- hideAllRecyclers()
- incomeRecycler.visibility = View.VISIBLE
- updateTabStyles(tabIncome)
- homeViewModel.loadIncomeData()
+ memberOnlyTabs.forEach { (tab, loadAction) ->
+ tab.setOnClickListener {
+ checkMembershipAndExecute(tab) {
+ hideAllRecyclers()
+ when (tab) {
+ tabFinance -> financeRecycler.visibility = View.VISIBLE
+ tabIncome -> incomeRecycler.visibility = View.VISIBLE
+ tabFlight -> flightRecycler.visibility = View.VISIBLE
+ tabTrain -> trainRecycler.visibility = View.VISIBLE
+ }
+ updateTabStyles(tab)
+ loadAction()
+ }
+ }
}
+ }
+ }
- tabFlight.setOnClickListener {
- hideAllRecyclers()
- flightRecycler.visibility = View.VISIBLE
- updateTabStyles(tabFlight)
- homeViewModel.loadFlightData()
- }
+ private fun checkMembershipAndExecute(tab: TextView, action: () -> Unit) {
+ // 从本地获取保存的手机号
+ val savedPhone = PreferencesManager.getPhone()
+ if (savedPhone.isNullOrEmpty()) {
+ Toast.makeText(requireContext(), "请先登录", Toast.LENGTH_SHORT).show()
+ return
+ }
- tabTrain.setOnClickListener {
- hideAllRecyclers()
- trainRecycler.visibility = View.VISIBLE
- updateTabStyles(tabTrain)
- homeViewModel.loadTrainData()
+ // 使用协程检查会员状态
+ lifecycleScope.launch {
+ try {
+ val response = RetrofitClient.apiService.getUserInfo(savedPhone)
+ if (response.code == "0" && response.data != null) {
+ if (response.data.isMember) {
+ action()
+ } else {
+ Toast.makeText(requireContext(), "该功能仅对会员开放", Toast.LENGTH_SHORT).show()
+ // 切回快递标签
+ binding.tabExpress.performClick()
+ }
+ } else {
+ Toast.makeText(requireContext(), "获取用户信息失败", Toast.LENGTH_SHORT).show()
+ binding.tabExpress.performClick()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ Toast.makeText(requireContext(), "网络错误,请稍后重试", Toast.LENGTH_SHORT).show()
+ binding.tabExpress.performClick()
}
}
}
@@ -211,8 +257,7 @@
}
}
- //这个方法用于观察 homeViewModel 中的 expressItems 数据。
- private fun observeViewModelData() {
+ private fun setupObservers() {
//当 expressItems 数据发生变化时,更新 RecyclerView 的数据。
homeViewModel.expressItems.observe(viewLifecycleOwner) { items ->
//将新的数据列表提交给适配器,以更新 RecyclerView 的显示内容。
@@ -223,6 +268,7 @@
financeAdapter.submitList(items)
}
+ // 观察收入数据变化
homeViewModel.incomeItems.observe(viewLifecycleOwner) { items ->
incomeAdapter.submitList(items)
}
diff --git a/app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt b/app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt
index d8c92f2..f915575 100644
--- a/app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt
+++ b/app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt
@@ -14,6 +14,8 @@
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 kotlinx.coroutines.launch
@@ -21,13 +23,13 @@
private val _expressItems = MutableLiveData<List<ExpressGroup>>()
private val _financeItems = MutableLiveData<List<FinanceGroup>>()
- private val _incomeItems = MutableLiveData<List<FinanceGroup>>()
+ private val _incomeItems = MutableLiveData<List<IncomeGroup>>()
private val _flightItems = MutableLiveData<List<FinanceGroup>>()
private val _trainItems = MutableLiveData<List<FinanceGroup>>()
val expressItems: LiveData<List<ExpressGroup>> = _expressItems
val financeItems: LiveData<List<FinanceGroup>> = _financeItems
- val incomeItems: LiveData<List<FinanceGroup>> = _incomeItems
+ val incomeItems: LiveData<List<IncomeGroup>> = _incomeItems
val flightItems: LiveData<List<FinanceGroup>> = _flightItems
val trainItems: LiveData<List<FinanceGroup>> = _trainItems
@@ -56,106 +58,90 @@
_categories.value?.let { updateVisibleCategories(it) }
}
- fun loadExpressData() {
+ private fun loadDataByType(type: String) {
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 //快递时间
- )
+ try {
+ // 获取该类型下的所有站点分组
+ 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)
+ }
+ 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)
+ "航班" -> _flightItems.postValue(groups)
+ "火车票" -> _trainItems.postValue(groups)
+ }
+ }
}
- ExpressGroup(
- stationName = station.nickname, packages = packages
- )
+ } catch (e: Exception) {
+ Log.e("HomeViewModel", "Failed to load $type data: ${e.message}")
}
-
- _expressItems.postValue(groups)
}
+ }
+
+ fun loadExpressData() {
+ loadDataByType("快递")
}
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)
- }
+ loadDataByType("还款")
}
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)
- }
+ loadDataByType("收入")
}
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)
- }
+ loadDataByType("航班")
}
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)
- }
+ loadDataByType("火车票")
}
fun loadCategories() {
diff --git a/app/src/main/res/layout/activity_phone_login.xml b/app/src/main/res/layout/activity_phone_login.xml
index 757b041..74d5644 100644
--- a/app/src/main/res/layout/activity_phone_login.xml
+++ b/app/src/main/res/layout/activity_phone_login.xml
@@ -43,7 +43,7 @@
android:layout_height="wrap_content"
android:background="@null"
android:hint="请输入手机号"
- android:text="17712345678"
+ android:text="15288241342"
android:inputType="phone"
android:maxLength="11"
android:textSize="16sp"
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index 17014a8..8fbd422 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -119,8 +119,7 @@
android:id="@+id/income_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="8dp"
- android:visibility="gone" />
+ android:padding="8dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/flight_recycler"
diff --git a/app/src/main/res/layout/item_income_group.xml b/app/src/main/res/layout/item_income_group.xml
new file mode 100644
index 0000000..6ae5c47
--- /dev/null
+++ b/app/src/main/res/layout/item_income_group.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.google.android.material.card.MaterialCardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="12dp"
+ android:layout_marginVertical="6dp"
+ app:cardCornerRadius="8dp"
+ app:cardElevation="2dp"
+ app:cardBackgroundColor="@android:color/white"
+ app:strokeColor="#FF000000"
+ app:strokeWidth="2dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginBottom="12dp">
+
+ <ImageView
+ android:id="@+id/iv_station_icon"
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:layout_gravity="center_vertical"
+ android:src="@drawable/location"/>
+
+ <TextView
+ android:id="@+id/tv_station_name"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginStart="8dp"
+ android:textSize="16sp"
+ android:textColor="#333333"/>
+
+ <TextView
+ android:id="@+id/tv_package_count"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="14sp"
+ android:textColor="#666666"/>
+ </LinearLayout>
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/rv_packages"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </LinearLayout>
+</com.google.android.material.card.MaterialCardView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_income_package_home.xml b/app/src/main/res/layout/item_income_package_home.xml
new file mode 100644
index 0000000..ef12f23
--- /dev/null
+++ b/app/src/main/res/layout/item_income_package_home.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="12dp"
+ android:gravity="center_vertical">
+
+ <ImageView
+ android:id="@+id/iv_company_logo"
+ android:layout_width="20dp"
+ android:layout_height="20dp"
+ android:layout_marginEnd="6dp"/>
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/tv_company"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="12sp"
+ android:textColor="#333333"
+ android:textStyle="bold"/>
+
+ <TextView
+ android:id="@+id/tv_create_time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="10sp"
+ android:textColor="#666666"
+ android:layout_marginTop="4dp"/>
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/tv_tracking_number"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="25sp"
+ android:textColor="#333333"
+ android:layout_marginStart="12dp"
+ android:textStyle="bold"/>
+
+</LinearLayout>
\ No newline at end of file
--
Gitblit v1.9.3