package com.example.defenseapplication.home import android.os.Bundle import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.example.defenseapplication.adapter.MessageListAdapter import com.example.defenseapplication.adapter.MessageListItem import com.example.defenseapplication.databinding.MessageActivityBinding import com.example.defenseapplication.utils.MessageStatusManager import com.example.defenseapplication.utils.RetrofitNetwork import com.gyf.immersionbar.ImmersionBar import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext //消息通知页面 class MessageActivity : AppCompatActivity() { private lateinit var binding: MessageActivityBinding private val messageAdapter by lazy { MessageListAdapter() } private var currentPage = 1 private val pageSize = 10 private var isLoading = false private var hasMoreData = true private val allMessages = mutableListOf() private var lastLoadedCount = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = MessageActivityBinding.inflate(layoutInflater) setContentView(binding.root) ImmersionBar.with(this) .statusBarDarkFont(true) .titleBar(binding.topBar) .init() initView() MessageStatusManager.clearUnreadCount() loadMessageList() } private fun initView() { binding.ivBack.setOnClickListener { finish() } binding.rvMessageList.layoutManager = LinearLayoutManager(this) binding.rvMessageList.adapter = messageAdapter binding.rvMessageList.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) val layoutManager = recyclerView.layoutManager as LinearLayoutManager val totalItemCount = layoutManager.itemCount val lastVisibleItem = layoutManager.findLastVisibleItemPosition() if (!isLoading && hasMoreData && lastVisibleItem >= totalItemCount - 3 && dy > 0) { loadMoreData() } } override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { super.onScrollStateChanged(recyclerView, newState) if (newState == RecyclerView.SCROLL_STATE_IDLE && !hasMoreData && !isLoading) { showNoMoreDataHint() } } }) } private fun loadMessageList() { if (isLoading) return isLoading = true CoroutineScope(Dispatchers.IO).launch { try { val messageResponse = RetrofitNetwork.getNetworkService().getMessage( pageNum = currentPage, pageSize = pageSize ) println("total: ${messageResponse.total}") println("rows size: ${messageResponse.rows.size}") println("当前页:$currentPage, 加载条数:${messageResponse.rows.size}") val newMessages = messageResponse.rows val loadedCount = newMessages.size if (loadedCount < pageSize) { hasMoreData = false } if (newMessages.isEmpty()) { if (currentPage == 1) { withContext(Dispatchers.Main) { showEmptyState() } } } else { if (currentPage == 1) { allMessages.clear() } allMessages.addAll(newMessages) lastLoadedCount = loadedCount val items = convertToMessageListItems(allMessages) withContext(Dispatchers.Main) { hideEmptyState() messageAdapter.submitList(items) if (!hasMoreData) { showNoMoreDataHint() } else { hideNoMoreDataHint() } } } withContext(Dispatchers.Main) { if (allMessages.isEmpty()) { println("items is empty, showing empty state") showEmptyState() } } } catch (e: Exception) { println("Exception: ${e.message}") e.printStackTrace() withContext(Dispatchers.Main) { if (allMessages.isEmpty()) { showEmptyState() } } } finally { isLoading = false } } } private fun loadMoreData() { if (!hasMoreData || isLoading) return currentPage++ loadMessageList() } private fun showEmptyState() { binding.rvMessageList.visibility = View.GONE binding.emptyLayout.visibility = View.VISIBLE binding.tvNoMoreData.visibility = View.GONE } private fun hideEmptyState() { binding.rvMessageList.visibility = View.VISIBLE binding.emptyLayout.visibility = View.GONE } private fun showNoMoreDataHint() { binding.tvNoMoreData.visibility = View.VISIBLE } private fun hideNoMoreDataHint() { binding.tvNoMoreData.visibility = View.GONE } private fun convertToMessageListItems(messages: List): List { val items = mutableListOf() val groupedMessages = messages.groupBy { extractDate(it.createTime ?: "") } groupedMessages.forEach { (date, messageList) -> val headerTitle = formatDate(date) messageList.forEachIndexed { index, message -> println(" 消息${index + 1}: id=${message.id}, categoryName=${message.categoryName}, createTime=${message.createTime}") } items.add(MessageListItem.Header(headerTitle)) messageList.forEach { message -> items.add( MessageListItem.Message( time = extractTime(message.createTime ?: ""), title = message.categoryName ?: "未知消息", dateTime = message.createTime ?: "", unread = false ) ) } } return items } private fun extractDate(dateTime: String): String { return if (dateTime.contains(" ")) { dateTime.split(" ")[0] } else { dateTime } } private fun formatDate(dateStr: String): String { return if (dateStr == "今天" || dateStr.contains("今天")) { "今天" } else if (dateStr.contains("-")) { val parts = dateStr.split("-") if (parts.size >= 3) { "${parts[1]}-${parts[2]}" } else { dateStr } } else { dateStr } } private fun extractTime(dateTime: String): String { return if (dateTime.contains(" ")) { dateTime.split(" ")[1].substring(0, 5) } else { dateTime } } }