cloudroam
2025-03-04 897ffe5e29ab022d75ad948ecf894e0a3ed3b2f5
fix: 1
已修改8个文件
239 ■■■■■ 文件已修改
app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/model/CourierStat.kt 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/model/DailyStat.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt 102 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/fragment_dashboard.xml 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/layout_week_stats.xml 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt
@@ -73,29 +73,31 @@
    fun getPackagesByDay(date: Long): Flow<List<Code>>
    @Query("""
        SELECT * FROM code
        WHERE strftime('%Y-%W', substr(createtime, 1, 10)) =
              strftime('%Y-%W', datetime(:date/1000, 'unixepoch', 'localtime'))
        ORDER BY createtime DESC
    """)
    fun getPackagesByWeek(date: Long): Flow<List<Code>>
    @Query("""
        SELECT category as courierName, COUNT(*) as count
        SELECT type as courierName, COUNT(*) as count
        FROM code 
        WHERE strftime('%Y-%W', substr(createtime, 1, 10)) = 
              strftime('%Y-%W', datetime(:date/1000, 'unixepoch', 'localtime'))
        GROUP BY category
        GROUP BY type
        ORDER BY count DESC
    """)
    fun getCourierStatsByWeek(date: Long): Flow<List<CourierStat>>
    @Query("""
        SELECT substr(createtime, 1, 10) as date,
               COUNT(*) as count
        SELECT strftime('%W', createtime) as date,
               COUNT(*) as count,
               MIN(createtime) as week_start
        FROM code 
        WHERE strftime('%Y-%W', substr(createtime, 1, 10)) =
              strftime('%Y-%W', datetime(:date/1000, 'unixepoch', 'localtime'))
        GROUP BY substr(createtime, 1, 10)
        WHERE strftime('%Y', createtime) = strftime('%Y', 'now')
        GROUP BY strftime('%W', createtime)
        ORDER BY week_start ASC
    """)
    fun getDailyStatsByWeek(date: Long): Flow<List<DailyStat>>
    fun getDailyStatsByWeek(): Flow<List<DailyStat>>
    @Query("""
        SELECT * FROM code
        WHERE substr(createtime, 1, 10) =
              date(:date/1000, 'unixepoch', 'localtime')
        ORDER BY createtime DESC
    """)
     fun getPackagesByWeek(date: Long): Flow<List<Code>>
}
app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt
@@ -43,7 +43,7 @@
    fun getCourierStats(date: Long) = codeDao.getCourierStatsByWeek(date)
    fun getDailyStats(date: Long) = codeDao.getDailyStatsByWeek(date)
    fun getDailyStats() = codeDao.getDailyStatsByWeek()
    @WorkerThread
app/src/main/java/com/example/firstapp/model/CourierStat.kt
@@ -4,10 +4,9 @@
@DatabaseView(
    """
    SELECT category as courierName, COUNT(*) as count
    SELECT type as courierName, COUNT(*) as count
    FROM Code 
    WHERE substr(createtime, 1, 10) = date('now')
    GROUP BY category
    GROUP BY type
    """
)
data class CourierStat(
app/src/main/java/com/example/firstapp/model/DailyStat.kt
@@ -7,11 +7,11 @@
    SELECT substr(createtime, 1, 10) as date, 
           COUNT(*) as count 
    FROM code 
    WHERE substr(createtime, 1, 10) = date('now')
    GROUP BY substr(createtime, 1, 10)
    """
)
data class DailyStat(
    val date: String,
    val count: Int
    val count: Int,
    val week_start: String? = null
)
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt
@@ -20,8 +20,10 @@
import com.github.mikephil.charting.components.XAxis
import com.github.mikephil.charting.data.*
import com.github.mikephil.charting.formatter.IndexAxisValueFormatter
import com.github.mikephil.charting.formatter.ValueFormatter
import java.util.*
import java.text.SimpleDateFormat
import android.util.Log
class DashboardFragment : Fragment() {
@@ -132,53 +134,115 @@
        setupPieChart()
    }
    private fun setupBarChart() {
        // 配置柱状图
        barChart.apply {
            description.isEnabled = false
            setDrawGridBackground(false)
            legend.isEnabled = false
            // 增大图表高度
            minimumHeight = (resources.displayMetrics.density * 300).toInt()
            // X轴设置
            xAxis.apply {
                position = XAxis.XAxisPosition.BOTTOM
                setDrawGridLines(false)
                valueFormatter = IndexAxisValueFormatter(getDayLabels())
                granularity = 1f
                labelRotationAngle = -45f
                textSize = 10f
            }
            // Y轴设置
            axisLeft.apply {
                setDrawGridLines(true)
                axisMinimum = 0f
                granularity = 1f
                valueFormatter = object : ValueFormatter() {
                    override fun getFormattedValue(value: Float): String {
                        return value.toInt().toString()
                    }
                }
            }
            axisRight.isEnabled = false
            // 设置图表交互
            setTouchEnabled(true)
            isDragEnabled = true
            setScaleEnabled(true)
        }
        updateBarChartData()
    }
    private fun updateBarChartData() {
        viewModel.getDailyStats(currentDate.timeInMillis).observe(viewLifecycleOwner) { stats ->
        viewModel.getDailyStats().observe(viewLifecycleOwner) { stats ->
            // 添加调试日志
            Log.d("DashboardFragment", "Stats size: ${stats.size}")
            stats.forEach { stat ->
                Log.d("DashboardFragment", "Week: ${stat.date}, Count: ${stat.count}, Start: ${stat.week_start}")
            }
            if (stats.isEmpty()) {
                Log.d("DashboardFragment", "No data found")
                return@observe
            }
            val entries = stats.mapIndexed { index, stat ->
                BarEntry(index.toFloat(), stat.count.toFloat())
            }
            val dataSet = BarDataSet(entries, "包裹数量")
            dataSet.color = resources.getColor(R.color.purple_500)
            dataSet.valueTextSize = 12f
            barChart.data = BarData(dataSet)
            val barData = BarData(dataSet)
            barChart.data = barData
            // 设置X轴标签
            barChart.xAxis.apply {
                valueFormatter = object : ValueFormatter() {
                    override fun getFormattedValue(value: Float): String {
                        val position = value.toInt()
                        if (position >= 0 && position < stats.size) {
                            val weekNum = stats[position].date.toIntOrNull() ?: 0
                            // 获取月份信息
                            val monthDay = stats[position].week_start?.let {
                                SimpleDateFormat("MM-dd", Locale.getDefault()).format(
                                    SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).parse(it)
                                )
                            } ?: ""
                            return "${monthDay}\n第${weekNum}周"
                        }
                        return ""
                    }
                }
                labelCount = stats.size
            }
            barChart.notifyDataSetChanged()
            barChart.invalidate()
        }
    }
    private fun setupPieChart() {
        // 配置饼图
        pieChart.apply {
            description.isEnabled = false
            setUsePercentValues(true)
            setUsePercentValues(false) // 改为显示实际数量
            setDrawEntryLabels(false)
            legend.isEnabled = true
            legend.verticalAlignment = Legend.LegendVerticalAlignment.CENTER
            legend.horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT
            legend.orientation = Legend.LegendOrientation.VERTICAL
            // 增大饼图尺寸
            setExtraOffsets(20f, 10f, 80f, 10f)
            minimumHeight = (resources.displayMetrics.density * 400).toInt() // 设置最小高度
            // 配置图例
            legend.apply {
                isEnabled = true
                verticalAlignment = Legend.LegendVerticalAlignment.CENTER
                horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT
                orientation = Legend.LegendOrientation.VERTICAL
                setDrawInside(false)
                xEntrySpace = 7f
                yEntrySpace = 0f
                yOffset = 0f
                textSize = 12f // 增大图例文字大小
            }
        }
        updatePieChartData()
@@ -186,16 +250,26 @@
    private fun updatePieChartData() {
        viewModel.getCourierStats(currentDate.timeInMillis).observe(viewLifecycleOwner) { stats ->
            val entries = stats.map { stat ->
                PieEntry(stat.count.toFloat(), stat.courierName)
                PieEntry(stat.count.toFloat(), "${stat.courierName}(${stat.count})")
            }
            val dataSet = PieDataSet(entries, "快递公司分布")
            dataSet.colors = listOf(
                resources.getColor(R.color.purple_500),
                resources.getColor(R.color.teal_200)
                resources.getColor(R.color.teal_200),
                resources.getColor(R.color.purple_200),
                resources.getColor(R.color.teal_700)
            )
            dataSet.valueTextSize = 14f // 增大数值文字大小
            pieChart.data = PieData(dataSet)
            val pieData = PieData(dataSet)
            pieData.setValueFormatter(object : ValueFormatter() {
                override fun getFormattedValue(value: Float): String {
                    return value.toInt().toString()
                }
            })
            pieChart.data = pieData
            pieChart.invalidate()
        }
    }
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt
@@ -23,7 +23,7 @@
    fun getCourierStats(date: Long) = repository.getCourierStats(date).asLiveData()
    fun getDailyStats(date: Long) = repository.getDailyStats(date).asLiveData()
    fun getDailyStats() = repository.getDailyStats().asLiveData()
    fun insert(code: Code) = viewModelScope.launch {
        repository.insert(code)
app/src/main/res/layout/fragment_dashboard.xml
@@ -81,49 +81,57 @@
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:padding="16dp">
            android:padding="16dp"
            android:gravity="center_vertical">
            <ImageView
                android:layout_width="0dp"
                android:layout_width="48dp"
                android:layout_height="48dp"
                android:layout_weight="1"
                android:src="@drawable/resource_package" />
            <TextView
                android:id="@+id/text_package_count"
                android:layout_width="0dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginStart="16dp"
                android:layout_weight="1"
                android:textSize="24sp"
                android:textStyle="bold"
                tools:text="4个" />
        </LinearLayout>
    </androidx.cardview.widget.CardView>
    <!-- 包裹列表 -->
    <ViewFlipper
        android:id="@+id/view_flipper_stats"
    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/card_package_stats">
        android:layout_height="0dp"
        android:fillViewport="true"
        android:clipToPadding="false"
        app:layout_constraintTop_toBottomOf="@id/card_package_stats"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="56dp">
        <!-- 日视图 -->
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_packages"
        <ViewFlipper
            android:id="@+id/view_flipper_stats"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
            android:layout_height="wrap_content">
        <!-- 周视图 -->
        <include
            android:id="@+id/layout_week_stats"
            layout="@layout/layout_week_stats"
            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" />
        <!-- 月视图和年视图可以根据需要添加 -->
            <!-- 周视图 -->
            <include
                android:id="@+id/layout_week_stats"
                layout="@layout/layout_week_stats"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
    </ViewFlipper>
        </ViewFlipper>
    </androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
app/src/main/res/layout/layout_week_stats.xml
@@ -4,53 +4,25 @@
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <!-- 包裹总数统计卡片 -->
    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:padding="16dp">
            <ImageView
                android:layout_width="48dp"
                android:layout_height="48dp"
                android:src="@drawable/resource_package" />
            <TextView
                android:id="@+id/text_total_packages"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginStart="16dp"
                android:textSize="24sp"
                android:textStyle="bold"
                android:text="4个" />
        </LinearLayout>
    </androidx.cardview.widget.CardView>
    <!-- 每日包裹数量柱状图 -->
    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_height="280dp"
        android:layout_marginHorizontal="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="16dp">
        <com.github.mikephil.charting.charts.BarChart
            android:id="@+id/chart_daily_packages"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="8dp" />
            android:padding="16dp" />
    </androidx.cardview.widget.CardView>
    <!-- 快递公司占比饼图 -->
    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_height="280dp"
        android:layout_marginHorizontal="16dp"
        android:layout_marginBottom="16dp">
@@ -58,6 +30,6 @@
            android:id="@+id/chart_courier_distribution"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="8dp" />
            android:padding="16dp" />
    </androidx.cardview.widget.CardView>
</LinearLayout>