From 793d4ee43f963935919f2ebf4b743e924c169e33 Mon Sep 17 00:00:00 2001
From: zuojincheng <lf_zuo@163.com>
Date: 星期一, 31 三月 2025 09:59:20 +0800
Subject: [PATCH] feat(search): 新增用户搜索功能并优化用户体验

---
 generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt |  114 +++++++++++++++++-
 generallibrary/src/main/res/layout/item_user_list.xml                        |   88 +++++++++++++-
 generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt     |   10 +
 generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt   |   69 ++++++++++
 generallibrary/src/main/res/layout/fragment_card.xml                         |    1 
 generallibrary/src/main/res/values/colors.xml                                |    1 
 generallibrary/src/main/java/com/dayu/general/activity/ManageListActivity.kt |   11 +
 generallibrary/src/main/res/layout/activity_search_user_ge.xml               |    7 +
 8 files changed, 270 insertions(+), 31 deletions(-)

diff --git a/generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt b/generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt
index 806c03e..b89fecf 100644
--- a/generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt
+++ b/generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt
@@ -33,13 +33,21 @@
 
     private fun initView() {
         binding?.homeNewCard?.setOnClickListener {
-            val intent = Intent(context, SearchUserActivity::class.java)
+            val intent = Intent(context, SearchUserActivity::class.java).apply {
+                putExtra("type", "newUser")
+            }
             startActivity(intent)
         }
         binding?.homeManage?.setOnClickListener {
             val intent = Intent(context, ManageListActivity::class.java)
             startActivity(intent)
         }
+        binding?.homeLossLL?.setOnClickListener {
+            val intent = Intent(context, SearchUserActivity::class.java).apply{
+                putExtra("type", "loss")
+            }
+            startActivity(intent)
+        }
     }
 }
 
diff --git a/generallibrary/src/main/java/com/dayu/general/activity/ManageListActivity.kt b/generallibrary/src/main/java/com/dayu/general/activity/ManageListActivity.kt
index bab9b4d..58644fa 100644
--- a/generallibrary/src/main/java/com/dayu/general/activity/ManageListActivity.kt
+++ b/generallibrary/src/main/java/com/dayu/general/activity/ManageListActivity.kt
@@ -19,13 +19,16 @@
     fun initView() {
         binding?.titleBar?.setOnItemclickListner(ClickType_LEFT_IMAGE) { this.finish() }
         binding?.tvCleanCard?.setOnClickListener {
-            var intent = Intent(this, ManagerReadActivity::class.java)
-            intent.putExtra("cardType", CardCommon.CLEAN_CARD_TYPE)
+            var intent = Intent(this, ManagerReadActivity::class.java).apply {
+                putExtra("cardType", CardCommon.CLEAN_CARD_TYPE)
+            }
+
             startActivity(intent)
         }
         binding?.tvCheckCard?.setOnClickListener {
-            var intent = Intent(this, ManagerReadActivity::class.java)
-            intent.putExtra("cardType", CardCommon.CHECK_CARD)
+            var intent = Intent(this, ManagerReadActivity::class.java).apply {
+                putExtra("cardType", CardCommon.CHECK_CARD)
+            }
             startActivity(intent)
         }
 
diff --git a/generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt b/generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt
index a0c6974..b284cea 100644
--- a/generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt
+++ b/generallibrary/src/main/java/com/dayu/general/activity/SearchUserActivity.kt
@@ -12,6 +12,8 @@
 import com.dayu.general.view.SearchDialog
 import com.dayu.general.net.ApiManager
 import com.dayu.general.net.BaseResponse
+import com.scwang.smart.refresh.layout.api.RefreshLayout
+import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
 
 /**
  * @author: zuo
@@ -23,6 +25,16 @@
     var binding: ActivitySearchUserGeBinding? = null
     private var userAdapter: SearchListAdapter? = null
     var searchDialog: SearchDialog? = null
+    
+    // 鍒嗛〉鐩稿叧鍙橀噺
+    private var currentPage = 1
+    private val pageSize = 20
+    private var hasMoreData = true
+    
+    // 淇濆瓨褰撳墠鎼滅储鏉′欢
+    private var currentFarmerId = ""
+    private var currentFarmerName = ""
+    private var currentCardNumber = ""
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -30,7 +42,7 @@
         setContentView(binding?.root)
         initView()
         setupRecyclerView()
-
+        setupRefreshLayout()
     }
 
 
@@ -41,12 +53,17 @@
         // 璁剧疆鎼滅储鐩戝惉鍣�
         searchDialog?.setOnSearchListener(object : SearchDialog.OnSearchListener {
             override fun onSearch(farmerId: String, farmerName: String, cardNumber: String) {
-                // 澶勭悊鎼滅储缁撴灉
-                // 杩欓噷鍙槸绀轰緥锛屽疄闄呭簲鐢ㄤ腑鍙兘闇�瑕佽皟鐢ˋPI鎴栨煡璇㈡暟鎹簱
-                val message =
-                    "鎼滅储鏉′欢锛歕n鍐滄埛缂栧彿锛�$farmerId\n鍐滄埛鍚嶇О锛�$farmerName\n鍗″彿锛�$cardNumber"
-                // 鎵ц瀹為檯鐨勬悳绱㈤�昏緫
-                searchUser(farmerId, farmerName, cardNumber)
+                // 淇濆瓨褰撳墠鎼滅储鏉′欢
+                currentFarmerId = farmerId
+                currentFarmerName = farmerName
+                currentCardNumber = cardNumber
+                
+                // 閲嶇疆鍒嗛〉鐘舵��
+                currentPage = 1
+                hasMoreData = true
+                
+                // 鎵ц鎼滅储
+                searchUser(farmerId, farmerName, cardNumber, true)
             }
         })
         binding?.titleBar?.setOnItemclickListner(ClickType_RIGHT_IMAGE) {
@@ -62,6 +79,42 @@
             layoutManager = LinearLayoutManager(this@SearchUserActivity)
             adapter = userAdapter
         }
+        
+        // 璁剧疆鍒楄〃椤圭偣鍑讳簨浠�
+        userAdapter?.setOnItemClickListener { user ->
+            // 澶勭悊鐢ㄦ埛鐐瑰嚮浜嬩欢
+            ToastUtil.show("宸查�夋嫨鐢ㄦ埛锛�${user.name}")
+            // 杩欓噷鍙互娣诲姞璺宠浆鍒扮敤鎴疯鎯呴〉闈㈢殑閫昏緫
+            // val intent = Intent(this, UserDetailActivity::class.java)
+            // intent.putExtra("userId", user.id)
+            // startActivity(intent)
+        }
+    }
+    
+    private fun setupRefreshLayout() {
+        binding?.refreshLayout?.apply {
+            // 璁剧疆鍒锋柊鍜屽姞杞芥洿澶氱洃鍚櫒
+            setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
+                override fun onRefresh(refreshLayout: RefreshLayout) {
+                    // 閲嶇疆椤电爜骞跺埛鏂版暟鎹�
+                    currentPage = 1
+                    hasMoreData = true
+                    searchUser(currentFarmerId, currentFarmerName, currentCardNumber, true)
+                }
+                
+                override fun onLoadMore(refreshLayout: RefreshLayout) {
+                    // 濡傛灉杩樻湁鏇村鏁版嵁锛屽姞杞戒笅涓�椤�
+                    if (hasMoreData) {
+                        currentPage++
+                        searchUser(currentFarmerId, currentFarmerName, currentCardNumber, false)
+                    } else {
+                        // 瀹屾垚鍔犺浇骞舵彁绀烘病鏈夋洿澶氭暟鎹�
+                        refreshLayout.finishLoadMore(500, true, false)
+                        ToastUtil.show("娌℃湁鏇村鏁版嵁浜�")
+                    }
+                }
+            })
+        }
     }
 
     /**
@@ -73,8 +126,9 @@
      * @param farmerId 鍐滄皯鐨勫敮涓�鏍囪瘑绗�
      * @param farmerName 鍐滄皯鐨勫鍚�
      * @param cardNumber 閾惰鍗″彿
+     * @param isRefresh 鏄惁涓哄埛鏂版搷浣�
      */
-    private fun searchUser(farmerId: String, farmerName: String, cardNumber: String) {
+    private fun searchUser(farmerId: String, farmerName: String, cardNumber: String, isRefresh: Boolean = true) {
         val map = mutableMapOf<String, Any>()
 
         if (farmerId.isNotEmpty()) {
@@ -88,6 +142,10 @@
         if (cardNumber.isNotEmpty()) {
             map["cardNum"] = cardNumber
         }
+        
+        // 娣诲姞鍒嗛〉鍙傛暟
+        map["pageCurr"] = currentPage
+        map["pageSize"] = pageSize
 
         // 浣跨敤姝g‘鐨勭被鍨嬪弬鏁�
         ApiManager.getInstance().requestGetLoading(
@@ -97,18 +155,38 @@
             map,
             object : SubscriberListener<BaseResponse<SearchUserResult>>() {
                 override fun onNext(t: BaseResponse<SearchUserResult>) {
+                    // 瀹屾垚鍒锋柊鎴栧姞杞藉姩浣�
+                    finishRefreshOrLoad(isRefresh)
+                    
                     if (t.success) {
                         // 澶勭悊鎼滅储鎴愬姛鐨勬儏鍐�
                         val result = t.content
                         if (result != null) {
                             // 澶勭悊鎼滅储缁撴灉
                             if (result.obj.isNotEmpty()) {
-                                userAdapter?.setData(result.obj)
+                                // 鏍规嵁鏄惁涓哄埛鏂版搷浣滃喅瀹氬浣曟洿鏂版暟鎹�
+                                if (isRefresh) {
+                                    userAdapter?.setData(result.obj)
+                                } else {
+                                    userAdapter?.addData(result.obj)
+                                }
+                                
+                                // 鍒ゆ柇鏄惁杩樻湁鏇村鏁版嵁锛氭牴鎹綋鍓嶉〉鐮佸拰鎬婚〉鏁板垽鏂�
+                                hasMoreData = currentPage < result.pageTotal
                             } else {
-                                ToastUtil.show("鏈壘鍒板尮閰嶇殑鐢ㄦ埛")
+                                if (isRefresh) {
+                                    userAdapter?.setData(emptyList())
+                                    ToastUtil.show("鏈壘鍒板尮閰嶇殑鐢ㄦ埛")
+                                } else {
+                                    hasMoreData = false
+                                    ToastUtil.show("娌℃湁鏇村鏁版嵁浜�")
+                                }
                             }
                         } else {
-                            ToastUtil.show("鏈壘鍒板尮閰嶇殑鐢ㄦ埛")
+                            if (isRefresh) {
+                                userAdapter?.setData(emptyList())
+                                ToastUtil.show("鏈壘鍒板尮閰嶇殑鐢ㄦ埛")
+                            }
                         }
                     } else {
                         // 澶勭悊鎼滅储澶辫触鐨勬儏鍐�
@@ -118,11 +196,25 @@
 
                 override fun onError(e: Throwable?) {
                     super.onError(e)
+                    // 瀹屾垚鍒锋柊鎴栧姞杞藉姩浣�
+                    finishRefreshOrLoad(isRefresh)
                     ToastUtil.show("鎼滅储澶辫触: ${e?.message ?: "鏈煡閿欒"}")
                 }
             }
         )
     }
+    
+    /**
+     * 瀹屾垚鍒锋柊鎴栧姞杞芥搷浣�
+     * @param isRefresh 鏄惁涓哄埛鏂版搷浣�
+     */
+    private fun finishRefreshOrLoad(isRefresh: Boolean) {
+        if (isRefresh) {
+            binding?.refreshLayout?.finishRefresh(true)
+        } else {
+            binding?.refreshLayout?.finishLoadMore(true)
+        }
+    }
 
     /**
      * 澶勭悊鎼滅储缁撴灉
diff --git a/generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt b/generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt
index debb5f1..d63f6ac 100644
--- a/generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt
+++ b/generallibrary/src/main/java/com/dayu/general/adapter/SearchListAdapter.kt
@@ -1,6 +1,7 @@
 package com.dayu.general.adapter
 
 import android.view.LayoutInflater
+import android.view.View
 import android.view.ViewGroup
 import androidx.recyclerview.widget.RecyclerView
 import com.dayu.general.bean.net.SearchUserResult
@@ -14,11 +15,22 @@
 class SearchListAdapter :  RecyclerView.Adapter<SearchListAdapter.UserViewHolder>(){
 
     private val userList = mutableListOf<SearchUserResult.UserInfo>()
+    private var onItemClickListener: ((SearchUserResult.UserInfo) -> Unit)? = null
 
     fun setData(users: List<SearchUserResult.UserInfo>) {
         userList.clear()
         userList.addAll(users)
         notifyDataSetChanged()
+    }
+    
+    fun addData(users: List<SearchUserResult.UserInfo>) {
+        val startPosition = userList.size
+        userList.addAll(users)
+        notifyItemRangeInserted(startPosition, users.size)
+    }
+    
+    fun setOnItemClickListener(listener: (SearchUserResult.UserInfo) -> Unit) {
+        this.onItemClickListener = listener
     }
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
@@ -35,14 +47,61 @@
 
     inner class UserViewHolder(private val binding: ItemUserListBinding) : RecyclerView.ViewHolder(binding.root) {
         fun bind(user: SearchUserResult.UserInfo) {
+            // 璁剧疆鏁版嵁鏄剧ず锛屾坊鍔犲垽绌哄鐞�
             binding.tvCardCount.text = "鍗℃暟閲忥細${user.cardCount ?: "0"}"
-            binding.tvFarmerId.text = "瀹㈡埛缂栧彿锛�${user.clientNum ?: ""}"
-            binding.tvIdCard.text = "韬唤璇侊細${user.idCard ?: ""}"
-            binding.tvName.text = "濮撳悕锛�${user.name ?: ""}"
-            binding.tvPhone.text = "鐢佃瘽锛�${user.phone ?: ""}"
+            binding.tvFarmerId.text = "瀹㈡埛缂栧彿锛�${user.clientNum ?: "鏃�"}"
+            binding.tvIdCard.text = "韬唤璇侊細${formatIdCard(user.idCard)}"
+            binding.tvName.text = "濮撳悕锛�${user.name ?: "鏈煡"}"
+            binding.tvPhone.text = "鐢佃瘽锛�${formatPhone(user.phone)}"
+            
+            // 娣诲姞鍦板潃淇℃伅鏄剧ず
+            user.address?.let { address ->
+                if (address.isNotEmpty()) {
+                    binding.tvAddress.text = "鍦板潃锛�$address"
+                    binding.tvAddress.visibility = View.VISIBLE
+                } else {
+                    binding.tvAddress.visibility = View.GONE
+                }
+            } ?: run {
+                binding.tvAddress.visibility = View.GONE
+            }
+            
+            // 鏄剧ず鎿嶄綔鏃ユ湡
+            user.operateDt?.let { date ->
+                if (date.isNotEmpty()) {
+                    binding.tvOperateDate.text = "鎿嶄綔鏃ユ湡锛�$date"
+                    binding.tvOperateDate.visibility = View.VISIBLE
+                } else {
+                    binding.tvOperateDate.visibility = View.GONE
+                }
+            } ?: run {
+                binding.tvOperateDate.visibility = View.GONE
+            }
 
             binding.root.setOnClickListener {
-                // 鍙互鍦ㄦ澶勬坊鍔犵偣鍑讳簨浠讹紝渚嬪鏌ョ湅鐢ㄦ埛璇︽儏
+                onItemClickListener?.invoke(user)
+            }
+        }
+        
+        // 鏍煎紡鍖栬韩浠借瘉鍙凤紝淇濇姢闅愮
+        private fun formatIdCard(idCard: String?): String {
+            return if (!idCard.isNullOrEmpty() && idCard.length >= 18) {
+                val start = idCard.substring(0, 6)
+                val end = idCard.substring(idCard.length - 4)
+                "$start****$end"
+            } else {
+                idCard ?: "鏃�"
+            }
+        }
+        
+        // 鏍煎紡鍖栨墜鏈哄彿锛屼繚鎶ら殣绉�
+        private fun formatPhone(phone: String?): String {
+            return if (!phone.isNullOrEmpty() && phone.length >= 11) {
+                val start = phone.substring(0, 3)
+                val end = phone.substring(phone.length - 4)
+                "$start****$end"
+            } else {
+                phone ?: "鏃�"
             }
         }
     }
diff --git a/generallibrary/src/main/res/layout/activity_search_user_ge.xml b/generallibrary/src/main/res/layout/activity_search_user_ge.xml
index 307148e..85198ca 100644
--- a/generallibrary/src/main/res/layout/activity_search_user_ge.xml
+++ b/generallibrary/src/main/res/layout/activity_search_user_ge.xml
@@ -23,11 +23,16 @@
         android:layout_height="match_parent"
         android:layout_below="@+id/titleBar">
 
+        <com.scwang.smart.refresh.header.ClassicsHeader
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
         <androidx.recyclerview.widget.RecyclerView
             android:id="@+id/recyclerView"
             android:layout_width="match_parent"
+
             android:layout_height="match_parent"
-            android:background="#ffffff"
+            android:background="@color/base_list_bg"
             android:overScrollMode="never"
             android:padding="10dp" />
 
diff --git a/generallibrary/src/main/res/layout/fragment_card.xml b/generallibrary/src/main/res/layout/fragment_card.xml
index d09e603..338af60 100644
--- a/generallibrary/src/main/res/layout/fragment_card.xml
+++ b/generallibrary/src/main/res/layout/fragment_card.xml
@@ -161,6 +161,7 @@
                 app:layout_constraintTop_toBottomOf="@+id/home_newCard">
 
                 <LinearLayout
+                    android:id="@+id/home_loss_LL"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:gravity="center"
diff --git a/generallibrary/src/main/res/layout/item_user_list.xml b/generallibrary/src/main/res/layout/item_user_list.xml
index e93821a..f2e4eab 100644
--- a/generallibrary/src/main/res/layout/item_user_list.xml
+++ b/generallibrary/src/main/res/layout/item_user_list.xml
@@ -1,13 +1,83 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.cardview.widget.CardView
+    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:orientation="vertical"
-    android:padding="12dp">
+    android:layout_marginBottom="8dp"
+    app:cardCornerRadius="8dp"
+    app:cardElevation="2dp">
 
-    <TextView android:id="@+id/tvCardCount" android:layout_width="match_parent" android:layout_height="wrap_content" />
-    <TextView android:id="@+id/tvFarmerId" android:layout_width="match_parent" android:layout_height="wrap_content" />
-    <TextView android:id="@+id/tvIdCard" android:layout_width="match_parent" android:layout_height="wrap_content" />
-    <TextView android:id="@+id/tvName" android:layout_width="match_parent" android:layout_height="wrap_content" />
-    <TextView android:id="@+id/tvPhone" android:layout_width="match_parent" android:layout_height="wrap_content" />
-</LinearLayout>
\ No newline at end of file
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:padding="16dp">
+
+        <TextView
+            android:id="@+id/tvName"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="18sp"
+            android:textStyle="bold"
+            android:textColor="#333333"
+            android:layout_marginBottom="8dp"/>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+            
+            <TextView
+                android:id="@+id/tvFarmerId"
+                android:layout_width="0dp"
+                android:layout_weight="1"
+                android:layout_height="wrap_content"
+                android:textSize="14sp"
+                android:textColor="#666666"
+                android:layout_marginBottom="4dp"/>
+                
+            <TextView
+                android:id="@+id/tvCardCount"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textSize="14sp"
+                android:textColor="#4CAF50"
+                android:layout_marginBottom="4dp"/>
+        </LinearLayout>
+
+        <TextView
+            android:id="@+id/tvIdCard"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="14sp"
+            android:textColor="#666666"
+            android:layout_marginBottom="4dp"/>
+
+        <TextView
+            android:id="@+id/tvPhone"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="14sp"
+            android:textColor="#666666"
+            android:layout_marginBottom="4dp"/>
+
+        <TextView
+            android:id="@+id/tvAddress"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="14sp"
+            android:textColor="#666666"
+            android:layout_marginBottom="4dp"
+            android:visibility="gone"/>
+
+        <TextView
+            android:id="@+id/tvOperateDate"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="12sp"
+            android:textColor="#999999"
+            android:layout_marginTop="4dp"
+            android:visibility="gone"/>
+    </LinearLayout>
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/generallibrary/src/main/res/values/colors.xml b/generallibrary/src/main/res/values/colors.xml
index f6ccfac..5729a42 100644
--- a/generallibrary/src/main/res/values/colors.xml
+++ b/generallibrary/src/main/res/values/colors.xml
@@ -4,5 +4,6 @@
     <color name="black">#333</color>
     <color name="white">#fff</color>
     <color name="nav_item_color">#555555</color>
+    <color name="base_list_bg">#e6e6e6</color>
 
 </resources>
\ No newline at end of file

--
Gitblit v1.8.0