From 27bbd0435881e408f267c99e6a253d2e17873bcc Mon Sep 17 00:00:00 2001 From: tj <1378534974@qq.com> Date: 星期五, 11 四月 2025 17:44:11 +0800 Subject: [PATCH] 1.2 --- app/src/main/java/com/example/firstapp/activity/SettingActivity.kt | 85 +++++- app/src/main/java/com/example/firstapp/database/response/AccountCloseResponse.kt | 7 app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt | 15 + app/src/main/java/com/example/firstapp/database/repository/KeywordRepository.kt | 5 app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt | 87 +++++- app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt | 59 ++++ app/src/main/res/layout/layout_week_stats.xml | 39 ++ app/src/main/java/com/example/firstapp/adapter/PackageAdapter.kt | 6 app/src/main/java/com/example/firstapp/database/dao/KeywordDao.kt | 4 app/src/main/res/layout/fragment_dashboard0411.xml | 262 ++++++++++++++++++ app/src/main/java/com/example/firstapp/database/service/ApiService.kt | 3 app/src/main/java/com/example/firstapp/model/DailyStat2.kt | 17 + app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt | 7 app/src/main/java/com/example/firstapp/model/DailyStat.kt | 1 app/src/main/res/layout/activity_setting.xml | 17 + app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt | 2 app/src/main/res/drawable/border_button.xml | 12 app/src/main/res/layout/fragment_dashboard.xml | 92 +++++- app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt | 4 app/src/main/res/layout/item_package_dashboard.xml | 8 app/src/main/res/layout/account_close_dialog_custom.xml | 87 ++++++ 21 files changed, 761 insertions(+), 58 deletions(-) diff --git a/app/src/main/java/com/example/firstapp/activity/SettingActivity.kt b/app/src/main/java/com/example/firstapp/activity/SettingActivity.kt index 017f581..371c4d8 100644 --- a/app/src/main/java/com/example/firstapp/activity/SettingActivity.kt +++ b/app/src/main/java/com/example/firstapp/activity/SettingActivity.kt @@ -4,22 +4,19 @@ import android.annotation.SuppressLint import android.app.AlertDialog import android.content.Intent -import android.os.Build import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.Gravity +import android.view.LayoutInflater import android.view.MenuItem -import android.view.MotionEvent -import android.view.View -import android.view.WindowInsets -import android.widget.LinearLayout -import android.widget.TextView -import androidx.appcompat.widget.Toolbar +import android.widget.Button import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import com.example.firstapp.databinding.ActivitySettingBinding import com.example.firstapp.R +import com.example.firstapp.core.Core +import com.example.firstapp.database.service.RetrofitClient import com.example.firstapp.ui.home.HomeViewModel +import com.example.firstapp.utils.Log +import kotlinx.coroutines.launch /** * An example full-screen activity that shows and hides the system UI (i.e. @@ -66,6 +63,70 @@ // // }) + + // 退出登录 + logout() + + // 账号注销 + accountClose() + + + + } + + private fun accountClose(){ + + + binding.accountClose.setOnClickListener { + + val dialogView = LayoutInflater.from(this).inflate(R.layout.account_close_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 { + dialog.dismiss() + } + + val btnCancel = dialogView.findViewById<Button>(R.id.btnCancel) + btnCancel.setOnClickListener { + // 关闭账户 + lifecycleScope.launch { + try { + // 清除本地的数据库 + RetrofitClient.apiService.closeAccount() + + Core.code.deleteAll() + Core.msg.deleteAll() + Core.keyword.deleteAll() + Core.reminder.deleteAll() + + dialog.dismiss() + // 跳转到 LoginActivity 并清除之前的任务栈 + var intent = Intent(this@SettingActivity, LoginActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + startActivity(intent) + // 关闭当前页面 + finish() + + } catch (ex: Exception) { + Log.e("关闭账户", ex.message ?: "关闭账户报错") + } + + } + } + + dialog.show() + + } + } + + private fun logout(){ + binding.settingExit.setOnClickListener { // 弹出确认退出的对话框 val alertDialog = AlertDialog.Builder(this) @@ -79,7 +140,6 @@ val intent = Intent(this, LoginActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK startActivity(intent) - // 关闭当前页面 finish() } @@ -92,9 +152,6 @@ // 显示对话框 alertDialog.show() } - - - } // 点击返回按钮时调用 diff --git a/app/src/main/java/com/example/firstapp/adapter/PackageAdapter.kt b/app/src/main/java/com/example/firstapp/adapter/PackageAdapter.kt index dc3df25..b85bc45 100644 --- a/app/src/main/java/com/example/firstapp/adapter/PackageAdapter.kt +++ b/app/src/main/java/com/example/firstapp/adapter/PackageAdapter.kt @@ -44,6 +44,10 @@ private val textPickTime: TextView = view.findViewById(R.id.text_pick_time) fun bind(code: Code) { + + textTime.textSize=10f + textPickTime.textSize=10f + // imgCourier.setImageResource(code.category) textCourierName.text = code.oneLevel textTrackingNumber.text = code.code @@ -53,7 +57,7 @@ try { val date: Date? = parser.parse(code.createTime) // 解析字符串 date?.let { - textTime.text = "到货:"+formatter.format(it) // 格式化并赋值 + textTime.text = "到货:"+formatter.format(it) // 格式化并赋值 } ?: run { // 处理解析失败(date 为 null 的情况) textTime.text = "Invalid Date" 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 7572a45..d8b0118 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 @@ -29,6 +29,9 @@ @Query("DELETE FROM Code where id=:id") fun delete(id: Long) + @Query("DELETE FROM Code") + fun deleteAll(): Completable + @Query("SELECT * FROM Code WHERE id = :id LIMIT 1") fun getCodeById(id: Long): Code? @@ -75,10 +78,18 @@ @Query(""" SELECT * FROM code WHERE substr(createTime, 1, 10) = - date(:date/1000, 'unixepoch', 'localtime') + date(:date/1000, 'unixepoch', 'localtime') ORDER BY createTime DESC """) fun getPackagesByDay(date: Long): Flow<List<Code>> + + @Query(""" + SELECT * FROM code + WHERE substr(createTime, 1, 10) = + date(:date/1000, 'unixepoch', 'localtime') and pickup = 1 + ORDER BY createTime DESC + """) + fun getPackagesByDayUnread(date: Long): Flow<List<Code>> @Query(""" SELECT oneLevel as courierName, COUNT(*) as count @@ -283,4 +294,50 @@ ORDER BY createTime DESC """) fun getPackagesByTypeAndStation(type: String, stationName: String): List<Code> + + + @Query(""" + SELECT COUNT(1) + FROM code + WHERE date(createTime) BETWEEN date(:startDateCur) AND date(:endDateCur) + """) + fun getCurrentWeekStats2(startDateCur: String, endDateCur: String): Flow<Long> + +// @Query(""" +// WITH RECURSIVE dates(date_value) AS ( +// SELECT date('now', 'weekday 1', '-7 days') +// UNION ALL +// SELECT date(date_value, '+1 day') +// FROM dates +// WHERE date_value < date('now', 'weekday 1', '-7 days', '+6 days') +// ) +// SELECT +// strftime('%d', date_value) AS date, +// COUNT(c.id) AS count, +// '' as weekStart +// FROM dates d +// LEFT JOIN code c ON date(c.createTime) = d.date_value +// GROUP BY d.date_value +// ORDER BY d.date_value ASC +// +// """) + + @Query(""" + WITH RECURSIVE dates(date_value) AS ( + SELECT date(:startDateCur) + UNION ALL + SELECT date(date_value, '+1 day') + FROM dates + WHERE date_value < date(:endDateCur) + ) + SELECT + strftime('%d', date_value) AS date, + COUNT(c.id) AS count, + '' AS weekStart + FROM dates d + LEFT JOIN code c ON date(c.createTime) = d.date_value + GROUP BY d.date_value + ORDER BY d.date_value ASC +""") + fun getWeeklyStatsChart(startDateCur: String, endDateCur: String): Flow<List<DailyStat>> } diff --git a/app/src/main/java/com/example/firstapp/database/dao/KeywordDao.kt b/app/src/main/java/com/example/firstapp/database/dao/KeywordDao.kt index 81a54e1..f128430 100644 --- a/app/src/main/java/com/example/firstapp/database/dao/KeywordDao.kt +++ b/app/src/main/java/com/example/firstapp/database/dao/KeywordDao.kt @@ -7,6 +7,7 @@ import androidx.room.Update import com.example.firstapp.database.entity.KeywordConfig import com.example.firstapp.database.entity.KeywordEntity +import io.reactivex.Completable //@Dao //interface KeywordDao { @@ -34,4 +35,7 @@ @Query("SELECT * FROM keywords") fun getAllKeywords(): List<KeywordEntity> + + @Query("DELETE FROM keywords") + fun deleteAll(): Completable } \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt b/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt index bf6ca23..8179240 100644 --- a/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt +++ b/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt @@ -23,4 +23,4 @@ @Query("DELETE FROM reminders") suspend fun deleteAllReminders() -} \ No newline at end of file +} \ No newline at end of file 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 ad83877..19aecf0 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.DailyStat import com.example.firstapp.model.StationGroup import kotlinx.coroutines.flow.Flow @@ -14,6 +15,9 @@ @WorkerThread fun delete(id: Long) = codeDao.delete(id) + + @WorkerThread + fun deleteAll() = codeDao.deleteAll() fun getAll() = codeDao.getAllCodes() @@ -36,6 +40,14 @@ fun getPackages(date: Long, dateType: String): Flow<List<Code>> { return when (dateType) { "DAY" -> codeDao.getPackagesByDay(date) + "WEEK" -> codeDao.getPackagesByWeek(date) + else -> codeDao.getPackagesByDay(date) + } + } + + fun getPackagesUnread(date: Long, dateType: String): Flow<List<Code>> { + return when (dateType) { + "DAY" -> codeDao.getPackagesByDayUnread(date) "WEEK" -> codeDao.getPackagesByWeek(date) else -> codeDao.getPackagesByDay(date) } @@ -87,4 +99,7 @@ return codeDao.getPackagesByTypeAndStation(type, stationName) } + fun getCurrentWeekStats2(startDateCur: String, endDateCur: String) = codeDao.getCurrentWeekStats2(startDateCur,endDateCur) + fun getWeeklyStatsChart(startDateCur: String, endDateCur: String): Flow<List<DailyStat>> = codeDao.getWeeklyStatsChart(startDateCur,endDateCur) + } \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/database/repository/KeywordRepository.kt b/app/src/main/java/com/example/firstapp/database/repository/KeywordRepository.kt index 26c45cb..9da32b4 100644 --- a/app/src/main/java/com/example/firstapp/database/repository/KeywordRepository.kt +++ b/app/src/main/java/com/example/firstapp/database/repository/KeywordRepository.kt @@ -1,5 +1,6 @@ package com.example.firstapp.database.repository +import androidx.annotation.WorkerThread import com.example.firstapp.database.dao.KeywordDao import com.example.firstapp.database.entity.KeywordConfig import com.example.firstapp.database.entity.KeywordEntity @@ -39,5 +40,9 @@ keywordDao.insertAll(keywordEntities) } + @WorkerThread + fun deleteAll() = keywordDao.deleteAll() + + } diff --git a/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt b/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt index 861e344..e6d8747 100644 --- a/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt +++ b/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt @@ -8,7 +8,7 @@ class ReminderRepository(context: Context) { - private val reminderDao: ReminderDao = AppDatabase.getInstance(context).reminderDao() + private val reminderDao: ReminderDao = AppDatabase.getInstance(context).reminderDao() fun getAllReminders(): Flow<List<Reminder>> = reminderDao.getAllReminders() suspend fun insertReminder(reminder: Reminder) { @@ -30,4 +30,4 @@ suspend fun deleteAllReminders() { reminderDao.deleteAllReminders() } -} \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/example/firstapp/database/response/AccountCloseResponse.kt b/app/src/main/java/com/example/firstapp/database/response/AccountCloseResponse.kt new file mode 100644 index 0000000..6c1e029 --- /dev/null +++ b/app/src/main/java/com/example/firstapp/database/response/AccountCloseResponse.kt @@ -0,0 +1,7 @@ +package com.example.firstapp.database.response + +data class AccountCloseResponse( + val code: Int, + val msg: String, + val data: 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 4201f27..41c83c2 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 @@ -6,6 +6,7 @@ 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.AccountCloseResponse import com.example.firstapp.database.response.AlipayOrderInfoResponse import com.example.firstapp.database.response.ContentResponse import com.example.firstapp.database.response.DictResponse @@ -68,6 +69,8 @@ @Part avatar: MultipartBody.Part? ): ApiResponse<Unit> + @POST("api/account/close") + suspend fun closeAccount(): AccountCloseResponse fun getUserCategories(currentUserId: String): List<CategoryConfig> diff --git a/app/src/main/java/com/example/firstapp/model/DailyStat.kt b/app/src/main/java/com/example/firstapp/model/DailyStat.kt index 54462ad..1ff696f 100644 --- a/app/src/main/java/com/example/firstapp/model/DailyStat.kt +++ b/app/src/main/java/com/example/firstapp/model/DailyStat.kt @@ -2,6 +2,7 @@ import androidx.room.DatabaseView import androidx.room.ColumnInfo +import androidx.room.Ignore @DatabaseView( """ diff --git a/app/src/main/java/com/example/firstapp/model/DailyStat2.kt b/app/src/main/java/com/example/firstapp/model/DailyStat2.kt new file mode 100644 index 0000000..393945f --- /dev/null +++ b/app/src/main/java/com/example/firstapp/model/DailyStat2.kt @@ -0,0 +1,17 @@ +package com.example.firstapp.model + +import androidx.room.ColumnInfo +import androidx.room.DatabaseView + +@DatabaseView( + """ + SELECT substr(createTime, 1, 10) as date, + COUNT(*) as count + FROM code + GROUP BY substr(createTime, 1, 10) + """ +) +data class DailyStat2( + val date: String, + val count: Int +) \ No newline at end of file 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 21cb233..f8808f2 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,17 +21,13 @@ 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() { @@ -45,6 +41,9 @@ private lateinit var pieChart: PieChart private lateinit var heatmapView: View private var currentUserInfo: UserInfo? = null // 确保使用你的实际数据类 + + private var startDateCur:String = "" + private var endDateCur:String = "" enum class DateType { @@ -113,6 +112,10 @@ } private fun setupTabLayout() { + val weekStatsView = binding.layoutWeekStats.root + val bar_title:TextView = weekStatsView.findViewById(R.id.bar_title) + val pie_title:TextView = weekStatsView.findViewById(R.id.pie_title) + binding.tabDateRange.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab?) { currentDateType = when(tab?.position) { @@ -122,6 +125,40 @@ 3 -> DateType.YEAR else -> DateType.DAY } + + when (currentDateType) { + DateType.DAY -> { + binding.cardPackageStatsTitleText.text = "本日收到包裹总数" + binding.layoutYearStatsTitleText.text = "包裹取件码记录" + + binding.cardPackageStatsTitleText.visibility = View.VISIBLE + binding.layoutYearStatsTitleText.visibility = View.VISIBLE + } + DateType.WEEK -> { + binding.cardPackageStatsTitleText.text = "本周收到包裹总数" + bar_title.text = "本周收到包裹数分布 ->" + pie_title.text = "本周包裹物流公司分布 ->" + binding.cardPackageStatsTitleText.visibility = View.VISIBLE + binding.layoutYearStatsTitleText.visibility = View.GONE + + } + DateType.MONTH -> { + binding.cardPackageStatsTitleText.text = "本月收到包裹总数" + bar_title.text = "本月收到包裹数分布 ->" + pie_title.text = "本月包裹物流公司分布 ->" + binding.cardPackageStatsTitleText.visibility = View.VISIBLE + binding.layoutYearStatsTitleText.visibility = View.GONE + } + DateType.YEAR -> { + bar_title.text = "本年收到包裹数分布 ->" + pie_title.text = "本年包裹物流公司分布 ->" + binding.cardPackageStatsTitleText.visibility = View.GONE + binding.layoutYearStatsTitleText.visibility = View.GONE + } + } + + + updateDateDisplay() updateCharts() loadPackages() @@ -160,10 +197,13 @@ val calendar = currentDate.clone() as Calendar calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY) val startDate = SimpleDateFormat("MM月dd日", Locale.getDefault()).format(calendar.time) - + startDateCur=SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(calendar.time) + calendar.add(Calendar.DAY_OF_WEEK, 6) val endDate = SimpleDateFormat("MM月dd日", Locale.getDefault()).format(calendar.time) - + endDateCur=SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(calendar.time) + + "$startDate-$endDate" } DateType.MONTH -> "yyyy年MM月" @@ -178,10 +218,15 @@ } } private fun setupView(view: View) { + val weekStatsView = binding.layoutWeekStats.root barChart = weekStatsView.findViewById(R.id.chart_daily_packages) pieChart = weekStatsView.findViewById(R.id.chart_courier_distribution) heatmapView = weekStatsView.findViewById(R.id.heatmap_yearly) + + barChart.setViewPortOffsets(100f, 100f, 100f, 200f) + +// barChart.invalidate() // 初始化时隐藏统计视图 weekStatsView.visibility = View.GONE @@ -190,6 +235,7 @@ setupPieChart() setupHeatmap() updateCharts() + } private fun setupBarChart() { barChart.apply { @@ -240,7 +286,8 @@ private fun updateBarChartData() { val statsFlow = when (currentDateType) { DateType.WEEK -> { - viewModel.getWeeklyStats(currentDate.timeInMillis, 6) +// viewModel.getWeeklyStats(currentDate.timeInMillis, 6) + viewModel.getWeeklyStatsChart(startDateCur,endDateCur) } DateType.MONTH -> { viewModel.getYearMonthlyStats(currentDate.timeInMillis) @@ -416,14 +463,26 @@ when (currentDateType) { DateType.DAY -> { binding.textPackageCount.text = "${packages.size}个" + + // 获取本周统计 + viewModel.getPackagesUnread(currentDate.timeInMillis, + currentDateType.name) + .observe(viewLifecycleOwner) { unpackages-> + // 只读取未取件的包裹 + packageAdapter.updatePackages(unpackages) + } + } DateType.WEEK -> { // 获取本周统计 - viewModel.getCurrentWeekStats(currentDate.timeInMillis) - .observe(viewLifecycleOwner) { stats -> - val weekTotal = stats.sumOf { it.count } - binding.textPackageCount.text = "${weekTotal}个" - } + viewModel.getCurrentWeekStats2(startDateCur,endDateCur).observe(viewLifecycleOwner) { stats -> + binding.textPackageCount.text = "${stats}个" + } +// viewModel.getCurrentWeekStats(currentDate.timeInMillis) +// .observe(viewLifecycleOwner) { stats -> +// val weekTotal = stats.sumOf { it.count } +// binding.textPackageCount.text = "${weekTotal}个" +// } } DateType.MONTH -> { // 获取本月统计 @@ -442,8 +501,8 @@ } } } - packageAdapter.updatePackages(packages) - packageAdapter.updatePackages(packages) + +// packageAdapter.updatePackages(packages) // binding.textPackageCount.text = "${packages.size}个" } } diff --git a/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt b/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt index 1a0a2cb..5969ea5 100644 --- a/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt +++ b/app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt @@ -4,7 +4,6 @@ import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope -import androidx.room.RewriteQueriesToDropUnusedColumns import com.example.firstapp.AppDatabase import com.example.firstapp.database.entity.Code import com.example.firstapp.database.repository.CodeRepository @@ -21,6 +20,9 @@ fun getPackages(date: Long, dateType: String) = repository.getPackages(date, dateType).asLiveData() + + fun getPackagesUnread(date: Long, dateType: String) = + repository.getPackagesUnread(date, dateType).asLiveData() fun getCourierStats(date: Long, dateType: String) = repository.getCourierStats(date, dateType).asLiveData() @@ -47,4 +49,7 @@ fun getCurrentYearStats(date: Long) = repository.getCurrentYearStats(date).asLiveData() + + fun getCurrentWeekStats2(startDateCur: String, endDateCur: String) = repository.getCurrentWeekStats2(startDateCur,endDateCur).asLiveData() + fun getWeeklyStatsChart(startDateCur: String, endDateCur: String) = repository.getWeeklyStatsChart(startDateCur, endDateCur).asLiveData() } \ No newline at end of file diff --git a/app/src/main/res/drawable/border_button.xml b/app/src/main/res/drawable/border_button.xml new file mode 100644 index 0000000..7a4669e --- /dev/null +++ b/app/src/main/res/drawable/border_button.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- 边框颜色和宽度 --> + <stroke + android:color="#000000" android:width="2dp" /> <!-- 边框宽度 --> + + <!-- 背景颜色 --> + <solid android:color="@android:color/transparent" /> <!-- 设置透明背景 --> + + <!-- 圆角半径 --> + <corners android:radius="200dp" /> <!-- 设置圆角半径,调整数值来控制圆角的大小 --> +</shape> diff --git a/app/src/main/res/layout/account_close_dialog_custom.xml b/app/src/main/res/layout/account_close_dialog_custom.xml new file mode 100644 index 0000000..8a0607a --- /dev/null +++ b/app/src/main/res/layout/account_close_dialog_custom.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout 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="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" /> + + <View + android:id="@+id/divider" + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="#E2E2E2" + android:layout_marginTop="5dp" + android:layout_marginHorizontal="0dp" /> + + + + <!-- 内容 --> + <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="left" + android:layout_marginTop="5dp" + android:paddingBottom="20dp" + + /> + + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="center" + android:padding="16dp" + > + + <!-- 同意按钮 --> + <Button + android:id="@+id/btnConfirm" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="我在想想" + android:textColor="@android:color/white" + android:backgroundTint="#000000" + android:gravity="center" /> + + + <!-- 不同意按钮 --> + <Button + android:id="@+id/btnCancel" + android:layout_width="0dp" + android:layout_height="40dp" + android:layout_weight="1" + android:text="确定注销" + android:textColor="#999999" + android:background="@drawable/border_button" + android:gravity="center" + android:elevation="0dp" + android:drawableLeft="@null" + + /> <!-- 确保没有图标 --> + </LinearLayout> + + +</LinearLayout> diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml index a0ccc5f..2029cc5 100644 --- a/app/src/main/res/layout/activity_setting.xml +++ b/app/src/main/res/layout/activity_setting.xml @@ -34,6 +34,23 @@ </androidx.appcompat.widget.Toolbar> + <LinearLayout + android:id="@+id/account_close" + android:layout_width="match_parent" + android:layout_height="50dp" + android:gravity="center" + android:orientation="vertical" + android:background="#F9F9F9" + android:layout_marginTop="1dp" + > + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="5dp" + android:text="账号注销" + android:textColor="#000000" /> + </LinearLayout> <LinearLayout android:id="@+id/setting_exit" diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml index 21efdba..243ba37 100644 --- a/app/src/main/res/layout/fragment_dashboard.xml +++ b/app/src/main/res/layout/fragment_dashboard.xml @@ -68,6 +68,22 @@ </LinearLayout> <!-- 包裹统计卡片 --> + <LinearLayout + android:id="@+id/card_package_stats_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toBottomOf="@id/layout_date_picker" + > + <TextView + android:id="@+id/card_package_stats_title_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="本日收到包裹总数 ->" + android:layout_marginLeft="16dp" + > + + </TextView> + </LinearLayout> <androidx.cardview.widget.CardView android:id="@+id/card_package_stats" android:layout_width="match_parent" @@ -75,7 +91,7 @@ android:layout_margin="16dp" app:cardCornerRadius="8dp" app:cardElevation="4dp" - app:layout_constraintTop_toBottomOf="@id/layout_date_picker"> + app:layout_constraintTop_toBottomOf="@id/card_package_stats_title"> <LinearLayout android:layout_width="match_parent" @@ -119,6 +135,7 @@ </LinearLayout> </androidx.cardview.widget.CardView> + <!-- 年度统计布局 --> <include android:id="@+id/layout_year_stats" @@ -136,27 +153,68 @@ app:layout_constraintTop_toBottomOf="@id/layout_year_stats" app:layout_constraintBottom_toBottomOf="parent"> - <ViewFlipper - android:id="@+id/view_flipper_stats" + <LinearLayout android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <!-- 日视图 --> - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/recycler_packages" + android:layout_height="wrap_content" + android:orientation="vertical"> + <LinearLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:clipToPadding="false" - android:paddingBottom="16dp" /> + android:layout_height="wrap_content"> + <ViewFlipper + android:id="@+id/view_flipper_stats" + android:layout_width="match_parent" + android:layout_height="match_parent"> - <!-- 周视图 --> - <include - android:id="@+id/layout_week_stats" - layout="@layout/layout_week_stats" + <!-- 日视图 --> + <LinearLayout + android:id="@+id/recycler_packages_11" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + > + <LinearLayout + android:id="@+id/layout_year_stats_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toBottomOf="@id/card_package_stats" + > + <TextView + android:id="@+id/layout_year_stats_title_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="包裹取件码记录 ->" + android:layout_margin="16dp" + > + + </TextView> + </LinearLayout> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/recycler_packages" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:clipToPadding="false" + android:paddingBottom="16dp" /> + + </LinearLayout> + + + + <!-- 周视图 --> + <include + android:id="@+id/layout_week_stats" + layout="@layout/layout_week_stats" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + </ViewFlipper> + </LinearLayout> + <LinearLayout android:layout_width="match_parent" - android:layout_height="wrap_content" /> + android:layout_height="80dp" /> - </ViewFlipper> +</LinearLayout> + </androidx.core.widget.NestedScrollView> <!-- 🔹 遮罩层 --> diff --git a/app/src/main/res/layout/fragment_dashboard0411.xml b/app/src/main/res/layout/fragment_dashboard0411.xml new file mode 100644 index 0000000..e60aca7 --- /dev/null +++ b/app/src/main/res/layout/fragment_dashboard0411.xml @@ -0,0 +1,262 @@ +<?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" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".ui.dashboard.DashboardFragment"> + + <!-- 时间范围选择器 --> + <com.google.android.material.tabs.TabLayout + android:id="@+id/tab_date_range" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent"> + + <com.google.android.material.tabs.TabItem + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="天" /> + + <com.google.android.material.tabs.TabItem + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="周" /> + + <com.google.android.material.tabs.TabItem + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="月" /> + + <com.google.android.material.tabs.TabItem + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="年" /> + </com.google.android.material.tabs.TabLayout> + + <!-- 日期选择器 --> + <LinearLayout + android:id="@+id/layout_date_picker" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:padding="16dp" + app:layout_constraintTop_toBottomOf="@id/tab_date_range"> + + <ImageButton + android:id="@+id/btn_previous_date" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground" + android:src="@android:drawable/ic_media_previous" /> + + <TextView + android:id="@+id/text_current_date" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center" + android:textSize="16sp" + tools:text="2025年1月14日" /> + + <ImageButton + android:id="@+id/btn_next_date" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground" + android:src="@android:drawable/ic_media_next" /> + </LinearLayout> + + <!-- 包裹统计卡片 --> + <LinearLayout + android:id="@+id/card_package_stats_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toBottomOf="@id/layout_date_picker" + > + <TextView + android:id="@+id/card_package_stats_title_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="本日收到包裹总数 ->" + android:layout_marginLeft="16dp" + > + + </TextView> + </LinearLayout> + <androidx.cardview.widget.CardView + android:id="@+id/card_package_stats" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="16dp" + app:cardCornerRadius="8dp" + app:cardElevation="4dp" + app:layout_constraintTop_toBottomOf="@id/card_package_stats_title"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:padding="16dp" + android:weightSum="3"> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center"> + + <ImageView + android:layout_width="48dp" + android:layout_height="48dp" + android:src="@drawable/resource_package" /> + </LinearLayout> + + <Space + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" /> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center"> + + <TextView + android:id="@+id/text_package_count" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="24sp" + android:textStyle="bold" + tools:text="4个" /> + </LinearLayout> + + </LinearLayout> + </androidx.cardview.widget.CardView> + + <LinearLayout + android:id="@+id/layout_year_stats_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toBottomOf="@id/card_package_stats" + > + <TextView + android:id="@+id/layout_year_stats_title_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="包裹取件码记录 ->" + android:layout_margin="16dp" + > + + </TextView> + </LinearLayout> + <!-- 年度统计布局 --> + <include + android:id="@+id/layout_year_stats" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" + app:layout_constraintTop_toBottomOf="@id/layout_year_stats_title" + layout="@layout/layout_year_stats" /> + + <!-- 包裹列表和统计图表 --> + <androidx.core.widget.NestedScrollView + android:layout_width="match_parent" + android:layout_height="0dp" + android:fillViewport="true" + app:layout_constraintTop_toBottomOf="@id/layout_year_stats" + app:layout_constraintBottom_toBottomOf="parent"> + + <ViewFlipper + android:id="@+id/view_flipper_stats" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <!-- 日视图 --> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/recycler_packages" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:clipToPadding="false" + android:paddingBottom="16dp" /> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="80dp"> + + </LinearLayout> + </LinearLayout> + + <!-- 周视图 --> + <include + android:id="@+id/layout_week_stats" + layout="@layout/layout_week_stats" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + + + </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/item_package_dashboard.xml b/app/src/main/res/layout/item_package_dashboard.xml index fbb34f9..f297510 100644 --- a/app/src/main/res/layout/item_package_dashboard.xml +++ b/app/src/main/res/layout/item_package_dashboard.xml @@ -31,7 +31,7 @@ <TextView android:id="@+id/text_courier_name" android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_height="25dp" android:textSize="16sp" android:textStyle="bold" tools:text="某快递" /> @@ -42,7 +42,7 @@ android:layout_height="wrap_content" android:layout_marginTop="4dp" android:textColor="@android:color/darker_gray" - android:textSize="12sp" + android:textSize="8sp" tools:text="2025-01-14 10:30" /> </LinearLayout> @@ -54,7 +54,7 @@ <TextView android:id="@+id/text_tracking_number" android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_height="25dp" android:textColor="@android:color/darker_gray" android:layout_gravity="end" tools:text="14-6-7023" /> @@ -66,7 +66,7 @@ android:layout_marginTop="4dp" android:textColor="@android:color/darker_gray" android:layout_gravity="end" - android:textSize="12sp" + android:textSize="8sp" tools:text="2025-01-15 11:30" /> </LinearLayout> diff --git a/app/src/main/res/layout/layout_week_stats.xml b/app/src/main/res/layout/layout_week_stats.xml index 41d6b61..b7c0bcf 100644 --- a/app/src/main/res/layout/layout_week_stats.xml +++ b/app/src/main/res/layout/layout_week_stats.xml @@ -4,19 +4,37 @@ android:layout_height="wrap_content" android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + > + <TextView + android:id="@+id/bar_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="本周包裹物流公司分布 ->" + android:layout_margin="16dp" + > + + </TextView> + </LinearLayout> <!-- 柱状图容器,内边距16dp --> <androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="280dp" android:layout_marginHorizontal="16dp" android:layout_marginTop="8dp" - android:layout_marginBottom="16dp"> + android:layout_marginBottom="16dp" + android:padding="100dp" + > <com.github.mikephil.charting.charts.BarChart android:id="@+id/chart_daily_packages" android:layout_width="match_parent" - android:layout_height="match_parent" - android:padding="16dp" /> + android:layout_height="wrap_content" + android:padding="50dp" + + /> </androidx.cardview.widget.CardView> <!-- 热力图容器 --> @@ -41,6 +59,21 @@ </HorizontalScrollView> </androidx.cardview.widget.CardView> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + > + <TextView + android:id="@+id/pie_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="本周包裹物流公司分布 ->" + android:layout_margin="16dp" + > + </TextView> + </LinearLayout> + <!-- 饼图容器 --> <androidx.cardview.widget.CardView android:layout_width="match_parent" -- Gitblit v1.9.3