Prechádzať zdrojové kódy

1、订单失败存储
2、订单上传

ccc 1 mesiac pred
rodič
commit
79f2212c5d

+ 16 - 2
lib_base/src/main/java/com/quyunshuo/sbm10/base/addressenum/PayEnum.kt

@@ -1,6 +1,9 @@
 package com.quyunshuo.sbm10.base.addressenum
 
+import android.util.Log
+import com.quyunshuo.sbm10.base.BaseApplication
 import com.quyunshuo.sbm10.base.R
+import com.quyunshuo.sbm10.base.utils.getString
 
 /**
  * 支付枚举
@@ -21,14 +24,25 @@ enum class PayEnum(val code:String,val remark:String,val nameId:Int,val imgId:In
 
     companion object {
         fun getEnumByValue(code: String): PayEnum {
-
             for (anEnum in PayEnum.values()) {
                 if (anEnum.code == code) {
                     return anEnum
                 }
             }
-            return PayEnum.FREE
+            return FREE
         }
 
+        fun getEnumByValuePayType(nameId: String): Int {
+            // 遍历所有枚举常量
+            for (payEnum in PayEnum.values()) {
+                Log.d("TAG3", "otoMake:payType: "+getString(payEnum.nameId))
+                Log.d("TAG2", "otoMake:payType: "+payEnum.nameId)
+                Log.d("TAG1", "otoMake:payType: "+nameId)
+                if (getString(payEnum.nameId) == nameId){
+                    return payEnum.payType
+                }
+            }
+            return 0
+        }
     }
 }

+ 2 - 2
lib_common/src/main/java/com/quyunshuo/sbm10/common/bean/ShoppingCartBean.kt

@@ -10,6 +10,6 @@ data class ShoppingCartBean(
     var imgID: String,//商品图片id
     var nameChinese: String,//商品中文名称
     var index:Int,//id 唯一标识
-    var count :Int//商品个数
-
+    var count :Int,//商品个数
+    var customName: String,//商品自定义名字
 )

+ 6 - 0
lib_common/src/main/java/com/quyunshuo/sbm10/common/constant/MMKVName.kt

@@ -274,6 +274,12 @@ abstract class MMKVName {
         val PRICE: String
             //上传 价格
             get() = "PRICE"
+
+        val OFFLINE_ORDER: String
+            //存储离线订单
+            get() = "offline_order"
+
+
     }
     // 这里可以继续添加其他常量
 

+ 5 - 0
lib_common/src/main/java/com/quyunshuo/sbm10/common/constant/MqName.kt

@@ -66,4 +66,9 @@ object MqName {
      * 远程制作
      */
     var PRODUCEGOODS= "produceGoods"
+    /**
+     * 订单上传成功
+     */
+    var UPLOADORDER= "uploadOrder"
+
 }

+ 10 - 3
module_database/src/main/java/com/module/database/room/SZDatabase.kt

@@ -7,18 +7,22 @@ import androidx.room.Database
 import androidx.room.Room
 import androidx.room.RoomDatabase
 import androidx.sqlite.db.SupportSQLiteDatabase
+import androidx.work.impl.Migration_1_2
 import com.module.database.BuildConfig
 import com.module.database.room.dao.BillDao
 import com.module.database.room.dao.LocalOrderDao
+import com.module.database.room.dao.OfflineOrderDao
 import com.module.database.room.dao.WarringDao
 import com.module.database.room.entity.BillBean
 import com.module.database.room.entity.LocalOrderBean
+import com.module.database.room.entity.OfflineOrderBean
 import com.module.database.room.entity.WarringBean
+import com.module.database.room.migration.MIGRATION_1_2
 
 //数据库版本修改
 @Database(
-    entities = [BillBean::class, WarringBean::class, LocalOrderBean::class],
-    version = 1
+    entities = [BillBean::class, WarringBean::class, LocalOrderBean::class, OfflineOrderBean::class],
+    version = 2
 )
 abstract class SZDatabase : RoomDatabase() {
 
@@ -28,6 +32,8 @@ abstract class SZDatabase : RoomDatabase() {
 
     abstract fun getLocalOrderDao(): LocalOrderDao
 
+    abstract fun getOfflineOrderDao(): OfflineOrderDao
+
     companion object {
         @Volatile
         private var INSTANCE: SZDatabase? = null
@@ -42,7 +48,8 @@ abstract class SZDatabase : RoomDatabase() {
                     context.applicationContext,
                     SZDatabase::class.java,
                     "sz_database"
-                ).build()
+                ).addMigrations(MIGRATION_1_2)
+                .build()
                 INSTANCE = instance
                 return instance
             }

+ 29 - 0
module_database/src/main/java/com/module/database/room/dao/OfflineOrderDao.kt

@@ -0,0 +1,29 @@
+package com.module.database.room.dao
+
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Update
+import com.module.database.room.entity.OfflineOrderBean
+
+@Dao
+interface OfflineOrderDao {
+
+    @Query("SELECT * FROM offlineorder")
+    suspend fun getAll():List<OfflineOrderBean>
+
+    @Insert(onConflict = OnConflictStrategy.IGNORE)
+    suspend fun insert(offlineOrderBean: OfflineOrderBean)
+
+    @Update
+    suspend fun update(offlineOrderBean: OfflineOrderBean): Int
+
+    @Delete
+    suspend fun delete(offlineOrderBean: OfflineOrderBean)
+
+    @Query("DELETE FROM offlineorder")
+    suspend fun deleteAll()
+
+}

+ 16 - 0
module_database/src/main/java/com/module/database/room/entity/OfflineOrderBean.kt

@@ -0,0 +1,16 @@
+package com.module.database.room.entity
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+/**
+ * 离线订单的数据保存
+ */
+@Entity(tableName = "offlineorder")
+data class OfflineOrderBean(
+    @PrimaryKey(autoGenerate = true)
+    val id: Long = 0,
+    @ColumnInfo
+    val map: String
+)

+ 16 - 0
module_database/src/main/java/com/module/database/room/migration/MigrationVersion.kt

@@ -0,0 +1,16 @@
+package com.module.database.room.migration
+
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+
+val MIGRATION_1_2 = object : Migration(1, 2) {
+    override fun migrate(database: SupportSQLiteDatabase) {
+        // 创建 offlineorder 表,确保列定义与 OfflineOrderBean 类匹配
+        database.execSQL("""
+            CREATE TABLE IF NOT EXISTS offlineorder (
+                id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+                map TEXT NOT NULL
+            )
+        """)
+    }
+}

+ 92 - 31
module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/HomeFragment.kt

@@ -47,6 +47,7 @@ import com.quyunshuo.module.home.utils.NetWorkUtils
 import com.quyunshuo.module.home.utils.PhoneStateUtils
 import com.quyunshuo.module.home.weight.NXHooldeIMGView
 import com.quyunshuo.sbm10.base.BuildConfig
+import com.quyunshuo.sbm10.base.addressenum.PayEnum
 import com.quyunshuo.sbm10.base.bean.Global
 import com.quyunshuo.sbm10.base.dialog.TipsDialog
 import com.quyunshuo.sbm10.base.ktx.observeLiveData
@@ -119,16 +120,20 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
 
     private var languageSelectorDialog: LanguageSelectorDialog? = null
     private var materialHashMap: HashMap<String, String> = HashMap()
-    private var materialValue=""
-    private var material = SpUtils.getBoolean(MMKVName.MATERIAL,false)
+    private var materialValue = ""
+    private var material = SpUtils.getBoolean(MMKVName.MATERIAL, false)
     private var productCount = 0
     private val shopCartSize = SpUtils.getString(MMKVName.SHOPPING_CART_SIZE, "3")?.toInt()
-    private val payType = SpUtils.getString(MMKVName.PAY_TYPE,"").toString()
+    private val payType = SpUtils.getString(MMKVName.PAY_TYPE, "").toString()
+
     @RequiresApi(Build.VERSION_CODES.P)
     override fun HomeFragmentHomeBinding.initView() {
-        if (material == true){
+        if (material == true) {
             materialValue = SpUtils.getString(MMKVName.MATERIAL_VALUE, MMKVName.MATERIAL_HASHMAP)!!
-            materialHashMap= Gson().fromJson(materialValue, object : TypeToken<HashMap<String, String>>() {}.type)
+            materialHashMap = Gson().fromJson(
+                materialValue,
+                object : TypeToken<HashMap<String, String>>() {}.type
+            )
         }
 
         startRefreshime()
@@ -137,7 +142,7 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
             productList = mViewModel.getPriceData()
             //设置布局排列方式,默认垂直排列
             layoutManager = createGridLayoutManager(productList.size)
-            homeProductAdapter = HomeProductAdapter(productList,materialHashMap)
+            homeProductAdapter = HomeProductAdapter(productList, materialHashMap)
             homeProductAdapter?.setOnclickListener { view, position, data ->
                 clickProduct(
                     position,
@@ -211,8 +216,8 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
             })
         if (payType.contains("BillCoin")) {
             llCashAacpe.visibility = View.VISIBLE
-        }else{
-            llCashAacpe.visibility=View.GONE
+        } else {
+            llCashAacpe.visibility = View.GONE
         }
     }
 
@@ -221,7 +226,12 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         return when (itemCount) {
             1 -> GridLayoutManager(this@HomeFragment.context, 1, GridLayoutManager.VERTICAL, false)
             2 -> GridLayoutManager(this@HomeFragment.context, 2, GridLayoutManager.VERTICAL, false)
-            else -> GridLayoutManager(this@HomeFragment.context, 2, GridLayoutManager.VERTICAL, false) // 默认情况下
+            else -> GridLayoutManager(
+                this@HomeFragment.context,
+                2,
+                GridLayoutManager.VERTICAL,
+                false
+            ) // 默认情况下
         }
     }
 
@@ -259,7 +269,8 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         val coinData = BigDecimal(coin)
         val coinMultiply = BigDecimal(SpUtils.getString(MMKVName.COIN_PULSE_MULTIPLY, "1"))
         val coinDivide = BigDecimal(SpUtils.getString(MMKVName.COIN_PULSE_DIVIDE, "1"))
-        Heartbeat.coinData = (coinData.multiply(coinMultiply)).divide(coinDivide).setScale(2, java.math.RoundingMode.HALF_UP)
+        Heartbeat.coinData = (coinData.multiply(coinMultiply)).divide(coinDivide)
+            .setScale(2, java.math.RoundingMode.HALF_UP)
 
         mBinding.tvAacpeCoin.setText("" + Heartbeat.coinData)
         if (lastCoin != Heartbeat.coinData) {
@@ -288,19 +299,19 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         product = productList[position]
         Log.d(TAG, "clickProduct: " + product)
         //点击前校验 有没有开机、有没有选择支付方式等。
-        if (material == true){
+        if (material == true) {
             val sweet = materialHashMap["sweet"].toString().toInt()
             val salty = materialHashMap["salty"].toString().toInt()
             val boxValue = materialHashMap["box"].toString().toInt()
-            if (boxValue<=0){
+            if (boxValue <= 0) {
                 showTipsDialog(UiUtil.getStringRes(R.string.box_not_enough))
                 return
             }
-            val productNo= product!!.productNo
-            if (productNo=="E01"&&sweet<=0){
+            val productNo = product!!.productNo
+            if (productNo == "E01" && sweet <= 0) {
                 return
             }
-            if (productNo=="E02"&&salty<=0){
+            if (productNo == "E02" && salty <= 0) {
                 return
             }
         }
@@ -313,12 +324,12 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
 //        bundle.putInt("SELECT_PRO",selectProductDataBean.proValue)
 //        findNavController.navigate(R.id.home_action_home_homefragment_to_home_makefragment,bundle)
         if (SpUtils.getBoolean(MMKVName.SHOPPING_TROLLEY, true)!!) {
-            if (productCount < shopCartSize!!){
+            if (productCount < shopCartSize!!) {
                 //添加进购物车
                 addAction(view)
                 mViewModel.shoppingTrolleyAdd(product!!)
-            }else{
-                ToastUtil.showToast(UiUtil.getStringRes(R.string.cannot_exceed_size)+shopCartSize)
+            } else {
+                ToastUtil.showToast(UiUtil.getStringRes(R.string.cannot_exceed_size) + shopCartSize)
                 return
             }
         } else {
@@ -331,7 +342,7 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
 
     private fun checkToBuy(): Boolean {
         val deviceStatusCheck = mViewModel.deviceStatusCheck()
-        if (SpUtils.getString(MMKVName.OPEN_DEV,"0")!="1"){
+        if (SpUtils.getString(MMKVName.OPEN_DEV, "0") != "1") {
             showTipsDialog(UiUtil.getStringRes(R.string.please_open_dev))
             return true
         }
@@ -343,7 +354,7 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
 //            showTipsDialog("价格低于0元,不能购买")
 //            return true
 //        }
-            if (product?.price!! <= 0 && MMKVName.APP_VERSION==1) {
+        if (product?.price!! <= 0 && MMKVName.APP_VERSION == 1) {
             showTipsDialog("价格低于0元,不能购买")
             return true
         }
@@ -418,13 +429,13 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         mBinding.homeRvProduct.adapter = null //为什么要手动呢?。。。。。
         try {
             NetWorkUtils.unRegisterNetWork(activity)
-        }catch (e:Exception){
-            Log.d(TAG, "onDestroyView:NetWorkUtils "+e.message)
+        } catch (e: Exception) {
+            Log.d(TAG, "onDestroyView:NetWorkUtils " + e.message)
         }
         try {
             PhoneStateUtils.unRegisterPhoneStateListener(activity)
-        }catch (e:Exception){
-            Log.d(TAG, "onDestroyView:PhoneStateUtils "+e.message)
+        } catch (e: Exception) {
+            Log.d(TAG, "onDestroyView:PhoneStateUtils " + e.message)
         }
         super.onDestroyView()
     }
@@ -433,6 +444,7 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         Log.d(TAG, "viewonDetach: ")
         super.onDetach()
     }
+
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun event(messageEvent: Message) {
         when (messageEvent.type) {
@@ -484,7 +496,6 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
     private fun gotoMake(name: String, payInfo: PaySuccessBean) {
         Log.d(TAG, "gotoMake: " + mViewModel.getShoppingTrolleyList())
 //       var selectProductDataBean = ProTypeEnum.getEnumByValue(name) //上线需要使用这个。
-        Log.d(TAG, "gotoMake: "+payInfo.payNamber)
         if (product != null) {
             val findNavController = findNavController()
             var bundle = Bundle()
@@ -495,14 +506,62 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
             bundle.putString("PROMOTION_CODE", promotionCode)
             bundle.putString("MATERIAL_VALUE", materialValue)
             makeList = splitProductsByCount(mViewModel.getShoppingTrolleyList())
+            var productCount=0
+            var name=""
+            var no=""
+            var isFirst = true // 用于跟踪是否是第一次添加
+            for (productList in mViewModel.getShoppingTrolleyList()){
+                val count: Int = productList.count //单件商品数量
+                val nameId :String = productList.nameId//默认商品名字
+                val customName :String = productList.customName//自定义商品名字
+                val productNo :String = productList.productNo//商品唯一编号
+                if (!isFirst) {
+                    name += "," // 不是第一次添加时,加上逗号
+                    no += ","   // 同样,对于 no 字符串也加上逗号
+                } else {
+                    isFirst = false // 第一次添加之后,将 isFirst 设置为 false
+                }
+                if (customName!=""){
+                    name +=customName +"-"+count
+                    no += customName+"-"+ productNo+"-"+count
+                }else{
+                    val productName = UiUtil.getResId(nameId, R.string::class.java)
+                    name +=getString(productName) +"-"+count
+                    no += getString(productName) +"-"+ productNo+"-"+count
+                }
+                productCount+=count
+            }
             makeList?.let {
                 val allPrice = calculateTotal(it)
-                val name = buildNameString(it)
+                val orderName = buildNameString(it)
                 val sn = payInfo.payNamber
                 val payType = payInfo.payType
                 CoroutineScope(Dispatchers.Main).launch {
-                    Log.d(TAG, "insert: sn:${sn}allPrice:${allPrice}payType:${payType}name:${name}")
-                    mViewModel.addLocalOrder(sn, allPrice, payType, name)
+                    Log.d(TAG, "insert: sn:${sn}allPrice:${allPrice}payType:${payType}name:${orderName}")
+                    val sysTime = System.currentTimeMillis() //获取系统时间
+                    val sysTimeStr = DateFormat.format("yyyy-MM-dd HH:mm:ss", sysTime) //时间显示格式
+                    val responseContent = hashMapOf(
+                        "sn" to sn,
+                        "createDate" to  sysTimeStr.toString(),
+                        "name" to name,
+                        "no" to no,
+                        "clientId" to Heartbeat.deviceId,
+                        "price" to allPrice,
+                        "payType" to PayEnum.getEnumByValuePayType(payInfo.payType).toString(),
+                        "productNumber" to productCount
+                    )
+                    val map = hashMapOf(
+                        "responseContent" to responseContent,
+                        "statusCode" to 200,
+                        "timestamp" to sysTime,
+                        "clientId" to Heartbeat.deviceId,
+                        "operation" to "uploadOrder",
+                        "direction" to 2,
+                    )
+                    Log.d(TAG, "gotoMake:toJsonmap "+Gson().toJson(map))
+                    mViewModel.addOfflineOrder(Gson().toJson(map).toString())
+                    EventBus.getDefault().post(ApiMessageEvent(MMKVName.OFFLINE_ORDER,Gson().toJson(map)))
+                    mViewModel.addLocalOrder(sn, allPrice, payType, orderName,sysTimeStr.toString())
                 }
             }
             try {
@@ -547,7 +606,8 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
                     product.imgID,
                     product.nameChinese,
                     product.index,
-                    1
+                    1,
+                    product.customName
                 )
                 resultList.add(newItem)
             }
@@ -652,7 +712,7 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
 
             if (fragment.pauseTime) {
                 fragment.backTime--
-                Log.d("backTime", "setTimeDate: "+fragment.backTime)
+                Log.d("backTime", "setTimeDate: " + fragment.backTime)
                 if (fragment.backTime == 0) {
                     val findNavController = fragment.findNavController()
                     findNavController.navigate(R.id.home_action_home_homefragment_to_home_buyfragment)
@@ -775,6 +835,7 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
                 val way = SpUtils.getString(MMKVName.CONTACT_WAY, "")
                 showContactDialog(name, way)
             }
+
             R.id.ll_language_switch,
             -> {
                 showLanguageDialog()
@@ -894,7 +955,7 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         }
         languageSelectorDialog?.setListener(object : LanguageClickListener {
             override fun onItemListener(type: Int) {
-                Log.d(TAG, "onItemListener: "+type)
+                Log.d(TAG, "onItemListener: " + type)
                 ARouter.getInstance().build(RouteUrl.Main.MainActivity).navigation()
                 activity?.finish()
             }

+ 21 - 5
module_home/src/main/java/com/quyunshuo/module/home/fragment/vm/HomeFragmentVM.kt

@@ -4,6 +4,8 @@ import android.text.format.DateFormat
 import android.util.Log
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
 import com.hboxs.serialport.plc.frame.ResponseFrame
 import com.hboxs.serialport.plc.message.Message
 import com.hboxs.serialport.plc.thread.ThreadHomeParam
@@ -14,6 +16,7 @@ import com.hboxs.serialport.sbc.VBoxMessage
 import com.hboxs.serialport.sbc.frame.VboxCommand
 import com.module.database.room.SZDatabase
 import com.module.database.room.entity.LocalOrderBean
+import com.module.database.room.entity.OfflineOrderBean
 import com.quyunshuo.sbm10.base.BaseApplication
 import com.quyunshuo.sbm10.base.addressenum.PlcHomeAddressEnum
 import com.quyunshuo.sbm10.base.mvvm.vm.BaseViewModel
@@ -25,9 +28,14 @@ import com.quyunshuo.module.home.R
 import com.quyunshuo.module.home.fragment.repo.HomeFragmentRepo
 import com.quyunshuo.module.home.interfaces.IShoppingTrolley
 import com.quyunshuo.sbm10.base.bean.Global
+import com.quyunshuo.sbm10.base.utils.GsonUtil
 import com.quyunshuo.sbm10.base.utils.SpUtils
+import com.quyunshuo.sbm10.common.bean.SettingTypeBean
 import com.quyunshuo.sbm10.common.constant.MMKVName
 import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 import javax.inject.Inject
 
 /**
@@ -52,6 +60,7 @@ class HomeFragmentVM @Inject constructor(private val mRepo: HomeFragmentRepo) :
     private val _shoppingCarSumPrice = MutableLiveData<Double>()
     val shoppingCarSumPrice: LiveData<Double> get() = _shoppingCarSumPrice
     private val localOrderDao = SZDatabase.getDatabase(BaseApplication.context).getLocalOrderDao()
+    private val offlineOrderDao = SZDatabase.getDatabase(BaseApplication.context).getOfflineOrderDao()
 
     private val _coinValue = MutableLiveData<String>()
     val coinValue: LiveData<String> get() = _coinValue
@@ -69,20 +78,26 @@ class HomeFragmentVM @Inject constructor(private val mRepo: HomeFragmentRepo) :
         return arrayList
     }
 
-    suspend fun addLocalOrder(sn: String, price: Double, payType: String, name: String) {
-        val sysTime = System.currentTimeMillis() //获取系统时间
-        val sysTimeStr = DateFormat.format("yyyy-MM-dd HH:mm:ss", sysTime) //时间显示格式
+    suspend fun addLocalOrder(sn: String, price: Double, payType: String, name: String,time :String) {
         localOrderDao.insert(
             LocalOrderBean(
                 price = price,
                 payType = payType,
                 sn = sn,
-                time = sysTimeStr.toString(),
+                time = time,
                 name = name
             )
         )
     }
 
+    suspend fun addOfflineOrder(map: String) {
+        offlineOrderDao.insert(
+            OfflineOrderBean(
+                map = map
+            )
+        )
+    }
+
     /**
      * 获取 banner 数据
      */
@@ -276,7 +291,8 @@ class HomeFragmentVM @Inject constructor(private val mRepo: HomeFragmentRepo) :
                 productDataBean.imgID,
                 productDataBean.nameChinese,
                 productDataBean.index,
-                1
+                1,
+                productDataBean.customName
             )
             shoppingCartList.add(newItem)
         }

+ 108 - 76
module_home/src/main/java/com/quyunshuo/module/home/service/GlobalService.kt

@@ -9,12 +9,9 @@ import android.content.Intent
 import android.content.IntentFilter
 import android.media.AudioManager
 import android.os.Build
-import android.os.Bundle
 import android.os.IBinder
 import android.util.Log
 import android.view.WindowManager
-import androidx.navigation.fragment.NavHostFragment.findNavController
-import androidx.navigation.fragment.findNavController
 import com.google.gson.Gson
 import com.google.gson.JsonObject
 import com.google.gson.reflect.TypeToken
@@ -23,6 +20,8 @@ import com.hboxs.serialport.sbc.VboxSerialPortSendQueue
 import com.hboxs.serialport.sbc.frame.VboxCommand
 import com.hboxs.serialport.sbc.frame.VboxWriteCommand
 import com.hjq.http.lifecycle.LifecycleService
+import com.module.database.room.SZDatabase
+import com.module.database.room.entity.OfflineOrderBean
 import com.module.pay.common.PayAgreementUtil
 import com.module.pay.nayax.CreditCardPresenter
 import com.module.pay.strategy.PaySendDataFactory
@@ -32,10 +31,10 @@ import com.quyunshuo.module.home.dialog.CountDownDialogFragment
 import com.quyunshuo.module.home.dialog.WarringDialog
 import com.quyunshuo.module.home.receiver.MqttHelper
 import com.quyunshuo.module.home.receiver.TimedCleaningTaskAlarmReceiver
+import com.quyunshuo.sbm10.base.BaseApplication
 import com.quyunshuo.sbm10.base.DialogClickListener
 import com.quyunshuo.sbm10.base.ktx.observeLiveData
 import com.quyunshuo.sbm10.base.utils.GsonUtil
-import com.quyunshuo.sbm10.base.utils.JsonUtils
 import com.quyunshuo.sbm10.base.utils.SpUtils
 import com.quyunshuo.sbm10.base.utils.TimeUtil
 import com.quyunshuo.sbm10.base.utils.XLogUtil
@@ -120,8 +119,8 @@ class GlobalService : LifecycleService() {
         }
         initPayIctMdb()
 
-        if (SpUtils.getString(MMKVName.OPEN_DEV,"0")!="0"){
-            SpUtils.putString(MMKVName.OPEN_DEV,"0")
+        if (SpUtils.getString(MMKVName.OPEN_DEV, "0") != "0") {
+            SpUtils.putString(MMKVName.OPEN_DEV, "0")
         }
         showTipsDialog(UiUtil.getStringRes(R.string.initializing))//是否开机
         observeLiveData(globalServiceViewModel.initIsSuccess, ::initIsSuccess)
@@ -129,15 +128,30 @@ class GlobalService : LifecycleService() {
         globalServiceViewModel.sendBackData()//心跳上传
 //        globalServiceViewModel.forceBackToApp()
         initMaterial()
+        initUpLoadOrder()
 
     }
 
+    private fun initUpLoadOrder() {
+        CoroutineScope(Dispatchers.Main).launch {
+            while (true) {
+                val list = offlineOrderDao.getAll()
+                Log.d(TAG, "initUpLoadOrder: "+list)
+                if (list.size<=0){
+                    return@launch
+                }
+                EventBus.getDefault().post(ApiMessageEvent(MMKVName.OFFLINE_ORDER, list[0].map))
+                delay(1000 * 60*3)
+            }
+        }
+    }
+
     private fun initMaterial() {
-        val isMaterial = SpUtils.getBoolean(MMKVName.MATERIAL,false)
-        if (isMaterial==true){
-            EventBus.getDefault().post(ApiMessageEvent(MMKVName.MATERIAL,"1"))
-        }else{
-            EventBus.getDefault().post(ApiMessageEvent(MMKVName.MATERIAL,"0"))
+        val isMaterial = SpUtils.getBoolean(MMKVName.MATERIAL, false)
+        if (isMaterial == true) {
+            EventBus.getDefault().post(ApiMessageEvent(MMKVName.MATERIAL, "1"))
+        } else {
+            EventBus.getDefault().post(ApiMessageEvent(MMKVName.MATERIAL, "0"))
         }
     }
 
@@ -279,16 +293,16 @@ class GlobalService : LifecycleService() {
                 if (sweet <= 0) {
                     //这里是缺甜玉米,那么将隐藏甜玉米这个商品
 //                    list[0].isSelected = false
-                    sweetType=2
+                    sweetType = 2
                     warnBean = WarningBean(
-                        "No.4" + UiUtil.getStringRes( R.string.alarm_message_04),
+                        "No.4" + UiUtil.getStringRes(R.string.alarm_message_04),
                         Heartbeat.clientId.toString(),
                         TimeUtil.getStrCurTime(),
                         1,
                         ""
                     )
                 } else {
-                    if (sweetType==0) {
+                    if (sweetType == 0) {
                         sweetType = 1
                         warnBean = WarningBean(
                             "No.4" + UiUtil.getStringRes(R.string.sweet_corn_remain) + ": " + sweet + "g",
@@ -305,9 +319,9 @@ class GlobalService : LifecycleService() {
             if (salty < 400) {
                 if (salty <= 0) {
                     //这里是缺咸玉米,那么将隐藏咸玉米这个商品
-                    saltyType=2
+                    saltyType = 2
                     warnBean = WarningBean(
-                        "No.3" + UiUtil.getStringRes( R.string.alarm_message_03),
+                        "No.3" + UiUtil.getStringRes(R.string.alarm_message_03),
                         Heartbeat.clientId.toString(),
                         TimeUtil.getStrCurTime(),
                         1,
@@ -315,7 +329,7 @@ class GlobalService : LifecycleService() {
                     )
 //                    list[1].isSelected = false
                 } else {
-                    if (saltyType==0) {
+                    if (saltyType == 0) {
                         saltyType = 1
                         warnBean = WarningBean(
                             "No.3" + UiUtil.getStringRes(R.string.salty_corn_remain) + ": " + salty + "g",
@@ -333,7 +347,7 @@ class GlobalService : LifecycleService() {
                 if (box <= 0) {
                     showWarringDialog("No.2", R.string.alarm_message_02)
                 } else {
-                    if (boxType==0) {
+                    if (boxType == 0) {
                         boxType = 1
                         warnBean = WarningBean(
                             "No.2" + UiUtil.getStringRes(R.string.box_remain) + ": " + box,
@@ -425,27 +439,31 @@ class GlobalService : LifecycleService() {
                 mqttHelper.sendData("response", Gson().toJson(map))
                 XLogUtil.d("本地主动消除报警")
             }
+
             MqName.MATERIAL -> {
                 mqttHelper.sendData("response", Gson().toJson(messageEvent.data))
-                Log.d(TAG, "event:MATERIAL "+Gson().toJson(messageEvent.data))
+                Log.d(TAG, "event:MATERIAL " + Gson().toJson(messageEvent.data))
             }
-            MqName.SLEEP ->{
+
+            MqName.SLEEP -> {
                 mqttHelper.sendData("response", Gson().toJson(messageEvent.data))
             }
-            MqName.PASSWORD->{
+
+            MqName.PASSWORD -> {
                 val map = Gson().fromJson(messageEvent.data.toString(), JsonObject::class.java)
-                val response= map.getAsJsonObject("responseContent")
+                val response = map.getAsJsonObject("responseContent")
                 val password = response["password"].toString()
                 val type = response["type"].toString()
-                Log.d(TAG, "event:PASSWORD "+password+":"+type)
-                if (type=="0"){
+                Log.d(TAG, "event:PASSWORD " + password + ":" + type)
+                if (type == "0") {
                     SpUtils.putString(MqName.ADMIN_PWD, password)
-                }else{
+                } else {
                     SpUtils.putString(MqName.GUEST_PWD, password)
                 }
                 mqttHelper.sendData("response", Gson().toJson(messageEvent.data))
             }
-            MqName.VOLUME->{
+
+            MqName.VOLUME -> {
                 val map = Gson().fromJson(messageEvent.data.toString(), JsonObject::class.java)
                 val progress = map.get("responseContent").asInt
                 val audioManager =
@@ -459,44 +477,44 @@ class GlobalService : LifecycleService() {
                 XLogUtil.d("远程修改了音量$progress")
             }
 
-            MqName.UPDATEPRODUCT->{
+            MqName.UPDATEPRODUCT -> {
                 val map = Gson().fromJson(messageEvent.data.toString(), JsonObject::class.java)
-                Log.d(TAG, "eventUPDATEPRODUCT: "+map)
-                val response= map.getAsJsonObject("responseContent")
+                Log.d(TAG, "eventUPDATEPRODUCT: " + map)
+                val response = map.getAsJsonObject("responseContent")
 //                val no = JsonUtils.getValue<String>(response.toString(),"no").toString()
 //                val productName = JsonUtils.getValue<String>(response.toString(),"productName")
 //                val codePrice = response["codePrice"].asDouble
 //                val sellStatus = response["sellStatus"].asBoolean
-                val no = GsonUtil.getAsString(response,"no","")
-                val productName = GsonUtil.getAsString(response,"productName","")
-                val codePrice = GsonUtil.getAsDouble(response,"codePrice",0.0)
-                val sellStatus = GsonUtil.getAsBoolean(response,"sellStatus",true)
-                val productData= SpUtils.getString(MMKVName.PRODUCT_DATA,"")
-                Log.d(TAG, "eventproductData1: "+productData)
+                val no = GsonUtil.getAsString(response, "no", "")
+                val productName = GsonUtil.getAsString(response, "productName", "")
+                val codePrice = GsonUtil.getAsDouble(response, "codePrice", 0.0)
+                val sellStatus = GsonUtil.getAsBoolean(response, "sellStatus", true)
+                val productData = SpUtils.getString(MMKVName.PRODUCT_DATA, "")
+                Log.d(TAG, "eventproductData1: " + productData)
                 val list: ArrayList<ProductDataBean> = Gson().fromJson(
                     productData,
                     object : TypeToken<ArrayList<ProductDataBean?>?>() {}.type
                 )
-                for (i in list.indices){
-                    if (list[i].productNo==no){
-                        list[i].price=codePrice
-                        list[i].customName=productName
-                        list[i].isSelected=sellStatus
+                for (i in list.indices) {
+                    if (list[i].productNo == no) {
+                        list[i].price = codePrice
+                        list[i].customName = productName
+                        list[i].isSelected = sellStatus
                     }
                 }
-                XLogUtil.d("远程修改了商品:"+Gson().toJson(list))
-                SpUtils.putString(MMKVName.PRODUCT_DATA,Gson().toJson(list))
-                Log.d(TAG, "eventPRODUCT_DATA: "+SpUtils.getString(MMKVName.PRODUCT_DATA,""))
+                XLogUtil.d("远程修改了商品:" + Gson().toJson(list))
+                SpUtils.putString(MMKVName.PRODUCT_DATA, Gson().toJson(list))
+                Log.d(TAG, "eventPRODUCT_DATA: " + SpUtils.getString(MMKVName.PRODUCT_DATA, ""))
                 mqttHelper.sendData("response", Gson().toJson(messageEvent.data))
             }
 
-            MqName.EQESTATUS->{
-                Log.d(TAG, " MqName.EQESTATUSevent: "+messageEvent.data)
+            MqName.EQESTATUS -> {
+                Log.d(TAG, " MqName.EQESTATUSevent: " + messageEvent.data)
                 val map = Gson().fromJson(messageEvent.data.toString(), JsonObject::class.java)
-                val response= map.getAsJsonObject("responseContent")
-                val eqeStatus = GsonUtil.getAsString(response,"eqeStatus","0")
-                Log.d(TAG, "eventeqeStatus: "+eqeStatus)
-                if (eqeStatus=="1"){
+                val response = map.getAsJsonObject("responseContent")
+                val eqeStatus = GsonUtil.getAsString(response, "eqeStatus", "0")
+                Log.d(TAG, "eventeqeStatus: " + eqeStatus)
+                if (eqeStatus == "1") {
                     globalServiceViewModel.threadGlobalParam.stopUp()
                     globalServiceViewModel.threadGlobalParam.startUp()
                     Log.d(TAG, "event: startUp")
@@ -504,10 +522,10 @@ class GlobalService : LifecycleService() {
                 mqttHelper.sendData("response", Gson().toJson(messageEvent.data))
             }
 
-            MqName.OPENDOOR->{
+            MqName.OPENDOOR -> {
                 val map = Gson().fromJson(messageEvent.data.toString(), JsonObject::class.java)
-                val response= map.getAsJsonObject("responseContent")
-                val productName = GsonUtil.getAsString(response,"status","0")
+                val response = map.getAsJsonObject("responseContent")
+                val productName = GsonUtil.getAsString(response, "status", "0")
                 VboxSerialPortSendQueue.getInstance()
                     .sendCommand(
                         VboxWriteCommand(
@@ -518,49 +536,63 @@ class GlobalService : LifecycleService() {
                 mqttHelper.sendData("response", Gson().toJson(messageEvent.data))
             }
 
-            MqName.PHONE->{
+            MqName.PHONE -> {
                 val map = Gson().fromJson(messageEvent.data.toString(), JsonObject::class.java)
-                val response= map.getAsJsonObject("responseContent")
-                val contactName = GsonUtil.getAsString(response,"contactName","")
-                val contactPhone = GsonUtil.getAsString(response,"contactPhone","")
-                SpUtils.putString(MMKVName.CONTACT,contactName)
-                SpUtils.putString(MMKVName.CONTACT_WAY,contactPhone)
+                val response = map.getAsJsonObject("responseContent")
+                val contactName = GsonUtil.getAsString(response, "contactName", "")
+                val contactPhone = GsonUtil.getAsString(response, "contactPhone", "")
+                SpUtils.putString(MMKVName.CONTACT, contactName)
+                SpUtils.putString(MMKVName.CONTACT_WAY, contactPhone)
                 mqttHelper.sendData("response", Gson().toJson(messageEvent.data))
             }
 
-            MqName.SLEEPDESC->{
+            MqName.SLEEPDESC -> {
                 val map = Gson().fromJson(messageEvent.data.toString(), JsonObject::class.java)
-                val responseContent= map.getAsJsonObject("responseContent")
-                val sleepDesc = GsonUtil.getAsString(responseContent,"sleepDesc",UiUtil.getStringRes(R.string.device_sleep))
-                SpUtils.putString(MMKVName.SLEEP_TEXT,sleepDesc)
-                EventBus.getDefault().post(ApiMessageEvent(MMKVName.SLEEP_TEXT,sleepDesc))
-                Log.d(TAG, "eventqName.SLEEPDESC: "+messageEvent.data)
+                val responseContent = map.getAsJsonObject("responseContent")
+                val sleepDesc = GsonUtil.getAsString(
+                    responseContent,
+                    "sleepDesc",
+                    UiUtil.getStringRes(R.string.device_sleep)
+                )
+                SpUtils.putString(MMKVName.SLEEP_TEXT, sleepDesc)
+                EventBus.getDefault().post(ApiMessageEvent(MMKVName.SLEEP_TEXT, sleepDesc))
+                Log.d(TAG, "eventqName.SLEEPDESC: " + messageEvent.data)
                 mqttHelper.sendData("response", Gson().toJson(messageEvent.data))
             }
-            MqName.BATCHUPDATEPRICE->{
+
+            MqName.BATCHUPDATEPRICE -> {
                 val map = Gson().fromJson(messageEvent.data.toString(), JsonObject::class.java)
-                val response= GsonUtil.getAsString(map,"responseContent","")
-                Log.d(TAG, "MqName.BATCHUPDATEPRICE:event: "+response)
-                Log.d(TAG, " MqName.BATCHUPDATEPRICE: "+messageEvent.data)
-                val productData= SpUtils.getString(MMKVName.PRODUCT_DATA,"")
+                val response = GsonUtil.getAsString(map, "responseContent", "")
+                Log.d(TAG, "MqName.BATCHUPDATEPRICE:event: " + response)
+                Log.d(TAG, " MqName.BATCHUPDATEPRICE: " + messageEvent.data)
+                val productData = SpUtils.getString(MMKVName.PRODUCT_DATA, "")
                 val list: ArrayList<ProductDataBean> = Gson().fromJson(
                     productData,
                     object : TypeToken<ArrayList<ProductDataBean?>?>() {}.type
                 )
-                for (i in list.indices){
-                        list[i].price= response.toDouble()
-                    }
-                XLogUtil.d("远程一键修改商品价格:"+Gson().toJson(list))
-                SpUtils.putString(MMKVName.PRODUCT_DATA,Gson().toJson(list))
+                for (i in list.indices) {
+                    list[i].price = response.toDouble()
+                }
+                XLogUtil.d("远程一键修改商品价格:" + Gson().toJson(list))
+                SpUtils.putString(MMKVName.PRODUCT_DATA, Gson().toJson(list))
                 mqttHelper.sendData("response", Gson().toJson(messageEvent.data))
             }
-            MqName.PRODUCEGOODS->{
-                Log.d(TAG, "PRODUCEGOODSevent:1 "+messageEvent.data.toString())
+
+            MqName.PRODUCEGOODS -> {
+                Log.d(TAG, "PRODUCEGOODSevent:1 " + messageEvent.data.toString())
+                mqttHelper.sendData("response", messageEvent.data.toString())
+            }
+
+            MMKVName.OFFLINE_ORDER -> {
+                Log.d(TAG, "OFFLINE_ORDERevent: " + messageEvent.data.toString())
                 mqttHelper.sendData("response", messageEvent.data.toString())
             }
         }
     }
 
+    private val offlineOrderDao =
+        SZDatabase.getDatabase(BaseApplication.context).getOfflineOrderDao()
+
     override fun onDestroy() {
         super.onDestroy()
         EventBus.getDefault().unregister(this)

+ 29 - 0
module_home/src/main/java/com/quyunshuo/module/home/utils/RemotePushUtil.kt

@@ -11,6 +11,8 @@ import com.google.gson.Gson
 import com.hboxs.serialport.plc.message.Message
 import com.hboxs.serialport.plc.thread.ThreadSettingParam
 import com.hboxs.serialport.sbc.SBCHeartbeat
+import com.module.database.room.SZDatabase
+import com.module.database.room.entity.OfflineOrderBean
 import com.qiniu.android.http.ResponseInfo
 import com.qiniu.android.storage.UpCompletionHandler
 import com.qiniu.android.storage.UploadManager
@@ -357,9 +359,36 @@ class RemotePushUtil @Inject constructor() {
                 Log.d(TAG, "PRODUCEGOODSgetMqttMessage: "+Gson().toJson(map))
                 EventBus.getDefault().post(ApiMessageEvent(MqName.PRODUCEGOODS, Gson().toJson(map)))
             }
+            MqName.UPLOADORDER->{
+                val timestamp = GsonUtil.getAsString(msg,"timestamp","").toLong()
+                Log.d(TAG, "UPLOADORDERgetMqttMessage: "+timestamp)
+                CoroutineScope(Dispatchers.Main).launch {
+                    deleteOrdersByTimestamp(timestamp)
+                }
+            }
         }
     }
 
+    private val offlineOrderDao = SZDatabase.getDatabase(BaseApplication.context).getOfflineOrderDao()
+
+    suspend fun addOfflineOrder(): List<OfflineOrderBean> {
+        return offlineOrderDao.getAll()
+    }
+
+    suspend fun deleteOrdersByTimestamp(targetTimestamp: Long) {
+        // 获取所有的离线订单
+        val offlineOrders = offlineOrderDao.getAll()
+        Log.d(TAG, "deleteOrdersByTimestamp:1 "+offlineOrders)
+        // 遍历每个订单,检查其 map 中的 timestamp
+        for (order in offlineOrders) {
+            val timestamp = GsonUtil.getAsString(order.map,"timestamp","").toLong()
+            Log.d(TAG, "deleteOrdersByTimestamp: "+timestamp)
+//            // 如果找到匹配的 timestamp,则删除该订单
+            if (timestamp == targetTimestamp) {
+                offlineOrderDao.delete(order)
+            }
+        }
+    }
     private fun setMap(msgId: String, response: Any): HashMap<String, *> {
         val map = hashMapOf(
             "clientId" to Heartbeat.deviceId,