package com.example.firstapp.ui.dashboard 
 | 
  
 | 
import com.example.firstapp.R 
 | 
import android.os.Bundle 
 | 
import android.view.LayoutInflater 
 | 
import android.view.View 
 | 
import android.view.ViewGroup 
 | 
import android.widget.TextView 
 | 
import androidx.fragment.app.Fragment 
 | 
import androidx.fragment.app.viewModels 
 | 
import com.example.firstapp.databinding.FragmentDashboardBinding 
 | 
import com.google.android.material.tabs.TabLayout 
 | 
import androidx.recyclerview.widget.LinearLayoutManager 
 | 
import com.example.firstapp.adapter.PackageAdapter 
 | 
import com.github.mikephil.charting.charts.BarChart 
 | 
import com.github.mikephil.charting.charts.PieChart 
 | 
import com.github.mikephil.charting.components.Legend 
 | 
import com.github.mikephil.charting.components.XAxis 
 | 
import com.github.mikephil.charting.data.* 
 | 
import com.github.mikephil.charting.formatter.ValueFormatter 
 | 
import java.util.* 
 | 
import java.text.SimpleDateFormat 
 | 
import android.graphics.Color 
 | 
import android.widget.GridLayout 
 | 
import android.widget.Toast 
 | 
import androidx.cardview.widget.CardView 
 | 
import androidx.lifecycle.lifecycleScope 
 | 
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 kotlinx.coroutines.launch 
 | 
  
 | 
class DashboardFragment : Fragment() { 
 | 
  
 | 
    private var _binding: FragmentDashboardBinding? = null 
 | 
    private val binding get() = _binding!! 
 | 
    private val packageAdapter = PackageAdapter() 
 | 
    private var currentDate = Calendar.getInstance() 
 | 
    private var currentDateType = DateType.DAY 
 | 
    private lateinit var barChart: BarChart 
 | 
    private lateinit var pieChart: PieChart 
 | 
    private lateinit var chartCourierDistriBution:CardView 
 | 
    private lateinit var heatmapView: View 
 | 
    private var currentUserInfo: UserInfo? = null // 确保使用你的实际数据类 
 | 
  
 | 
    private var startDateCur:String = "" 
 | 
    private var endDateCur:String = "" 
 | 
    private lateinit var bar_title:TextView 
 | 
    private lateinit var pie_title:TextView 
 | 
  
 | 
  
 | 
    enum class DateType { 
 | 
        DAY, WEEK, MONTH, YEAR 
 | 
    } 
 | 
    private val viewModel: DashboardViewModel by viewModels() 
 | 
  
 | 
    override fun onCreateView( 
 | 
        inflater: LayoutInflater, 
 | 
        container: ViewGroup?, 
 | 
        savedInstanceState: Bundle? 
 | 
    ): View { 
 | 
        _binding = FragmentDashboardBinding.inflate(inflater, container, false) 
 | 
        return binding.root 
 | 
    } 
 | 
  
 | 
    override fun onResume() { 
 | 
        super.onResume() 
 | 
        // 重新加载用户信息 
 | 
        loadUserInfo() 
 | 
    } 
 | 
  
 | 
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 
 | 
        super.onViewCreated(view, savedInstanceState) 
 | 
  
 | 
        //渲染包裹列表 
 | 
        setupRecyclerView() 
 | 
        //初始化tab内容和数据 
 | 
        setupTabLayout() 
 | 
        //日期调整 
 | 
        setupDatePicker() 
 | 
        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 { 
 | 
            layoutManager = LinearLayoutManager(context) 
 | 
            adapter = packageAdapter 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private fun setupTabLayout() { 
 | 
        val weekStatsView = binding.layoutWeekStats.root 
 | 
        bar_title = weekStatsView.findViewById(R.id.bar_title) 
 | 
        pie_title = weekStatsView.findViewById(R.id.pie_title) 
 | 
  
 | 
        binding.tabDateRange.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { 
 | 
            override fun onTabSelected(tab: TabLayout.Tab?) { 
 | 
                currentDateType = when(tab?.position) { 
 | 
                    0 -> DateType.DAY 
 | 
                    1 -> DateType.WEEK 
 | 
                    2 -> DateType.MONTH 
 | 
                    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() 
 | 
            } 
 | 
            override fun onTabUnselected(tab: TabLayout.Tab?) {} 
 | 
            override fun onTabReselected(tab: TabLayout.Tab?) {} 
 | 
        }) 
 | 
    } 
 | 
  
 | 
    private fun setupDatePicker() { 
 | 
        binding.btnPreviousDate.setOnClickListener { 
 | 
            adjustDate(-1) 
 | 
        } 
 | 
        binding.btnNextDate.setOnClickListener { 
 | 
            adjustDate(1) 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private fun adjustDate(amount: Int) { 
 | 
        when (currentDateType) { 
 | 
            DateType.DAY -> currentDate.add(Calendar.DAY_OF_MONTH, amount) 
 | 
            DateType.WEEK -> currentDate.add(Calendar.WEEK_OF_YEAR, amount) 
 | 
            DateType.MONTH -> currentDate.add(Calendar.MONTH, amount) 
 | 
            DateType.YEAR -> currentDate.add(Calendar.YEAR, amount) 
 | 
        } 
 | 
        updateDateDisplay() 
 | 
        updateCharts() 
 | 
        loadPackages() 
 | 
    } 
 | 
  
 | 
    private fun updateDateDisplay() { 
 | 
        val dateFormat = when (currentDateType) { 
 | 
            DateType.DAY -> "yyyy年MM月dd日" 
 | 
            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 -> "yyyy年MM月" 
 | 
            DateType.YEAR -> "yyyy年" 
 | 
        } 
 | 
         
 | 
        if (currentDateType == DateType.WEEK) { 
 | 
            binding.textCurrentDate.text = dateFormat 
 | 
        } else { 
 | 
            binding.textCurrentDate.text = SimpleDateFormat(dateFormat, Locale.getDefault()) 
 | 
                .format(currentDate.time) 
 | 
        } 
 | 
    } 
 | 
    private fun setupView(view: View) { 
 | 
  
 | 
        val weekStatsView = binding.layoutWeekStats.root 
 | 
        barChart = weekStatsView.findViewById(R.id.chart_daily_packages) 
 | 
        chartCourierDistriBution=weekStatsView.findViewById(R.id.chart_courier_card_view) 
 | 
        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 
 | 
         
 | 
        setupBarChart() 
 | 
        setupPieChart() 
 | 
        setupHeatmap() 
 | 
        updateCharts() 
 | 
  
 | 
    } 
 | 
    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) 
 | 
                granularity = 1f 
 | 
                labelRotationAngle = 0f 
 | 
                textSize = 10f  //标签字体 
 | 
                setExtraLeftOffset(5f)  // 减少左侧留白 
 | 
                setExtraBottomOffset(15f) 
 | 
            } 
 | 
  
 | 
            // Y轴设置 
 | 
            axisLeft.apply { 
 | 
                setDrawGridLines(true) 
 | 
                axisMinimum = 0f 
 | 
                granularity = 1f 
 | 
                valueFormatter = object : ValueFormatter() { 
 | 
                    override fun getFormattedValue(value: Float): String { 
 | 
                        return if (value > 0) value.toInt().toString() else "" 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
            axisRight.isEnabled = false 
 | 
             
 | 
            // 设置图表交互 
 | 
            setTouchEnabled(true) 
 | 
            isDragEnabled = true 
 | 
            setScaleEnabled(true) 
 | 
             
 | 
            // 设置边距 
 | 
            setExtraOffsets(10f, 10f, 10f, 20f) 
 | 
        } 
 | 
  
 | 
  
 | 
         
 | 
        updateBarChartData() 
 | 
    } 
 | 
    private fun updateBarChartData() { 
 | 
        val statsFlow = when (currentDateType) { 
 | 
            DateType.WEEK -> { 
 | 
//                viewModel.getWeeklyStats(currentDate.timeInMillis, 6) 
 | 
                viewModel.getWeeklyStatsChart(startDateCur,endDateCur) 
 | 
            } 
 | 
            DateType.MONTH -> { 
 | 
                viewModel.getYearMonthlyStats(currentDate.timeInMillis) 
 | 
            } 
 | 
            else -> return 
 | 
        } 
 | 
  
 | 
        statsFlow.observe(viewLifecycleOwner) { stats -> 
 | 
            if (stats.isEmpty()) return@observe 
 | 
             
 | 
            val entries = stats.mapIndexed { index, stat -> 
 | 
                val entry = BarEntry(index.toFloat(), stat.count.toFloat()) 
 | 
                if (stat.count == 0) { 
 | 
                    entry.data = "hide_label" 
 | 
                } 
 | 
                entry 
 | 
            } 
 | 
  
 | 
            val dataSet = BarDataSet(entries, "包裹数量") 
 | 
            dataSet.apply { 
 | 
                color = resources.getColor(R.color.purple_500) 
 | 
                valueTextSize = 12f 
 | 
                valueFormatter = object : ValueFormatter() { 
 | 
                    override fun getFormattedValue(value: Float): String { 
 | 
                        return if (value > 0) value.toInt().toString() else "" 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
  
 | 
            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) { 
 | 
                            return when(currentDateType) { 
 | 
                                DateType.WEEK -> { 
 | 
                                    val weekStat = stats[position] 
 | 
                                    try { 
 | 
                                        // 解析日期字符串 
 | 
                                        val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()) 
 | 
                                        val date = sdf.parse(weekStat.date) 
 | 
                                        val calendar = Calendar.getInstance() 
 | 
                                        calendar.time = date 
 | 
                                         
 | 
                                        // 获取年份和周数 
 | 
                                        val weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR) 
 | 
                                        val year = calendar.get(Calendar.YEAR) 
 | 
                                         
 | 
                                        // 显示格式:第X周 
 | 
//                                        "第${weekOfYear}周" 
 | 
                                        "${weekOfYear}" 
 | 
                                    } catch (e: Exception) { 
 | 
                                        weekStat.date 
 | 
                                    } 
 | 
                                } 
 | 
//                                DateType.MONTH -> "${stats[position].date}月" 
 | 
                                DateType.MONTH -> { 
 | 
                                    stats[position].date.replaceFirst("^0+".toRegex(), "") 
 | 
                                } 
 | 
                                else -> "" 
 | 
                            } 
 | 
                        } 
 | 
                        return "" 
 | 
                    } 
 | 
                } 
 | 
                labelCount = stats.size 
 | 
                setAvoidFirstLastClipping(true) 
 | 
                labelRotationAngle = 0f 
 | 
                 
 | 
                // 增加标签间距 
 | 
//                setExtraBottomOffset(20f) 
 | 
                textSize = 11f  // 稍微调小字体 
 | 
            } 
 | 
             
 | 
            // 高亮显示 
 | 
            if (currentDateType == DateType.MONTH) { 
 | 
                val currentMonth = currentDate.get(Calendar.MONTH) 
 | 
                dataSet.setColors(List(stats.size) { index -> 
 | 
                    if (index == currentMonth) resources.getColor(R.color.purple_500) 
 | 
                    else resources.getColor(R.color.purple_200) 
 | 
                }) 
 | 
            } else if (currentDateType == DateType.WEEK) { 
 | 
                val highlightIndex = 3 // 当前周在第4个位置 
 | 
                dataSet.setColors(List(stats.size) { index -> 
 | 
                    if (index == highlightIndex) resources.getColor(R.color.purple_500) 
 | 
                    else resources.getColor(R.color.purple_200) 
 | 
                }) 
 | 
            } 
 | 
             
 | 
            // 刷新图表 
 | 
            barChart.notifyDataSetChanged() 
 | 
            barChart.invalidate() 
 | 
        } 
 | 
    } 
 | 
    private fun setupPieChart() { 
 | 
        pieChart.apply { 
 | 
            // 隐藏图表描述(右下角默认文字) 
 | 
            description.isEnabled = false 
 | 
            // 显示实际值而非百分比 
 | 
            setUsePercentValues(false) 
 | 
            // 隐藏饼图区块上的标签(如数值或名称) 
 | 
            setDrawEntryLabels(false) 
 | 
  
 | 
            // 设置饼图与容器的边距,参数顺序:左、上、右、下 
 | 
            // 右侧留出 80f 空间,可能为图例腾出位置 
 | 
            setExtraOffsets(20f, 20f, 20f, 20f) 
 | 
  
 | 
  
 | 
  
 | 
            // 配置图例 
 | 
            legend.apply { 
 | 
                isEnabled = true // 启用图例 
 | 
                verticalAlignment = Legend.LegendVerticalAlignment.CENTER // 垂直居中 
 | 
                horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT // 水平靠右对齐 
 | 
                orientation = Legend.LegendOrientation.VERTICAL // 图例项垂直排列 
 | 
                setDrawInside(false)  // 图例绘制在图表外部(而非覆盖在图上) 
 | 
                xEntrySpace = 10f  // 图例项水平间距 
 | 
                yEntrySpace = 5f  // 图例项垂直间距 
 | 
                yOffset = 0f      // 图例整体 Y 轴无偏移 
 | 
                textSize = 12f   // 图例文字大小 
 | 
            } 
 | 
  
 | 
            // 调整中心空白区域大小 
 | 
            holeRadius = 20f  // 中间空心圆的半径(占饼图比例) 
 | 
            transparentCircleRadius = 25f  // 透明圆圈的半径(可能用于边框效果) 
 | 
  
 | 
        } 
 | 
  
 | 
        updatePieChartData() 
 | 
    } 
 | 
    private fun updatePieChartData() { 
 | 
        viewModel.getCourierStats( 
 | 
            currentDate.timeInMillis, 
 | 
            currentDateType.name 
 | 
        ).observe(viewLifecycleOwner) { stats -> 
 | 
            val entries = stats.map { stat -> 
 | 
                PieEntry(stat.count.toFloat(), "${stat.courierName}(${stat.count})") 
 | 
            } 
 | 
  
 | 
            if (entries.isNotEmpty()) { 
 | 
                val dataSet = PieDataSet(entries, "快递公司分布") 
 | 
                dataSet.colors = listOf( 
 | 
                    resources.getColor(R.color.light_blue_600_1), 
 | 
                    resources.getColor(R.color.sunflower), 
 | 
                    resources.getColor(R.color.light_blue), 
 | 
                    resources.getColor(R.color.vermillion), 
 | 
                    resources.getColor(R.color.fish_belly_white), 
 | 
                    resources.getColor(R.color.light_green), 
 | 
                    resources.getColor(R.color.crimson), 
 | 
                    resources.getColor(R.color.sky_blue), 
 | 
                    resources.getColor(R.color.gold), 
 | 
                    resources.getColor(R.color.light_purple), 
 | 
                    resources.getColor(R.color.yellow), 
 | 
                    resources.getColor(R.color.canary_yellow), 
 | 
                    resources.getColor(R.color.red_purple), 
 | 
                    resources.getColor(R.color.light_cyan), 
 | 
                    resources.getColor(R.color.orange), 
 | 
                    resources.getColor(R.color.magenta), 
 | 
                    resources.getColor(R.color.light_purple_2), 
 | 
                    resources.getColor(R.color.bright_yellow), 
 | 
                    resources.getColor(R.color.emerald_green), 
 | 
                    resources.getColor(R.color.turmeric), 
 | 
                    resources.getColor(R.color.red_gold), 
 | 
                    resources.getColor(R.color.off_white), 
 | 
                    resources.getColor(R.color.tangerine), 
 | 
                    resources.getColor(R.color.aqua_blue), 
 | 
                    resources.getColor(R.color.frost), 
 | 
                    resources.getColor(R.color.wisteria), 
 | 
                    resources.getColor(R.color.cyan) 
 | 
                ) 
 | 
                dataSet.valueTextSize = 14f // 增大数值文字大小 
 | 
  
 | 
                val pieData = PieData(dataSet) 
 | 
                pieData.setValueFormatter(object : ValueFormatter() { 
 | 
                    override fun getFormattedValue(value: Float): String { 
 | 
                        return value.toInt().toString() 
 | 
                    } 
 | 
                }) 
 | 
  
 | 
                pieChart.data = pieData 
 | 
                pieChart.invalidate() 
 | 
  
 | 
                pieChart.visibility = View.VISIBLE  // 例如:隐藏 PieChart 
 | 
  
 | 
                pie_title.visibility = View.VISIBLE 
 | 
  
 | 
                chartCourierDistriBution.visibility =View.VISIBLE 
 | 
  
 | 
            } else { 
 | 
                // 如果 entries 为空,可以选择隐藏图表或设置一个默认显示 
 | 
                pieChart.visibility = View.GONE  // 例如:隐藏 PieChart 
 | 
  
 | 
                pie_title.visibility = View.GONE 
 | 
  
 | 
                chartCourierDistriBution.visibility =View.GONE 
 | 
  
 | 
            } 
 | 
  
 | 
  
 | 
//            val dataSet = PieDataSet(entries, "快递公司分布") 
 | 
//            dataSet.colors = listOf( 
 | 
//                resources.getColor(R.color.purple_500), 
 | 
//                resources.getColor(R.color.teal_200), 
 | 
//                resources.getColor(R.color.purple_200), 
 | 
//                resources.getColor(R.color.teal_700) 
 | 
//            ) 
 | 
//            dataSet.valueTextSize = 14f // 增大数值文字大小 
 | 
// 
 | 
//            val pieData = PieData(dataSet) 
 | 
//            pieData.setValueFormatter(object : ValueFormatter() { 
 | 
//                override fun getFormattedValue(value: Float): String { 
 | 
//                    return value.toInt().toString() 
 | 
//                } 
 | 
//            }) 
 | 
// 
 | 
//            pieChart.data = pieData 
 | 
//            pieChart.invalidate() 
 | 
        } 
 | 
    } 
 | 
    private fun getDayLabels(): Array<String> { 
 | 
        return arrayOf("周一", "周二", "周三", "周四", "周五", "周六", "周日") 
 | 
    } 
 | 
  
 | 
    private fun loadPackages() { 
 | 
        viewModel.getPackages( 
 | 
            currentDate.timeInMillis, 
 | 
            currentDateType.name 
 | 
        ).observe(viewLifecycleOwner) { packages -> 
 | 
            when (currentDateType) { 
 | 
                DateType.DAY -> { 
 | 
                    binding.textPackageCount.text = "${packages.size}个" 
 | 
  
 | 
                    // 获取本周统计 
 | 
                    viewModel.getPackagesUnread(currentDate.timeInMillis, 
 | 
                        currentDateType.name) 
 | 
                        .observe(viewLifecycleOwner) { unpackages-> 
 | 
                            // 只读取未取件的包裹 
 | 
                            packageAdapter.updatePackages(unpackages) 
 | 
                        } 
 | 
  
 | 
                } 
 | 
                DateType.WEEK -> { 
 | 
                    // 获取本周统计 
 | 
                    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 -> { 
 | 
                    // 获取本月统计 
 | 
                    viewModel.getMonthlyStats(currentDate.timeInMillis) 
 | 
                        .observe(viewLifecycleOwner) { stats -> 
 | 
                            val monthTotal = stats.sumOf { it.count } 
 | 
                            binding.textPackageCount.text = "${monthTotal}个" 
 | 
                        } 
 | 
                } 
 | 
                DateType.YEAR -> { 
 | 
                    // 获取本年统计 
 | 
                    viewModel.getCurrentYearStats(currentDate.timeInMillis) 
 | 
                        .observe(viewLifecycleOwner) { stats -> 
 | 
                            val yearTotal = stats.sumOf { it.count } 
 | 
                            binding.textPackageCount.text = "${yearTotal}个" 
 | 
                        } 
 | 
                } 
 | 
            } 
 | 
  
 | 
//            packageAdapter.updatePackages(packages) 
 | 
//            binding.textPackageCount.text = "${packages.size}个" 
 | 
        } 
 | 
    } 
 | 
    private fun setupHeatmap() { 
 | 
        heatmapView.visibility = View.GONE 
 | 
    } 
 | 
  
 | 
    private fun updateHeatmapData() { 
 | 
        viewModel.getYearlyHeatmap(currentDate.timeInMillis).observe(viewLifecycleOwner) { stats -> 
 | 
            if (stats.isEmpty()) return@observe 
 | 
  
 | 
            // 创建52周x7天的数据矩阵 
 | 
            val heatmapMatrix = Array(7) { IntArray(52) } 
 | 
             
 | 
            // 填充数据 
 | 
            stats.forEach { stat -> 
 | 
                val week = stat.weekOfYear - 1 // 0-51 
 | 
                val dayOfWeek = stat.dayOfWeek - 1 // 0-6 
 | 
                if (week in 0..51 && dayOfWeek in 0..6) { 
 | 
                    heatmapMatrix[dayOfWeek][week] = stat.count 
 | 
                } 
 | 
            } 
 | 
  
 | 
            // 更新UI 
 | 
            binding.layoutWeekStats.heatmapYearly.apply { 
 | 
                removeAllViews() 
 | 
                 
 | 
                val gridLayout = GridLayout(context).apply { 
 | 
                    rowCount = 8 // 增加一行用于显示月份 
 | 
                    columnCount = 53 // 增加一列用于显示星期标签 
 | 
                } 
 | 
  
 | 
                // 添加月份标签 
 | 
                val months = arrayOf("1月", "2月", "3月", "4月", "5月", "6月",  
 | 
                                   "7月", "8月", "9月", "10月", "11月", "12月") 
 | 
                months.forEachIndexed { index, month -> 
 | 
                    val label = TextView(context).apply { 
 | 
                        text = month 
 | 
                        textSize = 10f 
 | 
                        setPadding(0, 0, 8, 4) 
 | 
                        // 计算每个月份标签的位置 
 | 
                        val weekPosition = (index * 4.3).toInt() 
 | 
                        val params = GridLayout.LayoutParams() 
 | 
                        params.columnSpec = GridLayout.spec(weekPosition + 1) 
 | 
                        params.rowSpec = GridLayout.spec(0) 
 | 
                        layoutParams = params 
 | 
                    } 
 | 
                    gridLayout.addView(label) 
 | 
                } 
 | 
  
 | 
                // 添加星期标签 
 | 
                val dayLabels = arrayOf("周一", "周二", "周三", "周四", "周五", "周六", "周日") 
 | 
                dayLabels.forEachIndexed { index, label -> 
 | 
                    val textView = TextView(context).apply { 
 | 
                        text = label 
 | 
                        textSize = 10f 
 | 
                        setPadding(4, 0, 8, 0) 
 | 
                        val params = GridLayout.LayoutParams() 
 | 
                        params.columnSpec = GridLayout.spec(0) 
 | 
                        params.rowSpec = GridLayout.spec(index + 1) 
 | 
                        layoutParams = params 
 | 
                    } 
 | 
                    gridLayout.addView(textView) 
 | 
                } 
 | 
  
 | 
                // 添加热力图单元格 
 | 
                for (day in 0..6) { 
 | 
                    for (week in 0..51) { 
 | 
                        val count = heatmapMatrix[day][week] 
 | 
                        val cell = View(context).apply { 
 | 
                            val params = GridLayout.LayoutParams().apply { 
 | 
                                width = resources.getDimensionPixelSize(R.dimen.heatmap_cell_size) 
 | 
                                height = resources.getDimensionPixelSize(R.dimen.heatmap_cell_size) 
 | 
                                columnSpec = GridLayout.spec(week + 1) 
 | 
                                rowSpec = GridLayout.spec(day + 1) 
 | 
                                setMargins(1, 1, 1, 1) 
 | 
                            } 
 | 
                            layoutParams = params 
 | 
                            setBackgroundColor(getHeatmapColor(count)) 
 | 
                        } 
 | 
                        gridLayout.addView(cell) 
 | 
                    } 
 | 
                } 
 | 
  
 | 
                addView(gridLayout) 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private fun getHeatmapColor(count: Int): Int { 
 | 
        return when { 
 | 
            count == 0 -> Color.parseColor("#EBEDF0") 
 | 
            count == 1 -> Color.parseColor("#9BE9A8") 
 | 
            count == 2 -> Color.parseColor("#40C463") 
 | 
            count <= 4 -> Color.parseColor("#30A14E") 
 | 
            else -> Color.parseColor("#216E39") 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private fun updateCharts() { 
 | 
        when (currentDateType) { 
 | 
            DateType.DAY -> { 
 | 
                // 日视图显示包裹列表,隐藏统计图表 
 | 
                binding.recyclerPackages.visibility = View.VISIBLE 
 | 
                binding.layoutWeekStats.root.visibility = View.GONE 
 | 
                binding.layoutYearStats.root.visibility = View.GONE 
 | 
                binding.cardPackageStats.visibility = View.VISIBLE 
 | 
            } 
 | 
            DateType.WEEK, DateType.MONTH -> { 
 | 
                // 周和月视图显示柱状图和饼图,隐藏包裹列表 
 | 
                binding.recyclerPackages.visibility = View.GONE 
 | 
                binding.layoutWeekStats.root.visibility = View.VISIBLE 
 | 
                binding.layoutYearStats.root.visibility = View.GONE 
 | 
                binding.layoutWeekStats.chartDailyPackages.visibility = View.VISIBLE 
 | 
                (binding.layoutWeekStats.chartDailyPackages.parent as? View)?.visibility = View.VISIBLE 
 | 
                binding.layoutWeekStats.heatmapYearly.visibility = View.GONE 
 | 
                binding.cardPackageStats.visibility = View.VISIBLE 
 | 
                updateBarChartData() 
 | 
                updatePieChartData() 
 | 
            } 
 | 
            DateType.YEAR -> { 
 | 
                // 年视图显示热力图和饼图,隐藏包裹列表和柱状图 
 | 
                binding.recyclerPackages.visibility = View.GONE 
 | 
                binding.layoutWeekStats.root.visibility = View.VISIBLE 
 | 
                binding.layoutYearStats.root.visibility = View.VISIBLE 
 | 
                (binding.layoutWeekStats.chartDailyPackages.parent as? View)?.visibility = View.GONE 
 | 
                binding.layoutWeekStats.heatmapYearly.visibility = View.VISIBLE 
 | 
                binding.cardPackageStats.visibility = View.GONE 
 | 
                updateHeatmapData() 
 | 
                updatePieChartData() 
 | 
                updateYearlyStats() 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private fun updateYearlyStats() { 
 | 
        viewModel.getYearlyStats(currentDate.timeInMillis).observe(viewLifecycleOwner) { stats: List<DailyStat> -> 
 | 
            if (stats.isEmpty()) return@observe 
 | 
             
 | 
            // 更新年度包裹总数 
 | 
            binding.layoutYearStats.textTotalPackages.text = "${stats.sumOf { it.count }}个" 
 | 
             
 | 
            // 更新平均每天包裹数 
 | 
            val avgDaily = stats.sumOf { it.count }.toFloat() / 365 
 | 
            binding.layoutYearStats.textDailyAverage.text = String.format("%.2f", avgDaily) 
 | 
        } 
 | 
    } 
 | 
  
 | 
    override fun onDestroyView() { 
 | 
        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() 
 | 
            } 
 | 
        } 
 | 
  
 | 
    } 
 | 
} 
 |