From fe04012057d024770e0180543483d393281a542f Mon Sep 17 00:00:00 2001
From: zhujie <leon.zhu@cloudroam.com.cn>
Date: 星期四, 03 四月 2025 09:18:16 +0800
Subject: [PATCH] Merge branch 'master' of http://47.96.225.205:8888/r/FirstApp2

---
 app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt         |   73 
 app/src/main/res/drawable/error_placeholder.xml                                  |    9 
 app/src/main/java/com/example/firstapp/network/TokenExpiredInterceptor.kt        |   19 
 app/src/main/java/com/example/firstapp/view/UnderlineTextView.kt                 |   43 
 app/src/main/res/drawable/more_benefit_shape.xml                                 |   10 
 .idea/misc.xml                                                                   |    2 
 app/src/main/res/drawable/ic_reminder.xml                                        |   12 
 app/src/main/res/mipmap/vip_more.png                                             |    0 
 .idea/gradle.xml                                                                 |    3 
 app/src/main/java/com/example/firstapp/database/response/OAuth2TokenResponse.kt  |   17 
 app/src/main/res/layout/vip_protocol_dialog_custom.xml                           |   44 
 app/src/main/java/com/example/firstapp/adapter/CategorySelectorAdapter.kt        |   66 
 app/src/main/res/mipmap/vip_bar_sta.png                                          |    0 
 app/src/main/res/drawable/vip_white_background.xml                               |   16 
 app/src/main/java/com/example/firstapp/adapter/IncomeAdapter.kt                  |  111 +
 app/src/main/res/drawable/round_red_bg.xml                                       |    5 
 app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt                   |    3 
 app/src/main/java/com/example/firstapp/util/CategoryDragCallback.kt              |   25 
 app/src/main/res/layout/fragment_notifications.xml                               |    6 
 app/src/main/res/drawable/wechat_shape.xml                                       |    6 
 app/src/main/res/mipmap/vip_ling.png                                             |    0 
 app/src/main/res/layout/fragment_second.xml                                      |   35 
 app/src/main/res/mipmap/vip_ai_ass_icon.png                                      |    0 
 app/src/main/java/com/example/firstapp/activity/SecondFragment.kt                |   45 
 app/src/main/res/drawable/dialog_background.xml                                  |   16 
 app/src/main/java/com/example/firstapp/database/request/SmsLoginRequest.kt       |    7 
 app/src/main/res/drawable/round_transition_gray_bg.xml                           |    9 
 app/src/main/java/com/example/firstapp/adapter/CardAdapter.kt                    |  126 +
 app/src/main/res/layout/item_card_yearly.xml                                     |  115 +
 app/src/main/res/values/themes.xml                                               |    6 
 app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt                   |   28 
 app/src/main/res/layout/vip_protocol_dialog_custom_bak.xml                       |   52 
 app/src/main/res/xml/network_security_config.xml                                 |    1 
 app/src/main/res/drawable/gold_border_shape.xml                                  |    7 
 app/src/main/java/com/example/firstapp/model/IncomeGroup.kt                      |   14 
 app/src/main/res/mipmap/vip_wechat.png                                           |    0 
 app/src/main/res/drawable/vip_black_background.xml                               |   17 
 app/src/main/res/mipmap/vip_copy.png                                             |    0 
 app/src/main/res/layout/item_income_package_home.xml                             |   47 
 app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt |   74 
 app/src/main/java/com/example/firstapp/activity/ContentDetailActivity.kt         |   14 
 app/src/main/res/mipmap/vip_free_member.png                                      |    0 
 app/src/main/res/mipmap/vip_card.png                                             |    0 
 app/src/main/res/mipmap/vip_cancel.png                                           |    0 
 app/src/main/java/com/example/firstapp/database/service/ApiService.kt            |   63 
 app/src/main/java/com/example/firstapp/database/request/ProductOrdersRequest.kt  |   11 
 app/src/main/java/com/example/firstapp/model/CardData.kt                         |   26 
 app/src/main/res/layout/fragment_home.xml                                        |  236 +-
 app/src/main/java/com/example/firstapp/model/CategoryConfigSync.kt               |    6 
 app/src/main/java/com/example/firstapp/model/MemberBenefitItem.kt                |    5 
 app/src/main/java/com/example/firstapp/network/AuthInterceptor.kt                |   24 
 app/src/main/res/mipmap/avatar_default.png                                       |    0 
 app/src/main/java/com/example/firstapp/activity/FirstFragment.kt                 |   45 
 app/src/main/java/com/example/firstapp/model/CategoryConfig.kt                   |   11 
 app/src/main/res/drawable/tab_selected_background.xml                            |    9 
 app/src/main/res/layout/item_income_group.xml                                    |   56 
 app/src/main/java/com/example/firstapp/database/response/UserInfo.kt             |    6 
 app/src/main/res/drawable/member_background.xml                                  |    8 
 app/src/main/res/values-v23/themes.xml                                           |   12 
 .idea/deploymentTargetSelector.xml                                               |    4 
 app/src/main/res/mipmap/overlay2.jpg                                             |    0 
 app/src/main/res/drawable/gray_border_shape.xml                                  |    7 
 app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardViewModel.kt         |   92 +
 app/src/main/res/layout/content_vip.xml                                          |   19 
 app/src/main/res/layout/item_card_single_month.xml                               |   68 
 app/src/main/res/navigation/nav_graph.xml                                        |   28 
 app/src/main/res/mipmap/vip_no.png                                               |    0 
 app/src/main/res/mipmap/vip_ad_no.png                                            |    0 
 app/src/main/res/layout/item_category_selector.xml                               |   22 
 app/build.gradle                                                                 |   10 
 app/src/main/res/drawable/checkbox_round.xml                                     |    7 
 app/src/main/res/values-w1240dp/dimens.xml                                       |    3 
 app/src/main/res/values/dimens.xml                                               |    1 
 app/src/main/java/com/example/firstapp/activity/PickupActivity.kt                |   55 
 app/src/main/res/layout/fragment_member_info_card.xml                            |   96 +
 app/src/main/java/com/example/firstapp/model/MoreMemberBenefitItem.kt            |    4 
 app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt     |   14 
 app/src/main/res/drawable/home_add.xml                                           |    9 
 app/src/main/res/layout/activity_vip.xml                                         |  518 ++++++
 app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt            |    6 
 app/src/main/java/com/example/firstapp/database/service/ModelService.kt          |   33 
 app/src/main/res/drawable/checkbox_round_selected.xml                            |    7 
 app/src/main/res/drawable/ic_check.xml                                           |   14 
 app/src/main/res/mipmap/vip_right.png                                            |    0 
 app/src/main/res/drawable/ic_category.xml                                        |   12 
 app/src/main/res/mipmap/vip_crown.png                                            |    0 
 app/src/main/res/values-w600dp/dimens.xml                                        |    3 
 app/src/main/java/com/example/firstapp/App.kt                                    |    3 
 app/src/main/res/layout/fragment_first.xml                                       |   35 
 app/src/main/java/com/example/firstapp/database/request/SmsSendRequest.kt        |    6 
 app/src/main/res/drawable/overlay_black_background.xml                           |   17 
 app/src/main/res/drawable/up.png                                                 |    0 
 .gitignore                                                                       |    3 
 app/src/main/res/mipmap/vip_life_insurance.png                                   |    0 
 app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt                |   58 
 app/src/main/java/com/example/firstapp/activity/VipActivity.kt                   |  544 ++++++
 app/src/main/res/mipmap/vip_cancel_link.png                                      |    0 
 app/src/main/res/mipmap/vip_circle_pie.png                                       |    0 
 app/src/main/res/values-land/dimens.xml                                          |    3 
 app/src/main/java/com/example/firstapp/ui/home/HomeViewModel.kt                  |  238 ++
 app/src/main/res/drawable/up_back.jpg                                            |    0 
 app/src/main/res/mipmap/vip.png                                                  |    0 
 app/src/main/res/mipmap/overlay.png                                              |    0 
 app/src/main/res/layout/fragment_dashboard.xml                                   |   51 
 app/src/main/java/com/example/firstapp/MainActivity.kt                           |  261 +-
 app/src/main/res/mipmap/vip_alipay.png                                           |    0 
 app/src/main/res/drawable/set.xml                                                |   13 
 app/src/main/java/com/example/firstapp/database/response/ContentResponse.kt      |   11 
 app/src/main/res/layout/activity_phone_login.xml                                 |    1 
 app/src/main/res/drawable/alipay_shape.xml                                       |    6 
 app/src/main/AndroidManifest.xml                                                 |   14 
 app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardFragment.kt          |  162 ++
 app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt               |   58 
 app/src/main/res/layout/item_card.xml                                            |   46 
 app/src/main/java/com/example/firstapp/model/StationGroup.kt                     |    6 
 /dev/null                                                                        |   29 
 app/src/main/java/com/example/firstapp/ui/home/HomeFragment.kt                   |  387 ++++
 app/src/main/java/com/example/firstapp/util/SecureStorage.kt                     |   49 
 app/src/main/res/layout/dialog_category_selector.xml                             |   29 
 app/src/main/res/drawable/black_button_background.xml                            |    6 
 app/src/main/res/drawable/ic_stats.xml                                           |   12 
 app/src/main/res/layout/item_card_continue_monthly.xml                           |  163 ++
 122 files changed, 4,341 insertions(+), 503 deletions(-)

diff --git a/.gitignore b/.gitignore
index aa724b7..8654057 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,9 @@
 /.idea/workspace.xml
 /.idea/navEditor.xml
 /.idea/assetWizardSettings.xml
+/.idea/deploymentTargetSelector.xml
+/.idea/gradle.xml
+/.idea/misc.xml
 .DS_Store
 /build
 /captures
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index 3b8cd93..e918287 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -4,10 +4,10 @@
     <selectionStates>
       <SelectionState runConfigName="app">
         <option name="selectionMode" value="DROPDOWN" />
-        <DropdownSelection timestamp="2025-02-25T09:44:45.437232500Z">
+        <DropdownSelection timestamp="2025-03-28T01:17:48.834725500Z">
           <Target type="DEFAULT_BOOT">
             <handle>
-              <DeviceId pluginId="PhysicalDevice" identifier="serial=88Y5T19C14010323" />
+              <DeviceId pluginId="PhysicalDevice" identifier="serial=HMQNW19A24001406" />
             </handle>
           </Target>
         </DropdownSelection>
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index ad84da2..cb865f6 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -4,9 +4,8 @@
   <component name="GradleSettings">
     <option name="linkedExternalProjectsSettings">
       <GradleProjectSettings>
-        <option name="testRunner" value="CHOOSE_PER_TEST" />
         <option name="externalProjectPath" value="$PROJECT_DIR$" />
-        <option name="gradleJvm" value="17" />
+        <option name="gradleJvm" value="jbr-17" />
         <option name="modules">
           <set>
             <option value="$PROJECT_DIR$" />
diff --git a/.idea/misc.xml b/.idea/misc.xml
index d7916a5..8978d23 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,6 @@
 <project version="4">
   <component name="ExternalStorageConfigurationManager" enabled="true" />
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>
   <component name="ProjectType">
diff --git a/app/build.gradle b/app/build.gradle
index 88aea3e..3afa1de 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -283,11 +283,15 @@
     // 支付宝支付SDK
     api 'com.alipay.sdk:alipaysdk-android:+@aar'
 
-    implementation 'com.google.android.material:material:1.4.0'
+    //implementation 'com.google.android.material:material:1.4.0'
+
+    // 加密SharedPreferences
+    implementation "androidx.security:security-crypto:1.1.0-alpha06"
+    
+    // Material Design组件im
+    implementation 'com.google.android.material:material:1.9.0'
 
     implementation 'de.hdodenhof:circleimageview:3.1.0'
 
     implementation 'com.github.castorflex:SmoothProgressBar:1.1.0'
-
-
 }
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d826628..99381b1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -83,7 +83,13 @@
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:theme="@style/Theme.FirstApp"
-        tools:targetApi="31">
+        tools:targetApi="31"
+        android:usesCleartextTraffic="true"
+        >
+        <activity
+            android:name=".activity.VipActivity"
+            android:exported="false"
+            android:theme="@style/Theme.FirstApp" />
         <activity
             android:name=".ui.reminderOther.ReminderOtherAddActivity2"
             android:configChanges="orientation|keyboardHidden|screenSize"
@@ -106,11 +112,11 @@
             android:exported="false" />
         <activity
             android:name=".activity.PickupActivity"
-            android:exported="false"/>
+            android:exported="false" />
         <activity
             android:name=".activity.ContentDetailActivity"
-            android:theme="@style/Theme.ContentDetail"
-            android:exported="false" />
+            android:exported="false"
+            android:theme="@style/Theme.ContentDetail" />
         <activity
             android:name=".ui.profile.EditProfileActivity"
             android:exported="false"/>
diff --git a/app/src/main/java/com/example/firstapp/App.kt b/app/src/main/java/com/example/firstapp/App.kt
index 6663556..7c60e3a 100644
--- a/app/src/main/java/com/example/firstapp/App.kt
+++ b/app/src/main/java/com/example/firstapp/App.kt
@@ -39,6 +39,7 @@
 import com.example.firstapp.utils.FRPC_LIB_VERSION
 import com.example.firstapp.utils.HistoryUtils
 import com.example.firstapp.utils.Log
+import com.example.firstapp.utils.PreferencesManager
 import com.example.firstapp.utils.SettingUtils
 import com.example.firstapp.utils.SharedPreference
 
@@ -154,7 +155,7 @@
         try {
             context = applicationContext
             initLibs()
-
+            PreferencesManager.init(this)
             //纯客户端模式
             if (SettingUtils.enablePureClientMode) return
 
diff --git a/app/src/main/java/com/example/firstapp/MainActivity.kt b/app/src/main/java/com/example/firstapp/MainActivity.kt
index 8b689c9..c59ca87 100644
--- a/app/src/main/java/com/example/firstapp/MainActivity.kt
+++ b/app/src/main/java/com/example/firstapp/MainActivity.kt
@@ -17,28 +17,20 @@
 import android.net.Uri
 import android.os.Build
 import androidx.annotation.RequiresApi
-import androidx.work.ExistingPeriodicWorkPolicy
-import androidx.work.PeriodicWorkRequestBuilder
-import androidx.work.WorkManager
 import com.example.firstapp.activity.LoginActivity
-import com.example.firstapp.adapter.MyAdapter
 import com.example.firstapp.core.Core
 import com.example.firstapp.database.entity.Code
 import com.example.firstapp.database.entity.Msg
 import com.example.firstapp.database.service.RetrofitClient
-import com.example.firstapp.ui.home.HomeViewModel
+import com.example.firstapp.database.service.RetrofitModelClient
 import com.example.firstapp.utils.Log
-import com.example.firstapp.workers.KeywordUpdateWorker
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import java.text.SimpleDateFormat
-import java.time.LocalDateTime
 import java.util.Calendar
 import java.util.Date
 import java.util.Locale
-import java.util.concurrent.TimeUnit
-import java.time.ZoneId
 
 class MainActivity : AppCompatActivity() {
     // 安全防护关键词数组
@@ -47,9 +39,6 @@
     private lateinit var binding: ActivityMainBinding
 
     private var smsReceiver: SmsReceiver? = null
-
-    private lateinit var adapter: MyAdapter
-    private lateinit var homeViewModel: HomeViewModel
 
     private val multiplePermissionRequest =
         registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
@@ -60,8 +49,6 @@
                 ) && permissions.getOrDefault(Manifest.permission.READ_SMS, false) -> {
                     // 两个权限都获得授权
                     registerSmsReceiver()
-//                syncRecentSms()
-//                initializeSecurityKeywords()
                 }
 
                 else -> {
@@ -82,13 +69,6 @@
         binding = ActivityMainBinding.inflate(layoutInflater)
         setContentView(binding.root)
         setupViews()
-//        binding.btnLogout.setOnClickListener {
-//            logout()
-//        }
-        // 在此位置初始化 homeViewModel
-//        homeViewModel = ViewModelProvider(this).get(HomeViewModel::class.java)
-//
-//        val navView: BottomNavigationView = binding.navView
         val navView = binding.navView
         val navController = findNavController(R.id.nav_host_fragment_activity_main)
 
@@ -113,35 +93,6 @@
             registerSmsReceiver()
             syncRecentSms()
         }
-//        val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
-//        recyclerView.layoutManager = LinearLayoutManager(this)
-//
-//        // 初始化适配器
-//        adapter = MyAdapter()
-//        recyclerView.adapter = adapter
-//
-//        // 观察 LiveData 数据
-//        homeViewModel.codeList.observe(this) { codeList ->
-//            // 如果 codeList 为 null,避免闪退
-//            if (codeList != null) {
-//                adapter.submitList(codeList)
-//                // 滚动到顶部
-//                recyclerView.scrollToPosition(0)
-//            } else {
-//                // 如果数据为空,可以显示空列表或其他处理
-//                Toast.makeText(this, "No data available", Toast.LENGTH_SHORT).show()
-//            }
-//        }
-
-//        // 注册广播接收器来监听数据更新
-//        val filter = IntentFilter("com.example.firstapp.DATA_UPDATED")
-//        registerReceiver(object : BroadcastReceiver() {
-//            override fun onReceive(context: Context, intent: Intent) {
-//                // 数据已更新,刷新 LiveData
-//                homeViewModel.loadData()
-//            }
-//        }, filter)
-
     }
 
     private fun registerSmsReceiver() {
@@ -161,25 +112,9 @@
         registerReceiver(smsReceiver, filter)
     }
 
-    private fun setupKeywordUpdate() {
-        val updateRequest = PeriodicWorkRequestBuilder<KeywordUpdateWorker>(
-            1, TimeUnit.HOURS,  // 每小时更新一次
-            15, TimeUnit.MINUTES  // 灵活时间窗口
-        ).build()
-
-        WorkManager.getInstance(this).enqueueUniquePeriodicWork(
-            "keyword_update", ExistingPeriodicWorkPolicy.REPLACE, updateRequest
-        )
-    }
-
     private fun setupViews() {
         // 获取并显示当前登录的手机号
-        val phone =
-            getSharedPreferences("user_info", Context.MODE_PRIVATE).getString("phone", "") ?: ""
-
-//        binding.apply {
-//            tvPhone.text = "当前登录手机号:$phone"
-//        }
+        getSharedPreferences("user_info", Context.MODE_PRIVATE).getString("phone", "") ?: ""
     }
 
     private fun logout() {
@@ -247,120 +182,126 @@
                     val msgId = Core.msg.insert(msg)
 
                     // 禁用关键词拦截
-                    if (securityKeywordsList.any { it in messageBody }) {
-                        android.util.Log.d("MainActivity", "历史短信含有禁用关键词,跳过处理")
-                        continue
-                    }
+//                    if (securityKeywordsList.any { it in messageBody }) {
+//                        android.util.Log.d("MainActivity", "历史短信含有禁用关键词,跳过处理")
+//                        continue
+//                    }
 
                     // 使用协程处理API调用和数据库操作
                     CoroutineScope(Dispatchers.IO).launch {
                         try {
-                            // API调用移到synchronized块外
-                            val response = RetrofitClient.apiService.processSms(mapOf("content" to messageBody))
+                            val response = RetrofitModelClient.modelService.processSms(mapOf("content" to messageBody))
                             
-                            // 数据库操作放在synchronized块内
                             synchronized(syncLock) {
                                 if (response.status == "success") {
                                     when (response.data.category) {
                                         "快递" -> {
-                                            val existingCode = Core.code.queryByTypeAndCodeAndDate(
-                                                response.data.category,
-                                                response.data.details.pickupCode ?: "",
-                                                dateString
-                                            )
-
-                                            if (existingCode == null) {
-                                                val code = Code(
-                                                    id = 0,
-                                                    category = response.data.category,
-                                                    categoryId = 1,
-                                                    typeId = 1,
-                                                    ruleId = 1,
-                                                    msgId = msgId,
-                                                    createTime = dateString,
-                                                    oneLevel = response.data.details.post ?: "",
-                                                    secondLevel = response.data.details.company ?: "",
-                                                    code = response.data.details.pickupCode ?: "",
-                                                    pickup = 0,
-                                                    pickupTime = "",
-                                                    overTime = "",
-                                                    address = response.data.details.address ?: "",
-                                                    remarks = response.data.details.time ?: "",
+                                            val pickupCode = response.data.details.pickupCode ?: ""
+                                            if (pickupCode.isNotEmpty()) {
+                                                val existingCode = Core.code.queryByTypeAndCodeAndDate(
+                                                    response.data.category,
+                                                    pickupCode,
+                                                    dateString
                                                 )
-                                                if(code.oneLevel!=""  && code.secondLevel!="" && code.code!="") {
-                                                    Core.code.insert(code)
+
+                                                if (existingCode == null) {
+                                                    val code = Code(
+                                                        id = 0,
+                                                        category = response.data.category,
+                                                        categoryId = 1,
+                                                        typeId = 1,
+                                                        ruleId = 1,
+                                                        msgId = msgId,
+                                                        createTime = dateString,
+                                                        oneLevel = response.data.details.post ?: "",
+                                                        secondLevel = response.data.details.company ?: "",
+                                                        code = pickupCode,
+                                                        pickup = 0,
+                                                        pickupTime = "",
+                                                        overTime = "",
+                                                        address = response.data.details.address ?: "",
+                                                        remarks = response.data.details.time ?: "",
+                                                    )
+                                                    if(code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) {
+                                                        Core.code.insert(code)
+                                                        android.util.Log.d("MainActivity", "历史快递短信已保存: $pickupCode")
+                                                    }
+                                                } else {
+                                                    android.util.Log.d("MainActivity", "发现重复快递短信,跳过保存: $pickupCode")
                                                 }
-                                                android.util.Log.d("MainActivity", "历史快递短信已保存: ${response.data.details.pickupCode}")
-                                            } else {
-                                                android.util.Log.d("MainActivity", "发现重复快递短信,跳过保存: ${response.data.details.pickupCode}")
                                             }
                                         }
                                         "还款" -> {
-                                            val existingCode = Core.code.queryByTypeAndCodeAndDate(
-                                                response.data.category,
-                                                response.data.details.amount ?: "",
-                                                dateString
-                                            )
-
-                                            if (existingCode == null) {
-                                                val code = Code(
-                                                    id = 0,
-                                                    category = response.data.category,
-                                                    categoryId = 2,
-                                                    typeId = 1,
-                                                    ruleId = 2,
-                                                    msgId = msgId,
-                                                    createTime = dateString,
-                                                    oneLevel = response.data.details.type ?: "",
-                                                    secondLevel = response.data.details.bank ?: "",
-                                                    code = response.data.details.amount ?: "",
-                                                    pickup = 0,
-                                                    pickupTime = "",
-                                                    overTime = response.data.details.date ?: "",
-                                                    address = response.data.details.address ?: "",
-                                                    remarks = "最小还款金额${response.data.details.min_amount}还款卡号${response.data.details.number}"
+                                            val amount = response.data.details.amount ?: ""
+                                            if (amount.isNotEmpty()) {
+                                                val existingCode = Core.code.queryByTypeAndCodeAndDate(
+                                                    response.data.category,
+                                                    amount,
+                                                    dateString
                                                 )
-                                                if(code.oneLevel!=""  && code.secondLevel!="" && code.code!="") {
-                                                    Core.code.insert(code)
+
+                                                if (existingCode == null) {
+                                                    val code = Code(
+                                                        id = 0,
+                                                        category = response.data.category,
+                                                        categoryId = 2,
+                                                        typeId = 1,
+                                                        ruleId = 2,
+                                                        msgId = msgId,
+                                                        createTime = dateString,
+                                                        oneLevel = response.data.details.type ?: "",
+                                                        secondLevel = response.data.details.bank ?: "",
+                                                        code = amount,
+                                                        pickup = 0,
+                                                        pickupTime = "",
+                                                        overTime = response.data.details.date ?: "",
+                                                        address = response.data.details.address ?: "",
+                                                        remarks = "最小还款金额${response.data.details.min_amount}还款卡号${response.data.details.number}"
+                                                    )
+                                                    if(code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) {
+                                                        Core.code.insert(code)
+                                                        android.util.Log.d("MainActivity", "历史还款短信已保存: $amount")
+                                                    }
+                                                } else {
+                                                    android.util.Log.d("MainActivity", "发现重复还款短信,跳过保存: $amount")
                                                 }
-                                                android.util.Log.d("MainActivity", "历史还款短信已保存: ${response.data.details.amount}")
-                                            } else {
-                                                android.util.Log.d("MainActivity", "发现重复还款短信,跳过保存: ${response.data.details.amount}")
                                             }
                                         }
-
                                         "收入" -> {
-                                            val existingCode = Core.code.queryByTypeAndCodeAndDate(
-                                                response.data.category,
-                                                response.data.details.amount ?: "",
-                                                dateString
-                                            )
-
-                                            if (existingCode == null) {
-                                                val code = Code(
-                                                    id = 0,
-                                                    category = response.data.category,
-                                                    categoryId = 3, // 3-收入类型
-                                                    typeId = 1,     //暂时没有根据type分类
-                                                    ruleId = 2,     //1-还款类型
-                                                    msgId = msgId,
-                                                    createTime = dateString,
-                                                    oneLevel = response.data.details.bank ?: "",
-                                                    secondLevel = response.data.details.bank ?: "",
-                                                    code = response.data.details.amount ?: "",
-                                                    pickup = 0, // 0-未取件,1-已取件
-                                                    pickupTime = "", // 取件时间为空
-                                                    overTime = response.data.details.datetime
-                                                        ?: "",  // 超时时间为空,暂时没有这块处理逻辑
-                                                    address = response.data.details.address ?: "",
-                                                    remarks = "余额" + response.data.details.balance ?: "",
+                                            val amount = response.data.details.amount ?: ""
+                                            if (amount.isNotEmpty()) {
+                                                val existingCode = Core.code.queryByTypeAndCodeAndDate(
+                                                    response.data.category,
+                                                    amount,
+                                                    dateString
                                                 )
-                                                if(code.oneLevel!=""  && code.secondLevel!="" && code.code!="") {
-                                                    Core.code.insert(code)
+
+                                                if (existingCode == null) {
+                                                    val code = Code(
+                                                        id = 0,
+                                                        category = response.data.category,
+                                                        categoryId = 3, // 3-收入类型
+                                                        typeId = 1,     //暂时没有根据type分类
+                                                        ruleId = 2,     //1-还款类型
+                                                        msgId = msgId,
+                                                        createTime = dateString,
+                                                        oneLevel = response.data.details.bank ?: "",
+                                                        secondLevel = response.data.details.bank ?: "",
+                                                        code = amount,
+                                                        pickup = 0, // 0-未取件,1-已取件
+                                                        pickupTime = "", // 取件时间为空
+                                                        overTime = response.data.details.datetime
+                                                            ?: "",  // 超时时间为空,暂时没有这块处理逻辑
+                                                        address = response.data.details.address ?: "",
+                                                        remarks = "余额" + response.data.details.balance ?: "",
+                                                    )
+                                                    if(code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) {
+                                                        Core.code.insert(code)
+                                                        android.util.Log.d("MainActivity", "历史还款短信已保存: $amount")
+                                                    }
+                                                } else {
+                                                    android.util.Log.d("MainActivity", "发现重复还款短信,跳过保存: $amount")
                                                 }
-                                                android.util.Log.d("MainActivity", "历史还款短信已保存: ${response.data.details.amount}")
-                                            } else {
-                                                android.util.Log.d("MainActivity", "发现重复还款短信,跳过保存: ${response.data.details.amount}")
                                             }
                                         }
                                     }
diff --git a/app/src/main/java/com/example/firstapp/activity/ContentDetailActivity.kt b/app/src/main/java/com/example/firstapp/activity/ContentDetailActivity.kt
index f82b1c0..a87d06e 100644
--- a/app/src/main/java/com/example/firstapp/activity/ContentDetailActivity.kt
+++ b/app/src/main/java/com/example/firstapp/activity/ContentDetailActivity.kt
@@ -14,7 +14,7 @@
     private lateinit var toolbar: androidx.appcompat.widget.Toolbar
 
     companion object {
-        const val EXTRA_CONTENT_TYPE = "content_type"
+        const val ID = "id"
         const val EXTRA_TITLE = "title"
     }
 
@@ -34,20 +34,20 @@
         toolbar.setNavigationOnClickListener { finish() }
 
         // 获取内容类型
-        val contentType = intent.getStringExtra(EXTRA_CONTENT_TYPE)
-        if (contentType != null) {
-            loadContent(contentType)
+        val id = intent.getStringExtra(ID)
+        if (id != null) {
+            loadContent(id)
         } else {
             Toast.makeText(this, "参数错误", Toast.LENGTH_SHORT).show()
             finish()
         }
     }
 
-    private fun loadContent(type: String) {
+    private fun loadContent(id: String) {
         lifecycleScope.launch {
             try {
-                val response = RetrofitClient.apiService.getContentByType(type)
-                if (response.code == 200 && response.data != null) {
+                val response = RetrofitClient.apiService.getContentById(id)
+                if (response.code == "0" && response.data != null) {
                     // 构建HTML内容
                     val htmlContent = """
                         <!DOCTYPE html>
diff --git a/app/src/main/java/com/example/firstapp/activity/FirstFragment.kt b/app/src/main/java/com/example/firstapp/activity/FirstFragment.kt
new file mode 100644
index 0000000..9cc51ef
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/activity/FirstFragment.kt
@@ -0,0 +1,45 @@
+package com.example.firstapp.activity
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.navigation.fragment.findNavController
+import com.example.firstapp.R
+import com.example.firstapp.databinding.FragmentFirstBinding
+
+/**
+ * A simple [Fragment] subclass as the default destination in the navigation.
+ */
+class FirstFragment : Fragment() {
+
+    private var _binding: FragmentFirstBinding? = null
+
+    // This property is only valid between onCreateView and
+    // onDestroyView.
+    private val binding get() = _binding!!
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View {
+
+        _binding = FragmentFirstBinding.inflate(inflater, container, false)
+        return binding.root
+
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        binding.buttonFirst.setOnClickListener {
+            findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
+        }
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        _binding = null
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt b/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt
index 457e213..8432373 100644
--- a/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt
+++ b/app/src/main/java/com/example/firstapp/activity/PhoneLoginActivity.kt
@@ -10,6 +10,7 @@
 import com.example.firstapp.databinding.ActivityPhoneLoginBinding
 import com.example.firstapp.ui.login.LoginViewModel
 import com.example.firstapp.utils.Log
+import com.example.firstapp.utils.PreferencesManager
 
 class PhoneLoginActivity : AppCompatActivity() {
     private lateinit var binding: ActivityPhoneLoginBinding
@@ -28,6 +29,9 @@
 
     private fun setupViews() {
         binding.apply {
+            // 设置上次登录的手机号
+            etPhone.setText(PreferencesManager.getLastLoginPhone())
+            
             btnBack.setOnClickListener {
                 startActivity(Intent(this@PhoneLoginActivity, LoginActivity::class.java))
                 finish()
@@ -48,6 +52,8 @@
                 val phone = etPhone.text.toString()
                 val code = etCode.text.toString()
                 if (phone.length == 11 && code.length == 6) {
+                    // 保存登录的手机号
+                    PreferencesManager.saveLastLoginPhone(phone)
                     viewModel.login(phone, code)
                 } else {
                     Toast.makeText(this@PhoneLoginActivity,
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/activity/SecondFragment.kt b/app/src/main/java/com/example/firstapp/activity/SecondFragment.kt
new file mode 100644
index 0000000..8f44618
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/activity/SecondFragment.kt
@@ -0,0 +1,45 @@
+package com.example.firstapp.activity
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.navigation.fragment.findNavController
+import com.example.firstapp.R
+import com.example.firstapp.databinding.FragmentSecondBinding
+
+/**
+ * A simple [Fragment] subclass as the second destination in the navigation.
+ */
+class SecondFragment : Fragment() {
+
+    private var _binding: FragmentSecondBinding? = null
+
+    // This property is only valid between onCreateView and
+    // onDestroyView.
+    private val binding get() = _binding!!
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View {
+
+        _binding = FragmentSecondBinding.inflate(inflater, container, false)
+        return binding.root
+
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        binding.buttonSecond.setOnClickListener {
+            findNavController().navigate(R.id.action_SecondFragment_to_FirstFragment)
+        }
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        _binding = null
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/activity/VipActivity.kt b/app/src/main/java/com/example/firstapp/activity/VipActivity.kt
new file mode 100644
index 0000000..9cf1f11
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/activity/VipActivity.kt
@@ -0,0 +1,544 @@
+package com.example.firstapp.activity
+
+import android.app.AlertDialog
+import android.content.Intent
+import android.graphics.Color
+import android.os.Bundle
+import android.util.TypedValue
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.Button
+import android.widget.CheckBox
+import android.widget.CompoundButton
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.TextView
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.cardview.widget.CardView
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.core.content.ContentProviderCompat.requireContext
+import androidx.core.content.ContextCompat
+import androidx.lifecycle.Observer
+import androidx.lifecycle.lifecycleScope
+import androidx.navigation.ui.AppBarConfiguration
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.bumptech.glide.Glide
+import com.example.firstapp.R
+import com.example.firstapp.adapter.CardAdapter
+import com.example.firstapp.database.request.ProductOrdersRequest
+import com.example.firstapp.database.response.UserInfo
+import com.example.firstapp.database.service.RetrofitClient
+import com.example.firstapp.databinding.ActivityVipBinding
+import com.example.firstapp.model.CardData
+import com.example.firstapp.model.MemberBenefitItem
+import com.example.firstapp.pay.PayAbility
+import com.example.firstapp.ui.vip.MemberInfoCardFragment
+import com.example.firstapp.utils.Log
+import com.example.firstapp.utils.PreferencesManager
+import com.google.gson.Gson
+import kotlinx.coroutines.launch
+import java.math.BigDecimal
+
+
+class VipActivity : AppCompatActivity() {
+
+    private lateinit var appBarConfiguration: AppBarConfiguration
+    private lateinit var binding: ActivityVipBinding
+    private var isPaymentSelected = false // 全局变量,默认未选中
+
+    private var orderName = ""
+    private var orderType=""
+    private var currentPrice = BigDecimal.ZERO
+    private var originalPrice = BigDecimal.ZERO
+    private var paymentMethod = ""
+
+    private var currentUserInfo: UserInfo? = null // 确保使用你的实际数据类
+
+
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        binding = ActivityVipBinding.inflate(layoutInflater)
+        setContentView(binding.root)
+
+        setSupportActionBar(binding.toolbar)
+
+        // 显式设置 MaterialToolbar 的标题
+        supportActionBar?.title = ""
+
+        // 如果不需要 ActionBar 的导航功能,可以禁用
+//        supportActionBar?.setDisplayHomeAsUpEnabled(false)
+//        supportActionBar?.setDisplayShowHomeEnabled(false)
+
+
+        // 返回事件
+        binding.ivBack.setOnClickListener{
+            finish()
+        }
+
+//        会员基本信息初始化
+        loadUserInfo()
+
+//        会员卡片初始化
+        vipCardInit()
+
+//        会员权益初始化
+        memberBenefitInit()
+
+        // 支付宝点击事件
+        handleAlipayClick()
+
+        // 微信点击事件
+        handleWechatClick()
+
+        // 勾选协议点击事件
+        handlePrototalClick()
+
+        // VIP会员服务协议
+        handleVipProtocolClick()
+
+    }
+
+
+    private fun handlePrototalClick(){
+        val protocol: CheckBox = findViewById(R.id.protocol_checkbox);
+
+        // 监听 RadioButton 选中状态
+        protocol.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
+            isPaymentSelected = isChecked // 更新全局变量
+//            if(isChecked){
+//                protocol.background = ContextCompat.getDrawable(this, R.drawable.checkbox_round_selected)
+//            }else{
+//                protocol.background = ContextCompat.getDrawable(this, R.drawable.checkbox_round)
+//            }
+        })
+    }
+
+    // 这里添加alipay_layout的点击事件
+    private fun handleAlipayClick() {
+        // 绑定按钮
+        val btnAlipay: LinearLayout = findViewById(R.id.alipay_layout);
+        btnAlipay.setOnClickListener(View.OnClickListener {
+            // 判断协议是否勾选
+            if (!isPaymentSelected){
+                // 这里需要弹出框
+                showConfirmDialog()
+            }else{
+                doAlipay()
+            }
+
+
+        })
+    }
+
+    private fun doAlipay(){
+        lifecycleScope.launch {
+            try {
+
+                var request = ProductOrdersRequest(
+                    orderName=orderName,
+                    orderType=orderType,
+                    originalPrice=originalPrice,
+                    currentPrice=currentPrice,
+                    paymentMethod=""
+                )
+
+                Log.d("REQUEST", Gson().toJson(request))
+                val response = RetrofitClient.apiService.getPayOrderInfo(request)
+                Log.d("API_RESPONSE", response.toString())
+
+                var orderInfo=response.data
+                Log.d("AliPayHelper","获取订单信息时: ${response}")
+                // 这里调用支付宝
+                PayAbility.aliPay(this@VipActivity, orderInfo, Observer {
+                    when (it.resultStatus) {
+                        "9000" -> {
+//                                Snackbar.make(binding.root, "支付成功", Snackbar.LENGTH_LONG).show()
+                            runOnUiThread {
+                                Toast.makeText(this@VipActivity, "支付成功", Toast.LENGTH_LONG).show()
+                                loadUserInfo()
+                            }
+                        }
+                        else -> {
+//                                Snackbar.make(binding.root, "支付失败", Snackbar.LENGTH_LONG).show()
+
+                            runOnUiThread {
+                                Toast.makeText(this@VipActivity, "支付失败", Toast.LENGTH_LONG).show()
+                            }
+                        }
+                    }
+                })
+
+            } catch (e: Exception) {
+                Toast.makeText(this@VipActivity, e.message, Toast.LENGTH_LONG).show()
+                Log.d("AliPayHelper","获取订单信息时发生错误: ${e.message}")
+            }
+        }
+    }
+
+    private fun showConfirmDialog() {
+        val dialogView = LayoutInflater.from(this).inflate(R.layout.vip_protocol_dialog_custom, null)
+
+        val dialog = AlertDialog.Builder(this)
+            .setView(dialogView)
+            .create()
+
+        // 设置自定义背景
+        dialog.window?.setBackgroundDrawableResource(R.drawable.dialog_background)
+
+        // 获取按钮并设置点击事件
+        val btnConfirm = dialogView.findViewById<Button>(R.id.btnConfirm)
+        btnConfirm.setOnClickListener {
+            // 将协议勾选上
+            val protocol: CheckBox = findViewById(R.id.protocol_checkbox);
+            protocol.isChecked = true
+
+            doAlipay()
+            dialog.dismiss()
+        }
+
+        // 显示对话框
+        dialog.show()
+    }
+    private fun showConfirmDialog2() {
+        // 创建标题 TextView 并居中
+        val titleView = TextView(this).apply {
+            text = "确认开通"
+            textSize = 20f
+            gravity = Gravity.CENTER
+            setPadding(20, 20, 20, 20)
+        }
+
+        // 创建内容 TextView 并居中
+        val messageView = TextView(this).apply {
+            text = "请阅读并同意《会员协议》?"
+            textSize = 16f
+            gravity = Gravity.CENTER
+            setPadding(40, 20, 40, 20)
+        }
+
+        AlertDialog.Builder(this)
+            .setCustomTitle(titleView)  // 自定义标题
+            .setView(messageView)  // 自定义内容
+            .setPositiveButton("继续开通") { _, _ ->
+
+
+
+                // 确认支付
+                doAlipay()
+            }
+            .setNegativeButton("取消") { dialog, _ ->
+                dialog.dismiss() // 关闭对话框
+            }
+            .show()
+    }
+
+    // 这里添加alipay_layout的点击事件
+    private fun handleWechatClick() {
+
+        // 绑定按钮
+        val wechatAlipay: LinearLayout = findViewById(R.id.wechat_layout);
+        wechatAlipay.setOnClickListener(View.OnClickListener {
+            lifecycleScope.launch {
+                try {
+                    // 判断协议是否勾选
+                    if (!isPaymentSelected){
+
+                        Toast.makeText(this@VipActivity, "请勾选协议", Toast.LENGTH_LONG).show()
+                        return@launch // 直接 return,不往下执行
+                    }
+                    Toast.makeText(this@VipActivity, "功能暂未开放", Toast.LENGTH_LONG).show()
+                    return@launch
+
+
+                } catch (e: Exception) {
+                    Toast.makeText(this@VipActivity, e.message, Toast.LENGTH_LONG).show()
+                    Log.d("AliPayHelper","获取订单信息时发生错误: ${e.message}")
+                }
+            }
+        })
+
+
+    }
+
+
+    private fun vipCardInit() {
+        val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
+        recyclerView.layoutManager =
+            LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
+
+        val cardList = listOf(
+            CardData.ContinueMonthly(
+                "首月限时特惠",
+                "连续包月",
+                "首次开通",
+                BigDecimal("0.01"),
+                "次月起12元/月",
+                "自动续费可随时取消",
+            ),
+            CardData.Yearly(
+                "折合9元/月",
+                "年卡",
+                BigDecimal("0.01"),
+                BigDecimal("168")
+            ),
+            CardData.SingleMonth(
+                "1个月",
+                BigDecimal("0.01")
+            )
+        )
+
+        // 这里获取列表的第一项作为初始化的值
+        // 获取第一项作为初始化的值
+        try {
+            val curentPriceTmp = cardList.firstOrNull()
+
+            // 确保 currentPrice 不为空并获取价格
+            currentPrice = when (curentPriceTmp) {
+                is CardData.ContinueMonthly -> curentPriceTmp.price
+                is CardData.Yearly -> curentPriceTmp.price
+                is CardData.SingleMonth -> curentPriceTmp.price
+                else -> BigDecimal.ZERO // 兜底处理,避免 null 时报错
+            }
+
+
+            val title = when (curentPriceTmp) {
+                is CardData.ContinueMonthly -> curentPriceTmp.title
+                is CardData.Yearly -> curentPriceTmp.title
+                is CardData.SingleMonth -> curentPriceTmp.title
+                else -> ""
+            }
+
+            originalPrice =  when (curentPriceTmp) {
+                is CardData.ContinueMonthly -> BigDecimal.ZERO
+                is CardData.Yearly -> curentPriceTmp.originalPrice
+                is CardData.SingleMonth -> BigDecimal.ZERO
+                else -> BigDecimal.ZERO
+            }
+
+            // 初始化支付
+            orderName = title
+            orderType = title
+
+
+            val alipayAmount:TextView = findViewById(R.id.alipay_amount);
+            val wechatAmount:TextView = findViewById(R.id.wechat_amount);
+            val protocolDescLayout:TextView = findViewById(R.id.protocol_desc_layout);
+
+
+            alipayAmount.text=currentPrice.toString()
+            wechatAmount.text=currentPrice.toString()
+            protocolDescLayout.text="自动续费可随时取消,开通后每月按${currentPrice.toString()}元自动续费,可随时取消自动续费"
+
+
+        }catch (e: Exception) {
+            Toast.makeText(this@VipActivity, e.message, Toast.LENGTH_LONG).show()
+            Log.d("AliPayHelper","支付失败: ${e.message}")
+        }
+
+        val adapter = CardAdapter(cardList) { cardViewList, cardData, cardView ->
+            handleVipCardClick(cardViewList, cardData, cardView)
+        }
+
+        recyclerView.adapter = adapter
+    }
+
+    private fun memberBenefitInit() {
+        val container = findViewById<ConstraintLayout>(R.id.dynamicContainer)
+
+        // 传递过来的数据列表
+        val itemList = listOf(
+            MemberBenefitItem(R.mipmap.vip_life_insurance, "自定义更多分类", true),
+            MemberBenefitItem(R.mipmap.vip_ad_no, "自动去广告", false),
+            MemberBenefitItem(R.mipmap.vip_ling, "公众号提醒待办", true),
+            MemberBenefitItem(R.mipmap.vip_circle_pie, "数据统计", false)
+        )
+
+        var previousViewId = R.id.dynamicContainer
+
+        for ((index, item) in itemList.withIndex()) {
+            val iconView = ImageView(this).apply {
+                id = View.generateViewId()
+                setImageResource(item.iconRes)
+                layoutParams = ConstraintLayout.LayoutParams(
+                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30f, resources.displayMetrics).toInt(),
+                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30f, resources.displayMetrics).toInt()
+                ).apply {
+                    // 设置 margin
+                    setMargins(
+                        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20f, resources.displayMetrics).toInt(), // left
+                        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30f, resources.displayMetrics).toInt(), // top
+                        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20f, resources.displayMetrics).toInt(), // right
+                        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30f, resources.displayMetrics).toInt()  // bottom
+                    )
+                }
+
+            }
+
+            val textView = TextView(this).apply {
+                id = View.generateViewId()
+                text = item.text
+                textSize = 16f
+                setTextColor(Color.parseColor("#DFC08E"))
+            }
+
+            val checkView = ImageView(this).apply {
+                id = View.generateViewId()
+//                setImageResource(R.drawable.ic_check)
+                setImageResource(R.mipmap.vip_right)
+                layoutParams = ConstraintLayout.LayoutParams(
+                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30f, resources.displayMetrics).toInt(),
+                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30f, resources.displayMetrics).toInt()
+                )
+            }
+
+            container.addView(iconView)
+            container.addView(textView)
+            container.addView(checkView)
+
+            val constraintSet = ConstraintSet()
+            constraintSet.clone(container)
+
+            // Icon 位置
+            constraintSet.connect(
+                iconView.id,
+                ConstraintSet.TOP,
+                previousViewId,
+                if (index == 0) ConstraintSet.TOP else ConstraintSet.BOTTOM,
+                32
+            )
+            constraintSet.connect(
+                iconView.id,
+                ConstraintSet.START,
+                ConstraintSet.PARENT_ID,
+                ConstraintSet.START,
+                32
+            )
+
+            // Text 位置
+            constraintSet.connect(textView.id, ConstraintSet.TOP, iconView.id, ConstraintSet.TOP)
+            constraintSet.connect(
+                textView.id,
+                ConstraintSet.START,
+                iconView.id,
+                ConstraintSet.END,
+                32
+            )
+
+            // Check 位置
+            constraintSet.connect(checkView.id, ConstraintSet.TOP, iconView.id, ConstraintSet.TOP)
+            constraintSet.connect(
+                checkView.id,
+                ConstraintSet.END,
+                ConstraintSet.PARENT_ID,
+                ConstraintSet.END,
+                32
+            )
+
+            constraintSet.applyTo(container)
+
+            previousViewId = iconView.id
+        }
+    }
+
+    /**
+     * 会员卡样式点击事件
+     */
+    private fun handleVipCardClick(cardViewList: MutableList<CardView>, cardData: CardData, cardView: CardView) {
+        // 处理点击事件,修改样式
+        // 修改所有的边框色都是灰色
+        cardViewList.forEach { card ->
+            card.foreground = ContextCompat.getDrawable(this, R.drawable.gray_border_shape)  // 设置自定义背景
+        }
+
+        // 单独将点击的卡片边框颜色改为金色
+//            cardView.setCardBackgroundColor(Color.parseColor("#FF0000")) // 举例:设置背景颜色
+        cardView.foreground = ContextCompat.getDrawable(this, R.drawable.gold_border_shape)  // 设置自定义背景
+        val title = when (cardData) {
+            is CardData.ContinueMonthly -> cardData.title
+            is CardData.Yearly -> cardData.title
+            is CardData.SingleMonth -> cardData.title
+        }
+        currentPrice = when (cardData) {
+            is CardData.ContinueMonthly -> cardData.price
+            is CardData.Yearly -> cardData.price
+            is CardData.SingleMonth -> cardData.price
+        }
+        originalPrice =  when (cardData) {
+            is CardData.ContinueMonthly -> BigDecimal.ZERO
+            is CardData.Yearly -> cardData.originalPrice
+            is CardData.SingleMonth -> BigDecimal.ZERO
+        }
+
+
+        val alipayAmount:TextView = findViewById(R.id.alipay_amount);
+        val wechatAmount:TextView = findViewById(R.id.wechat_amount);
+        alipayAmount.text=currentPrice.toString()
+        wechatAmount.text=currentPrice.toString()
+        // 处理点击事件,这里我们只是简单地展示一个 Toast
+//        Toast.makeText(this, "点击了: ${title}", Toast.LENGTH_SHORT).show()
+        // 只有连续包月才展示
+        val xieyiLayout:LinearLayout = findViewById(R.id.xieyi_layout);
+        if (title == "连续包月") {
+            xieyiLayout.visibility = View.VISIBLE
+        }else{
+            xieyiLayout.visibility = View.GONE
+        }
+
+        orderName = title
+        orderType=title
+
+    }
+
+    private fun loadUserInfo() {
+        // 获取Fragment实例
+        val memberInfoCardFragment = supportFragmentManager.findFragmentById(R.id.memberInfoCardFragment) as MemberInfoCardFragment?
+        lifecycleScope.launch {
+            try {
+                // 从本地获取保存的手机号
+                val savedPhone = PreferencesManager.getPhone()
+                if (savedPhone.isNullOrEmpty()) {
+                    Toast.makeText(this@VipActivity, "用户未登录", Toast.LENGTH_SHORT).show()
+                    return@launch
+                }
+
+                val response = RetrofitClient.apiService.getUserInfo(savedPhone)
+                if (response.code == "0" && response.data != null) {
+                    // 保存用户信息
+                    currentUserInfo = response.data
+                    val userInfo = response.data
+                    // 调用ViewModel的刷新方法
+                    memberInfoCardFragment?.viewModel?.updateMemberStatus(userInfo)
+
+                }
+            } catch (e: Exception) {
+                e.printStackTrace()
+                Toast.makeText(this@VipActivity, "获取用户信息失败", Toast.LENGTH_SHORT).show()
+            }
+        }
+
+    }
+
+    // VIP会员服务协议
+    private fun handleVipProtocolClick(){
+
+        binding.protocolVip.setOnClickListener{
+            startContentActivity("VIP会员服务协议", "VIP会员服务协议")
+        }
+
+    }
+
+    private fun startContentActivity(type: String, title: String) {
+        val intent = Intent(this, ContentDetailActivity::class.java).apply {
+            putExtra(ContentDetailActivity.ID, type)
+            putExtra(ContentDetailActivity.EXTRA_TITLE, title)
+        }
+        startActivity(intent)
+    }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/adapter/CardAdapter.kt b/app/src/main/java/com/example/firstapp/adapter/CardAdapter.kt
new file mode 100644
index 0000000..a12ce57
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/adapter/CardAdapter.kt
@@ -0,0 +1,126 @@
+package com.example.firstapp.adapter
+
+import android.graphics.Color
+import android.graphics.Paint
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.cardview.widget.CardView
+import androidx.recyclerview.widget.RecyclerView
+import com.example.firstapp.R
+import com.example.firstapp.model.CardData
+
+
+class CardAdapter(private val cardList: List<CardData>,
+                  private val itemClickListener: (MutableList<CardView>, CardData, CardView) -> Unit
+    ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
+
+    private val CONTINUE_MONTHLY_VIEW_TYPE = 0
+    private val YEARLY_VIEW_TYPE = 1
+    private val SINGLE_MONTH_VIEW_TYPE = 2
+
+    private val cardViewList: MutableList<CardView> = mutableListOf()
+
+    override fun getItemViewType(position: Int): Int {
+        return when (cardList[position]) {
+            is CardData.ContinueMonthly -> CONTINUE_MONTHLY_VIEW_TYPE
+            is CardData.Yearly -> YEARLY_VIEW_TYPE
+            is CardData.SingleMonth -> SINGLE_MONTH_VIEW_TYPE
+        }
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+        return when (viewType) {
+            CONTINUE_MONTHLY_VIEW_TYPE -> {
+                val view = LayoutInflater.from(parent.context).inflate(R.layout.item_card_continue_monthly, parent, false)
+                ContinueMonthlyViewHolder(view)
+            }
+            YEARLY_VIEW_TYPE -> {
+                val view = LayoutInflater.from(parent.context).inflate(R.layout.item_card_yearly, parent, false)
+                YearlyViewHolder(view)
+            }
+            SINGLE_MONTH_VIEW_TYPE -> {
+                val view = LayoutInflater.from(parent.context).inflate(R.layout.item_card_single_month, parent, false)
+                SingleMonthViewHolder(view)
+            }
+            else -> throw IllegalArgumentException("Unknown view type")
+        }
+    }
+
+    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+        when (holder) {
+            is ContinueMonthlyViewHolder -> {
+                val data = cardList[position] as CardData.ContinueMonthly
+
+                holder.firstMonthTag.text = data.firstMonthTag
+                holder.titleText.text = data.title
+                holder.subTitleText.text = data.subTitle
+                holder.priceText.text = data.price.toString()
+                holder.nextPriceText.text = data.nextPrice
+                holder.autoRenewText.text = data.autoRenew
+
+                cardViewList.add(holder.cardView)
+
+                holder.itemView.setOnClickListener { itemClickListener(cardViewList,data, holder.cardView) } // 设置点击事件
+            }
+            is YearlyViewHolder -> {
+                val data = cardList[position] as CardData.Yearly
+                holder.discountTag.text = data.discountTag
+                holder.titleText.text = data.title
+                holder.priceText.text = data.price.toString()
+                holder.originalPriceText.text = data.originalPrice.toString()
+
+                // 设置中划线
+                val paint = holder.originalPriceText.paint
+                paint.flags = paint.flags or Paint.STRIKE_THRU_TEXT_FLAG
+                paint.color = Color.RED // 设置中划线的颜色
+
+                cardViewList.add(holder.cardView)
+
+                holder.itemView.setOnClickListener { itemClickListener(cardViewList,data, holder.cardView) } // 设置点击事件
+            }
+            is SingleMonthViewHolder -> {
+                val data = cardList[position] as CardData.SingleMonth
+                holder.titleText.text = data.title
+                holder.priceText.text = data.price.toString()
+
+                cardViewList.add(holder.cardView)
+
+                holder.itemView.setOnClickListener { itemClickListener(cardViewList,data, holder.cardView) } // 设置点击事件
+
+            }
+        }
+    }
+
+    override fun getItemCount(): Int {
+        return cardList.size
+    }
+
+    inner class ContinueMonthlyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+        val cardView: CardView = view.findViewById(R.id.vip_first_month_card_view)
+        val firstMonthTag: TextView = view.findViewById(R.id.first_month_tag)
+        val titleText: TextView = view.findViewById(R.id.title_text)
+        val subTitleText: TextView = view.findViewById(R.id.sub_title_text)
+        val priceText: TextView = view.findViewById(R.id.price_text)
+        val nextPriceText: TextView = view.findViewById(R.id.next_price_text)
+        val autoRenewText: TextView = view.findViewById(R.id.auto_renew_text)
+
+    }
+
+    inner class YearlyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+        val cardView: CardView = view.findViewById(R.id.vip_year_card_view)
+        val discountTag: TextView = view.findViewById(R.id.discount_tag)
+        val titleText: TextView = view.findViewById(R.id.yearly_title_text)
+        val priceText: TextView = view.findViewById(R.id.yearly_price_text)
+        val originalPriceText: TextView = view.findViewById(R.id.yearly_original_price_text)
+
+    }
+
+    inner class SingleMonthViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+        val cardView: CardView = view.findViewById(R.id.vip_month_card_view)
+        val titleText: TextView = view.findViewById(R.id.single_month_title_text)
+        val priceText: TextView = view.findViewById(R.id.single_month_price_text)
+
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/adapter/CategorySelectorAdapter.kt b/app/src/main/java/com/example/firstapp/adapter/CategorySelectorAdapter.kt
new file mode 100644
index 0000000..f3c46b9
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/adapter/CategorySelectorAdapter.kt
@@ -0,0 +1,66 @@
+package com.example.firstapp.adapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.firstapp.databinding.ItemCategorySelectorBinding
+import com.example.firstapp.model.CategoryConfig
+import java.util.Collections
+
+/**
+ * Adapter for the category selector recycler view.分类选择的适配器
+ */
+class CategorySelectorAdapter : RecyclerView.Adapter<CategorySelectorAdapter.ViewHolder>() {
+    
+    private var categories = mutableListOf<CategoryConfig>()
+    private var lastCheckedPosition = -1 // 记录最后一个选中的位置
+
+    class ViewHolder(val binding: ItemCategorySelectorBinding) : RecyclerView.ViewHolder(binding.root)
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+        val binding = ItemCategorySelectorBinding.inflate(
+            LayoutInflater.from(parent.context), parent, false
+        )
+        return ViewHolder(binding)
+    }
+
+    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+        val category = categories[position]
+        holder.binding.apply {
+            categoryName.text = category.name
+            categoryCheckBox.isChecked = category.isEnabled
+            
+            // 如果只有一个选中的项,禁用其复选框
+            categoryCheckBox.isEnabled = !(getEnabledCount() == 1 && category.isEnabled)
+            
+            categoryCheckBox.setOnCheckedChangeListener { _, isChecked ->
+                if (isChecked || getEnabledCount() > 1) {
+                    categories[position] = category.copy(isEnabled = isChecked)
+                    notifyDataSetChanged() // 刷新所有项以更新禁用状态
+                } else {
+                    // 如果要取消选中且只有一个选中项,恢复选中状态
+                    categoryCheckBox.isChecked = true
+                }
+            }
+        }
+    }
+
+    private fun getEnabledCount(): Int {
+        return categories.count { it.isEnabled }
+    }
+
+    override fun getItemCount() = categories.size
+
+    fun moveItem(fromPosition: Int, toPosition: Int) {
+        Collections.swap(categories, fromPosition, toPosition)
+        notifyItemMoved(fromPosition, toPosition)
+    }
+
+    fun setCategories(newCategories: List<CategoryConfig>) {
+        categories.clear()
+        categories.addAll(newCategories)
+        notifyDataSetChanged()
+    }
+
+    fun getCategories() = categories.toList()
+} 
\ 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..58bcc20 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
 
@@ -54,8 +55,14 @@
     """)
     fun getByKeyword(keyword: String): List<Code>
 
-    @Query("SELECT * FROM Code WHERE oneLevel = :content and code= :code and createTime = :dateString LIMIT 1")
-    fun queryByTypeAndCodeAndDate(content: String, code: String, dateString: String): Code
+    @Query("""
+        SELECT * FROM Code 
+        WHERE category = :category 
+        AND code = :code 
+        AND substr(createTime, 1, 10) = substr(:dateString, 1, 10)
+        LIMIT 1
+    """)
+    fun queryByTypeAndCodeAndDate(category: String, code: String, dateString: String): Code?
 
 
     @Query("update  Code set pickup = '1' ,  pickuptime = CURRENT_TIMESTAMP  where id=:id")
@@ -261,4 +268,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..ad83877 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
 
 
@@ -23,7 +24,8 @@
         return codeDao.getByKeyword(keyword)
     }
 
-    fun queryByTypeAndCodeAndDate(content: String, code: String, dateString: String): Code {
+    @WorkerThread
+    fun queryByTypeAndCodeAndDate(content: String, code: String, dateString: String): Code? {
         return codeDao.queryByTypeAndCodeAndDate(content, code, dateString)
     }
 
@@ -75,4 +77,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/database/request/ProductOrdersRequest.kt b/app/src/main/java/com/example/firstapp/database/request/ProductOrdersRequest.kt
new file mode 100644
index 0000000..5d40cb9
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/database/request/ProductOrdersRequest.kt
@@ -0,0 +1,11 @@
+package com.example.firstapp.database.request
+
+import java.math.BigDecimal
+
+data class ProductOrdersRequest(
+    val orderName: String,
+    val orderType: String,
+    val originalPrice: BigDecimal,
+    val currentPrice: BigDecimal,
+    val paymentMethod: String
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/request/SmsLoginRequest.kt b/app/src/main/java/com/example/firstapp/database/request/SmsLoginRequest.kt
new file mode 100644
index 0000000..d76dce6
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/database/request/SmsLoginRequest.kt
@@ -0,0 +1,7 @@
+package com.example.firstapp.database.request
+
+data class SmsLoginRequest(
+    val username: String,
+    val smsCode: String,
+    val userType: String,
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/request/SmsSendRequest.kt b/app/src/main/java/com/example/firstapp/database/request/SmsSendRequest.kt
new file mode 100644
index 0000000..ea46ff7
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/database/request/SmsSendRequest.kt
@@ -0,0 +1,6 @@
+package com.example.firstapp.database.request
+
+data class SmsSendRequest(
+    val tel: String,
+    val userType: String
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/response/ContentResponse.kt b/app/src/main/java/com/example/firstapp/database/response/ContentResponse.kt
index 9cfa6a5..9fb7e80 100644
--- a/app/src/main/java/com/example/firstapp/database/response/ContentResponse.kt
+++ b/app/src/main/java/com/example/firstapp/database/response/ContentResponse.kt
@@ -1,20 +1,13 @@
 package com.example.firstapp.database.response
 
 data class ContentResponse(
-    val code: Int,
+    val code: String,
     val msg: String,
     val data: ContentData?
 )
 
 data class ContentData(
-    val id: Long,
-    val type: String,
+    val id: String,
     val title: String,
     val content: String,
-    val version: String,
-    val status: Int,
-    val createTime: String,
-    val updateTime: String,
-    val creator: String?,
-    val updater: String?
 )
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/response/OAuth2TokenResponse.kt b/app/src/main/java/com/example/firstapp/database/response/OAuth2TokenResponse.kt
new file mode 100644
index 0000000..18ea0b5
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/database/response/OAuth2TokenResponse.kt
@@ -0,0 +1,17 @@
+import com.google.gson.annotations.SerializedName
+
+data class OAuth2AccessToken(
+    @SerializedName("access_token")
+    val value: String,          // token值
+    @SerializedName("token_type")
+    val tokenType: String,      // token类型
+    @SerializedName("refresh_token")
+    val refreshToken: String,   // 刷新token
+    val scope: String          // 作用域
+)
+
+data class TokenResponse(
+    val code: String,          // 注意这里改为 String 类型
+    val msg: String,
+    val data: OAuth2AccessToken?
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt b/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt
index 3e5c46c..dcea53b 100644
--- a/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt
+++ b/app/src/main/java/com/example/firstapp/database/response/UserInfo.kt
@@ -6,7 +6,7 @@
     val name: String,
     val cover: String,
     val contactTel: String,
-    val passTime: String,
-    val overTime: String,
-    val showed: Boolean
+    val memberOvertime: String,
+    val memberOverDate: String,
+    val isMember: Boolean
 )
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/service/ApiService.kt b/app/src/main/java/com/example/firstapp/database/service/ApiService.kt
index 3171ff6..2fbbb90 100644
--- a/app/src/main/java/com/example/firstapp/database/service/ApiService.kt
+++ b/app/src/main/java/com/example/firstapp/database/service/ApiService.kt
@@ -1,25 +1,33 @@
 package com.example.firstapp.database.service
 
+import TokenResponse
 import com.example.firstapp.database.entity.ApiResponse
 import com.example.firstapp.database.entity.KeywordConfig
+import com.example.firstapp.database.request.ProductOrdersRequest
+import com.example.firstapp.database.request.SmsLoginRequest
+import com.example.firstapp.database.request.SmsSendRequest
 import com.example.firstapp.database.response.AlipayOrderInfoResponse
 import com.example.firstapp.database.response.ContentResponse
 import com.example.firstapp.database.response.DictResponse
 import com.example.firstapp.database.response.LoginResponse
 import com.example.firstapp.database.response.SecurityResponse
-import com.example.firstapp.database.response.SmsProcessResponse
 import com.example.firstapp.database.response.UserInfo
+import com.example.firstapp.model.CategoryConfig
+import com.example.firstapp.model.CategoryConfigSync
+import com.example.firstapp.network.AuthInterceptor
 import okhttp3.MultipartBody
+import okhttp3.OkHttpClient
 import okhttp3.RequestBody
 import retrofit2.Retrofit
 import retrofit2.converter.gson.GsonConverterFactory
-import retrofit2.http.Body
 import retrofit2.http.GET
 import retrofit2.http.Multipart
 import retrofit2.http.POST
 import retrofit2.http.Part
 import retrofit2.http.Path
 import retrofit2.http.Query
+import retrofit2.http.Body
+import java.util.concurrent.TimeUnit
 
 /**
  * API调用接口
@@ -29,48 +37,67 @@
     @GET("keywords")
     suspend fun getKeywords():ApiResponse<List<KeywordConfig>>  //异步挂起
 
-    @GET("cloudContent/getByType")
-    suspend fun getContentByType(@Query("type") type: String): ContentResponse
+    @GET("api/config/content/list/view")
+    suspend fun getContentById(@Query("id") id: String): ContentResponse
 
     @GET("sysDict/getByDictCodeAndItemText")
     suspend fun getDictValue(@Query("dictCode") dictCode: String, @Query("itemText") itemText: String): DictResponse
 
-    @POST("sms/send-code")
-    suspend fun sendVerificationCode(@Query("phone") phone: String): LoginResponse
+    // 发送短信验证码
+    @POST("api/sms/send/code")
+    suspend fun sendVerificationCode(@Body request: SmsSendRequest): LoginResponse
 
-    @POST("sms/login")
-    suspend fun verifyCode(@Query("phone") phone: String, @Query("code") code: String): LoginResponse
+    // 验证短信验证码
+    @POST("api/login/customer/phone/v2")
+    suspend fun verifyCode(@Body request: SmsLoginRequest): TokenResponse
 
     @GET("config-security/enable-list-all")
     suspend fun getSecurityList(): SecurityResponse
 
-    @GET("alipay/pay-order-info")
-    suspend fun getPayOrderInfo(): AlipayOrderInfoResponse
+    @POST("v2/alipay/pay-order-info")
+    suspend fun getPayOrderInfo(@Body request: ProductOrdersRequest): AlipayOrderInfoResponse
 
-    @GET("flower/api/supplier/info/{phone}")
+    // 获取用户信息
+    @GET("api/customer/info/{phone}")
     suspend fun getUserInfo(@Path("phone") phone: String): ApiResponse<UserInfo>
 
     @Multipart
-    @POST("api/supplier/operation/update")
+    @POST("flower/api/supplier/operation/update")
     suspend fun updateProfile(
         @Part("nickname") nickname: RequestBody,
         @Part avatar: MultipartBody.Part?
     ): ApiResponse<Unit>
 
-    @POST("process-sms")
-    suspend fun processSms(@Body body: Map<String, String>): SmsProcessResponse
+
+    fun getUserCategories(currentUserId: String): List<CategoryConfig>
+
+    fun saveUserCategories(categoryConfigSync: CategoryConfigSync)
+
 }
 
 // 创建Retrofit实例(单例)
 object RetrofitClient{
 
-//    private const val BASE_URL ="http://192.168.1.213:8888/jshERP-boot/"
-    private const val BASE_URL ="http://192.168.1.213:5000/"
+    private const val BASE_URL ="http://192.168.1.213:8080/flower/"
+
+    // 创建OkHttpClient,配置拦截器和超时时间
+    private val okHttpClient = OkHttpClient.Builder()
+        .addInterceptor(AuthInterceptor())
+        .connectTimeout(30, TimeUnit.SECONDS)
+        .readTimeout(30, TimeUnit.SECONDS)
+        .writeTimeout(30, TimeUnit.SECONDS)
+        .build()
+
 
     //添加Gson解析器,用于自动将JSON响应转换为Kotlin/Java对象
-    private val retrofit = Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build()
+    private val retrofit = Retrofit
+        .Builder()
+        .client(okHttpClient)
+        .baseUrl(BASE_URL)
+        .addConverterFactory(GsonConverterFactory.create())
+        .build()
 
     //通过动态代理技术创建ApiService接口的具体实现类
     val apiService:ApiService = retrofit.create(ApiService::class.java)
 
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/example/firstapp/database/service/ModelService.kt b/app/src/main/java/com/example/firstapp/database/service/ModelService.kt
new file mode 100644
index 0000000..27bfbd9
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/database/service/ModelService.kt
@@ -0,0 +1,33 @@
+package com.example.firstapp.database.service
+
+import com.example.firstapp.database.response.SmsProcessResponse
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import retrofit2.http.Body
+import retrofit2.http.POST
+
+/**
+ * 模型相关接口
+ */
+interface ModelService {
+
+    @POST("process-sms")
+    suspend fun processSms(@Body body: Map<String, String>): SmsProcessResponse
+}
+
+// 创建Retrofit实例(单例)
+object RetrofitModelClient {
+
+    private const val BASE_URL = "http://192.168.1.213:5000/"
+
+    //添加Gson解析器,用于自动将JSON响应转换为Kotlin/Java对象
+    private val retrofit = Retrofit
+        .Builder()
+        .baseUrl(BASE_URL)
+        .addConverterFactory(GsonConverterFactory.create())
+        .build()
+
+    //通过动态代理技术创建ApiService接口的具体实现类
+    val modelService: ModelService = retrofit.create(ModelService::class.java)
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/model/CardData.kt b/app/src/main/java/com/example/firstapp/model/CardData.kt
new file mode 100644
index 0000000..1752dcf
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/model/CardData.kt
@@ -0,0 +1,26 @@
+package com.example.firstapp.model
+
+import java.math.BigDecimal
+
+sealed class CardData {
+    data class ContinueMonthly(
+        val firstMonthTag: String,
+        val title: String,
+        val subTitle: String,
+        val price: BigDecimal,
+        val nextPrice: String,
+        val autoRenew: String
+    ) : CardData()
+
+    data class Yearly(
+        val discountTag: String,
+        val title: String,
+        val price: BigDecimal,
+        val originalPrice: BigDecimal
+    ) : CardData()
+
+    data class SingleMonth(
+        val title: String,
+        val price: BigDecimal
+    ) : CardData()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/model/CategoryConfig.kt b/app/src/main/java/com/example/firstapp/model/CategoryConfig.kt
new file mode 100644
index 0000000..29a37e9
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/model/CategoryConfig.kt
@@ -0,0 +1,11 @@
+package com.example.firstapp.model
+
+/**
+ * Created by fanghaowei on 2025/03/27. 首页数据配置类
+ */
+data class CategoryConfig(
+    val id: Int,
+    val name: String,
+    val order: Int,
+    val isEnabled: Boolean = true
+) 
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/model/CategoryConfigSync.kt b/app/src/main/java/com/example/firstapp/model/CategoryConfigSync.kt
new file mode 100644
index 0000000..82bf6d0
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/model/CategoryConfigSync.kt
@@ -0,0 +1,6 @@
+package com.example.firstapp.model
+
+data class CategoryConfigSync(
+    val userId: String,
+    val categories: List<CategoryConfig>
+) 
\ 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/MemberBenefitItem.kt b/app/src/main/java/com/example/firstapp/model/MemberBenefitItem.kt
new file mode 100644
index 0000000..179daa5
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/model/MemberBenefitItem.kt
@@ -0,0 +1,5 @@
+package com.example.firstapp.model
+
+class MemberBenefitItem ( val iconRes: Int,
+                          val text: String,
+                          val isChecked: Boolean )
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/model/MoreMemberBenefitItem.kt b/app/src/main/java/com/example/firstapp/model/MoreMemberBenefitItem.kt
new file mode 100644
index 0000000..ceb96ad
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/model/MoreMemberBenefitItem.kt
@@ -0,0 +1,4 @@
+package com.example.firstapp.model
+
+class MoreMemberBenefitItem (val iconRes: Int,
+                             val text: 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/network/AuthInterceptor.kt b/app/src/main/java/com/example/firstapp/network/AuthInterceptor.kt
new file mode 100644
index 0000000..1f1a191
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/network/AuthInterceptor.kt
@@ -0,0 +1,24 @@
+package com.example.firstapp.network
+
+import com.example.firstapp.utils.PreferencesManager
+import okhttp3.Interceptor
+import okhttp3.Response
+
+class AuthInterceptor : Interceptor {
+    override fun intercept(chain: Interceptor.Chain): Response {
+        val originalRequest = chain.request()
+        
+        // 获取token
+        val token = PreferencesManager.getToken()
+        
+        // 如果token存在,添加到请求头
+        return if (!token.isNullOrEmpty()) {
+            val newRequest = originalRequest.newBuilder()
+                .header("Authorization", "Bearer $token")
+                .build()
+            chain.proceed(newRequest)
+        } else {
+            chain.proceed(originalRequest)
+        }
+    }
+} 
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/network/TokenExpiredInterceptor.kt b/app/src/main/java/com/example/firstapp/network/TokenExpiredInterceptor.kt
new file mode 100644
index 0000000..1c73d50
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/network/TokenExpiredInterceptor.kt
@@ -0,0 +1,19 @@
+package com.example.firstapp.network
+
+import com.example.firstapp.utils.PreferencesManager
+import okhttp3.Interceptor
+import okhttp3.Response
+
+class TokenExpiredInterceptor : Interceptor {
+    override fun intercept(chain: Interceptor.Chain): Response {
+        val response = chain.proceed(chain.request())
+        
+        // 如果返回401,说明token可能过期
+        if (response.code == 401) {
+            PreferencesManager.clearUserData() // 清除本地token
+            // TODO: 处理token过期,例如跳转到登录页面
+        }
+        
+        return response
+    }
+} 
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt b/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt
index 3d732b4..9a611bb 100644
--- a/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt
+++ b/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt
@@ -13,6 +13,7 @@
 import com.example.firstapp.database.entity.Code
 import com.example.firstapp.database.entity.Msg
 import com.example.firstapp.database.service.RetrofitClient
+import com.example.firstapp.database.service.RetrofitModelClient
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -58,7 +59,7 @@
                 CoroutineScope(Dispatchers.IO).launch {
                     try {
                         val response =
-                            RetrofitClient.apiService.processSms(mapOf("content" to messageBody.toString()))
+                            RetrofitModelClient.modelService.processSms(mapOf("content" to messageBody.toString()))
 
                         if (response.status == "success") {
                             // 获取当前时间
diff --git a/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt b/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt
index 967a83c..21cb233 100644
--- a/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt
+++ b/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt
@@ -21,9 +21,18 @@
 import java.util.*
 import java.text.SimpleDateFormat
 import android.graphics.Color
+import android.widget.Button
 import android.widget.GridLayout
+import android.widget.Toast
+import androidx.core.content.ContextCompat
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.example.firstapp.database.response.UserInfo
+import com.example.firstapp.database.service.RetrofitClient
 import com.example.firstapp.model.DailyStat
+import com.example.firstapp.utils.PreferencesManager
 import com.github.mikephil.charting.components.YAxis
+import kotlinx.coroutines.launch
 
 class DashboardFragment : Fragment() {
 
@@ -35,6 +44,9 @@
     private lateinit var barChart: BarChart
     private lateinit var pieChart: PieChart
     private lateinit var heatmapView: View
+    private var currentUserInfo: UserInfo? = null // 确保使用你的实际数据类
+
+
     enum class DateType {
         DAY, WEEK, MONTH, YEAR
     }
@@ -49,6 +61,12 @@
         return binding.root
     }
 
+    override fun onResume() {
+        super.onResume()
+        // 重新加载用户信息
+        loadUserInfo()
+    }
+
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
@@ -61,7 +79,31 @@
         setupView(view)
         updateDateDisplay()
         loadPackages()
+
+        // 遮罩层
+        loadUserInfo()
+
+        // 遮罩层点击时间
+        binding.overlayContent.setOnClickListener {
+            // 跳转到vipActivity
+            val intent = android.content.Intent(requireContext(), com.example.firstapp.activity.VipActivity::class.java)
+            startActivity(intent)
+        }
     }
+
+    private fun showOverlay() {
+        binding.viewOverlay.visibility = View.VISIBLE
+        binding.overlayContent.visibility = View.VISIBLE
+
+    }
+
+    private fun hiddleOverlay() {
+        binding.viewOverlay.visibility = View.GONE
+        binding.overlayContent.visibility = View.GONE
+
+
+    }
+
 
     private fun setupRecyclerView() {
         binding.recyclerPackages.apply {
@@ -554,4 +596,35 @@
         super.onDestroyView()
         _binding = null
     }
+    private fun loadUserInfo() {
+
+        lifecycleScope.launch {
+            try {
+                // 从本地获取保存的手机号
+                val savedPhone = PreferencesManager.getPhone()
+                if (savedPhone.isNullOrEmpty()) {
+                    Toast.makeText(context, "用户未登录", Toast.LENGTH_SHORT).show()
+                    return@launch
+                }
+
+                val response = RetrofitClient.apiService.getUserInfo(savedPhone)
+                if (response.code == "0" && response.data != null) {
+                    // 保存用户信息
+                    currentUserInfo = response.data
+                    val userInfo = response.data
+                    if(userInfo.isMember){
+                        hiddleOverlay()
+                    }else{
+                        // 显示遮罩层
+                        showOverlay()
+                    }
+
+                }
+            } catch (e: Exception) {
+                e.printStackTrace()
+                Toast.makeText(context, "获取用户信息失败", Toast.LENGTH_SHORT).show()
+            }
+        }
+
+    }
 }
\ 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 230fb9c..3fcc370 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
@@ -8,29 +8,45 @@
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.TextView
+import android.widget.Toast
 import androidx.core.content.ContextCompat
 import androidx.fragment.app.Fragment
 import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
 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.activity.VipActivity
 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.CategoryConfig
+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
+import com.example.firstapp.view.UnderlineTextView
 
 class HomeFragment : Fragment() {
 
     private var _binding: FragmentHomeBinding? = null
 
-    // This property is only valid between onCreateView and
-    // onDestroyView.
     private val binding get() = _binding!!
 
     private lateinit var homeViewModel: HomeViewModel
     private lateinit var expressAdapter: ExpressAdapter
     private lateinit var financeAdapter: FinanceAdapter
-//    private lateinit var memorialAdapter: MemorialAdapter
+    private lateinit var incomeAdapter: IncomeAdapter
+    private lateinit var flightAdapter: FinanceAdapter
+    private lateinit var trainAdapter: FinanceAdapter
     private lateinit var dataUpdateReceiver: BroadcastReceiver
 
     //onCreateView这个方法创建后被调用,通常是初始化视图组件和观察者
@@ -46,15 +62,37 @@
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
-        //通过 ViewModelProvider 获取 HomeViewModel 的实例,以便在视图中使用。
         homeViewModel = ViewModelProvider(this).get(HomeViewModel::class.java)
-        // 加载广告图片
-        //loadAdvertisements()
-        //调用这个方法来设置 RecyclerView用于设置 RecyclerView 的布局和适配器。
-        setupRecyclerViews()
+        val userId = "123456"
+        homeViewModel.initialize(requireContext(), userId)
+
+        // 检查是否是首次安装
+        val isFirstInstall = PreferencesManager.isFirstInstall()
+        if (isFirstInstall) {
+            // 首次安装,设置默认显示快递和还款
+            val defaultCategories = listOf(
+                CategoryConfig(
+                    id = 1,
+                    name = "快递",
+                    order = 1,
+                    isEnabled = true
+                ),
+                CategoryConfig(
+                    id = 2,
+                    name = "还款",
+                    order = 2,
+                    isEnabled = true
+                )
+            )
+            homeViewModel.saveCategories(defaultCategories)
+            // 标记为非首次安装
+            PreferencesManager.setFirstInstall(false)
+        }
+
+        setupAdapters()
         setupTabSwitching()
-        //调用这个方法来观察 ViewModel 中的数据变化
-        observeViewModelData()
+        setupObservers()
+        setupCategorySelector()
     }
 
     override fun onCreate(savedInstanceState: Bundle?) {
@@ -71,7 +109,7 @@
         }
     }
 
-    private fun setupRecyclerViews() {
+    private fun setupAdapters() {
         binding.expressRecycler.apply {
             layoutManager = LinearLayoutManager(context)
             expressAdapter = ExpressAdapter()
@@ -83,6 +121,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)
             }
@@ -103,17 +142,47 @@
                 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)
             }
         }
-//
-//        // 纪念日列表
-//        binding.memorialRecycler.apply {
-//            layoutManager = LinearLayoutManager(context)
-//            memorialAdapter = MemorialAdapter()
-//            adapter = memorialAdapter
-//        }
+
+        // 添加新的 RecyclerView
+        binding.incomeRecycler.apply {
+            layoutManager = LinearLayoutManager(context)
+            incomeAdapter = IncomeAdapter()
+            adapter = incomeAdapter
+
+            // 设置初始状态 - 添加这行
+            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 {
+            layoutManager = LinearLayoutManager(context)
+            flightAdapter = FinanceAdapter()
+            adapter = flightAdapter
+            visibility = View.GONE
+        }
+
+        binding.trainRecycler.apply {
+            layoutManager = LinearLayoutManager(context)
+            trainAdapter = FinanceAdapter()
+            adapter = trainAdapter
+            visibility = View.GONE
+        }
     }
 
     private fun setupTabSwitching() {
@@ -121,51 +190,105 @@
             // 设置初始状态
             tabExpress.setTextColor(ContextCompat.getColor(requireContext(), R.color.tab_selected))
             tabFinance.setTextColor(ContextCompat.getColor(requireContext(), R.color.gray))
-            others.setTextColor(ContextCompat.getColor(requireContext(), R.color.gray))
-            
+
             // 快递标签点击事件
             tabExpress.setOnClickListener {
+                hideAllRecyclers()
                 expressRecycler.visibility = View.VISIBLE
-                financeRecycler.visibility = View.GONE
-                tabExpress.setTextColor(ContextCompat.getColor(requireContext(), R.color.tab_selected))
-                tabFinance.setTextColor(ContextCompat.getColor(requireContext(), R.color.gray))
-                others.setTextColor(ContextCompat.getColor(requireContext(), R.color.gray))
-                tabExpress.textSize = 16f
-                tabFinance.textSize = 14f
-                others.textSize = 14f
+                updateTabStyles(tabExpress)
+                homeViewModel.loadExpressData()
             }
-            
-            // 财务标签点击事件
-            tabFinance.setOnClickListener {
-                expressRecycler.visibility = View.GONE
-                financeRecycler.visibility = View.VISIBLE
-                tabExpress.setTextColor(ContextCompat.getColor(requireContext(), R.color.gray))
-                tabFinance.setTextColor(ContextCompat.getColor(requireContext(), R.color.tab_selected))
-                others.setTextColor(ContextCompat.getColor(requireContext(), R.color.gray))
-                tabExpress.textSize = 14f
-                tabFinance.textSize = 16f
-                others.textSize = 14f
 
-                // 在切换到财务标签时加载数据 - 添加这行
+            // 还款标签点击事件 - 非会员也可以使用
+            tabFinance.setOnClickListener {
+                hideAllRecyclers()
+                financeRecycler.visibility = View.VISIBLE
+                updateTabStyles(tabFinance)
                 homeViewModel.loadFinanceData()
             }
+            
+            // 其他标签点击事件需要检查会员状态
+            val memberOnlyTabs = mapOf(
+                tabIncome to { homeViewModel.loadIncomeData() },
+                tabFlight to { homeViewModel.loadFlightData() },
+                tabTrain to { homeViewModel.loadTrainData() }
+            )
 
-            // 其他标签点击事件
-            others.setOnClickListener {
-                expressRecycler.visibility = View.GONE
-                financeRecycler.visibility = View.GONE
-                tabExpress.setTextColor(ContextCompat.getColor(requireContext(), R.color.gray))
-                tabFinance.setTextColor(ContextCompat.getColor(requireContext(), R.color.gray))
-                others.setTextColor(ContextCompat.getColor(requireContext(), R.color.tab_selected))
-                tabExpress.textSize = 14f
-                tabFinance.textSize = 14f
-                others.textSize = 16f
+            memberOnlyTabs.forEach { (tab, loadAction) ->
+                tab.setOnClickListener {
+                    checkMembershipAndExecute(tab) {
+                        hideAllRecyclers()
+                        when (tab) {
+                            tabIncome -> incomeRecycler.visibility = View.VISIBLE
+                            tabFlight -> flightRecycler.visibility = View.VISIBLE
+                            tabTrain -> trainRecycler.visibility = View.VISIBLE
+                        }
+                        updateTabStyles(tab)
+                        loadAction()
+                    }
+                }
             }
         }
     }
 
-    //这个方法用于观察 homeViewModel 中的 expressItems 数据。
-    private fun observeViewModelData() {
+    private fun checkMembershipAndExecute(tab: TextView, action: () -> Unit) {
+        // 从本地获取保存的手机号
+        val savedPhone = PreferencesManager.getPhone()
+        if (savedPhone.isNullOrEmpty()) {
+            Toast.makeText(requireContext(), "请先登录", Toast.LENGTH_SHORT).show()
+            return
+        }
+
+        // 使用协程检查会员状态
+        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()
+            }
+        }
+    }
+
+    private fun hideAllRecyclers() {
+        binding.apply {
+            expressRecycler.visibility = View.GONE
+            financeRecycler.visibility = View.GONE
+            incomeRecycler.visibility = View.GONE
+            flightRecycler.visibility = View.GONE
+            trainRecycler.visibility = View.GONE
+        }
+    }
+
+    private fun updateTabStyles(selectedTab: UnderlineTextView) {
+        binding.apply {
+            val tabs = listOf(tabExpress, tabFinance, tabIncome, tabFlight, tabTrain)
+            tabs.forEach { tab ->
+                // 设置文字颜色为黑色或灰色
+                tab.setTextColor(ContextCompat.getColor(requireContext(), 
+                    if (tab == selectedTab) android.R.color.black else R.color.gray))
+                // 设置文字大小
+                tab.textSize = if (tab == selectedTab) 16f else 14f
+                // 设置下划线
+                tab.setUnderlineVisible(tab == selectedTab)
+            }
+        }
+    }
+
+    private fun setupObservers() {
         //当 expressItems 数据发生变化时,更新 RecyclerView 的数据。
         homeViewModel.expressItems.observe(viewLifecycleOwner) { items ->
             //将新的数据列表提交给适配器,以更新 RecyclerView 的显示内容。
@@ -175,10 +298,83 @@
         homeViewModel.financeItems.observe(viewLifecycleOwner) { items ->
             financeAdapter.submitList(items)
         }
-//
-//        homeViewModel.memorialItems.observe(viewLifecycleOwner) { items ->
-//            memorialAdapter.submitList(items)
-//        }
+
+        // 观察收入数据变化
+        homeViewModel.incomeItems.observe(viewLifecycleOwner) { items ->
+            incomeAdapter.submitList(items)
+        }
+
+        homeViewModel.flightItems.observe(viewLifecycleOwner) { items ->
+            flightAdapter.submitList(items)
+        }
+
+        homeViewModel.trainItems.observe(viewLifecycleOwner) { items ->
+            trainAdapter.submitList(items)
+        }
+
+        // 观察可见分类的变化
+        homeViewModel.visibleCategories.observe(viewLifecycleOwner) { categories: List<CategoryConfig> ->
+            binding.apply {
+                // 隐藏所有标签
+                tabExpress.visibility = View.GONE
+                tabFinance.visibility = View.GONE
+                tabIncome.visibility = View.GONE
+                tabFlight.visibility = View.GONE
+                tabTrain.visibility = View.GONE
+
+                // 获取用户信息判断是否是会员
+                val savedPhone = PreferencesManager.getPhone()
+                lifecycleScope.launch {
+                    try {
+                        val response = RetrofitClient.apiService.getUserInfo(savedPhone ?: "")
+                        val isMember = response.code == "0" && response.data?.isMember == true
+
+                        if (!isMember) {
+                            // 非会员只显示快递和还款
+                            tabExpress.visibility = View.VISIBLE
+                            tabFinance.visibility = View.VISIBLE
+                            if (categories.firstOrNull()?.name == "快递") {
+                                tabExpress.performClick()
+                            } else {
+                                tabFinance.performClick()
+                            }
+                        } else {
+                            // 会员显示所有选中的分类
+                            categories.forEach { category ->
+                                when (category.name) {
+                                    "快递" -> {
+                                        tabExpress.visibility = if (category.isEnabled) View.VISIBLE else View.GONE
+                                        if (categories.indexOf(category) == 0 && category.isEnabled) tabExpress.performClick()
+                                    }
+                                    "还款" -> {
+                                        tabFinance.visibility = if (category.isEnabled) View.VISIBLE else View.GONE
+                                        if (categories.indexOf(category) == 0 && category.isEnabled) tabFinance.performClick()
+                                    }
+                                    "收入" -> {
+                                        tabIncome.visibility = if (category.isEnabled) View.VISIBLE else View.GONE
+                                        if (categories.indexOf(category) == 0 && category.isEnabled) tabIncome.performClick()
+                                    }
+                                    "航班" -> {
+                                        tabFlight.visibility = if (category.isEnabled) View.VISIBLE else View.GONE
+                                        if (categories.indexOf(category) == 0 && category.isEnabled) tabFlight.performClick()
+                                    }
+                                    "火车票" -> {
+                                        tabTrain.visibility = if (category.isEnabled) View.VISIBLE else View.GONE
+                                        if (categories.indexOf(category) == 0 && category.isEnabled) tabTrain.performClick()
+                                    }
+                                }
+                            }
+                        }
+                    } catch (e: Exception) {
+                        e.printStackTrace()
+                        // 发生错误时默认显示快递和还款
+                        tabExpress.visibility = View.VISIBLE
+                        tabFinance.visibility = View.VISIBLE
+                        tabExpress.performClick()
+                    }
+                }
+            }
+        }
     }
 
     override fun onResume() {
@@ -220,4 +416,85 @@
             .load("http://192.168.1.235:9999/advertisement/down.png")
             .into(binding.bottomAdBanner)
     }
+
+    // 设置分类选择器 检查会员状态
+    private fun setupCategorySelector() {
+        binding.categoryButton.setOnClickListener {
+            // 从本地获取保存的手机号
+            val savedPhone = PreferencesManager.getPhone()
+            if (savedPhone.isNullOrEmpty()) {
+                Toast.makeText(requireContext(), "请先登录", Toast.LENGTH_SHORT).show()
+                return@setOnClickListener
+            }
+
+            // 使用协程检查会员状态
+            lifecycleScope.launch {
+                try {
+                    val response = RetrofitClient.apiService.getUserInfo(savedPhone)
+                    if (response.code == "0" && response.data != null) {
+                        if (response.data.isMember) {
+                            showCategorySelectorDialog()
+                        } else {
+                            // 非会员跳转到VIP开通页面
+                            val intent = Intent(requireContext(), VipActivity::class.java)
+                            startActivity(intent)
+                        }
+                    } else {
+                        Toast.makeText(requireContext(), "获取用户信息失败", Toast.LENGTH_SHORT).show()
+                    }
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                    Toast.makeText(requireContext(), "网络错误,请稍后重试", Toast.LENGTH_SHORT).show()
+                }
+            }
+        }
+    }
+
+    private fun showCategorySelectorDialog() {
+        val dialog = BottomSheetDialog(requireContext())
+        val dialogBinding = DialogCategorySelectorBinding.inflate(layoutInflater)
+        dialog.setContentView(dialogBinding.root)
+
+        val adapter = CategorySelectorAdapter()
+        dialogBinding.categoryRecyclerView.apply {
+            layoutManager = LinearLayoutManager(context)
+            this.adapter = adapter
+        }
+
+        // 加载所有分类
+        homeViewModel.categories.observe(viewLifecycleOwner) { categories ->
+            // 如果是会员,显示所有分类供选择
+            lifecycleScope.launch {
+                try {
+                    val savedPhone = PreferencesManager.getPhone()
+                    val response = RetrofitClient.apiService.getUserInfo(savedPhone ?: "")
+                    val isMember = response.code == "0" && response.data?.isMember == true
+
+                    if (isMember) {
+                        // 会员可以看到所有分类
+                        adapter.setCategories(categories)
+                    } else {
+                        // 非会员只能看到快递和还款
+                        val limitedCategories = categories.filter { 
+                            it.name == "快递" || it.name == "还款" 
+                        }
+                        adapter.setCategories(limitedCategories)
+                    }
+                } catch (e: Exception) {
+                    // 发生错误时只显示基础分类
+                    val limitedCategories = categories.filter { 
+                        it.name == "快递" || it.name == "还款" 
+                    }
+                    adapter.setCategories(limitedCategories)
+                }
+            }
+        }
+
+        dialogBinding.saveButton.setOnClickListener {
+            homeViewModel.saveCategories(adapter.getCategories())
+            dialog.dismiss()
+        }
+
+        dialog.show()
+    }
 }
\ No newline at end of file
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 7b5c3fb..d40df61 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
@@ -1,23 +1,47 @@
 package com.example.firstapp.ui.home
 
+import android.content.Context
+import android.util.Log
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import com.example.firstapp.core.Core
-import com.example.firstapp.database.entity.Code
+import com.example.firstapp.database.service.RetrofitClient
+import com.example.firstapp.model.CategoryConfig
+import com.example.firstapp.model.CategoryConfigSync
 import com.example.firstapp.model.ExpressGroup
 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
 
 class HomeViewModel : ViewModel() {
 
     private val _expressItems = MutableLiveData<List<ExpressGroup>>()
     private val _financeItems = 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<IncomeGroup>> = _incomeItems
+    val flightItems: LiveData<List<FinanceGroup>> = _flightItems
+    val trainItems: LiveData<List<FinanceGroup>> = _trainItems
+
+    private val _categories = MutableLiveData<List<CategoryConfig>>()
+    val categories: LiveData<List<CategoryConfig>> = _categories
+
+    private val _visibleCategories = MutableLiveData<List<CategoryConfig>>()
+    val visibleCategories: LiveData<List<CategoryConfig>> = _visibleCategories
+
+    private lateinit var secureStorage: SecureStorage
+    private lateinit var currentUserId: String
 
     init {
         // 初始化时加载包裹列表数据
@@ -26,52 +50,194 @@
         //  loadFinanceData()
     }
 
-    fun loadExpressData() {
+    fun initialize(context: Context, userId: String) {
+        secureStorage = SecureStorage(context)
+        currentUserId = userId
+        loadCategories()
+        // 初始化时更新可见分类
+        _categories.value?.let { updateVisibleCategories(it) }
+    }
+
+    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() {
+        loadDataByType("还款")
+    }
+
+    fun loadIncomeData() {
+        loadDataByType("收入")
+    }
+
+    fun loadFlightData() {
+        loadDataByType("航班")
+    }
+
+    fun loadTrainData() {
+        loadDataByType("火车票")
+    }
+
+    private fun loadCategories() {
         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
+            try {
+                // 先尝试从本地获取配置
+                val localCategories = secureStorage.getCategories(currentUserId)
+                
+                // 默认完整分类列表
+                val fullCategories = listOf(
+                    CategoryConfig(1, "快递", 0, true),
+                    CategoryConfig(2, "还款", 1, true),
+                    CategoryConfig(3, "收入", 2, true),
+                    CategoryConfig(4, "航班", 3, true),
+                    CategoryConfig(5, "火车票", 4, true)
                 )
-            }
+                
+                // 基础分类(非会员可见)
+                val basicCategories = listOf(
+                    CategoryConfig(1, "快递", 0, true),
+                    CategoryConfig(2, "还款", 1, true)
+                )
 
-            _financeItems.postValue(groups)
+                if (localCategories.isNotEmpty()) {
+                    // 如果本地有配置,直接使用本地配置
+                    _categories.value = localCategories
+                } else {
+                    try {
+                        // 尝试从服务器获取用户信息判断是否是会员
+                        val savedPhone = PreferencesManager.getPhone()
+                        val response = RetrofitClient.apiService.getUserInfo(savedPhone ?: "")
+                        val isMember = response.code == "0" && response.data?.isMember == true
+
+                        // 根据会员状态设置默认分类
+                        val defaultCategories = if (isMember) fullCategories else basicCategories
+                        _categories.value = defaultCategories
+                        secureStorage.saveCategories(currentUserId, defaultCategories)
+                        
+                        // 同步到服务器
+                        try {
+                            syncCategoriesToServer(defaultCategories)
+                        } catch (e: Exception) {
+                            Log.e("HomeViewModel", "Failed to sync categories: ${e.message}")
+                        }
+                    } catch (e: Exception) {
+                        // 如果获取用户信息失败,使用基础分类
+                        _categories.value = basicCategories
+                        secureStorage.saveCategories(currentUserId, basicCategories)
+                    }
+                }
+                
+                // 更新可见分类
+                _categories.value?.let { updateVisibleCategories(it) }
+                
+            } catch (e: Exception) {
+                Log.e("HomeViewModel", "Failed to load categories: ${e.message}")
+            }
         }
     }
 
+    private fun syncCategoriesToServer(categories: List<CategoryConfig>) {
+        viewModelScope.launch {
+            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)
+        // 同步到服务器
+        syncCategoriesToServer(categories)
+        // 更新可见分类
+        updateVisibleCategories(categories)
+    }
+
+    private fun updateVisibleCategories(categories: List<CategoryConfig>) {
+        val visibleNames = categories
+            .filter { it.isEnabled }
+            .sortedBy { it.order }
+            .map { it.name }
+        
+        _visibleCategories.value = categories.filter { it.isEnabled }
+    }
+
+    // 登出时不再清除本地数据
+    fun logout() {
+        // 只清除内存中的数据
+        _categories.value = emptyList()
+    }
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt b/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt
index f61b646..92f03e9 100644
--- a/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt
+++ b/app/src/main/java/com/example/firstapp/ui/login/LoginViewModel.kt
@@ -5,8 +5,12 @@
 import androidx.lifecycle.viewModelScope
 import kotlinx.coroutines.launch
 import androidx.lifecycle.ViewModel
+import com.example.firstapp.database.request.SmsLoginRequest
+import com.example.firstapp.database.request.SmsSendRequest
 import com.example.firstapp.database.service.RetrofitClient
 import com.example.firstapp.utils.Log
+import com.example.firstapp.ui.home.HomeViewModel
+import com.example.firstapp.utils.PreferencesManager
 
 
 class LoginViewModel : ViewModel() {
@@ -19,16 +23,26 @@
     private val _isLoading = MutableLiveData<Boolean>()
     val isLoading: LiveData<Boolean> = _isLoading
 
+    private lateinit var homeViewModel: HomeViewModel
+
     fun sendVerificationCode(phone: String) {
         viewModelScope.launch {
             _isLoading.value = true
             try {
-//                val response = RetrofitClient.apiService.sendVerificationCode(phone)
-//                if (response.code == 200) {
+                // 创建 SmsSendRequest 对象
+                val request = SmsSendRequest(
+                    tel = phone,
+                    userType = "customer"
+                )
+                //Retrofit 进行网络请求时,类名不需要完全一致,只要保证类的属性名称和类型与后端 DTO 对象的属性一致即可。
+                //Retrofit + Gson 在序列化时会将对象转换为 JSON,后端 Spring 框架会将 JSON 反序列化为 SmsSendDTO 对象
+                //HTTP 请求实际传输的是 JSON 格式的数据,而不是 Java/Kotlin 对象。
+                val response = RetrofitClient.apiService.sendVerificationCode(request)
+                if (response.code == 0) {
                     _loginMessage.value = "验证码已发送"
-//                } else {
-//                    _loginMessage.value = response.msg.ifEmpty { "发送验证码失败" }
-//                }
+                } else {
+                    _loginMessage.value = response.msg.ifEmpty { "发送验证码失败" }
+                }
             } catch (e: Exception) {
                 Log.e("LoginError", "Login failed: ${e.message}", e)
                 _loginMessage.value = "网络错误,请稍后重试"
@@ -42,12 +56,20 @@
         viewModelScope.launch {
             _isLoading.value = true
             try {
-//                val response = RetrofitClient.apiService.verifyCode(phone, code)
-//                if (response.code == 200 && response.data) {
+                val request = SmsLoginRequest(
+                    username = phone,
+                    smsCode = code,
+                    userType = "customer"
+                )
+                //HttpServletRequest request这是后端 Spring 框架中的一个特殊参数,
+                //用于获取 HTTP 请求的相关信息(如请求头、Cookie 等),它会由 Spring 框架自动注入,不需要客户端显式传递。
+                val response = RetrofitClient.apiService.verifyCode(request)
+                if (response.code == "0" && response.data != null) {
+                    saveToken(response.data.value,phone)  // 这里获取的是 access_token
                     _loginState.value = true
-//                } else {
-//                    _loginMessage.value = response.msg.ifEmpty { "登录失败" }
-//                }
+                } else {
+                    _loginMessage.value = response.msg.ifEmpty { "登录失败" }
+                }
             } catch (e: Exception) {
                 Log.e("LoginError", "Login failed: ${e.message}", e)
                 _loginMessage.value = "网络错误,请稍后重试"
@@ -57,4 +79,20 @@
         }
     }
 
+    fun logout() {
+        viewModelScope.launch {
+            // 不再清除用户数据,只执行登出操作
+            homeViewModel.logout()
+            // 其他登出操作...
+        }
+    }
+
+    private fun saveToken(token: String,phone:String) {
+        // TODO: 实现token存储逻辑
+        // 可能还需要存储 refresh_token
+        PreferencesManager.saveToken(token)
+        // 保存登录的手机号
+        PreferencesManager.savePhone(phone)
+    }
+
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt b/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt
index 38a6f08..91fcafb 100644
--- a/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt
+++ b/app/src/main/java/com/example/firstapp/ui/notifications/NotificationsFragment.kt
@@ -31,9 +31,10 @@
 import com.google.android.material.snackbar.Snackbar
 import kotlinx.coroutines.launch
 import com.bumptech.glide.Glide
-import com.example.firstapp.MainActivity
+import com.example.firstapp.activity.VipActivity
 import com.example.firstapp.database.response.UserInfo
 import com.example.firstapp.ui.invitation.InvitationActivity
+import com.example.firstapp.utils.PreferencesManager
 
 class NotificationsFragment : Fragment() {
 
@@ -131,39 +132,6 @@
 
     private fun setupClickListeners() {
 
-        // 支付插件
-//        binding.payPlugin.setOnClickListener {
-//            // 跳转到支付插件页面
-//            lifecycleScope.launch {
-//                try {
-//                    val response = RetrofitClient.apiService.getPayOrderInfo()
-//                    var orderInfo=response.data
-//                    Log.d("AliPayHelper","获取订单信息时: ${response}")
-//                    // 这里调用支付宝
-//                    PayAbility.aliPay(requireActivity(), orderInfo, Observer {
-//                        when (it.resultStatus) {
-//                            "9000" -> {
-////                                Snackbar.make(binding.root, "支付成功", Snackbar.LENGTH_LONG).show()
-//                                requireActivity().runOnUiThread {
-//                                    Toast.makeText(requireContext(), "支付成功", Toast.LENGTH_LONG).show()
-//                                }
-//                            }
-//                            else -> {
-////                                Snackbar.make(binding.root, "支付失败", Snackbar.LENGTH_LONG).show()
-//                                requireActivity().runOnUiThread {
-//                                    Toast.makeText(requireContext(), "支付失败", Toast.LENGTH_LONG).show()
-//                                }
-//
-//                            }
-//                        }
-//                    })
-//
-//                } catch (e: Exception) {
-//                    Log.d("AliPayHelper","获取订单信息时发生错误: ${e.message}")
-//                }
-//            }
-//        }
-
 
         // 设置提醒
         binding.layoutReminder.setOnClickListener {
@@ -213,12 +181,12 @@
 
         // 隐私协议
         binding.layoutPrivacy.setOnClickListener {
-            startContentActivity("privacy_policy", "隐私协议")
+            startContentActivity("隐私协议", "隐私协议")
         }
 
         // 使用教程
         binding.layoutTutorial.setOnClickListener {
-            startContentActivity("user_guide", "使用教程")
+            startContentActivity("使用教程", "使用教程")
         }
 
         // 头像点击老的处理逻辑
@@ -236,8 +204,20 @@
 
         // VIP续费
         binding.btnRenew.setOnClickListener {
-            Toast.makeText(context, "VIP续费功能开发中", Toast.LENGTH_SHORT).show()
+//            Toast.makeText(context, "VIP续费功能开发中", Toast.LENGTH_SHORT).show()
+            // 跳转到vipActivity
+            val intent = Intent(requireContext(), VipActivity::class.java)
+            startActivity(intent)
         }
+
+        binding.cardVip.setOnClickListener {
+//            Toast.makeText(context, "VIP续费功能开发中", Toast.LENGTH_SHORT).show()
+            // 跳转到vipActivity
+            val intent = Intent(requireContext(), VipActivity::class.java)
+            startActivity(intent)
+        }
+
+
     }
 
     private fun showEmailDialog() {
@@ -292,9 +272,9 @@
         }
     }
 
-    private fun startContentActivity(type: String, title: String) {
+    private fun startContentActivity(id: String, title: String) {
         val intent = Intent(requireContext(), ContentDetailActivity::class.java).apply {
-            putExtra(ContentDetailActivity.EXTRA_CONTENT_TYPE, type)
+            putExtra(ContentDetailActivity.ID, id)
             putExtra(ContentDetailActivity.EXTRA_TITLE, title)
         }
         startActivity(intent)
@@ -302,7 +282,14 @@
 
     private suspend fun loadUserInfo() {
         try {
-            val response = RetrofitClient.apiService.getUserInfo("17586582287")
+            // 从本地获取保存的手机号
+            val savedPhone = PreferencesManager.getPhone()
+            if (savedPhone.isNullOrEmpty()) {
+                Toast.makeText(context, "用户未登录", Toast.LENGTH_SHORT).show()
+                return
+            }
+
+            val response = RetrofitClient.apiService.getUserInfo(savedPhone)
             if (response.code == "0" && response.data != null) {
                 // 保存用户信息
                 currentUserInfo = response.data
@@ -319,15 +306,16 @@
                 binding.tvUserId.text = "个人账号:${userInfo.contactTel}"
 
                 // 设置VIP信息
-                if (userInfo.showed) {
+                if (userInfo.isMember) {
                     binding.ivVip.visibility = View.VISIBLE
                     binding.cardVip.visibility = View.VISIBLE
-                    binding.tvVipExpire.text = "${userInfo.overTime} 到期"
+                    binding.tvVipExpire.text = "${userInfo.memberOverDate} 到期"
                 } else {
                     //非会员信息
+                    binding.ivVip.visibility = View.GONE
+                    binding.cardVip.visibility = View.VISIBLE
                     binding.btnRenew.text = "立即开通"
                     binding.linearVipContainer.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.gray))
-                    binding.cardVip.visibility = View.GONE
                 }
             }
         } catch (e: Exception) {
diff --git a/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardFragment.kt b/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardFragment.kt
new file mode 100644
index 0000000..0d3247e
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardFragment.kt
@@ -0,0 +1,162 @@
+package com.example.firstapp.ui.vip
+
+import android.graphics.Color
+import android.graphics.drawable.Drawable
+import androidx.fragment.app.viewModels
+import android.os.Bundle
+import android.util.Log
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.engine.GlideException
+import com.bumptech.glide.load.resource.bitmap.RoundedCorners
+import com.bumptech.glide.request.RequestListener
+import com.bumptech.glide.request.target.Target
+import com.bumptech.glide.load.DataSource
+import com.example.firstapp.R
+
+import com.example.firstapp.databinding.FragmentMemberInfoCardBinding
+import kotlinx.coroutines.launch
+
+class MemberInfoCardFragment : Fragment() {
+
+
+    companion object {
+        fun newInstance() = MemberInfoCardFragment()
+    }
+
+     val viewModel: MemberInfoCardViewModel by viewModels()
+
+    // 绑定变量
+    private var _binding: FragmentMemberInfoCardBinding? = null
+    private val binding get() = _binding!!
+
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+    }
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View {
+        // 使用 DataBindingUtil.inflate 来绑定布局
+        _binding = FragmentMemberInfoCardBinding.inflate(inflater, container, false)
+        binding.viewModel = viewModel
+        binding.lifecycleOwner = this
+
+        // 绑定头像
+
+        Glide.with(this)
+            .load(viewModel.cover)
+            .transform(RoundedCorners(100))  // 设置圆角
+//            .error(R.drawable.error_placeholder) // 如果加载失败,显示占位图
+            .error(R.mipmap.avatar_default)
+            .listener(object : RequestListener<Drawable> {
+                override fun onResourceReady(
+                    resource: Drawable?,
+                    model: Any?,
+                    target: Target<Drawable>?,  // 正确使用 Target 作为泛型参数
+                    dataSource: DataSource?,  // 导入正确的 DataSource
+                    isFirstResource: Boolean
+                ): Boolean {
+                    Log.d("Glide", "Image loaded successfully")
+                    return false
+                }
+
+                override fun onLoadFailed(
+                    e: GlideException?,
+                    model: Any?,
+                    target: Target<Drawable>?,  // 正确使用 Target 作为泛型参数
+                    isFirstResource: Boolean
+                ): Boolean {
+                    Log.e("Glide", "Image load failed", e)
+                    return false
+                }
+            })
+            .into(binding.memberAvatarView)
+
+
+        // 绑定会员徽章
+
+        Glide.with(this)
+            .load(viewModel.vipCover)
+            .transform(RoundedCorners(100))  // 设置圆角
+//            .error(R.drawable.error_placeholder) // 如果加载失败,显示占位图
+            .error(R.mipmap.vip_no)
+            .listener(object : RequestListener<Drawable> {
+                override fun onResourceReady(
+                    resource: Drawable?,
+                    model: Any?,
+                    target: Target<Drawable>?,  // 正确使用 Target 作为泛型参数
+                    dataSource: DataSource?,  // 导入正确的 DataSource
+                    isFirstResource: Boolean
+                ): Boolean {
+                    Log.d("Glide", "Image loaded successfully")
+                    return false
+                }
+
+                override fun onLoadFailed(
+                    e: GlideException?,
+                    model: Any?,
+                    target: Target<Drawable>?,  // 正确使用 Target 作为泛型参数
+                    isFirstResource: Boolean
+                ): Boolean {
+                    Log.e("Glide", "Image load failed", e)
+                    return false
+                }
+            })
+            .into(binding.memberImageView)
+
+
+        // 监听 cover 变化
+        viewLifecycleOwner.lifecycleScope.launch {
+            viewModel.cover.collect { coverUrl ->
+                Glide.with(this@MemberInfoCardFragment)
+                    .load(coverUrl)
+                    .transform(RoundedCorners(100))
+                    .error(R.drawable.error_placeholder)
+                    .into(binding.memberAvatarView)
+            }
+        }
+
+        // 监听 vipCover 变化
+        viewLifecycleOwner.lifecycleScope.launch {
+            viewModel.vipCover.collect { vipCoverUrl ->
+                Glide.with(this@MemberInfoCardFragment)
+                    .load(vipCoverUrl)
+                    .transform(RoundedCorners(100))
+                    .error(R.drawable.error_placeholder)
+                    .into(binding.memberImageView)
+            }
+        }
+
+        // 监听 background 变化
+        viewLifecycleOwner.lifecycleScope.launch {
+            viewModel.background.collect { backgroundColor ->
+//                binding.memberCardCardView.setBackgroundColor(Color.parseColor(backgroundColor))
+                binding.memberCardCardView.setBackgroundResource(backgroundColor)
+            }
+        }
+
+        viewLifecycleOwner.lifecycleScope.launch {
+            viewModel.color.collect { color ->
+                binding.phoneNumberText.setTextColor(Color.parseColor(color))
+                binding.memberStatus.setTextColor(Color.parseColor(color))
+            }
+        }
+
+        return binding.root
+    }
+
+    override fun onDestroyView() {
+        super.onDestroyView()
+        _binding = null
+    }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardViewModel.kt b/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardViewModel.kt
new file mode 100644
index 0000000..fa18bcf
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/ui/vip/MemberInfoCardViewModel.kt
@@ -0,0 +1,92 @@
+package com.example.firstapp.ui.vip
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.example.firstapp.R
+import com.example.firstapp.database.response.UserInfo
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.launch
+
+class MemberInfoCardViewModel : ViewModel() {
+
+    // 联系方式
+    private val _phoneNumber = MutableStateFlow("18099999999")
+    val phoneNumber: StateFlow<String> = _phoneNumber
+
+    // 开通状态
+    private val _memberStatus = MutableStateFlow("未开通")
+    val memberStatus: StateFlow<String> = _memberStatus
+
+    // 头像
+    private val _cover = MutableStateFlow("http://192.168.1.201:9000/sms/avatar/avatar_default.png")
+    val cover: StateFlow<String> = _cover
+
+    // vip头像
+    private val _vipCover = MutableStateFlow("")
+    val vipCover: StateFlow<String> = _vipCover
+
+    // 背景色
+    private val _background = MutableStateFlow(R.drawable.dialog_background)
+    val background: StateFlow<Int> = _background
+
+    // 背景色
+    private val _color = MutableStateFlow("#E8EAEE")
+    val color: StateFlow<String> = _color
+
+
+    // 更新数据的方法
+    fun updatePhoneNumber(phoneNumber: String) {
+        viewModelScope.launch {
+            _phoneNumber.value = phoneNumber
+        }
+    }
+
+    fun updateMemberStatus(userInfo: UserInfo) {
+        viewModelScope.launch {
+
+            // 电话号码
+            _phoneNumber.value=userInfo.contactTel
+
+            // 开通状态
+            if(userInfo.isMember){
+                // 判断userInfo.memberOvertime是否为空,如果不为空,则截取字符串到年月日
+//                if(userInfo.memberOvertime.isNotEmpty()){
+//                    _memberStatus.value = userInfo.memberOvertime.substring(0,10)+" 到期"
+//                }
+
+                _memberStatus.value = " 到期"
+                userInfo.memberOvertime?.let {
+                    if (it.isNotEmpty()) {
+                        _memberStatus.value = it.substring(0, 10) + " 到期"
+                    }
+                }
+                // vip头像
+                _vipCover.value ="http://192.168.1.201:9000/sms/member/vip.png"
+                _background.value = R.drawable.vip_black_background
+                _color.value ="#A9A9AB"
+
+            }else{
+                _memberStatus.value = "未开通"
+                _vipCover.value ="http://192.168.1.201:9000/sms/member/vip_no.png"
+                _background.value =R.drawable.vip_white_background
+                _color.value ="#A4A4A4"
+            }
+
+            // 头像
+            // 如果头像不为空的话,则更新头像
+//            if(userInfo.cover.isNotEmpty()){
+//                _cover.value = userInfo.cover
+//            }
+            userInfo.cover?.let {
+                if (it.isNotEmpty()) {
+                    _cover.value = it
+                }
+            }
+
+
+        }
+    }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/util/CategoryDragCallback.kt b/app/src/main/java/com/example/firstapp/util/CategoryDragCallback.kt
new file mode 100644
index 0000000..5c8c5ae
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/util/CategoryDragCallback.kt
@@ -0,0 +1,25 @@
+package com.example.firstapp.util
+
+import androidx.recyclerview.widget.ItemTouchHelper
+import androidx.recyclerview.widget.RecyclerView
+import com.example.firstapp.adapter.CategorySelectorAdapter
+
+/**
+ * 拖拽回调
+ */
+class CategoryDragCallback(private val adapter: CategorySelectorAdapter) : ItemTouchHelper.Callback() {
+    
+    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
+        val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
+        return makeMovementFlags(dragFlags, 0)
+    }
+
+    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
+        adapter.moveItem(viewHolder.adapterPosition, target.adapterPosition)
+        return true
+    }
+
+    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
+        // 不需要实现
+    }
+} 
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/util/SecureStorage.kt b/app/src/main/java/com/example/firstapp/util/SecureStorage.kt
new file mode 100644
index 0000000..ee656c7
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/util/SecureStorage.kt
@@ -0,0 +1,49 @@
+package com.example.firstapp.util
+
+import android.content.Context
+import androidx.security.crypto.EncryptedSharedPreferences
+import androidx.security.crypto.MasterKeys
+import com.google.gson.Gson
+import com.example.firstapp.model.CategoryConfig
+
+class SecureStorage(context: Context) {
+    private val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
+    
+    private val sharedPreferences = EncryptedSharedPreferences.create(
+        "secure_prefs",
+        masterKeyAlias,
+        context,
+        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
+        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
+    )
+
+    private val gson = Gson()
+
+    private fun getStorageKey(userId: String): String {
+        return "categories_$userId"
+    }
+
+    fun saveCategories(userId: String, categories: List<CategoryConfig>) {
+        val json = gson.toJson(categories)
+        sharedPreferences.edit().putString(getStorageKey(userId), json).apply()
+    }
+
+    fun getCategories(userId: String): List<CategoryConfig> {
+        val json = sharedPreferences.getString(getStorageKey(userId), null)
+        return if (json != null) {
+            gson.fromJson(json, Array<CategoryConfig>::class.java).toList()
+        } else {
+            emptyList()
+        }
+    }
+
+    // 清除指定用户的数据
+    fun clearUserData(userId: String) {
+        sharedPreferences.edit().remove(getStorageKey(userId)).apply()
+    }
+
+    // 清除所有数据
+    fun clearAllData() {
+        sharedPreferences.edit().clear().apply()
+    }
+} 
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt b/app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt
new file mode 100644
index 0000000..34b85f4
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/utils/PreferencesManager.kt
@@ -0,0 +1,58 @@
+package com.example.firstapp.utils
+
+import android.content.Context
+import android.content.SharedPreferences
+
+object PreferencesManager {
+    private const val PREF_NAME = "app_preferences"
+    private const val KEY_TOKEN = "user_token"
+    private const val KEY_PHONE = "user_phone"
+    private const val KEY_FIRST_INSTALL = "first_install"
+    private const val LAST_LOGIN_PHONE = "last_login_phone"
+
+    private lateinit var preferences: SharedPreferences
+
+    fun init(context: Context) {
+        preferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
+    }
+
+    fun saveToken(token: String) {
+        preferences.edit().putString(KEY_TOKEN, token).apply()
+    }
+
+    fun getToken(): String? {
+        return preferences.getString(KEY_TOKEN, null)
+    }
+
+    fun savePhone(phone: String) {
+        preferences.edit().putString(KEY_PHONE, phone).apply()
+    }
+
+    fun getPhone(): String? {
+        return preferences.getString(KEY_PHONE, null)
+    }
+
+    fun clearUserData() {
+        preferences.edit().apply {
+            remove(KEY_TOKEN)
+            remove(KEY_PHONE)
+            apply()
+        }
+    }
+
+    fun isFirstInstall(): Boolean {
+        return preferences.getBoolean(KEY_FIRST_INSTALL, true)
+    }
+
+    fun setFirstInstall(isFirst: Boolean) {
+        preferences.edit().putBoolean(KEY_FIRST_INSTALL, isFirst).apply()
+    }
+
+    fun saveLastLoginPhone(phone: String) {
+        preferences.edit().putString(LAST_LOGIN_PHONE, phone).apply()
+    }
+
+    fun getLastLoginPhone(): String {
+        return preferences.getString(LAST_LOGIN_PHONE, "") ?: ""
+    }
+} 
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/view/UnderlineTextView.kt b/app/src/main/java/com/example/firstapp/view/UnderlineTextView.kt
new file mode 100644
index 0000000..b07faa0
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/view/UnderlineTextView.kt
@@ -0,0 +1,43 @@
+package com.example.firstapp.view
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.util.AttributeSet
+import androidx.appcompat.widget.AppCompatTextView
+import androidx.core.content.ContextCompat
+
+class UnderlineTextView @JvmOverloads constructor(
+    context: Context,
+    attrs: AttributeSet? = null,
+    defStyleAttr: Int = 0
+) : AppCompatTextView(context, attrs, defStyleAttr) {
+
+    private val underlinePaint = Paint().apply {
+        color = ContextCompat.getColor(context, android.R.color.black)
+        strokeWidth = context.resources.displayMetrics.density * 2 // 2dp
+    }
+
+    private var showUnderline = false
+
+    fun setUnderlineVisible(visible: Boolean) {
+        showUnderline = visible
+        invalidate()
+    }
+
+    override fun onDraw(canvas: Canvas) {
+        super.onDraw(canvas)
+        
+        if (showUnderline) {
+            val textWidth = paint.measureText(text.toString())
+            val startX = (width - textWidth) / 2
+            canvas.drawLine(
+                startX,
+                height - underlinePaint.strokeWidth,
+                startX + textWidth,
+                height - underlinePaint.strokeWidth,
+                underlinePaint
+            )
+        }
+    }
+} 
\ No newline at end of file
diff --git a/app/src/main/res/drawable/alipay_shape.xml b/app/src/main/res/drawable/alipay_shape.xml
new file mode 100644
index 0000000..df5109c
--- /dev/null
+++ b/app/src/main/res/drawable/alipay_shape.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#D5EBFF"/>
+    <corners android:radius="30dp"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/black_button_background.xml b/app/src/main/res/drawable/black_button_background.xml
new file mode 100644
index 0000000..73a1897
--- /dev/null
+++ b/app/src/main/res/drawable/black_button_background.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <corners android:radius="5dp" />
+    <solid android:color="#000000" />
+    <padding android:left="10dp" android:right="10dp" android:top="5dp" android:bottom="5dp"/>
+</shape>
diff --git a/app/src/main/res/drawable/checkbox_round.xml b/app/src/main/res/drawable/checkbox_round.xml
new file mode 100644
index 0000000..2f3d2fb
--- /dev/null
+++ b/app/src/main/res/drawable/checkbox_round.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@android:color/transparent" /> <!-- 设置圆形的背景颜色 -->
+    <corners android:radius="300dp" /> <!-- 设置圆角半径为50%来形成圆形 -->
+    <stroke
+        android:color="#6B6A70" android:width="2dp" />     <!-- 设置边框宽度 -->
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/checkbox_round_selected.xml b/app/src/main/res/drawable/checkbox_round_selected.xml
new file mode 100644
index 0000000..f3ce711
--- /dev/null
+++ b/app/src/main/res/drawable/checkbox_round_selected.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#FF6200EE" /> <!-- 设置圆形的背景颜色 -->
+    <corners android:radius="300dp"  /> <!-- 设置圆角半径为50%来形成圆形 -->
+    <stroke
+        android:color="#6B6A70" android:width="2dp" />     <!-- 设置边框宽度 -->
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/dialog_background.xml b/app/src/main/res/drawable/dialog_background.xml
new file mode 100644
index 0000000..530fb77
--- /dev/null
+++ b/app/src/main/res/drawable/dialog_background.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- 圆角 10dp -->
+    <corners android:radius="10dp" />
+
+    <!-- 背景色:黑色 -->
+    <solid android:color="#FFFFFF" />
+
+    <!-- 内边距 -->
+    <padding android:left="10dp"
+        android:top="10dp"
+        android:right="10dp"
+        android:bottom="10dp"/>
+
+    <stroke android:width="0dp" android:color="#FFFFFF"/>
+</shape>
diff --git a/app/src/main/res/drawable/error_placeholder.xml b/app/src/main/res/drawable/error_placeholder.xml
new file mode 100644
index 0000000..c556fa1
--- /dev/null
+++ b/app/src/main/res/drawable/error_placeholder.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="100dp"
+    android:height="100dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#FF6666"
+        android:pathData="M12,2L2,22h20L12,2zM13,18h-2v-2h2v2zm0,-4h-2v-4h2v4z"/>
+</vector>
diff --git a/app/src/main/res/drawable/gold_border_shape.xml b/app/src/main/res/drawable/gold_border_shape.xml
new file mode 100644
index 0000000..b660c93
--- /dev/null
+++ b/app/src/main/res/drawable/gold_border_shape.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="@android:color/transparent"/> <!-- 背景透明 -->
+    <stroke android:width="2dp" android:color="#F9EBC6"/> <!-- 金色边框 -->
+    <corners android:radius="16dp"/> <!-- 圆角大小 -->
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/gray_border_shape.xml b/app/src/main/res/drawable/gray_border_shape.xml
new file mode 100644
index 0000000..843e22f
--- /dev/null
+++ b/app/src/main/res/drawable/gray_border_shape.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="@android:color/transparent"/> <!-- 背景透明 -->
+    <stroke android:width="1dp" android:color="#FFFFFF"/> <!-- 金色边框 -->
+    <corners android:radius="16dp"/> <!-- 圆角大小 -->
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/home_add.xml b/app/src/main/res/drawable/home_add.xml
new file mode 100644
index 0000000..7ece592
--- /dev/null
+++ b/app/src/main/res/drawable/home_add.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="1024"
+    android:viewportHeight="1024">
+  <path
+      android:fillColor="#FF000000"
+      android:pathData="M991.7,915.6V90.9c0,-36.9 -29.9,-66.8 -66.8,-66.8H99.1c-36.9,0 -66.8,29.9 -66.8,66.8v824.7c0,36.9 29.9,66.8 66.8,66.8h825.7c36.9,0 66.8,-29.9 66.8,-66.8zM822.8,503.2c0,30.9 -25.1,56 -56,56H568v198.9c0,30.9 -25.1,56 -56,56s-56,-25.1 -56,-56V559.2H257.2c-30.9,0 -56,-25.1 -56,-56s25.1,-56 56,-56h198.9V248.4c0,-30.9 25.1,-56 56,-56s56,25.1 56,56v198.9h198.9c30.9,0 56,25.1 56,56z"/>
+</vector>
diff --git a/app/src/main/res/drawable/ic_category.xml b/app/src/main/res/drawable/ic_category.xml
new file mode 100644
index 0000000..2c57814
--- /dev/null
+++ b/app/src/main/res/drawable/ic_category.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#00BFFF"
+        android:pathData="M10,6L8.59,7.41 13.17,12 8.59,16.59 10,18l6,-6z"/>
+
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_check.xml b/app/src/main/res/drawable/ic_check.xml
new file mode 100644
index 0000000..a9a2051
--- /dev/null
+++ b/app/src/main/res/drawable/ic_check.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#8A5C37"
+        android:strokeWidth="2"
+        android:strokeColor="#8A5C37"
+        android:pathData="M10.29,15.29 4,9 5.41,7.59 10.29,12.47 19.59,3.17 21,4.59 10.29,15.29"/>
+
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_reminder.xml b/app/src/main/res/drawable/ic_reminder.xml
new file mode 100644
index 0000000..310d415
--- /dev/null
+++ b/app/src/main/res/drawable/ic_reminder.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#FFD700"
+        android:pathData="M12,1a11,11 0 0,1 0,22a11,11 0 0,1 0,-22zM12,18a2,2 0 0,1 0,4h-2v-4h2zm0,-12a3,3 0 0,0 -3,3v5h6V9a3,3 0 0,0 -3,-3z"/>
+
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_stats.xml b/app/src/main/res/drawable/ic_stats.xml
new file mode 100644
index 0000000..957f134
--- /dev/null
+++ b/app/src/main/res/drawable/ic_stats.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#FF5733"
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm0,18c-4.42,0 -8 -3.58 -8 -8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z M16,6h-4v10h4V6z"/>
+
+</vector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/member_background.xml b/app/src/main/res/drawable/member_background.xml
new file mode 100644
index 0000000..675c783
--- /dev/null
+++ b/app/src/main/res/drawable/member_background.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <gradient
+        android:startColor="#2B225C"
+        android:endColor="#726C8E"
+        android:angle="90"/>
+</shape>
diff --git a/app/src/main/res/drawable/more_benefit_shape.xml b/app/src/main/res/drawable/more_benefit_shape.xml
new file mode 100644
index 0000000..f305ef0
--- /dev/null
+++ b/app/src/main/res/drawable/more_benefit_shape.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <gradient
+        android:angle="90"
+        android:startColor="#130F27"
+        android:endColor="#15102D"
+        android:type="linear"/>
+    <corners android:radius="30dp"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/overlay_black_background.xml b/app/src/main/res/drawable/overlay_black_background.xml
new file mode 100644
index 0000000..5afeda5
--- /dev/null
+++ b/app/src/main/res/drawable/overlay_black_background.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- 圆角 10dp -->
+    <corners android:radius="100dp" />
+
+    <!-- 背景色:黑色 -->
+<!--    <solid android:color="#FFFFFF" />-->
+    <solid android:color="#000000" />
+
+    <!-- 内边距 -->
+    <padding android:left="10dp"
+        android:top="10dp"
+        android:right="10dp"
+        android:bottom="10dp"/>
+
+    <stroke android:width="0dp" android:color="#FFFFFF"/>
+</shape>
diff --git a/app/src/main/res/drawable/round_red_bg.xml b/app/src/main/res/drawable/round_red_bg.xml
new file mode 100644
index 0000000..8fcd59b
--- /dev/null
+++ b/app/src/main/res/drawable/round_red_bg.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#FD6478"/> <!-- 设置背景颜色 -->
+    <corners android:radius="100dp"/> <!-- 设置圆角半径 -->
+</shape>
diff --git a/app/src/main/res/drawable/round_transition_gray_bg.xml b/app/src/main/res/drawable/round_transition_gray_bg.xml
new file mode 100644
index 0000000..0bcc740
--- /dev/null
+++ b/app/src/main/res/drawable/round_transition_gray_bg.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- 设置透明背景 -->
+    <solid android:color="@android:color/transparent"/>
+    <!-- 设置灰色边框 -->
+    <stroke android:color="#808080" android:width="1dp"/> <!-- 可以调整宽度 -->
+    <!-- 设置圆角 -->
+    <corners android:radius="16dp"/> <!-- 设置圆角半径 -->
+</shape>
diff --git a/app/src/main/res/drawable/set.xml b/app/src/main/res/drawable/set.xml
index cec8ed9..4ff2b5e 100644
--- a/app/src/main/res/drawable/set.xml
+++ b/app/src/main/res/drawable/set.xml
@@ -1,12 +1,9 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="217.6dp"
-    android:height="200dp"
-    android:viewportWidth="1114"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="1024"
     android:viewportHeight="1024">
   <path
-      android:pathData="M1081,394.7l-162.5,-278.6c-41.8,-72 -118.4,-116.1 -199.7,-116.1L393.7,-0c-81.3,0 -160.2,44.1 -199.7,116.1l-162.5,278.6c-41.8,72 -41.8,162.5 0,234.5l162.5,278.6c41.8,72 118.4,116.1 199.7,116.1h325.1c81.3,0 160.2,-44.1 199.7,-116.1l162.5,-278.6c41.8,-74.3 41.8,-162.5 0,-234.5zM1002,580.5l-162.5,278.6c-25.5,41.8 -72,69.7 -120.7,69.7L393.7,928.8c-48.8,0 -95.2,-25.5 -120.7,-69.7l-162.5,-278.6c-25.5,-44.1 -25.5,-97.5 0,-139.3l162.5,-278.6c25.5,-41.8 72,-69.7 120.7,-69.7h325.1c48.8,0 95.2,25.5 120.7,69.7l162.5,278.6c25.5,41.8 25.5,97.5 0,139.3z"
-      android:fillColor="#707070"/>
-  <path
-      android:pathData="M556.2,301.9c-116.1,0 -209,92.9 -209,209s92.9,209 209,209 209,-92.9 209,-209 -92.9,-209 -209,-209zM556.2,626.9c-65,0 -116.1,-51.1 -116.1,-116.1s51.1,-116.1 116.1,-116.1 116.1,51.1 116.1,116.1 -51.1,116.1 -116.1,116.1z"
-      android:fillColor="#707070"/>
+      android:fillColor="#FF000000"
+      android:pathData="M737,647c-5.6,-5.6 -11.3,-11.3 -16.9,-11.3 -16.9,0 -28.1,11.3 -28.1,28.1 0,11.3 5.6,16.9 11.3,22.5C770.8,737 815.8,815.8 821.4,905.8h50.6c-5.6,-106.9 -56.3,-196.9 -135,-258.8M523.3,551.4c-101.3,0 -185.6,-84.4 -185.6,-185.6C332,258.9 416.4,174.5 523.3,174.5 624.5,174.5 708.9,258.9 708.9,360.1c0,106.9 -84.4,191.3 -185.6,191.3zM765.1,365.8C765.1,230.8 658.3,118.3 517.6,118.3c-129.4,0 -241.9,106.9 -241.9,247.5 0,90 50.6,168.8 123.8,213.8 -140.6,39.4 -241.9,168.8 -247.5,326.3H202.6c5.6,-163.1 140.6,-292.5 303.8,-298.1H523.3c135,0 241.9,-106.9 241.9,-241.9z"/>
 </vector>
diff --git a/app/src/main/res/drawable/tab_selected_background.xml b/app/src/main/res/drawable/tab_selected_background.xml
new file mode 100644
index 0000000..e0872bf
--- /dev/null
+++ b/app/src/main/res/drawable/tab_selected_background.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:gravity="bottom">
+        <shape android:shape="rectangle">
+            <size android:height="2dp" />
+            <solid android:color="@android:color/black" />
+        </shape>
+    </item>
+</layer-list> 
\ No newline at end of file
diff --git a/app/src/main/res/drawable/up.png b/app/src/main/res/drawable/up.png
new file mode 100644
index 0000000..f7379a8
--- /dev/null
+++ b/app/src/main/res/drawable/up.png
Binary files differ
diff --git a/app/src/main/res/drawable/up.jpg b/app/src/main/res/drawable/up_back.jpg
similarity index 100%
rename from app/src/main/res/drawable/up.jpg
rename to app/src/main/res/drawable/up_back.jpg
Binary files differ
diff --git a/app/src/main/res/drawable/vip_black_background.xml b/app/src/main/res/drawable/vip_black_background.xml
new file mode 100644
index 0000000..c6e6a0b
--- /dev/null
+++ b/app/src/main/res/drawable/vip_black_background.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- 圆角 10dp -->
+    <corners android:radius="10dp" />
+
+    <!-- 背景色:黑色 -->
+<!--    <solid android:color="#FFFFFF" />-->
+    <solid android:color="#000000" />
+
+    <!-- 内边距 -->
+    <padding android:left="10dp"
+        android:top="10dp"
+        android:right="10dp"
+        android:bottom="10dp"/>
+
+    <stroke android:width="0dp" android:color="#FFFFFF"/>
+</shape>
diff --git a/app/src/main/res/drawable/vip_white_background.xml b/app/src/main/res/drawable/vip_white_background.xml
new file mode 100644
index 0000000..e5f1307
--- /dev/null
+++ b/app/src/main/res/drawable/vip_white_background.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- 圆角 10dp -->
+    <corners android:radius="10dp" />
+
+    <!-- 背景色:白色 -->
+    <solid android:color="#FFFFFF" />
+
+    <!-- 内边距 -->
+    <padding android:left="10dp"
+        android:top="10dp"
+        android:right="10dp"
+        android:bottom="10dp"/>
+
+    <stroke android:width="0dp" android:color="#FFFFFF"/>
+</shape>
diff --git a/app/src/main/res/drawable/wechat_shape.xml b/app/src/main/res/drawable/wechat_shape.xml
new file mode 100644
index 0000000..5c6381a
--- /dev/null
+++ b/app/src/main/res/drawable/wechat_shape.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="#E7F8E7"/>
+    <corners android:radius="30dp"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_phone_login.xml b/app/src/main/res/layout/activity_phone_login.xml
index 757b041..cfb7880 100644
--- a/app/src/main/res/layout/activity_phone_login.xml
+++ b/app/src/main/res/layout/activity_phone_login.xml
@@ -43,7 +43,6 @@
             android:layout_height="wrap_content"
             android:background="@null"
             android:hint="请输入手机号"
-            android:text="17712345678"
             android:inputType="phone"
             android:maxLength="11"
             android:textSize="16sp"
diff --git a/app/src/main/res/layout/activity_vip.xml b/app/src/main/res/layout/activity_vip.xml
new file mode 100644
index 0000000..2d46ec5
--- /dev/null
+++ b/app/src/main/res/layout/activity_vip.xml
@@ -0,0 +1,518 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".activity.VipActivity">
+    <androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        xmlns:tools="http://schemas.android.com/tools"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:fillViewport="true"
+        tools:context=".activity.VipActivity">
+
+        <androidx.coordinatorlayout.widget.CoordinatorLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:fitsSystemWindows="true"
+            android:background="@drawable/member_background">
+
+            <!-- 这里是原来CoordinatorLayout中的内容,保持不变 -->
+
+            <com.google.android.material.appbar.AppBarLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:fitsSystemWindows="true"
+                android:background="@android:color/transparent">
+
+                <com.google.android.material.appbar.MaterialToolbar
+                    android:id="@+id/toolbar"
+                    android:layout_width="match_parent"
+                    android:layout_height="?attr/actionBarSize">
+                    <!-- 直接在Toolbar中添加TextView -->
+                    <ImageView
+                        android:id="@+id/ivBack"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="left"
+                        android:layout_marginStart="16dp"
+                        android:src="@drawable/ic_back" />
+                    <TextView
+                        android:id="@+id/tvTitle"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="智信会员"
+                        android:textColor="#FFFFFF"
+                        android:textSize="18sp"
+                        android:layout_gravity="left"
+                        android:layout_marginEnd="16dp" />
+                </com.google.android.material.appbar.MaterialToolbar>
+
+            </com.google.android.material.appbar.AppBarLayout>
+            <!-- 引入MemberInfoCardFragment -->
+            <fragment
+                android:name="com.example.firstapp.ui.vip.MemberInfoCardFragment"
+                android:id="@+id/memberInfoCardFragment"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+
+            <!-- 滑动框 -->
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/recycler_view"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="165dp"
+                android:layout_marginLeft="15dp"
+                app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                android:background="@android:color/transparent" />
+
+
+            <!--        会员权益&#45;&#45;动态-->
+            <androidx.constraintlayout.widget.ConstraintLayout
+                xmlns:android="http://schemas.android.com/apk/res/android"
+                xmlns:app="http://schemas.android.com/apk/res-auto"
+                android:id="@+id/benefit_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="300dp"
+                android:layout_marginLeft="15dp"
+                android:layout_marginRight="15dp"
+                android:padding="0dp"
+                android:background="@android:color/transparent"
+                app:cardBackgroundColor="@android:color/transparent"
+                android:foreground="@drawable/gray_border_shape"
+
+                tools:context=".MainActivity">
+                <!-- 标题 -->
+                <TextView
+                    android:id="@+id/title_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="会员权益"
+                    android:textColor="#8A5C37"
+                    android:textSize="20sp"
+                    android:textStyle="bold"
+                    app:layout_constraintTop_toTopOf="parent"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    app:layout_constraintHorizontal_bias="0.5"
+                    android:layout_marginTop="5dp" />
+
+                <!-- 分割线 -->
+                <View
+                    android:id="@+id/divider"
+                    android:layout_width="0dp"
+                    android:layout_height="1dp"
+                    android:background="#615B7F"
+                    app:layout_constraintTop_toBottomOf="@id/title_text"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintEnd_toEndOf="parent"
+                    android:layout_marginTop="8dp"
+                    android:layout_marginHorizontal="16dp" />
+                <androidx.constraintlayout.widget.ConstraintLayout
+                    xmlns:android="http://schemas.android.com/apk/res/android"
+                    xmlns:app="http://schemas.android.com/apk/res-auto"
+                    android:id="@+id/dynamicContainer"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:padding="10dp"
+                    android:layout_marginTop="0dp"
+                    android:background="@android:color/transparent"
+                    app:layout_constraintTop_toBottomOf="@id/divider"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintEnd_toEndOf="parent"
+
+                    />
+            </androidx.constraintlayout.widget.ConstraintLayout>
+
+            <!--        更多权益-->
+
+            <LinearLayout
+                android:id="@+id/more_benefit_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:background="@drawable/more_benefit_shape"
+                android:layout_marginTop="550dp"
+                android:layout_marginLeft="13dp"
+                android:layout_marginRight="13dp"
+                android:padding="15dp"
+                android:orientation="vertical"
+                android:gravity="center">
+
+                <TextView
+                    android:id="@+id/more_benefit_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="更多权益敬请期待"
+                    android:textColor="#D5D4DA"
+                    android:textStyle="italic|bold"
+                    android:textSize="16sp"
+                    android:layout_marginBottom="10dp"
+                    android:gravity="center"
+                    android:layout_gravity="center"/>
+
+                <!-- 第一项 -->
+                <LinearLayout
+                    android:layout_width="200dp"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="start"
+                    android:baselineAligned="false"
+                    android:layout_marginBottom="8dp"
+                    android:padding="5dp"
+                    >
+
+                    <ImageView
+                        android:layout_width="30dp"
+                        android:layout_height="30dp"
+                        android:src="@mipmap/vip_ai_ass_icon"
+                        android:layout_marginEnd="8dp"/>
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="解锁AI语音助手"
+                        android:textColor="#93B7D9"
+                        android:textSize="16sp"
+                        android:gravity="start"/>
+                </LinearLayout>
+                <!-- 第二项 -->
+                <LinearLayout
+                    android:layout_width="200dp"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="start"
+                    android:baselineAligned="false"
+                    android:layout_marginBottom="8dp"
+                    android:padding="5dp"
+                    >
+                    <ImageView
+                        android:layout_width="30dp"
+                        android:layout_height="30dp"
+                        android:src="@mipmap/vip_bar_sta"
+                        android:layout_marginEnd="8dp"
+                        />
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="数据智能预测"
+                        android:textColor="#93B7D9"
+                        android:textSize="16sp"
+                        android:gravity="start"/>
+                </LinearLayout>
+
+                <!-- 第三项 -->
+                <LinearLayout
+                    android:layout_width="200dp"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="start"
+                    android:baselineAligned="false"
+                    android:layout_marginBottom="8dp"
+                    android:padding="5dp"
+                    >
+
+                    <ImageView
+                        android:layout_width="30dp"
+                        android:layout_height="30dp"
+                        android:src="@mipmap/vip_life_insurance"
+                        android:layout_marginEnd="8dp"/>
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="家庭分类共享"
+                        android:textColor="#93B7D9"
+                        android:textSize="16sp"
+                        android:gravity="start"/>
+                </LinearLayout>
+
+                <LinearLayout
+                    android:layout_width="160dp"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="start"
+                    android:baselineAligned="false"
+                    android:layout_marginBottom="8dp"
+                    android:padding="5dp"
+                    >
+
+                    <ImageView
+                        android:layout_width="25dp"
+                        android:layout_height="25dp"
+                        android:src="@mipmap/vip_more"
+                        android:layout_marginEnd="8dp"/>
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="敬请期待......"
+                        android:textColor="#D6D5DB"
+                        android:textSize="16sp"
+                        android:gravity="start"/>
+                </LinearLayout>
+
+            </LinearLayout>
+
+            <View
+                android:id="@+id/divider2"
+                android:layout_width="match_parent"
+                android:layout_height="1dp"
+                android:background="#646174"
+                app:layout_constraintTop_toBottomOf="@id/more_benefit_layout"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                android:layout_marginTop="840dp"
+                android:layout_marginHorizontal="0dp" />
+
+
+
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="180dp"
+                android:layout_marginTop="880dp"
+                >
+
+            </LinearLayout>
+
+
+        </androidx.coordinatorlayout.widget.CoordinatorLayout>
+    </androidx.core.widget.NestedScrollView>
+
+    <androidx.cardview.widget.CardView
+        android:id="@+id/card_view_fixed"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="0dp"
+        android:layout_marginTop="10dp"
+        android:layout_gravity="bottom"
+        app:cardCornerRadius="0dp"
+        app:cardElevation="6dp"
+        android:background="#030308"
+        app:cardBackgroundColor="#030308"
+        android:layout_alignParentBottom="true">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:padding="10dp"
+            android:gravity="center_horizontal">
+
+            <LinearLayout
+                android:id="@+id/alipay_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:background="@drawable/alipay_shape"
+                android:layout_marginTop="15dp"
+                android:layout_marginLeft="15dp"
+                android:layout_marginRight="15dp"
+                android:padding="3dp"
+                android:orientation="vertical"
+                android:gravity="center">
+
+                <LinearLayout
+                    android:layout_width="250dp"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="center"
+                    android:baselineAligned="false"
+                    >
+
+                    <ImageView
+                        android:layout_width="30dp"
+                        android:layout_height="30dp"
+                        android:src="@mipmap/vip_alipay"
+                        android:layout_marginEnd="8dp"/>
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="确认协议并支付"
+                        android:textColor="#419AE4"
+                        android:textSize="16sp"
+                        android:gravity="start"/>
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="¥"
+                        android:textColor="#419AE4"
+                        android:textSize="16sp"
+                        android:layout_marginLeft="10dp"
+                        android:layout_marginRight="5dp"
+                        android:gravity="start"/>
+
+                    <TextView
+                        android:id="@+id/alipay_amount"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="30"
+                        android:textColor="#419AE4"
+                        android:textSize="16sp"
+                        android:gravity="start"/>
+                </LinearLayout>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:id="@+id/wechat_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:background="@drawable/wechat_shape"
+                android:layout_marginTop="15dp"
+                android:layout_marginLeft="15dp"
+                android:layout_marginRight="15dp"
+                android:padding="3dp"
+                android:orientation="vertical"
+                android:gravity="center">
+
+                <LinearLayout
+                    android:layout_width="250dp"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="center"
+                    android:baselineAligned="false"
+                    >
+
+                    <ImageView
+                        android:layout_width="30dp"
+                        android:layout_height="30dp"
+                        android:src="@mipmap/vip_wechat"
+                        android:layout_marginEnd="8dp"/>
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="确认协议并支付"
+                        android:textColor="#77E382"
+                        android:textSize="16sp"
+                        android:gravity="start"/>
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="¥"
+                        android:textColor="#77E382"
+                        android:textSize="16sp"
+                        android:layout_marginLeft="10dp"
+                        android:layout_marginRight="5dp"
+                        android:gravity="start"/>
+
+                    <TextView
+                        android:id="@+id/wechat_amount"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="30"
+                        android:textColor="#77E382"
+                        android:textSize="16sp"
+                        android:gravity="start"/>
+                </LinearLayout>
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:id="@+id/xieyi_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:background="@android:color/transparent"
+                android:layout_marginTop="15dp"
+                android:layout_marginLeft="15dp"
+                android:layout_marginRight="15dp"
+                android:padding="1dp"
+                android:orientation="vertical"
+                android:gravity="center">
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="start"
+                    android:baselineAligned="false"
+                    >
+
+                    <TextView
+                        android:id="@+id/protocol_desc_layout"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="自动续费可随时取消,开通后每月按12元自动续费,可随时取消自动续费"
+                        android:textColor="#A19FA7"
+                        android:textSize="12sp"
+                        android:gravity="start"/>
+                </LinearLayout>
+
+            </LinearLayout>
+
+
+            <LinearLayout
+                android:id="@+id/protocol_layout"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:background="@android:color/transparent"
+                android:layout_marginTop="15dp"
+                android:layout_marginLeft="15dp"
+                android:layout_marginRight="15dp"
+                android:padding="1dp"
+                android:orientation="vertical"
+                android:gravity="center">
+
+                <LinearLayout
+                    android:layout_width="300dp"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:gravity="center_vertical"
+                    android:baselineAligned="false"
+                    >
+
+    <!--                <CheckBox-->
+    <!--                    android:id="@+id/protocol_checkbox"-->
+    <!--                    android:layout_width="20dp"-->
+    <!--                    android:layout_height="20dp"-->
+    <!--                    android:text=""-->
+    <!--                    android:orientation="horizontal"-->
+    <!--                    android:gravity="start"-->
+    <!--                    />-->
+
+                    <CheckBox
+                        android:id="@+id/protocol_checkbox"
+                        android:layout_width="20dp"
+                        android:layout_height="20dp"
+                        />
+
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="已阅读并同意"
+                        android:textColor="#7E5C3C"
+                        android:textSize="14sp"
+                        android:gravity="start"
+                        android:layout_marginLeft="10dp"
+                        android:orientation="horizontal"
+                        />
+
+                    <TextView
+                        android:id="@+id/protocol_vip"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="《VIP会员服务协议》"
+                        android:textColor="#15759E"
+                        android:textSize="14sp"
+                        android:gravity="start"
+                        android:orientation="horizontal"
+                        />
+                </LinearLayout>
+
+            </LinearLayout>
+
+        </LinearLayout>
+    </androidx.cardview.widget.CardView>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_vip.xml b/app/src/main/res/layout/content_vip.xml
new file mode 100644
index 0000000..a2d7fbb
--- /dev/null
+++ b/app/src/main/res/layout/content_vip.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
+    app:layout_behavior="@string/appbar_scrolling_view_behavior">
+
+    <fragment
+        android:id="@+id/nav_host_fragment_content_vip"
+        android:name="androidx.navigation.fragment.NavHostFragment"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:defaultNavHost="true"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:navGraph="@navigation/nav_graph" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_category_selector.xml b/app/src/main/res/layout/dialog_category_selector.xml
new file mode 100644
index 0000000..6828364
--- /dev/null
+++ b/app/src/main/res/layout/dialog_category_selector.xml
@@ -0,0 +1,29 @@
+<?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="vertical"
+    android:padding="12dp">
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="选择分类"
+        android:textSize="18sp"
+        android:textStyle="bold"
+        android:layout_marginBottom="8dp"/>
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/categoryRecyclerView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+
+    <Button
+        android:id="@+id/saveButton"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="保存"
+        android:layout_marginTop="12dp"
+        android:backgroundTint="#000000"
+        android:textColor="#FFFFFF"/>
+</LinearLayout> 
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml
index ad51843..21efdba 100644
--- a/app/src/main/res/layout/fragment_dashboard.xml
+++ b/app/src/main/res/layout/fragment_dashboard.xml
@@ -159,4 +159,55 @@
         </ViewFlipper>
     </androidx.core.widget.NestedScrollView>
 
+    <!-- 🔹 遮罩层 -->
+    <View
+        android:id="@+id/view_overlay"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@mipmap/overlay2"
+        android:elevation="10dp"
+        android:visibility="gone"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent" />
+
+    <!-- 🔹 遮罩层上的按钮 -->
+    <!-- 🔹 遮罩层上的内容容器(LinearLayout) -->
+    <LinearLayout
+        android:id="@+id/overlay_content"
+        android:layout_width="300dp"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:orientation="horizontal"
+        android:padding="10dp"
+        android:background="@drawable/overlay_black_background"
+        android:elevation="20dp"
+        android:translationZ="20dp"
+        android:visibility="gone"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+
+        <ImageView
+            android:id="@+id/overlay_content_vip_image"
+            android:layout_width="40dp"
+            android:layout_height="40dp"
+            android:layout_marginLeft="10dp"
+            android:layout_marginRight="10dp"
+            android:scaleType="centerCrop"
+            android:src="@mipmap/vip_crown"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <!-- 🔹 示例内容:标题 -->
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="免费查看统计数据"
+            android:textSize="18sp"
+            android:textColor="#EEBC93" />
+
+    </LinearLayout>
+
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_first.xml b/app/src/main/res/layout/fragment_first.xml
new file mode 100644
index 0000000..44baecd
--- /dev/null
+++ b/app/src/main/res/layout/fragment_first.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".FirstFragment">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="16dp">
+
+        <Button
+            android:id="@+id/button_first"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/next"
+            app:layout_constraintBottom_toTopOf="@id/textview_first"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/textview_first"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:text="@string/lorem_ipsum"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/button_first" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</androidx.core.widget.NestedScrollView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index 18a5e11..5305951 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -1,117 +1,177 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout 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="match_parent">
 
-<ScrollView
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginTop="40dp"> <!-- 留出顶部广告位的高度 -->
-    >
-
-<!--    LinearLayout的作用是按照垂直或者水平方向排列其子视图-->
-<!--    CardView组件是用于实现卡片式布局-->
-<!--    RecyclerView 回收商视图 它使用适配器(Adapter)来管理数据的显示,-->
-<!--    开发者可以根据自己的需求实现适配器的方法,将数据与视图进行绑定。-->
-<!--    这使得 RecyclerView 能够轻松地处理各种类型的数据,并按照自定义的布局方式展示。-->
-<!--    支持局部刷新 通知数据集变化-->
-    <LinearLayout
+    <ScrollView
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
+        android:layout_height="match_parent"
+        android:layout_marginTop="40dp"> <!-- 留出顶部广告位的高度 -->
+        >
 
-
-
-        <!-- 快递/财务切换区域 -->
+        <!--    LinearLayout的作用是按照垂直或者水平方向排列其子视图-->
+        <!--    CardView组件是用于实现卡片式布局-->
+        <!--    RecyclerView 回收商视图 它使用适配器(Adapter)来管理数据的显示,-->
+        <!--    开发者可以根据自己的需求实现适配器的方法,将数据与视图进行绑定。-->
+        <!--    这使得 RecyclerView 能够轻松地处理各种类型的数据,并按照自定义的布局方式展示。-->
+        <!--    支持局部刷新 通知数据集变化-->
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:layout_marginBottom="8dp">
+            android:orientation="vertical">
 
-            <TextView
-                android:id="@+id/tabExpress"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:text="快递"
-                android:gravity="center"
-                android:padding="8dp"
-                android:textSize="16sp"
-                android:textStyle="bold"/>
 
-            <TextView
-                android:id="@+id/tabFinance"
-                android:layout_width="0dp"
+            <!-- 快递/财务切换区域 -->
+            <FrameLayout
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:text="财务"
-                android:gravity="center"
-                android:padding="8dp"
-                android:textSize="16sp"/>
+                android:layout_marginBottom="8dp"
+                android:layout_marginTop="8dp"
+                android:layout_marginHorizontal="8dp">
 
-            <TextView
-                android:id="@+id/others"
-                android:layout_width="0dp"
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginEnd="30dp"
+                    android:orientation="horizontal">
+
+                    <com.example.firstapp.view.UnderlineTextView
+                        android:id="@+id/tabExpress"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:gravity="center"
+                        android:padding="6dp"
+                        android:text="快递"
+                        android:textSize="14sp"
+                        android:textStyle="bold" />
+
+                    <com.example.firstapp.view.UnderlineTextView
+                        android:id="@+id/tabFinance"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:gravity="center"
+                        android:padding="6dp"
+                        android:text="还款"
+                        android:textSize="14sp" />
+
+                    <com.example.firstapp.view.UnderlineTextView
+                        android:id="@+id/tabIncome"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:gravity="center"
+                        android:padding="6dp"
+                        android:text="收入"
+                        android:textSize="14sp" />
+
+                    <com.example.firstapp.view.UnderlineTextView
+                        android:id="@+id/tabFlight"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:gravity="center"
+                        android:padding="6dp"
+                        android:text="航班"
+                        android:textSize="14sp" />
+
+                    <com.example.firstapp.view.UnderlineTextView
+                        android:id="@+id/tabTrain"
+                        android:layout_width="0dp"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:gravity="center"
+                        android:padding="6dp"
+                        android:text="火车票"
+                        android:textSize="14sp" />
+
+                </LinearLayout>
+
+                <ImageButton
+                    android:id="@+id/categoryButton"
+                    android:layout_width="28dp"
+                    android:layout_height="28dp"
+                    android:layout_gravity="center_vertical|end"
+                    android:background="?attr/selectableItemBackgroundBorderless"
+                    android:contentDescription="分类设置"
+                    android:padding="4dp"
+                    android:scaleType="fitCenter"
+                    android:src="@drawable/home_add" />
+
+            </FrameLayout>
+
+            <!-- 内容区域 -->
+            <FrameLayout
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:text="其他"
-                android:gravity="center"
-                android:padding="8dp"
-                android:textSize="16sp"/>
+                android:layout_margin="16dp">
+
+                <androidx.recyclerview.widget.RecyclerView
+                    android:id="@+id/express_recycler"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:padding="8dp" />
+
+                <androidx.recyclerview.widget.RecyclerView
+                    android:id="@+id/finance_recycler"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:padding="8dp" />
+
+                <androidx.recyclerview.widget.RecyclerView
+                    android:id="@+id/income_recycler"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:padding="8dp" />
+
+                <androidx.recyclerview.widget.RecyclerView
+                    android:id="@+id/flight_recycler"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:padding="8dp"
+                    android:visibility="gone" />
+
+                <androidx.recyclerview.widget.RecyclerView
+                    android:id="@+id/train_recycler"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:padding="8dp"
+                    android:visibility="gone" />
+
+            </FrameLayout>
+
+            <!-- 底部广告位 -->
+            <androidx.cardview.widget.CardView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                app:cardCornerRadius="8dp"
+                app:cardElevation="2dp">
+
+                <ImageView
+                    android:id="@+id/bottomAdBanner"
+                    android:layout_width="match_parent"
+                    android:layout_height="80dp"
+                    android:scaleType="centerCrop" />
+            </androidx.cardview.widget.CardView>
+
         </LinearLayout>
-
-        <!-- 内容区域 -->
-        <FrameLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_margin="16dp">
-
-            <androidx.recyclerview.widget.RecyclerView
-                android:id="@+id/express_recycler"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:padding="8dp"/>
-
-            <androidx.recyclerview.widget.RecyclerView
-                android:id="@+id/finance_recycler"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:padding="8dp"/>
-
-        </FrameLayout>
-
-        <!-- 底部广告位 -->
-        <androidx.cardview.widget.CardView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            app:cardCornerRadius="8dp"
-            app:cardElevation="2dp">
-            
-            <ImageView
-                android:id="@+id/bottomAdBanner"
-                android:layout_width="match_parent"
-                android:layout_height="80dp"
-                android:scaleType="centerCrop"/>
-        </androidx.cardview.widget.CardView>
-
-    </LinearLayout>
-</ScrollView>
+    </ScrollView>
 
     <!-- 顶部广告位 -->
     <androidx.cardview.widget.CardView
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-       >
+        android:layout_height="wrap_content">
 
         <ImageView
             android:id="@+id/adBanner"
             android:layout_width="match_parent"
             android:layout_height="40dp"
             android:scaleType="centerCrop"
-            android:src="@drawable/up"/>
+            android:src="@drawable/up_back" />
     </androidx.cardview.widget.CardView>
 
+    <!-- 在适当的位置添加 -->
+
 </FrameLayout>
diff --git a/app/src/main/res/layout/fragment_member_info_card.xml b/app/src/main/res/layout/fragment_member_info_card.xml
new file mode 100644
index 0000000..d1789c5
--- /dev/null
+++ b/app/src/main/res/layout/fragment_member_info_card.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <data>
+        <variable
+            name="viewModel"
+            type="com.example.firstapp.ui.vip.MemberInfoCardViewModel"/>
+    </data>
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        tools:context=".ui.vip.MemberInfoCardFragment">
+
+        <!-- CardView 内部的内容 -->
+        <androidx.cardview.widget.CardView
+            android:id="@+id/memberCardCardView"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="15dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginRight="15dp"
+            android:elevation="0dp"
+            android:clipChildren="false"
+            android:clipToOutline="true"
+            app:cardCornerRadius="10dp">  <!-- 设置CardView的elevation -->
+
+
+            <androidx.constraintlayout.widget.ConstraintLayout
+                android:id="@+id/memberCard"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                tools:ignore="MissingConstraints"
+                android:background="@android:color/transparent"
+                >
+
+                <ImageView
+                    android:id="@+id/memberAvatarView"
+                    android:layout_width="40dp"
+                    android:layout_height="40dp"
+                    android:layout_marginLeft="10dp"
+                    android:layout_marginRight="10dp"
+                    android:scaleType="centerCrop"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toTopOf="parent" />
+
+                <TextView
+                    android:id="@+id/phoneNumberText"
+                    android:layout_width="120dp"
+                    android:layout_height="40dp"
+                    android:gravity="center"
+                    android:text="@{viewModel.phoneNumber}"
+                    app:layout_constraintStart_toEndOf="@id/memberAvatarView"
+                    app:layout_constraintTop_toTopOf="parent" />
+
+<!--                <TextView-->
+<!--                    android:id="@+id/memberStatus"-->
+<!--                    android:layout_width="match_parent"-->
+<!--                    android:layout_height="wrap_content"-->
+<!--                    android:gravity="start"-->
+<!--                    android:text="@{viewModel.memberStatus}"-->
+<!--                    app:layout_constraintStart_toEndOf="@id/memberCard"-->
+<!--                    app:layout_constraintTop_toTopOf="parent" />-->
+
+                <TextView
+                    android:id="@+id/memberStatus"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:gravity="start"
+                    android:text="@{viewModel.memberStatus}"
+                    android:layout_marginLeft="8dp"
+                    android:padding="2dp"
+                    app:layout_constraintStart_toStartOf="parent"
+                    app:layout_constraintTop_toBottomOf="@id/memberAvatarView" />
+
+            </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+        </androidx.cardview.widget.CardView>
+
+        <!-- 悬浮的 ImageView, 位于右侧 -->
+        <ImageView
+            android:id="@+id/memberImageView"
+            android:layout_width="80dp"
+            android:layout_height="80dp"
+            android:layout_marginTop="-10dp"
+            android:layout_marginRight="40dp"
+            android:scaleType="centerCrop"
+            android:layout_gravity="end|top"
+            android:elevation="4dp" />  <!-- 设置memberImageView的elevation,确保它在上层 -->
+
+    </FrameLayout>
+
+</layout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_notifications.xml
index 23b5b81..e176684 100644
--- a/app/src/main/res/layout/fragment_notifications.xml
+++ b/app/src/main/res/layout/fragment_notifications.xml
@@ -110,7 +110,7 @@
                             android:id="@+id/tv_vip_expire"
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
-                            android:textColor="#FFD700"
+                            android:textColor="#F2F2F2"
                             android:textSize="14sp"/>
                     </LinearLayout>
 
@@ -120,7 +120,7 @@
                         android:layout_height="wrap_content"
                         android:layout_marginTop="4dp"
                         android:text="续费畅享更多会员权益"
-                        android:textColor="#B8741A"
+                        android:textColor="#F0DCBF"
                         android:textSize="12sp"
                         android:textStyle="bold"/>
                 </LinearLayout>
@@ -131,7 +131,7 @@
                     android:layout_height="wrap_content"
                     android:backgroundTint="#7A441E"
                     android:text="立即续费"
-                    android:textColor="#FFFFFF" />
+                    android:textColor="#F0DCBF" />
             </LinearLayout>
         </androidx.cardview.widget.CardView>
 
diff --git a/app/src/main/res/layout/fragment_second.xml b/app/src/main/res/layout/fragment_second.xml
new file mode 100644
index 0000000..d074310
--- /dev/null
+++ b/app/src/main/res/layout/fragment_second.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".SecondFragment">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="16dp">
+
+        <Button
+            android:id="@+id/button_second"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/previous"
+            app:layout_constraintBottom_toTopOf="@id/textview_second"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/textview_second"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dp"
+            android:text="@string/lorem_ipsum"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/button_second" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</androidx.core.widget.NestedScrollView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_card.xml b/app/src/main/res/layout/item_card.xml
new file mode 100644
index 0000000..9728346
--- /dev/null
+++ b/app/src/main/res/layout/item_card.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<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="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_margin="8dp"
+    app:cardBackgroundColor="#F0F0F0"
+    app:cardCornerRadius="16dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:padding="16dp">
+
+        <TextView
+            android:id="@+id/tag_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:background="#FF0000"
+            android:text="首月限时特惠"
+            android:textColor="#FFFFFF"
+            android:padding="16dp"
+             />
+
+        <TextView
+            android:id="@+id/title_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="连续包月"
+            android:textSize="18sp"
+            android:textColor="#333333"
+            android:layout_marginTop="8dp" />
+
+        <TextView
+            android:id="@+id/price_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="¥9.9"
+            android:textSize="24sp"
+            android:textColor="#FF0000"
+            android:layout_marginTop="8dp" />
+
+    </LinearLayout>
+
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_card_continue_monthly.xml b/app/src/main/res/layout/item_card_continue_monthly.xml
new file mode 100644
index 0000000..6e7cb52
--- /dev/null
+++ b/app/src/main/res/layout/item_card_continue_monthly.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="utf-8"?>
+<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="240dp"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="10dp"
+    android:layout_marginRight="10dp"
+    android:background="@android:color/transparent"
+    app:cardBackgroundColor="@android:color/transparent"
+    app:cardElevation="0dp"
+    app:cardUseCompatPadding="false"
+    >
+
+    <androidx.cardview.widget.CardView
+        android:id="@+id/vip_first_month_card_view"
+        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="100dp"
+        android:layout_marginTop="10dp"
+        app:cardCornerRadius="16dp"
+        android:foreground="@drawable/gold_border_shape"
+        app:cardBackgroundColor="@android:color/transparent"
+        app:cardElevation="0dp"
+        app:cardUseCompatPadding="false">
+
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="5dp"
+            android:paddingStart="15dp"
+            android:background="@android:color/transparent">
+
+            <!-- Title Text -->
+            <TextView
+                android:id="@+id/title_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="连续包月"
+                android:textSize="18sp"
+                android:textColor="#F9EBC6"
+
+                android:background="@android:color/transparent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintStart_toStartOf="parent" />
+
+            <!-- Subtitle Text -->
+            <TextView
+                android:id="@+id/sub_title_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="首次开通"
+                android:textSize="10dp"
+                android:textColor="#CCCCCC"
+                android:paddingStart="5dp"
+                android:paddingTop="2dp"
+                android:paddingEnd="5dp"
+                android:paddingBottom="2dp"
+                android:background="@drawable/round_transition_gray_bg"
+                app:layout_constraintTop_toBottomOf="@id/title_text"
+                app:layout_constraintStart_toStartOf="parent"
+                android:layout_marginStart="85dp"
+                android:layout_marginTop="-20dp"
+                />
+
+            <!-- Price Text -->
+            <TextView
+                android:id="@+id/price_text_tag"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="¥"
+                android:textSize="20sp"
+                android:textColor="#F9EBC6"
+                android:layout_marginTop="10dp"
+                android:layout_marginLeft="135dp"
+                android:background="@android:color/transparent"
+                app:layout_constraintTop_toBottomOf="@id/sub_title_text"
+                app:layout_constraintStart_toStartOf="parent" />
+            <TextView
+                android:id="@+id/price_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="9.9"
+                android:textSize="30sp"
+                android:textColor="#F9EBC6"
+                android:layout_marginTop="0dp"
+                android:layout_marginLeft="150dp"
+                android:background="@android:color/transparent"
+                app:layout_constraintTop_toBottomOf="@id/sub_title_text"
+                app:layout_constraintStart_toStartOf="parent" />
+
+            <!-- Next Price Text -->
+            <TextView
+                android:id="@+id/next_price_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="次月起12元/月"
+                android:textSize="14sp"
+                android:textColor="#CCCCCC"
+                android:layout_marginTop="10dp"
+                android:background="@android:color/transparent"
+                app:layout_constraintTop_toBottomOf="@id/title_text"
+                app:layout_constraintStart_toStartOf="parent" />
+
+            <!-- Auto Renew Text -->
+            <TextView
+                android:id="@+id/auto_renew_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="自动续费可随时取消"
+                android:textSize="12sp"
+                android:textColor="#CCCCCC"
+                android:layout_marginTop="4dp"
+                android:background="@android:color/transparent"
+                app:layout_constraintTop_toBottomOf="@id/next_price_text"
+                app:layout_constraintStart_toStartOf="parent" />
+
+<!--            <TextView-->
+<!--                android:id="@+id/auto_renew_text2"-->
+<!--                android:layout_width="wrap_content"-->
+<!--                android:layout_height="wrap_content"-->
+<!--                android:text="活动须知"-->
+<!--                android:textSize="12sp"-->
+<!--                android:textColor="#CCCCCC"-->
+<!--                android:layout_marginTop="4dp"-->
+<!--                android:background="@android:color/transparent"-->
+<!--                app:layout_constraintTop_toBottomOf="@id/auto_renew_text"-->
+<!--                app:layout_constraintStart_toStartOf="parent" />-->
+<!--            <TextView-->
+<!--                android:id="@+id/auto_renew_text3"-->
+<!--                android:layout_width="wrap_content"-->
+<!--                android:layout_height="wrap_content"-->
+<!--                android:text=">"-->
+<!--                android:textSize="16sp"-->
+<!--                android:textColor="#CCCCCC"-->
+<!--                android:layout_marginTop="0dp"-->
+<!--                android:background="@android:color/transparent"-->
+<!--                android:layout_marginLeft="60dp"-->
+<!--                app:layout_constraintTop_toBottomOf="@id/auto_renew_text"-->
+<!--                app:layout_constraintStart_toStartOf="parent" />-->
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+
+</androidx.cardview.widget.CardView>
+    <TextView
+        android:id="@+id/first_month_tag"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="0dp"
+        android:layout_marginRight="5dp"
+        android:scaleType="centerCrop"
+        android:layout_gravity="end|top"
+        android:text="首月限时特惠"
+        android:textColor="#FFFFFF"
+        android:padding="4dp"
+        android:elevation="4dp"
+        android:textSize="10sp"
+        android:background="@drawable/round_red_bg"
+        />
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_card_single_month.xml b/app/src/main/res/layout/item_card_single_month.xml
new file mode 100644
index 0000000..739b66c
--- /dev/null
+++ b/app/src/main/res/layout/item_card_single_month.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<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="160dp"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="10dp"
+    android:layout_marginRight="10dp"
+    android:background="@android:color/transparent"
+    app:cardBackgroundColor="@android:color/transparent"
+    app:cardElevation="0dp"
+    app:cardUseCompatPadding="false"
+    >
+
+    <androidx.cardview.widget.CardView
+        android:id="@+id/vip_month_card_view"
+        android:layout_width="160dp"
+        android:layout_height="100dp"
+        android:padding="8dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginEnd="20dp"
+        android:background="@android:color/transparent"
+        android:foreground="@drawable/gray_border_shape"
+        app:cardBackgroundColor="@android:color/transparent"
+        app:cardCornerRadius="16dp"
+        app:cardElevation="0dp"
+        app:cardUseCompatPadding="false">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="20dp"
+            android:gravity="center"
+            android:orientation="vertical"
+            android:padding="5dp">
+
+            <TextView
+                android:id="@+id/single_month_title_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:text="1个月"
+                android:textColor="#F9EBC6"
+                android:textSize="18sp" />
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content">
+                <TextView
+                    android:id="@+id/single_month_price_tag"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dp"
+                    android:text="¥"
+                    android:textColor="#F9EBC6"
+                    android:textSize="20sp" />
+                <TextView
+                    android:id="@+id/single_month_price_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dp"
+                    android:text="15"
+                    android:textColor="#F9EBC6"
+                    android:textSize="30sp" />
+            </LinearLayout>
+
+        </LinearLayout>
+    </androidx.cardview.widget.CardView>
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_card_yearly.xml b/app/src/main/res/layout/item_card_yearly.xml
new file mode 100644
index 0000000..b7b61fa
--- /dev/null
+++ b/app/src/main/res/layout/item_card_yearly.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<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="160dp"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="10dp"
+    android:layout_marginRight="10dp"
+    android:background="@android:color/transparent"
+    app:cardBackgroundColor="@android:color/transparent"
+    app:cardElevation="0dp"
+    app:cardUseCompatPadding="false"
+    >
+    <androidx.cardview.widget.CardView
+        android:id="@+id/vip_year_card_view"
+        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_marginTop="10dp"
+        app:cardCornerRadius="16dp"
+        android:foreground="@drawable/gray_border_shape"
+        app:cardBackgroundColor="@android:color/transparent"
+        app:cardElevation="0dp"
+        app:cardUseCompatPadding="false">
+
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="100dp"
+            android:orientation="vertical"
+            android:gravity="center"
+            android:padding="0dp">
+
+            <TextView
+                android:id="@+id/yearly_title_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="年卡"
+                android:textSize="18sp"
+                android:textColor="#F9EBC6"
+                android:layout_marginTop="8dp"/>
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content">
+                <TextView
+                    android:id="@+id/yearly_price_tag"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="¥"
+                    android:textSize="20sp"
+                    android:textColor="#F9EBC6"
+                    android:layout_marginTop="2dp"/>
+                <TextView
+                    android:id="@+id/yearly_price_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="108"
+                    android:textSize="20sp"
+                    android:textColor="#F9EBC6"
+                    android:layout_marginTop="2dp"/>
+                <TextView
+                    android:id="@+id/yearly_price_unit"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="/年"
+                    android:textSize="20sp"
+                    android:textColor="#F9EBC6"
+                    android:layout_marginTop="2dp"/>
+            </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content">
+            <TextView
+                android:id="@+id/yearly_original_price_tag"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="¥"
+                android:textSize="12sp"
+                android:textColor="#CCCCCC"
+                android:layout_marginTop="2dp"/>
+            <TextView
+                android:id="@+id/yearly_original_price_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="168"
+                android:textSize="12sp"
+                android:textColor="#CCCCCC"
+                android:layout_marginTop="2dp"
+                />
+        </LinearLayout>
+
+    </LinearLayout>
+
+
+</androidx.cardview.widget.CardView>
+
+    <TextView
+        android:id="@+id/discount_tag"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="0dp"
+        android:layout_marginRight="5dp"
+        android:scaleType="centerCrop"
+        android:layout_gravity="end|top"
+        android:text="折合9元/月"
+        android:textColor="#FFFFFF"
+        android:padding="4dp"
+        android:textSize="10sp"
+        android:elevation="4dp"
+        android:background="@drawable/round_red_bg"
+        />
+
+</androidx.cardview.widget.CardView>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_category_selector.xml b/app/src/main/res/layout/item_category_selector.xml
new file mode 100644
index 0000000..557638f
--- /dev/null
+++ b/app/src/main/res/layout/item_category_selector.xml
@@ -0,0 +1,22 @@
+<?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="8dp"
+    android:gravity="center_vertical">
+
+    <TextView
+        android:id="@+id/categoryName"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:textSize="16sp"/>
+
+    <CheckBox
+        android:id="@+id/categoryCheckBox"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"/>
+
+</LinearLayout> 
\ No newline at end of file
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
diff --git a/app/src/main/res/layout/vip_protocol_dialog_custom.xml b/app/src/main/res/layout/vip_protocol_dialog_custom.xml
new file mode 100644
index 0000000..94d6cab
--- /dev/null
+++ b/app/src/main/res/layout/vip_protocol_dialog_custom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="300dp"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:background="@drawable/dialog_background"
+    android:padding="20dp"
+    android:gravity="center"
+
+    >
+
+    <!-- 标题 -->
+    <TextView
+        android:id="@+id/dialogTitle"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="确认开通"
+        android:textSize="20sp"
+        android:textColor="#000000"
+        android:gravity="center"
+        android:paddingBottom="10dp" />
+
+    <!-- 内容 -->
+    <TextView
+        android:id="@+id/dialogMessage"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="请阅读并同意《会员协议》?"
+        android:textSize="16sp"
+        android:textColor="#000000"
+        android:gravity="center"
+        android:paddingBottom="20dp" />
+
+    <!-- 按钮 -->
+    <Button
+        android:id="@+id/btnConfirm"
+        android:layout_width="200dp"
+        android:layout_height="wrap_content"
+        android:text="继续开通"
+        android:textColor="@android:color/white"
+
+        android:backgroundTint="#000000"
+        android:gravity="center" />
+</LinearLayout>
diff --git a/app/src/main/res/layout/vip_protocol_dialog_custom_bak.xml b/app/src/main/res/layout/vip_protocol_dialog_custom_bak.xml
new file mode 100644
index 0000000..e3b23ec
--- /dev/null
+++ b/app/src/main/res/layout/vip_protocol_dialog_custom_bak.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<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="300dp"
+    android:layout_height="wrap_content"
+    app:cardCornerRadius="10dp"
+    app:cardElevation="5dp"
+    app:cardBackgroundColor="#FFFFFF"
+    android:layout_gravity="center">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:padding="20dp"
+        android:gravity="center">
+
+        <!-- 标题 -->
+        <TextView
+            android:id="@+id/dialogTitle"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="确认开通"
+            android:textSize="20sp"
+            android:textColor="#000000"
+            android:gravity="center"
+            android:paddingBottom="10dp" />
+
+        <!-- 内容 -->
+        <TextView
+            android:id="@+id/dialogMessage"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="请阅读并同意《会员协议》?"
+            android:textSize="16sp"
+            android:textColor="#000000"
+            android:gravity="center"
+            android:paddingBottom="20dp" />
+
+        <!-- 按钮 -->
+        <Button
+            android:id="@+id/btnConfirm"
+            android:layout_width="200dp"
+            android:layout_height="wrap_content"
+            android:text="继续开通"
+            android:textColor="@android:color/white"
+            android:backgroundTint="#000000"
+            android:textColorHint="@android:color/black"
+            android:gravity="center" />
+    </LinearLayout>
+
+</androidx.cardview.widget.CardView>
diff --git a/app/src/main/res/mipmap/avatar_default.png b/app/src/main/res/mipmap/avatar_default.png
new file mode 100644
index 0000000..6b95b68
--- /dev/null
+++ b/app/src/main/res/mipmap/avatar_default.png
Binary files differ
diff --git a/app/src/main/res/mipmap/overlay.png b/app/src/main/res/mipmap/overlay.png
new file mode 100644
index 0000000..9905124
--- /dev/null
+++ b/app/src/main/res/mipmap/overlay.png
Binary files differ
diff --git a/app/src/main/res/mipmap/overlay2.jpg b/app/src/main/res/mipmap/overlay2.jpg
new file mode 100644
index 0000000..0dc91e8
--- /dev/null
+++ b/app/src/main/res/mipmap/overlay2.jpg
Binary files differ
diff --git a/app/src/main/res/mipmap/vip.png b/app/src/main/res/mipmap/vip.png
new file mode 100644
index 0000000..6cdf762
--- /dev/null
+++ b/app/src/main/res/mipmap/vip.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_ad_no.png b/app/src/main/res/mipmap/vip_ad_no.png
new file mode 100644
index 0000000..981fdce
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_ad_no.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_ai_ass_icon.png b/app/src/main/res/mipmap/vip_ai_ass_icon.png
new file mode 100644
index 0000000..a8ec7b9
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_ai_ass_icon.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_alipay.png b/app/src/main/res/mipmap/vip_alipay.png
new file mode 100644
index 0000000..d770490
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_alipay.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_bar_sta.png b/app/src/main/res/mipmap/vip_bar_sta.png
new file mode 100644
index 0000000..77a41cc
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_bar_sta.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_cancel.png b/app/src/main/res/mipmap/vip_cancel.png
new file mode 100644
index 0000000..9fc891d
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_cancel.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_cancel_link.png b/app/src/main/res/mipmap/vip_cancel_link.png
new file mode 100644
index 0000000..1f5f091
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_cancel_link.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_card.png b/app/src/main/res/mipmap/vip_card.png
new file mode 100644
index 0000000..75d9e76
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_card.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_circle_pie.png b/app/src/main/res/mipmap/vip_circle_pie.png
new file mode 100644
index 0000000..94e153d
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_circle_pie.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_copy.png b/app/src/main/res/mipmap/vip_copy.png
new file mode 100644
index 0000000..c6a5e8a
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_copy.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_crown.png b/app/src/main/res/mipmap/vip_crown.png
new file mode 100644
index 0000000..c86537f
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_crown.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_free_member.png b/app/src/main/res/mipmap/vip_free_member.png
new file mode 100644
index 0000000..d6bd848
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_free_member.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_life_insurance.png b/app/src/main/res/mipmap/vip_life_insurance.png
new file mode 100644
index 0000000..445c54e
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_life_insurance.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_ling.png b/app/src/main/res/mipmap/vip_ling.png
new file mode 100644
index 0000000..3de1c6a
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_ling.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_more.png b/app/src/main/res/mipmap/vip_more.png
new file mode 100644
index 0000000..34dfb7f
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_more.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_no.png b/app/src/main/res/mipmap/vip_no.png
new file mode 100644
index 0000000..e07563a
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_no.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_right.png b/app/src/main/res/mipmap/vip_right.png
new file mode 100644
index 0000000..5d46f9f
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_right.png
Binary files differ
diff --git a/app/src/main/res/mipmap/vip_wechat.png b/app/src/main/res/mipmap/vip_wechat.png
new file mode 100644
index 0000000..d66bbb2
--- /dev/null
+++ b/app/src/main/res/mipmap/vip_wechat.png
Binary files differ
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
new file mode 100644
index 0000000..b22fff5
--- /dev/null
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<navigation xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/nav_graph"
+    app:startDestination="@id/FirstFragment">
+
+    <fragment
+        android:id="@+id/FirstFragment"
+        android:name="com.example.firstapp.activity.FirstFragment"
+        android:label="@string/first_fragment_label"
+        tools:layout="@layout/fragment_first">
+
+        <action
+            android:id="@+id/action_FirstFragment_to_SecondFragment"
+            app:destination="@id/SecondFragment" />
+    </fragment>
+    <fragment
+        android:id="@+id/SecondFragment"
+        android:name="com.example.firstapp.activity.SecondFragment"
+        android:label="@string/second_fragment_label"
+        tools:layout="@layout/fragment_second">
+
+        <action
+            android:id="@+id/action_SecondFragment_to_FirstFragment"
+            app:destination="@id/FirstFragment" />
+    </fragment>
+</navigation>
\ No newline at end of file
diff --git a/app/src/main/res/values-land/dimens.xml b/app/src/main/res/values-land/dimens.xml
new file mode 100644
index 0000000..22d7f00
--- /dev/null
+++ b/app/src/main/res/values-land/dimens.xml
@@ -0,0 +1,3 @@
+<resources>
+    <dimen name="fab_margin">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
deleted file mode 100644
index 4925b55..0000000
--- a/app/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<resources xmlns:tools="http://schemas.android.com/tools">
-    <!-- Base application theme. -->
-    <style name="Theme.FirstApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
-        <!-- Primary brand color. -->
-        <item name="colorPrimary">@color/purple_200</item>
-        <item name="colorPrimaryVariant">@color/purple_700</item>
-        <item name="colorOnPrimary">@color/black</item>
-        <!-- Secondary brand color. -->
-        <item name="colorSecondary">@color/teal_200</item>
-        <item name="colorSecondaryVariant">@color/teal_200</item>
-        <item name="colorOnSecondary">@color/black</item>
-        <!-- Status bar color. -->
-        <item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
-        <!-- 确保没有ActionBar -->
-        <item name="windowActionBar">false</item>
-        <item name="windowNoTitle">true</item>
-        <!-- Customize your theme here. -->
-    </style>
-
-    <style name="ThemeOverlay.FirstApp.FullscreenContainer" parent="">
-        <item name="fullscreenBackgroundColor">@color/light_blue_900</item>
-        <item name="fullscreenTextColor">@color/light_blue_A400</item>
-    </style>
-    <!-- Base application theme. -->
-    <style name="Base.Theme.FirstApp" parent="Theme.Material3.DayNight.NoActionBar">
-        <!-- Customize your dark theme here. -->
-        <!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
-    </style>
-</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values-v23/themes.xml b/app/src/main/res/values-v23/themes.xml
index b806642..940849b 100644
--- a/app/src/main/res/values-v23/themes.xml
+++ b/app/src/main/res/values-v23/themes.xml
@@ -1,9 +1,9 @@
 <resources xmlns:tools="http://schemas.android.com/tools">
 
-    <style name="Theme.FirstApp" parent="Base.Theme.FirstApp">
-        <!-- Transparent system bars for edge-to-edge. -->
-        <item name="android:navigationBarColor">@android:color/transparent</item>
-        <item name="android:statusBarColor">@android:color/transparent</item>
-        <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
-    </style>
+<!--    <style name="Theme.FirstApp" parent="Base.Theme.FirstApp">-->
+<!--        &lt;!&ndash; Transparent system bars for edge-to-edge. &ndash;&gt;-->
+<!--        <item name="android:navigationBarColor">@android:color/transparent</item>-->
+<!--        <item name="android:statusBarColor">@android:color/transparent</item>-->
+<!--        <item name="android:windowLightStatusBar">?attr/isLightTheme</item>-->
+<!--    </style>-->
 </resources>
\ No newline at end of file
diff --git a/app/src/main/res/values-w1240dp/dimens.xml b/app/src/main/res/values-w1240dp/dimens.xml
new file mode 100644
index 0000000..d73f4a3
--- /dev/null
+++ b/app/src/main/res/values-w1240dp/dimens.xml
@@ -0,0 +1,3 @@
+<resources>
+    <dimen name="fab_margin">200dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values-w600dp/dimens.xml b/app/src/main/res/values-w600dp/dimens.xml
new file mode 100644
index 0000000..22d7f00
--- /dev/null
+++ b/app/src/main/res/values-w600dp/dimens.xml
@@ -0,0 +1,3 @@
+<resources>
+    <dimen name="fab_margin">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 29be459..dd87850 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -5,4 +5,5 @@
     <dimen name="list_item_spacing">16dp</dimen>
     <dimen name="list_item_spacing_half">8dp</dimen>
     <dimen name="heatmap_cell_size">12dp</dimen>
+    <dimen name="fab_margin">16dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 02c10a9..74c31b4 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -19,9 +19,9 @@
     </style>
 
     <style name="Theme.FirstApp.Fullscreen" parent="Theme.FirstApp">
-        <item name="android:actionBarStyle">@style/Widget.Theme.FirstApp.ActionBar.Fullscreen</item>
-        <item name="android:windowActionBarOverlay">true</item>
-        <item name="android:windowBackground">@null</item>
+<!--        <item name="android:actionBarStyle">@style/Widget.Theme.FirstApp.ActionBar.Fullscreen</item>-->
+<!--        <item name="android:windowActionBarOverlay">true</item>-->
+<!--        <item name="android:windowBackground">@null</item>-->
     </style>
 
     <style name="ThemeOverlay.FirstApp.FullscreenContainer" parent="">
diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml
index d1689af..f8bbdd2 100644
--- a/app/src/main/res/xml/network_security_config.xml
+++ b/app/src/main/res/xml/network_security_config.xml
@@ -5,6 +5,7 @@
         <domain includeSubdomains="true">192.168.1.213</domain>
         <domain includeSubdomains="true">192.168.1.198</domain>
         <domain includeSubdomains="true">192.168.1.199</domain>
+        <domain includeSubdomains="true">192.168.1.201</domain>
         <!-- 可添加其他域名或IP(如192.168.0.101) -->
 <!--        如果本地服务使用自签名证书,需在 network_security_config.xml 中信任该证书:-->
 <!--        <trust-anchors>-->

--
Gitblit v1.9.3