cloudroam
2025-03-04 2a117297daf83b2e1a104603e9641226d5beeba3
fix: 按天统计相关逻辑
已删除3个文件
已修改13个文件
339 ■■■■ 文件已修改
app/src/main/java/com/example/firstapp/MainActivity.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/adapter/PackageAdapter.kt 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/dao/PackageDao.kt 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/AppDatabase.kt 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/entity/Code.kt 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/model/CourierStat.kt 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/model/DailyStat.kt 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/model/PackageInfo.kt 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/repository/PackageRepository.kt 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/fragment_dashboard.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_package_dashboard.xml 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/example/firstapp/MainActivity.kt
@@ -232,7 +232,7 @@
                                android.util.Log.d("SmsReceiver", "Received SMS code: ${code}")
                                val msg = Msg(0, "1111", "111111", messageBody.toString(), 1, "111", 1, 1)
                                val msgId = Core.msg.insert(msg)
                                val code = Code(0, rule.type, 1, rule.content, 1, 1, msgId, code, dateString, "中通",0)
                                val code = Code(0, rule.type, 1, rule.content, 1, 1, msgId, code, dateString, "中通",0,"","")
                                Core.code.insert(code)
                                android.util.Log.d("SMS_DEBUG", "历史短信已保存到数据库")
                            }else{
app/src/main/java/com/example/firstapp/adapter/PackageAdapter.kt
@@ -7,20 +7,23 @@
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.firstapp.R
import com.example.firstapp.model.PackageInfo
import com.example.firstapp.database.entity.Code
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
class PackageAdapter : RecyclerView.Adapter<PackageAdapter.PackageViewHolder>() {
    private var packages = listOf<PackageInfo>()
    private var packages = listOf<Code>()
    fun updatePackages(newPackages: List<PackageInfo>) {
    fun updatePackages(newPackages: List<Code>) {
        packages = newPackages
        notifyDataSetChanged()
    }
    //此处是渲染数据
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PackageViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_package_dashboard, parent, false)
@@ -38,13 +41,39 @@
        private val textCourierName: TextView = view.findViewById(R.id.text_courier_name)
        private val textTrackingNumber: TextView = view.findViewById(R.id.text_tracking_number)
        private val textTime: TextView = view.findViewById(R.id.text_time)
        private val textPickTime: TextView = view.findViewById(R.id.text_pick_time)
        fun bind(packageInfo: PackageInfo) {
            imgCourier.setImageResource(packageInfo.courierIcon)
            textCourierName.text = packageInfo.courierName
            textTrackingNumber.text = packageInfo.trackingNumber
            textTime.text = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault())
                .format(packageInfo.receivedTime)
        fun bind(code: Code) {
//            imgCourier.setImageResource(code.category)
            textCourierName.text = code.type
            textTrackingNumber.text = code.code
            // 步骤1:定义解析器,将字符串转为 Date
            val parser = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
            val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault())
            try {
                val date: Date? = parser.parse(code.createtime)  // 解析字符串
                date?.let {
                    textTime.text = "到货:"+formatter.format(it)  // 格式化并赋值
                } ?: run {
                    // 处理解析失败(date 为 null 的情况)
                    textTime.text = "Invalid Date"
                }
            } catch (e: ParseException) {
                e.printStackTrace()
                textTime.text = "Format Error"
            }
            try {
                val date2: Date? = parser.parse(code.pickuptime)  // 解析字符串
                date2?.let {
                    textPickTime.text = "取件:"+formatter.format(it)  // 格式化并赋值
                } ?: run {
                    textPickTime.text = "未取件"
                }
            } catch (e: ParseException) {
                e.printStackTrace()
                textPickTime.text = "未取件"
            }
        }
    }
}
app/src/main/java/com/example/firstapp/dao/PackageDao.kt
文件已删除
app/src/main/java/com/example/firstapp/database/AppDatabase.kt
@@ -7,7 +7,6 @@
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.example.firstapp.dao.PackageDao
import com.example.firstapp.database.dao.CodeDao
import com.example.firstapp.database.dao.KeywordDao
import com.example.firstapp.database.dao.MsgDao
@@ -21,7 +20,6 @@
import com.example.firstapp.utils.TAG_LIST
import com.example.firstapp.database.ext.ConvertersDate
import com.example.firstapp.model.PackageInfo
import com.example.firstapp.model.CourierStat
import com.example.firstapp.model.DailyStat
@@ -31,8 +29,7 @@
        Msg::class, 
        Code::class, 
        KeywordEntity::class, 
        Reminder::class,
        PackageInfo::class
        Reminder::class
    ],
    views = [
        CourierStat::class,
@@ -47,7 +44,6 @@
    abstract fun codeDao(): CodeDao
    abstract fun keywordDao(): KeywordDao
    abstract fun reminderDao(): ReminderDao
    abstract fun packageDao(): PackageDao
    companion object {
        @Volatile
app/src/main/java/com/example/firstapp/database/dao/CodeDao.kt
@@ -7,7 +7,10 @@
import androidx.room.Update
import com.example.firstapp.database.entity.Code
import com.example.firstapp.database.entity.Msg
import com.example.firstapp.model.CourierStat
import com.example.firstapp.model.DailyStat
import io.reactivex.Completable
import kotlinx.coroutines.flow.Flow
@Dao
interface CodeDao {
@@ -54,6 +57,43 @@
    fun queryByTypeAndCodeAndDate(content: String, code: String, dateString: String): Code
    @Query("update  Code set pickup = '1' where id=:id")
    @Query("update  Code set pickup = '1' ,  pickuptime = CURRENT_TIMESTAMP  where id=:id")
    fun pickup(id: Long)
    //查询当天包裹信息
    @Query("SELECT * FROM code WHERE date(createtime) = date(:date/1000, 'unixepoch', 'localtime') ORDER BY createtime DESC")
    fun getNewPackagesByDay(date: Long): List<Code>
    @Query("SELECT * FROM code WHERE date(createtime/1000, 'unixepoch', 'localtime') = date(:date/1000, 'unixepoch', 'localtime') ORDER BY createtime DESC")
    fun getPackagesByDay(date: Long): Flow<List<Code>>
    @Query("""
        SELECT * FROM code
        WHERE strftime('%Y-%W', createtime/1000, 'unixepoch', 'localtime') =
              strftime('%Y-%W', :date/1000, 'unixepoch', 'localtime')
        ORDER BY createtime DESC
    """)
    fun getPackagesByWeek(date: Long): Flow<List<Code>>
    @Query("""
        SELECT * FROM CourierStat
        WHERE EXISTS (
            SELECT 1 FROM code p
            WHERE p.category = CourierStat.category
            AND strftime('%Y-%W', p.createtime/1000, 'unixepoch', 'localtime') =
                strftime('%Y-%W', :date/1000, 'unixepoch', 'localtime')
        )
    """)
    fun getCourierStatsByWeek(date: Long): Flow<List<CourierStat>>
    @Query("""
        SELECT * FROM DailyStat
        WHERE EXISTS (
            SELECT 1 FROM code p
            WHERE date(p.createtime/1000, 'unixepoch', 'localtime') = DailyStat.date
            AND strftime('%Y-%W', p.createtime/1000, 'unixepoch', 'localtime') =
                strftime('%Y-%W', :date/1000, 'unixepoch', 'localtime')
        )
    """)
    fun getDailyStatsByWeek(date: Long): Flow<List<DailyStat>>
}
app/src/main/java/com/example/firstapp/database/entity/Code.kt
@@ -17,7 +17,7 @@
    var createtime: String,
    var name: String,
    var pickup: Int,
    var pickuptime: String,  //取件时间
    var overtime: String,   // 超期时间
    var time: Date = Date(),
//    var overtime: String,
)
app/src/main/java/com/example/firstapp/database/repository/CodeRepository.kt
@@ -3,6 +3,9 @@
import androidx.annotation.WorkerThread
import com.example.firstapp.database.dao.CodeDao
import com.example.firstapp.database.entity.Code
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext
class CodeRepository(private val codeDao: CodeDao) {
@@ -23,9 +26,30 @@
    }
    fun queryByTypeAndCodeAndDate(content: String, code: String, dateString: String): Code {
        return codeDao.queryByTypeAndCodeAndDate(content,code,dateString)
        return codeDao.queryByTypeAndCodeAndDate(content, code, dateString)
    }
    @WorkerThread
    fun pickup(id: Long) = codeDao.pickup(id)
    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 getCourierStats(date: Long) = codeDao.getCourierStatsByWeek(date)
    fun getDailyStats(date: Long) = codeDao.getDailyStatsByWeek(date)
    @WorkerThread
    fun getPackagesByDay(date: Long): List<Code> {
        return codeDao.getNewPackagesByDay(date)
    }
}
app/src/main/java/com/example/firstapp/model/CourierStat.kt
@@ -4,12 +4,12 @@
@DatabaseView(
    """
    SELECT courierName, COUNT(*) as count
    FROM packages
    GROUP BY courierName
    SELECT category, COUNT(*) as count
    FROM Code
    GROUP BY category
    """
)
data class CourierStat(
    val courierName: String,
    val category: String,
    val count: Int
app/src/main/java/com/example/firstapp/model/DailyStat.kt
@@ -4,10 +4,10 @@
@DatabaseView(
    """
    SELECT date(receivedTime/1000, 'unixepoch', 'localtime') as date,
    SELECT date(createtime/1000, 'unixepoch', 'localtime') as date,
           COUNT(*) as count 
    FROM packages
    GROUP BY date(receivedTime/1000, 'unixepoch', 'localtime')
    FROM code
    GROUP BY date(createtime/1000, 'unixepoch', 'localtime')
    """
)
data class DailyStat(
app/src/main/java/com/example/firstapp/model/PackageInfo.kt
文件已删除
app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt
@@ -85,7 +85,7 @@
                            val createtime = sdf.format(date)
                            val existingCode = Core.code.queryByTypeAndCodeAndDate(rule.content, code, createtime)
                            if (existingCode == null) {
                                val code = Code(0, rule.type, 1, rule.content, 1, 1, msgId, code, createtime, "中通",0)
                                val code = Code(0, rule.type, 1, rule.content, 1, 1, msgId, code, createtime, "中通",0,"","")
                                Core.code.insert(code)
                                Log.d("SMS_DEBUG", "新短信已保存到数据库")
app/src/main/java/com/example/firstapp/repository/PackageRepository.kt
文件已删除
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardFragment.kt
@@ -13,7 +13,7 @@
import com.google.android.material.tabs.TabLayout
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.firstapp.adapter.PackageAdapter
import com.example.firstapp.model.PackageInfo
import com.example.firstapp.core.Core
import com.github.mikephil.charting.charts.BarChart
import com.github.mikephil.charting.charts.PieChart
import com.github.mikephil.charting.components.Legend
@@ -185,7 +185,7 @@
    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.category)
            }
            val dataSet = PieDataSet(entries, "快递公司分布")
@@ -204,24 +204,18 @@
    private fun loadPackages() {
        // 这里应该从数据库或网络加载数据
        // 这里使用模拟数据作为示例
        val mockPackages = listOf(
            PackageInfo(
                trackingNumber = "14-6-7023",
                courierName = "某快递",
                receivedTime = System.currentTimeMillis(),
                courierIcon = R.drawable.data
            ),
            PackageInfo(
                trackingNumber = "230721",
                courierName = "京东",
                receivedTime = System.currentTimeMillis() - 3600000,
                courierIcon = R.drawable.data
            )
        )
        packageAdapter.updatePackages(mockPackages)
        binding.textPackageCount.text = "${mockPackages.size}个"
        // 根据当前选择的日期类型传入对应参数
        val packages = when (currentDateType) {
            DateType.DAY -> Core.code.getPackagesByDay(currentDate.timeInMillis)
//            DateType.WEEK -> Core.code.getPackagesByWeek(currentDate.timeInMillis)
//            DateType.MONTH -> Core.code.getPackagesByMonth(currentDate.timeInMillis)
//            DateType.YEAR -> Core.code.getPackagesByYear(currentDate.timeInMillis)
            DateType.WEEK -> TODO()
            DateType.MONTH -> TODO()
            DateType.YEAR -> TODO()
        }
        packageAdapter.updatePackages(packages)
        binding.textPackageCount.text = "${packageAdapter.itemCount}个"
    }
    private fun observePackages() {
        viewModel.getPackages(
@@ -235,8 +229,8 @@
                    updatePieChartData()
                }
                else -> {
                    packageAdapter.updatePackages(packages)
                }
                packageAdapter.updatePackages(packages)
            }
            }
            binding.textPackageCount.text = "${packages.size}个"
        }
app/src/main/java/com/example/firstapp/ui/dashboard/DashboardViewModel.kt
@@ -5,31 +5,27 @@
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import com.example.firstapp.AppDatabase
import com.example.firstapp.model.PackageInfo
import com.example.firstapp.repository.PackageRepository
import com.example.firstapp.database.entity.Code
import com.example.firstapp.database.repository.CodeRepository
import kotlinx.coroutines.launch
class DashboardViewModel(application: Application) : AndroidViewModel(application) {
    private val repository: PackageRepository
    private val repository: CodeRepository
    init {
        val packageDao = AppDatabase.getInstance(application).packageDao()
        repository = PackageRepository(packageDao)
        val codeDao = AppDatabase.getInstance(application).codeDao()
        repository = CodeRepository(codeDao)
    }
    fun getPackages(date: Long, dateType: String) =
    fun getPackages(date: Long, dateType: String) =
        repository.getPackages(date, dateType).asLiveData()
    fun getCourierStats(date: Long) = repository.getCourierStats(date).asLiveData()
    fun getDailyStats(date: Long) = repository.getDailyStats(date).asLiveData()
    fun updatePackageStatus(packageInfo: PackageInfo) = viewModelScope.launch {
        repository.update(packageInfo)
    }
    fun insert(packageInfo: PackageInfo) = viewModelScope.launch {
        repository.insert(packageInfo)
    fun insert(code: Code) = viewModelScope.launch {
        repository.insert(code)
    }
}
app/src/main/res/layout/fragment_dashboard.xml
@@ -84,16 +84,18 @@
            android:padding="16dp">
            <ImageView
                android:layout_width="48dp"
                android:layout_width="0dp"
                android:layout_height="48dp"
                android:layout_weight="1"
                android:src="@drawable/resource_package" />
            <TextView
                android:id="@+id/text_package_count"
                android:layout_width="wrap_content"
                android:layout_width="0dp"
                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个" />
app/src/main/res/layout/item_package_dashboard.xml
@@ -46,12 +46,30 @@
                tools:text="2025-01-14 10:30" />
        </LinearLayout>
        <TextView
            android:id="@+id/text_tracking_number"
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/darker_gray"
            tools:text="14-6-7023" />
            android:orientation="vertical">
            <TextView
                android:id="@+id/text_tracking_number"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@android:color/darker_gray"
                android:layout_gravity="end"
                tools:text="14-6-7023" />
            <TextView
                android:id="@+id/text_pick_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="4dp"
                android:textColor="@android:color/darker_gray"
                android:layout_gravity="end"
                android:textSize="12sp"
                tools:text="2025-01-15 11:30" />
        </LinearLayout>
    </LinearLayout>
</androidx.cardview.widget.CardView>