43	首页登录->首页登录
1.首页弹窗协议同意后,不能默认自动勾选,还需要用户手动勾选
2.退出登录后,再次登录需要手动勾选与用户协议(目前是默认勾选了)
44 首页登录->邀请码
邀请码默认填入“邀请码(选填)
47 数据统计->饼状图数据分类统计问题
1、只统计快递 无需统计还款其他分类
2、图形上下间隔过大"
48 数据统计 天、周、月、年
1.数据统计只统计快递类的,其他分类不需要统计展示,例如取件码记录
2.包括周、月、年的统计环状图,只需要统计快递分类的
已修改8个文件
已添加2个文件
241 ■■■■■ 文件已修改
app/build.gradle 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_login.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_phone_login.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/layout_week_stats.xml 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
keystore/sms-manager2.jks 补丁 | 查看 | 原始文档 | blame | 历史
keystore/sms-manager3.jks 补丁 | 查看 | 原始文档 | blame | 历史
app/build.gradle
@@ -15,8 +15,8 @@
    compileSdk 34
    defaultConfig {
        applicationId "com.cloudroam.smsManager"
//        applicationId "com.example.firstapp"
//        applicationId "com.cloudroam.smsManager"
        applicationId "com.example.firstapp"
//        applicationId "net.sourceforge.simcpux"
        minSdk 24
        targetSdk 34
@@ -28,7 +28,7 @@
    signingConfigs {
        release {
            storeFile file('../keystore/sms-manager2.jks')
            storeFile file('../keystore/sms-manager3.jks')
            storePassword 'Cloudroam!@#123'
            keyAlias 'sm'
            keyPassword 'Cloudroam!@#123'
app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt
@@ -86,16 +86,16 @@
    @Query("""
        SELECT * FROM code 
        WHERE substr(createTime, 1, 10) = 
              date(:date/1000, 'unixepoch', 'localtime') and pickup = 1
              date(:date/1000, 'unixepoch', 'localtime') and pickup = 1 and category='快递'
        ORDER BY createTime DESC
    """)
    fun getPackagesByDayUnread(date: Long): Flow<List<Code>>
    fun getPackagesByDayReaded(date: Long): Flow<List<Code>>
    @Query("""
        SELECT oneLevel as courierName, COUNT(*) as count 
        FROM code 
        WHERE strftime('%Y-%W', substr(createTime, 1, 10)) = 
              strftime('%Y-%W', datetime(:date/1000, 'unixepoch', 'localtime'))
              strftime('%Y-%W', datetime(:date/1000, 'unixepoch', 'localtime'))  and category='快递'
        GROUP BY oneLevel
        ORDER BY count DESC
    """)
@@ -135,7 +135,7 @@
        SELECT oneLevel as courierName, COUNT(*) as count 
        FROM code 
        WHERE strftime('%Y-%m', substr(createTime, 1, 10)) = 
              strftime('%Y-%m', datetime(:date/1000, 'unixepoch', 'localtime'))
              strftime('%Y-%m', datetime(:date/1000, 'unixepoch', 'localtime')) and category='快递'
        GROUP BY oneLevel
        ORDER BY count DESC
    """)
@@ -145,7 +145,7 @@
        SELECT oneLevel as courierName, COUNT(*) as count 
        FROM code 
        WHERE strftime('%Y', substr(createTime, 1, 10)) = 
              strftime('%Y', datetime(:date/1000, 'unixepoch', 'localtime'))
              strftime('%Y', datetime(:date/1000, 'unixepoch', 'localtime')) and category='快递'
        GROUP BY oneLevel
        ORDER BY count DESC
    """)
@@ -340,4 +340,12 @@
    ORDER BY d.date_value ASC
""")
    fun getWeeklyStatsChart(startDateCur: String, endDateCur: String): Flow<List<DailyStat>>
    @Query("""
        SELECT COUNT(1)
        FROM code
        WHERE date(createTime) BETWEEN date(:startDateCur) AND date(:endDateCur) and category =:type
    """)
    fun getDateStatsByType(startDateCur: String, endDateCur: String,type: String): Flow<Long>
}
app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt
@@ -45,9 +45,9 @@
        }
    }
    fun getPackagesUnread(date: Long, dateType: String): Flow<List<Code>> {
    fun getPackagesReaded(date: Long, dateType: String): Flow<List<Code>> {
        return when (dateType) {
            "DAY" -> codeDao.getPackagesByDayUnread(date)
            "DAY" -> codeDao.getPackagesByDayReaded(date)
            "WEEK" -> codeDao.getPackagesByWeek(date)
            else -> codeDao.getPackagesByDay(date)
        }
@@ -101,5 +101,6 @@
    fun getCurrentWeekStats2(startDateCur: String, endDateCur: String) = codeDao.getCurrentWeekStats2(startDateCur,endDateCur)
    fun getWeeklyStatsChart(startDateCur: String, endDateCur: String): Flow<List<DailyStat>> = codeDao.getWeeklyStatsChart(startDateCur,endDateCur)
    fun getDateStatsByType(startDateCur: String, endDateCur: String, type: String) = codeDao.getDateStatsByType(startDateCur,endDateCur,type)
}
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt
@@ -122,6 +122,8 @@
        binding.tabDateRange.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {
                currentDate = Calendar.getInstance()
                currentDateType = when(tab?.position) {
                    0 -> DateType.DAY
                    1 -> DateType.WEEK
@@ -194,6 +196,81 @@
    }
    private fun updateDateDisplay() {
        val dateFormat = when (currentDateType) {
            DateType.DAY -> {
                // 获取当天的起始和结束时间
                val calendar = currentDate.clone() as Calendar
                // 设置为当天的 00:00:00
                calendar.set(Calendar.HOUR_OF_DAY, 0)
                calendar.set(Calendar.MINUTE, 0)
                calendar.set(Calendar.SECOND, 0)
                calendar.set(Calendar.MILLISECOND, 0)
                startDateCur = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(calendar.time)
                // 设置为当天的 23:59:59
                calendar.set(Calendar.HOUR_OF_DAY, 23)
                calendar.set(Calendar.MINUTE, 59)
                calendar.set(Calendar.SECOND, 59)
                calendar.set(Calendar.MILLISECOND, 999)
                endDateCur = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(calendar.time)
                // 返回当天的日期格式
                SimpleDateFormat("yyyy年MM月dd日", Locale.getDefault()).format(currentDate.time)
            }
            DateType.WEEK -> {
                // 获取本周的起始和结束日期
                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 -> {
                // 获取本月的起始和结束日期
                val calendar = currentDate.clone() as Calendar
                calendar.set(Calendar.DAY_OF_MONTH, 1)
                startDateCur = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(calendar.time)
                calendar.add(Calendar.MONTH, 1)
                calendar.set(Calendar.DAY_OF_MONTH, 0)
                endDateCur = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(calendar.time)
                "yyyy年MM月"
            }
            DateType.YEAR -> {
                // 获取当前年的起始和结束日期
                val calendar = currentDate.clone() as Calendar
                // 设置为当前年份的 1 月 1 日
                calendar.set(Calendar.MONTH, Calendar.JANUARY)
                calendar.set(Calendar.DAY_OF_MONTH, 1)
                startDateCur = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(calendar.time)
                // 设置为当前年份的 12 月 31 日
                calendar.set(Calendar.MONTH, Calendar.DECEMBER)
                calendar.set(Calendar.DAY_OF_MONTH, 31)
                endDateCur = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(calendar.time)
                "yyyy年"
            }
        }
        // 更新界面显示
        if (currentDateType == DateType.WEEK) {
            binding.textCurrentDate.text = dateFormat
        } else {
            binding.textCurrentDate.text = SimpleDateFormat(dateFormat, Locale.getDefault())
                .format(currentDate.time)
        }
    }
    private fun updateDateDisplay_bak() {
        val dateFormat = when (currentDateType) {
            DateType.DAY -> "yyyy年MM月dd日"
            DateType.WEEK -> {
@@ -520,7 +597,116 @@
        return arrayOf("周一", "周二", "周三", "周四", "周五", "周六", "周日")
    }
    private fun loadPackages() {
    private fun loadPackages(){
//            根据日、周、月、年 获取统计数字
        when (currentDateType) {
            DateType.DAY -> {
                viewModel.getCurrentDayStatsByType(startDateCur,endDateCur,"快递") .observe(viewLifecycleOwner) { stats ->
                    binding.textPackageCount.text = "${stats}个"
                }
                // 获取取件记录
                viewModel.getPackagesReaded(currentDate.timeInMillis,
                    currentDateType.name)
                    .observe(viewLifecycleOwner) { unpackages->
                        // 只读取未取件的包裹
                        packageAdapter.updatePackages(unpackages)
                    }
            }
            DateType.WEEK -> {
                viewModel.getCurrentDayStatsByType(startDateCur,endDateCur,"快递") .observe(viewLifecycleOwner) { stats ->
                    binding.textPackageCount.text = "${stats}个"
                }
            }
            DateType.MONTH -> {
                viewModel.getCurrentDayStatsByType(startDateCur,endDateCur,"快递") .observe(viewLifecycleOwner) { stats ->
                    binding.textPackageCount.text = "${stats}个"
                }
            }
            DateType.YEAR -> {
                viewModel.getCurrentDayStatsByType(startDateCur,endDateCur,"快递") .observe(viewLifecycleOwner) { stats ->
                    binding.layoutYearStats.textTotalPackages.text = "${stats}个"
                }
            }
        }
    }
    private fun loadPackages_bak2(){
        val formatter = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
//            根据日、周、月、年 获取统计数字
        when (currentDateType) {
            DateType.DAY -> {
                val today = Calendar.getInstance()
                val tmpCurDateStart = formatter.format(currentDate.time)
                val tmpCurDateEnd = formatter.format(currentDate.time)
                viewModel.getCurrentDayStatsByType(tmpCurDateStart,tmpCurDateEnd,"快递") .observe(viewLifecycleOwner) { stats ->
                    binding.textPackageCount.text = "${stats}个"
                }
                // 获取本周统计
                viewModel.getPackagesReaded(currentDate.timeInMillis,
                    currentDateType.name)
                    .observe(viewLifecycleOwner) { unpackages->
                        // 只读取未取件的包裹
                        packageAdapter.updatePackages(unpackages)
                    }
            }
            DateType.WEEK -> {
                val today = Calendar.getInstance()
                // 获取本周的周一(第一天)
                today.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
                val firstDayOfWeek = formatter.format(today.time)
                // 获取本周的周日(最后一天)
                today.add(Calendar.DATE, 6)  // 加6天
                val lastDayOfWeek = formatter.format(today.time)
                viewModel.getCurrentDayStatsByType(firstDayOfWeek,lastDayOfWeek,"快递") .observe(viewLifecycleOwner) { stats ->
                    binding.textPackageCount.text = "${stats}个"
                }
            }
            DateType.MONTH -> {
                val today = Calendar.getInstance()
                today.set(Calendar.DAY_OF_MONTH, 1)  // 设置为本月第一天
                val firstDayOfMonth = formatter.format(today.time)
                today.add(Calendar.MONTH, 1)  // 移动到下个月
                today.set(Calendar.DAY_OF_MONTH, 0)  // 设置为下个月的最后一天
                val lastDayOfMonth = formatter.format(today.time)
                viewModel.getCurrentDayStatsByType(firstDayOfMonth,lastDayOfMonth,"快递") .observe(viewLifecycleOwner) { stats ->
                    binding.textPackageCount.text = "${stats}个"
                }
            }
            DateType.YEAR -> {
                val today = Calendar.getInstance()
                today.set(Calendar.MONTH, Calendar.JANUARY)  // 设置为第一月
                today.set(Calendar.DAY_OF_MONTH, 1)  // 设置为第一天
                val firstDayOfYear = formatter.format(today.time)
                today.add(Calendar.YEAR, 1)  // 移动到下一年
                today.set(Calendar.MONTH, Calendar.DECEMBER)  // 设置为最后一月
                today.set(Calendar.DAY_OF_MONTH, 31)  // 设置为最后一天
                val lastDayOfYear = formatter.format(today.time)
                viewModel.getCurrentDayStatsByType(firstDayOfYear,lastDayOfYear,"快递") .observe(viewLifecycleOwner) { stats ->
//                    binding.textPackageCount.text = "${stats}个"
                    binding.layoutYearStats.textTotalPackages.text = "${stats}个"
                }
            }
        }
    }
    private fun loadPackages_bak() {
        viewModel.getPackages(
            currentDate.timeInMillis,
            currentDateType.name
@@ -530,7 +716,7 @@
                    binding.textPackageCount.text = "${packages.size}个"
                    // 获取本周统计
                    viewModel.getPackagesUnread(currentDate.timeInMillis,
                    viewModel.getPackagesReaded(currentDate.timeInMillis,
                        currentDateType.name)
                        .observe(viewLifecycleOwner) { unpackages->
                            // 只读取未取件的包裹
@@ -708,7 +894,7 @@
            if (stats.isEmpty()) return@observe
            
            // 更新年度包裹总数
            binding.layoutYearStats.textTotalPackages.text = "${stats.sumOf { it.count }}个"
//            binding.layoutYearStats.textTotalPackages.text = "${stats.sumOf { it.count }}个"
            
            // 更新平均每天包裹数
            val avgDaily = stats.sumOf { it.count }.toFloat() / 365
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt
@@ -21,8 +21,8 @@
    fun getPackages(date: Long, dateType: String) =
        repository.getPackages(date, dateType).asLiveData()
    fun getPackagesUnread(date: Long, dateType: String) =
        repository.getPackagesUnread(date, dateType).asLiveData()
    fun getPackagesReaded(date: Long, dateType: String) =
        repository.getPackagesReaded(date, dateType).asLiveData()
    fun getCourierStats(date: Long, dateType: String) = 
        repository.getCourierStats(date, dateType).asLiveData()
@@ -52,4 +52,5 @@
    fun getCurrentWeekStats2(startDateCur: String, endDateCur: String) = repository.getCurrentWeekStats2(startDateCur,endDateCur).asLiveData()
    fun getWeeklyStatsChart(startDateCur: String, endDateCur: String) =  repository.getWeeklyStatsChart(startDateCur, endDateCur).asLiveData()
    fun getCurrentDayStatsByType(startDateCur: String, endDateCur: String,type: String) =repository.getDateStatsByType(startDateCur, endDateCur,type).asLiveData()
}
app/src/main/res/layout/activity_login.xml
@@ -54,7 +54,7 @@
            android:id="@+id/cbAgreement"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true" />
            android:checked="false" />
        <TextView
            android:layout_width="wrap_content"
app/src/main/res/layout/activity_phone_login.xml
@@ -96,7 +96,7 @@
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@null"
                android:hint="邀请码"
                android:hint="邀请码(选填)"
                android:inputType="textVisiblePassword"
                android:maxLength="11"
                android:textSize="16sp"
app/src/main/res/layout/layout_week_stats.xml
@@ -78,15 +78,16 @@
    <androidx.cardview.widget.CardView
        android:id="@+id/chart_courier_card_view"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:layout_marginHorizontal="16dp"
        android:layout_marginBottom="16dp">
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="0dp"
        android:layout_marginBottom="0dp">
        <com.github.mikephil.charting.charts.PieChart
            android:id="@+id/chart_courier_distribution"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="16dp" />
            android:layout_height="wrap_content"
            android:minHeight="300dp"
            android:padding="0dp" />
    </androidx.cardview.widget.CardView>
</LinearLayout>
keystore/sms-manager2.jks
Binary files differ
keystore/sms-manager3.jks
Binary files differ