From 7014cfae0729c677d1170f99216fc8a4c5d3b40b Mon Sep 17 00:00:00 2001
From: xiaowusky <chenyangyang3858@dingtalk.com>
Date: Fri, 9 Jun 2023 16:26:16 +0800
Subject: [PATCH] =?UTF-8?q?desc:=E6=9F=A5=E8=AF=A2=E6=B0=94=E4=BD=93?=
 =?UTF-8?q?=EF=BC=8C=E8=87=AA=E5=B7=B1=E8=AE=A1=E7=AE=97=E6=AD=A5=E9=95=BF?=
 =?UTF-8?q?=E5=B9=B3=E5=9D=87=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../watcher/adapter/HistoryDataAdapter.kt     | 10 +--
 .../watcher/adapter/WarnDataAdapter.kt        |  2 +-
 .../safetywatcher/watcher/db/AppDatabase.kt   | 13 ++-
 .../safetywatcher/watcher/db/dao/GasDao.kt    |  7 +-
 .../watcher/db/dao/GasTypeDao.kt              | 19 +++++
 .../safetywatcher/watcher/db/entity/Gas.kt    | 16 ++--
 .../watcher/db/entity/GasType.kt              | 10 +++
 .../watcher/db/entity/Warning.kt              | 14 ++--
 .../safetywatcher/watcher/ui/CloudActivity.kt | 66 ++++++++++++---
 .../watcher/ui/QueryDataActivity.kt           | 82 ++++++++++++++++++-
 10 files changed, 200 insertions(+), 39 deletions(-)
 create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/db/dao/GasTypeDao.kt
 create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/GasType.kt

diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/adapter/HistoryDataAdapter.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/adapter/HistoryDataAdapter.kt
index e83a558..6d52081 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/adapter/HistoryDataAdapter.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/adapter/HistoryDataAdapter.kt
@@ -4,17 +4,17 @@ import android.view.LayoutInflater
 import android.view.ViewGroup
 import com.yinuo.safetywatcher.databinding.LayoutItemHistoryBinding
 import com.yinuo.safetywatcher.watcher.base.BaseRvAdapter
-import com.yinuo.safetywatcher.watcher.bean.HistoryData
+import com.yinuo.safetywatcher.watcher.db.entity.Gas
 import com.yinuo.safetywatcher.watcher.utils.DateUtils
 
 class HistoryDataAdapter :
-    BaseRvAdapter<HistoryData, LayoutItemHistoryBinding, HistoryDataAdapter.HViewHolder>() {
+    BaseRvAdapter<Gas, LayoutItemHistoryBinding, HistoryDataAdapter.HViewHolder>() {
 
     class HViewHolder(val binding: LayoutItemHistoryBinding) :
-        BaseRvAdapter.BaseViewHolder<HistoryData, LayoutItemHistoryBinding>(binding) {
-        override fun bindView(data: HistoryData) {
+        BaseRvAdapter.BaseViewHolder<Gas, LayoutItemHistoryBinding>(binding) {
+        override fun bindView(data: Gas) {
             binding.tvTime.text = formatTime(data.time)
-            binding.tvSensor.text = data.sensor
+            binding.tvSensor.text = data.gasName
         }
 
         private fun formatTime(time: Long): CharSequence? {
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/adapter/WarnDataAdapter.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/adapter/WarnDataAdapter.kt
index 054902b..2654c9f 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/adapter/WarnDataAdapter.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/adapter/WarnDataAdapter.kt
@@ -12,7 +12,7 @@ import com.yinuo.safetywatcher.watcher.utils.DateUtils
 class WarnDataAdapter :
     BaseRvAdapter<WarnData, LayoutItemWarnBinding, WarnDataAdapter.WViewHolder>() {
 
-    class WViewHolder(val binding: LayoutItemWarnBinding) :
+    class WViewHolder(private val binding: LayoutItemWarnBinding) :
         BaseRvAdapter.BaseViewHolder<WarnData, LayoutItemWarnBinding>(binding) {
         override fun bindView(data: WarnData) {
             binding.tvTime.text = formatTime(data.time)
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/db/AppDatabase.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/AppDatabase.kt
index 787e009..59b5a32 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/db/AppDatabase.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/AppDatabase.kt
@@ -5,14 +5,21 @@ import androidx.room.Room
 import androidx.room.RoomDatabase
 import com.common.commonlib.CommonApplication
 import com.yinuo.safetywatcher.watcher.db.dao.GasDao
+import com.yinuo.safetywatcher.watcher.db.dao.GasTypeDao
 import com.yinuo.safetywatcher.watcher.db.dao.WarningDao
 import com.yinuo.safetywatcher.watcher.db.entity.Gas
+import com.yinuo.safetywatcher.watcher.db.entity.GasType
 import com.yinuo.safetywatcher.watcher.db.entity.Warning
 
-@Database(entities = [Warning::class, Gas::class], version = 1, exportSchema = false)
+@Database(
+    entities = [Warning::class, Gas::class, GasType::class],
+    version = 1,
+    exportSchema = false
+)
 abstract class AppDatabase : RoomDatabase() {
     abstract fun warningDao(): WarningDao
     abstract fun gasDao(): GasDao
+    abstract fun gasTypeDao(): GasTypeDao
 }
 
 object DBUtils {
@@ -30,4 +37,8 @@ object DBUtils {
     fun gasDao(): GasDao {
         return db.gasDao()
     }
+
+    fun gasTypeDao(): GasTypeDao {
+        return db.gasTypeDao()
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/db/dao/GasDao.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/dao/GasDao.kt
index baf714d..1736761 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/db/dao/GasDao.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/dao/GasDao.kt
@@ -11,8 +11,11 @@ interface GasDao {
     @Query("SELECT * FROM gas")
     suspend fun getAll(): List<Gas>
 
-    @Query("SELECT * FROM gas WHERE gas_name IS :name AND time BETWEEN :startTime AND :endTime")
-    suspend fun findByName(name: String, startTime: Long, endTime: Long): List<Gas>
+    @Query("SELECT * FROM gas WHERE sync_flag IS :flag OR time >= :startTime")
+    suspend fun getAllBySyncFlagOrTime(flag: Boolean, startTime: Long): List<Gas>
+
+    @Query("SELECT * FROM gas WHERE time BETWEEN :startTime AND :endTime")
+    suspend fun getAllByTime(startTime: Long, endTime: Long): List<Gas>
 
     @Insert
     suspend fun insertAll(vararg gases: Gas)
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/db/dao/GasTypeDao.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/dao/GasTypeDao.kt
new file mode 100644
index 0000000..c78bcd7
--- /dev/null
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/dao/GasTypeDao.kt
@@ -0,0 +1,19 @@
+package com.yinuo.safetywatcher.watcher.db.dao
+
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.Query
+import com.yinuo.safetywatcher.watcher.db.entity.GasType
+
+@Dao
+interface GasTypeDao {
+    @Query("SELECT * FROM gas_type")
+    suspend fun getAll(): List<GasType>
+
+    @Insert
+    suspend fun insert(gas: GasType)
+
+    @Delete
+    suspend fun delete(gas: GasType)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/Gas.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/Gas.kt
index 0eae66b..8f29a68 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/Gas.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/Gas.kt
@@ -6,12 +6,12 @@ import androidx.room.PrimaryKey
 
 @Entity
 data class Gas(
-    @PrimaryKey val id: Int,
-    @ColumnInfo(name = "time") val time: Long,
-    @ColumnInfo(name = "gas_name") val gasName: String,
-    @ColumnInfo(name = "gas_value") val gasValue: Double,
-    @ColumnInfo(name = "unit") val unit: String,
-    @ColumnInfo(name = "threshold_low") val thresholdLow: Double,
-    @ColumnInfo(name = "threshold_high") val thresholdHigh: Double,
-    @ColumnInfo(name = "sync_flag") val syncFlag: Boolean = false
+    @PrimaryKey var id: Int,
+    @ColumnInfo(name = "time") var time: Long,
+    @ColumnInfo(name = "gas_name") var gasName: String,
+    @ColumnInfo(name = "gas_value") var gasValue: Double,
+    @ColumnInfo(name = "unit") var unit: String,
+    @ColumnInfo(name = "threshold_low") var thresholdLow: Double,
+    @ColumnInfo(name = "threshold_high") var thresholdHigh: Double,
+    @ColumnInfo(name = "sync_flag") var syncFlag: Boolean = false
 )
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/GasType.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/GasType.kt
new file mode 100644
index 0000000..9b08ef5
--- /dev/null
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/GasType.kt
@@ -0,0 +1,10 @@
+package com.yinuo.safetywatcher.watcher.db.entity
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity(tableName = "gas_type")
+data class GasType(
+    @PrimaryKey @ColumnInfo(name = "gas_type") var type: String
+)
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/Warning.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/Warning.kt
index cc28a86..315606e 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/Warning.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/db/entity/Warning.kt
@@ -6,12 +6,12 @@ import androidx.room.PrimaryKey
 
 @Entity
 data class Warning(
-    @PrimaryKey val id: Int,
-    @ColumnInfo(name = "gas_name") val gasName: String,
-    @ColumnInfo(name = "gas_value") val gasValue: Double,
-    @ColumnInfo(name = "unit") val unit: String,
-    @ColumnInfo(name = "threshold_low") val thresholdLow: Double,
-    @ColumnInfo(name = "threshold_high") val thresholdHigh: Double,
-    @ColumnInfo(name = "start_time") val startTime: Long,
+    @PrimaryKey var id: Int,
+    @ColumnInfo(name = "gas_name") var gasName: String,
+    @ColumnInfo(name = "gas_value") var gasValue: Double,
+    @ColumnInfo(name = "unit") var unit: String,
+    @ColumnInfo(name = "threshold_low") var thresholdLow: Double,
+    @ColumnInfo(name = "threshold_high") var thresholdHigh: Double,
+    @ColumnInfo(name = "start_time") var startTime: Long,
     @ColumnInfo(name = "end_time") var endTime: Long = -1L,
 )
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/CloudActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/CloudActivity.kt
index df17eef..0b1c745 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/CloudActivity.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/CloudActivity.kt
@@ -6,8 +6,12 @@ import com.common.commonlib.net.callback.RequestResultCallBack
 import com.yinuo.safetywatcher.R
 import com.yinuo.safetywatcher.databinding.ActivityCloudBinding
 import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity
+import com.yinuo.safetywatcher.watcher.db.DBUtils
 import com.yinuo.safetywatcher.watcher.net.UploadFileApi
 import com.yinuo.safetywatcher.xls.utils.PathUtils
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
 
 class CloudActivity : NoOptionsActivity() {
     private val mBinding: ActivityCloudBinding by lazy {
@@ -28,19 +32,59 @@ class CloudActivity : NoOptionsActivity() {
 
     override fun initView() {
         mBinding.apply {
-            syncSensor.setOnClickListener { }
+            syncSensor.setOnClickListener {
+                uploadSensorData()
+            }
             syncVedio.setOnClickListener {
-                val path = PathUtils.getExternalStorageDirectory() + "/test2.mp4"
-                uploadApi.singleUpload(path, System.currentTimeMillis(), object :
-                    RequestResultCallBack<BaseResponse>() {
-                    override fun onResult(result: BaseResponse) {
-                    }
-
-                    override fun onError(error: String?) {
-                    }
-                })
+                uploadVideo()
+            }
+            syncOnce.setOnClickListener {
+                uploadOnece()
             }
-            syncOnce.setOnClickListener { }
         }
     }
+
+    private fun uploadOnece() {
+        uploadSensorData()
+        uploadVideo()
+    }
+
+    private fun uploadVideo() {
+        //TODO  1.拿到云端最新数据时间
+        val cloudTime = 0L
+        // 2. 拿到待上传文件列表
+        val fileList = getFileList(cloudTime)
+        // 上传
+        fileList?.forEach {
+            uploadFile(it)
+        }
+    }
+
+    @OptIn(DelicateCoroutinesApi::class)
+    private fun uploadSensorData() {
+        GlobalScope.launch {
+            //TODO  1.拿到云端最新数据时间
+            val cloudTime = 0L
+            // 2. 查询本地数据库中该时间之后的数据
+            val gasList = DBUtils.gasDao().getAllBySyncFlagOrTime(false, cloudTime)
+            // 3. 上传数据给服务器
+
+        }
+    }
+
+    private fun getFileList(cloudTime: Long): List<String>? {
+        return null
+    }
+
+    private fun uploadFile(path: String) {
+        val path = PathUtils.getExternalStorageDirectory() + "/test2.mp4"
+        uploadApi.singleUpload(path, System.currentTimeMillis(), object :
+            RequestResultCallBack<BaseResponse>() {
+            override fun onResult(result: BaseResponse) {
+            }
+
+            override fun onError(error: String?) {
+            }
+        })
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt
index 0d566fc..befe510 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt
@@ -3,6 +3,7 @@ package com.yinuo.safetywatcher.watcher.ui
 import android.annotation.SuppressLint
 import android.view.View
 import androidx.activity.result.contract.ActivityResultContracts
+import androidx.lifecycle.lifecycleScope
 import androidx.recyclerview.widget.LinearLayoutManager
 import com.yinuo.safetywatcher.R
 import com.yinuo.safetywatcher.databinding.ActivityQueryDataBinding
@@ -10,8 +11,14 @@ import com.yinuo.safetywatcher.watcher.adapter.HistoryDataAdapter
 import com.yinuo.safetywatcher.watcher.base.BaseActivity
 import com.yinuo.safetywatcher.watcher.bean.HistoryData
 import com.yinuo.safetywatcher.watcher.constant.TimeStep
+import com.yinuo.safetywatcher.watcher.db.DBUtils
+import com.yinuo.safetywatcher.watcher.db.entity.Gas
+import com.yinuo.safetywatcher.watcher.db.entity.GasType
 import com.yinuo.safetywatcher.watcher.utils.DateUtils
 import com.yinuo.safetywatcher.watcher.view.CommonTopBar
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import java.util.Collections
 
 class QueryDataActivity : BaseActivity() {
 
@@ -103,9 +110,76 @@ class QueryDataActivity : BaseActivity() {
     }
 
     private fun queryData() {
-        val datas = mutableListOf<HistoryData>()
-        datas.add(HistoryData(0, "气体传感器"))
-        datas.add(HistoryData(0, "温度传感器"))
-        mAdapter.setData(datas)
+        lifecycleScope.launch {
+            // 根据步长,多个数据合一。合一步长
+            val step = when (timeStep) {
+                TimeStep.SECOND_30 -> 1
+                TimeStep.MINUTE_1 -> 2
+                TimeStep.MINUTE_3 -> 6
+                TimeStep.MINUTE_5 -> 10
+                else -> 1
+            }
+            // 全量数据
+            val gasDao = DBUtils.gasDao()
+            val gasList = gasDao.getAllByTime(startTime, endTime)
+            if (step == 1) {
+                launch(Dispatchers.Main) {
+                    mAdapter.setData(gasList)
+                }
+            } else {
+                // 多气体,分开创建list,存储之后。 再分步
+                val gasTypeDao = DBUtils.gasTypeDao()
+                val gasTypes = gasTypeDao.getAll()
+                // 每种气体建立一个list
+                val gasMap = HashMap<String, MutableList<Gas>>()
+                // 预先创建分步合一之后的list
+                val gasNewMap = HashMap<String, MutableList<Gas>>()
+                gasTypes.forEach {
+                    gasMap[it.type] = mutableListOf()
+                    gasNewMap[it.type] = mutableListOf()
+                }
+                // 分开各个气体的数据
+                gasList.forEach {
+                    val list = gasMap[it.gasName]
+                    list?.add(it)
+                }
+                //根据步长分割数据填充新的列表
+                gasMap.forEach { (type, list) ->
+                    val newMapList = gasNewMap[type]
+                    var gasValue = 0.0
+                    var startGas: Gas? = null
+                    list.forEachIndexed { index, gas ->
+                        // 不能整除的时候,最后一个特殊处理
+                        if (list.size - 1 == index) {
+                            if (gasValue != 0.0) {
+                                startGas!!.gasValue = gasValue / (list.size % step)
+                                newMapList?.add(startGas!!)
+                            }
+                        }
+                        if (index % step == 0) {
+                            if (gasValue != 0.0) {
+                                startGas!!.gasValue = gasValue / step
+                                newMapList?.add(startGas!!)
+                            }
+                            startGas = gas
+                            gasValue = gas.gasValue
+                        } else {
+                            gasValue += gas.gasValue
+                        }
+                    }
+                }
+
+                var newList = mutableListOf<Gas>()
+                gasNewMap.forEach { t, u ->
+                    newList.addAll(u)
+                }
+                newList.sortWith { o1, o2 ->
+                    (o1.time - o2.time).toInt()
+                }
+                launch(Dispatchers.Main) {
+                    mAdapter.setData(newList)
+                }
+            }
+        }
     }
 }
\ No newline at end of file