Jelajahi Sumber

优化广告以及新增mqtt等逻辑

ccc 4 bulan lalu
induk
melakukan
ed06d2f13d
73 mengubah file dengan 2188 tambahan dan 517 penghapusan
  1. 3 1
      app/src/main/AndroidManifest.xml
  2. 2 1
      app/src/main/java/com/sunzee/app/AppApplication.kt
  3. 2 2
      buildSrc/src/main/kotlin/com/quyunshuo/androidbaseframemvvm/buildsrc/ProjectBuildConfig.kt
  4. 4 1
      lib_base/build.gradle
  5. TEMPAT SAMPAH
      lib_base/libs/ZtlApi.jar
  6. 5 0
      lib_base/src/main/java/com/quyunshuo/androidbaseframemvvm/base/bean/Global.kt
  7. 4 4
      lib_base/src/main/java/com/quyunshuo/androidbaseframemvvm/base/mvvm/v/BaseFrameFragment.kt
  8. 36 1
      lib_base/src/main/res/values/strings.xml
  9. 4 2
      lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/bean/ProductDataBean.kt
  10. 1 0
      lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/bean/ShoppingCartBean.kt
  11. 94 9
      lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/constant/MMKVName.kt
  12. 6 1
      lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/constant/MqName.kt
  13. 9 0
      lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/constant/SavaAddress.kt
  14. 1 1
      lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/util/AlarmManagerUtil.java
  15. 3 3
      lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/util/FileUtil.kt
  16. 18 2
      lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/util/XLogUtil.kt
  17. 7 2
      module_backstage/src/main/java/com/module/backstage/activity/setting/SettingActivity.kt
  18. 1 0
      module_backstage/src/main/java/com/module/backstage/activity/setting/SettingRepository.kt
  19. 28 7
      module_backstage/src/main/java/com/module/backstage/adapter/LocalAlarmClockAdapter.kt
  20. 286 46
      module_backstage/src/main/java/com/module/backstage/adapter/TestAdapter.kt
  21. 25 5
      module_backstage/src/main/java/com/module/backstage/fragment/LocalAlarmClockFragment.kt
  22. 4 5
      module_backstage/src/main/java/com/module/backstage/repo/OtherFragmentRepo.kt
  23. 42 13
      module_backstage/src/main/java/com/module/backstage/repo/SystemSettingsFragmentRepo.kt
  24. 24 0
      module_backstage/src/main/res/drawable/seekbar_progress_drawable.xml
  25. 23 0
      module_backstage/src/main/res/drawable/shape_radio_thumb.xml
  26. 10 10
      module_backstage/src/main/res/layout/backstage_activity_setting.xml
  27. 1 1
      module_backstage/src/main/res/layout/backstage_fragment_price.xml
  28. 36 0
      module_backstage/src/main/res/layout/backstage_item_button.xml
  29. 2 1
      module_backstage/src/main/res/layout/backstage_item_input.xml
  30. 37 0
      module_backstage/src/main/res/layout/backstage_item_slider.xml
  31. 1 1
      module_backstage/src/main/res/layout/backstage_item_system_settings.xml
  32. 38 0
      module_backstage/src/main/res/layout/backstage_item_text.xml
  33. 2 1
      module_home/src/main/AndroidManifest.xml
  34. 26 0
      module_home/src/main/assets/version_0.json
  35. 22 19
      module_home/src/main/java/com/quyunshuo/module/home/activity/main/MainViewModel.kt
  36. 4 0
      module_home/src/main/java/com/quyunshuo/module/home/bean/PaySuccessBean.kt
  37. 62 2
      module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/BuyFragment.kt
  38. 252 77
      module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/HomeFragment.kt
  39. 3 15
      module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/MakeFragment.kt
  40. 15 3
      module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/pay/BillCoinFragment.kt
  41. 13 1
      module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/pay/FreeMakeFragment.kt
  42. 26 14
      module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/pay/MDBCardFragment.kt
  43. 24 10
      module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/pay/NayaxCardFragment.kt
  44. 17 18
      module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/pay/QrCodeFragment.kt
  45. 0 5
      module_home/src/main/java/com/quyunshuo/module/home/fragment/repo/MakeFragmentRepo.kt
  46. 20 0
      module_home/src/main/java/com/quyunshuo/module/home/fragment/vm/HomeFragmentVM.kt
  47. 0 6
      module_home/src/main/java/com/quyunshuo/module/home/fragment/vm/MakeFragmentVM.kt
  48. 1 1
      module_home/src/main/java/com/quyunshuo/module/home/fragment/vm/QrCodeFragmentVM.kt
  49. 1 1
      module_home/src/main/java/com/quyunshuo/module/home/pay/WeChatAlipayPayMent.kt
  50. 1 1
      module_home/src/main/java/com/quyunshuo/module/home/pay/WeChatAlipayPayShoppingCartMent.kt
  51. 10 4
      module_home/src/main/java/com/quyunshuo/module/home/receiver/MqttHelper.kt
  52. 170 0
      module_home/src/main/java/com/quyunshuo/module/home/service/ForceBackToAppService.kt
  53. 24 7
      module_home/src/main/java/com/quyunshuo/module/home/service/ManageMqtt.kt
  54. 30 4
      module_home/src/main/java/com/quyunshuo/module/home/service/MqService.kt
  55. 2 1
      module_home/src/main/java/com/quyunshuo/module/home/service/MqServiceRepository.kt
  56. 63 0
      module_home/src/main/java/com/quyunshuo/module/home/utils/AssetManager.kt
  57. 133 0
      module_home/src/main/java/com/quyunshuo/module/home/utils/CommodityManage.java
  58. 156 0
      module_home/src/main/java/com/quyunshuo/module/home/utils/NetWorkUtils.java
  59. 29 0
      module_home/src/main/java/com/quyunshuo/module/home/utils/OrderNumberGenerator.java
  60. 30 0
      module_home/src/main/java/com/quyunshuo/module/home/utils/PhoneStateUtils.java
  61. 141 58
      module_home/src/main/java/com/quyunshuo/module/home/utils/RemotePushUtil.kt
  62. 14 128
      module_home/src/main/java/com/quyunshuo/module/home/utils/SimplePlayerUtil.kt
  63. TEMPAT SAMPAH
      module_home/src/main/res/drawable/leven0.png
  64. TEMPAT SAMPAH
      module_home/src/main/res/drawable/leven1.png
  65. TEMPAT SAMPAH
      module_home/src/main/res/drawable/leven2.png
  66. TEMPAT SAMPAH
      module_home/src/main/res/drawable/leven3.png
  67. TEMPAT SAMPAH
      module_home/src/main/res/drawable/leven4.png
  68. TEMPAT SAMPAH
      module_home/src/main/res/drawable/wifi.png
  69. 34 3
      module_home/src/main/res/layout/home_fragment_buy.xml
  70. 31 10
      module_home/src/main/res/layout/home_fragment_home.xml
  71. 47 7
      module_pay/src/main/java/com/module/pay/common/OtherEnum.kt
  72. 3 2
      module_pay/src/main/java/com/module/pay/strategy/PaySendDataMDBStrategy.kt
  73. 25 0
      serialport-api/src/main/java/com/hboxs/serialport/plc/message/MqttMessageBean.java

+ 3 - 1
app/src/main/AndroidManifest.xml

@@ -20,12 +20,14 @@
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:theme="@style/base_AppTheme"
+        tools:replace="android:allowBackup"
         android:requestLegacyExternalStorage="true"
         tools:ignore="UnusedAttribute">
 
         <service android:name="com.quyunshuo.module.home.service.GlobalService" />
         <service android:name="com.quyunshuo.module.home.service.MqService" />
-
+        <service android:name="com.quyunshuo.module.home.service.ForceBackToAppService"
+            android:process=":my_service_process"/>
     </application>
 
 </manifest>

+ 2 - 1
app/src/main/java/com/sunzee/app/AppApplication.kt

@@ -77,7 +77,8 @@ class AppApplication : BaseApplication() {
 
         // 网络请求框架初始化
         EasyConfig.with(okHttpClient)
-            .setServer { "http://192.168.1.105:8080/" } // 设置服务器配置(必须设置)
+//            .setServer { "http://192.168.1.105:8080/" } // 设置服务器配置(必须设置)
+            .setServer { "https://sz.sunzee.com.cn/" } // 设置服务器配置(必须设置)
             .setHandler(object : IRequestHandler {
                 override fun requestSuccess(p0: HttpRequest<*>, result: Response, p2: Type): Any {
                     return result

+ 2 - 2
buildSrc/src/main/kotlin/com/quyunshuo/androidbaseframemvvm/buildsrc/ProjectBuildConfig.kt

@@ -11,8 +11,8 @@ object ProjectBuildConfig {
     const val applicationId = "com.quyunshuo.androidbaseframemvvm"
     const val minSdkVersion = 21
     const val targetSdkVersion = 29
-    const val versionCode = 1
-    const val versionName = "1.0.1"
+    const val versionCode = 2
+    const val versionName = "1.0.2"
     const val isAppMode = false
     /**
      * 项目当前的版本状态

+ 4 - 1
lib_base/build.gradle

@@ -79,7 +79,10 @@ dependencies {
 //    api DependencyConfig.SDK.TencentTBSX5
     api DependencyConfig.SDK.GeTui
     api DependencyConfig.SDK.RabbitMq
-
+    api files('libs\\ZtlApi.jar')
+    api "com.github.weilinhu:mylibaray:1.0" //https://github.com/weilinhu/mylibaray //监听网络情况。
+    api 'com.github.ldt-libs:SpringBackLayout:1.0' //回弹效果
+    api 'com.github.kabouzeid:RecyclerView-FastScroll:1.0.16-kmod'
 
     kapt DependencyConfig.GitHub.ARouteCompiler
     kapt DependencyConfig.GitHub.EventBusAPT

TEMPAT SAMPAH
lib_base/libs/ZtlApi.jar


+ 5 - 0
lib_base/src/main/java/com/quyunshuo/androidbaseframemvvm/base/bean/Global.kt

@@ -0,0 +1,5 @@
+package com.quyunshuo.androidbaseframemvvm.base.bean
+
+object Global {
+    var isNetWork: Boolean = false //自主检测里面来测试是否有网络
+}

+ 4 - 4
lib_base/src/main/java/com/quyunshuo/androidbaseframemvvm/base/mvvm/v/BaseFrameFragment.kt

@@ -3,6 +3,7 @@ package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
 import android.os.Bundle
 import android.util.Log
 import android.view.LayoutInflater
+import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
 import androidx.fragment.app.Fragment
@@ -26,8 +27,7 @@ abstract class BaseFrameFragment<VB : ViewBinding, VM : BaseViewModel> : Fragmen
      */
     private var _binding: VB? = null
 
-    protected val mBinding :VB
-        get() = _binding!!
+    protected val mBinding get() = _binding!!
 
     protected abstract val mViewModel: VM
 
@@ -42,7 +42,6 @@ abstract class BaseFrameFragment<VB : ViewBinding, VM : BaseViewModel> : Fragmen
         savedInstanceState: Bundle?
     ): View? {
         _binding = createVB()
-
         return _binding?.root
     }
 
@@ -50,7 +49,8 @@ abstract class BaseFrameFragment<VB : ViewBinding, VM : BaseViewModel> : Fragmen
         super.onViewCreated(view, savedInstanceState)
         // ARouter 依赖注入
         ARouter.getInstance().inject(this)
-
+        var className=javaClass.name
+        Log.d("backinfo","类名:"+className)
         // 根据子类是否有 RegisterEventBus 注解決定是否进行注册 EventBus
         if (javaClass.isAnnotationPresent(RegisterEventBus::class.java)) {
             mHaveRegisterEventBus = true

+ 36 - 1
lib_base/src/main/res/values/strings.xml

@@ -184,7 +184,42 @@
     <string name="alarm_message_07">挡片复位失败</string>
     <string name="alarm_message_08">玉米芯卡住</string>
     <string name="heartbeat_temp">发生器温度</string>
+    <string name="mqtt_con_state">mqtt尚未连接,请稍后</string>
+    <string name="mdb_cash_sale">MDB Cash Sale</string>
+    <string name="contact_way">联系方式</string>
+    <string name="auto_start_hotspot">开启自启热点</string>
+    <string name="name_hotspot">热点名称</string>
+    <string name="long_click_show_status_bar">登录页长按显示状态栏</string>
+    <string name="pwd_hotspot">热点密码</string>
+    <string name="mdb_rate">MDB 倍率</string>
+    <string name="card_text">指引消费者刷卡文本</string>
+    <string name="bill_trust">纸币托管</string>
+    <string name="make_clean_price">制作后清零金额</string>
+    <string name="ad_rule">广告规则</string>
+    <string name="auto_return_home">自动返回首页(分钟)</string>
+    <string name="sleep_text">休眠中文本</string>
+    <string name="shopping_cart_size">购物车可添加数量</string>
+    <string name="two_price_discount">第二件折扣</string>
+    <string name="five_price_discount">第五件折扣</string>
+    <string name="three_price_discount">第三件折扣</string>
+    <string name="tips_discount_text">折扣提示文本</string>
+    <string name="discount_function">折扣功能</string>
+    <string name="change_function">找零功能</string>
+    <string name="change_bill">找零纸币</string>
+    <string name="change_coin">找零硬币</string>
+    <string name="change_dollar">一枚硬币的金额</string>
+    <string name="change_coin_rep">找零硬币库存</string>
+    <string name="change_allow_number">允许一次找零个数</string>
+    <string name="change_warning_number">找零预警库存</string>
+    <string name="volume">音量</string>
+    <string name="luminance">亮度</string>
     <string name="logo_text">图标变更</string>
-
+    <string name="sim">SIM</string>
+    <string name="sim_imei">SIM_IMEI</string>
+    <string name="cut_system_set">切换系统设置</string>
+    <string name="contact">联系名字</string>
+    <string name="wifi_hotspot">Wifi热点</string>
+    <string name="staff_login">员工登录</string>
+    <string name="backstage_operate">操作</string>
 
 </resources>

+ 4 - 2
lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/bean/ProductDataBean.kt

@@ -1,13 +1,15 @@
 package com.quyunshuo.androidbaseframemvvm.common.bean
 
 data class ProductDataBean(
+    var productId: Int,//id 唯一标识
+    var productNo: String,
     var price: Double,//商品价格
     var nameId: String,//商品名字id
     var imgID: String,//商品图片id
     var nameChinese: String,//商品中文名称
     var isSelected: Boolean = true,//是否显示
     var customName: String,//自定义名字
-    var index:Int,//id 唯一标识
-    var customImg:String,//自定义图片
+    var index: Int,
+    var customImg: String,//自定义图片
 
 )

+ 1 - 0
lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/bean/ShoppingCartBean.kt

@@ -4,6 +4,7 @@ package com.quyunshuo.androidbaseframemvvm.common.bean
  * 购物车list内容
  */
 data class ShoppingCartBean(
+    var productNo: String,
     var price: Double,//商品价格
     var nameId: String,//商品名字id
     var imgID: String,//商品图片id

+ 94 - 9
lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/constant/MMKVName.kt

@@ -23,10 +23,30 @@ abstract class MMKVName {
             get() = "ICT"//支付通讯协议
         val CHANGE: String
             get() = "CHANGE"//找零功能
-        val CONTACT_NAME: String
-            get() = "CONTACT_NAME"//联系人
-        val CONTACT_NUMBER: String
-            get() = "CONTACT_NUMBER"//联系方式
+        val CONTACT_WAY: String
+            get() = "CONTACT_WAY"//联系方式
+        val CONTACT: String
+            get() = "CONTACT"//联系人
+        val AUTO_START_HOTSPOT: String
+            get() = "AUTO_START_HOTSPOT"//开启自启热点
+        val NAME_HOTSPOT: String
+            get() = "NAME_HOTSPOT"//热点名称
+        val PWD_HOTSPOT: String
+            get() = "PWD_HOTSPOT"//热点密码
+        val LONG_CLICK_SHOW_STATUS_BAR: String
+            get() = "LONG_CLICK_SHOW_STATUS_BAR"//登录页长按显示状态栏
+        val LUMINANCE: String
+            get() = "LUMINANCE"//亮度
+        val SIM: String
+            get() = "SIM"//SIM 卡号
+        val SIM_IMEI: String
+            get() = "SIM_IMEI"//SIM_IMEI
+        val CUT_SYSTEM_SET: String
+            get() = "CUT_SYSTEM_SET"//切换系统设置
+        val WIFI_HOTSPOT: String
+            get() = "WIFI_HOTSPOT"//Wifi 热点
+        val VOLUME: String
+            get() = "VOLUME"//音量
         val PLAY_RULE: String
             get() = "PLAY_RULE"//播放规则
         val SETTING_TYPE: String
@@ -39,10 +59,8 @@ abstract class MMKVName {
             get() = "BLOCK"//锁机   true为锁机, false为不锁机
         val OPEN_DEV: String
             get() = "open"//开机,还是关机
-
         val QUEUE_DATA: String
             get() = "QUEUE_DATA"//连接设备id
-
         //        val SYSTEM_ID: String
 //            get()="SYSTEM_ID"//连接设备id
         val MACHINE_TYPE: String
@@ -64,9 +82,45 @@ abstract class MMKVName {
         val SHOPPING_TROLLEY: String
             //购物车开关
             get() = "SHOPPING_TROLLEY"
+        val SHOPPING_CART_SIZE: String
+            //购物车可添加数量
+            get() = "SHOPPING_CART_SIZE"
+        val TWO_PRICE_DISCOUNT: String
+            //第二件折扣
+            get() = "TWO_PIECE_DISCOUNT"
+        val THREE_PRICE_DISCOUNT: String
+            //第三件折扣
+            get() = "THREE_PIECE_DISCOUNT"
+        val FIVE_PRICE_DISCOUNT: String
+            //第五件折扣
+            get() = "FIVE_PIECE_DISCOUNT"
+        val TIPS_DISCOUNT_TEXT: String
+            //折扣提示文本
+            get() = "TIPS_DISCOUNT_TEXT"
         val PROMOTION_CODE: String
             //优惠码开关
             get() = "PROMOTION_CODE"
+        val MAKE_CLEAN_PRICE: String
+            //制作后清零金额
+            get() = "MAKE_CLEAN_PRICE"
+        val STAFF_LOGIN: String
+            //员工登录
+            get() = "STAFF_LOGIN"
+        val DISCOUNT_FUNCTION: String
+            //折扣功能
+            get() = "DISCOUNT_FUNCTION"
+        val AD_RULE: String
+            //广告规则
+            get() = "AD_RULE"
+        val AUTO_RETURN_HOME: String
+            //自动返回首页(分钟)
+            get() = "AUTO_RETURN_HOME"
+        val SLEEP_TEXT: String
+            //休眠中文本
+            get() = "SLEEP_TEXT"
+        val LOGO_TEXT: String
+            //休眠中文本
+            get() = "LOGO_TEXT"
         val BILL_COUNTRY: String
             //国家纸币选择
             get() = "BILL_COUNTRY"
@@ -88,15 +142,46 @@ abstract class MMKVName {
         val MDB_LEVEL: String
             //MDB L3级别
             get() = "MDB_LEVEL"
+        val MDB_RATE: String
+            //MDB 倍率
+            get() = "MDB_RATE"
+        val CARD_TEXT: String
+            //指引消费者刷卡文本
+            get() = "CARD_TEXT"
+        val BILL_TRUST: String
+            //纸币托管
+            get() = "BILL_TRUST"
+        val MDB_CASH_SALE: String
+            //MDB_CASH_SALE
+            get() = "MDB_CASH_SALE"
         val DIY_PAY: String
             //定制支付方式 显示开关
             get() = "DIY_PAY"
         val typeface1: Typeface
             //自定义字体样式
             get() =  Typeface.createFromAsset(BaseApplication.context.applicationContext.assets, "jiangchengyuanti.ttf")
-        val LOGO_TEXT: String
-            //logo号码
-            get() = "LOGO_TEXT"
+        val CHANGE_FUNCTION: String
+            //找零功能
+            get() = "CHANGE_FUNCTION"
+        val CHANGE_BILL: String
+            //找零纸币
+            get() = "CHANGE_BILL"
+        val CHANGE_COIN: String
+            //找零硬币
+            get() = "CHANGE_COIN"
+        val CHANGE_DOLLAR: String
+            //找零一枚硬币等于的金额
+            get() = "CHANGE_DOLLAR"
+        val CHANGE_COIN_REP: String
+            //找零硬币库存
+            get() = "CHANGE_COIN_REP"
+        val CHANGE_ALLOW_NUMBER: String
+            //允许一次找零个数
+            get() = "CHANGE_ALLOW_NUMBER"
+        val CHANGE_WARNING_NUMBER: String
+            //找零预警库存
+            get() = "CHANGE_WARNING_NUMBER"
+
     }
     // 这里可以继续添加其他常量
 

+ 6 - 1
lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/constant/MqName.kt

@@ -18,5 +18,10 @@ object MqName {
     var PHONE = "phone"//联系方式
     var ALARM_CLOCK = "alarmClock"//远程星期调节闹钟。
     var EQESTATUS = "eqeStatus"//远程开关机
-
+    var PUSHTIMERULE = "pushTimeRule"//广告规则
+    var SENDPRICE = "sendprice"//修改价格
+    var messageArrived = "messageArrived"//MQtt成功回调
+    var initialization= "initialization"//机器崩溃要重新启动
+    var updatePrice = "updatePrice"//MQtt修改价格
+    var log = "log"//上传log到服务器
 }

+ 9 - 0
lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/constant/SavaAddress.kt

@@ -0,0 +1,9 @@
+package com.quyunshuo.androidbaseframemvvm.common.constant
+
+import android.os.Environment
+
+object SavaAddress {
+    val log =Environment.getExternalStorageDirectory().path.toString() + "/logdata"
+    val savePhone =Environment.getExternalStorageDirectory().path.toString() + "/savePhone"
+    val MACHINE_TYPE="SBM10"
+}

+ 1 - 1
lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/util/AlarmManagerUtil.java

@@ -74,7 +74,7 @@ public class AlarmManagerUtil {
                 //只会执行一次,需要重复设置时间,知道吗?
        /* am.setExact(AlarmManager.RTC_WAKEUP, startLong,
                 sender);*/
-                am.setExact(AlarmManager.RTC_WAKEUP,calMethod(week, calendar.getTimeInMillis()),sender);
+                am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,calMethod(week, calendar.getTimeInMillis()),sender);
 //                AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(calMethod(week, calendar.getTimeInMillis()), null);
 //                am.setAlarmClock(alarmClockInfo,sender);
 //            }

+ 3 - 3
lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/util/FileUtil.kt

@@ -3,6 +3,7 @@ package com.quyunshuo.androidbaseframemvvm.common.util
 import android.graphics.BitmapFactory
 import android.text.TextUtils
 import android.util.Log
+import com.quyunshuo.androidbaseframemvvm.common.constant.SavaAddress
 import java.io.BufferedReader
 import java.io.File
 import java.io.FileInputStream
@@ -20,10 +21,9 @@ import java.util.Random
  * 文件工具类
  */
 object FileUtil {
-    var FILEPATH: String = "/storage/emulated/0/logdata/"
+    var FILEPATH: String = SavaAddress.log
     val SEVENT_DAYS: Long = 604800000
-    var FILEPATH_PHONE: String = "/storage/emulated/0/savePhone/"
-
+    var FILEPATH_PHONE: String = SavaAddress.savePhone
     private val TAG = "FileUtil"
 
     /**

+ 18 - 2
lib_common/src/main/java/com/quyunshuo/androidbaseframemvvm/common/util/XLogUtil.kt

@@ -14,6 +14,8 @@ import com.elvishew.xlog.printer.file.backup.FileSizeBackupStrategy
 import com.elvishew.xlog.printer.file.clean.FileLastModifiedCleanStrategy
 import com.elvishew.xlog.printer.file.naming.DateFileNameGenerator
 import com.elvishew.xlog.printer.file.writer.SimpleWriter
+import com.quyunshuo.androidbaseframemvvm.common.constant.SavaAddress
+import java.io.File
 
 /**
  * log 工具类:可以存储成文件。又可以输出,好东西。
@@ -33,8 +35,8 @@ object XLogUtil {
         val androidPrinter =
             AndroidPrinter(true)
 
-        val logFolder =
-            Environment.getExternalStorageDirectory().path.toString() + "/logdata"
+        val logFolder = SavaAddress.log
+        createExternalFolder(logFolder)
         val filePrinter = FilePrinter.Builder(logFolder)
             .fileNameGenerator(DateFileNameGenerator())//日志文件名格式
             .backupStrategy(FileSizeBackupStrategy((500 * 1024 * 1024).toLong()))//单个日志文件的大小默认:FileSizeBackupStrategy(1024 * 1024) 500MB
@@ -46,6 +48,20 @@ object XLogUtil {
         XLog.init(config, androidPrinter, filePrinter)
     }
 
+    fun createExternalFolder(folderName: String?) {
+        val folder = File(folderName)
+        if (!folder.exists()) {
+            val isCreated = folder.mkdir() // 或者使用mkdirs()
+            if (isCreated) {
+                Log.d("CreateFolder", "Folder created successfully")
+            } else {
+                Log.d("CreateFolder", "Folder creation failed")
+            }
+        } else {
+            Log.d("CreateFolder", "Folder already exists")
+        }
+    }
+
     fun d(msg: String) {
         XLog.d(msg)
     }

+ 7 - 2
module_backstage/src/main/java/com/module/backstage/activity/setting/SettingActivity.kt

@@ -53,6 +53,7 @@ import com.quyunshuo.androidbaseframemvvm.common.constant.RouteUrl.Main.MainActi
 import com.quyunshuo.androidbaseframemvvm.common.constant.event.ApiMessageEvent
 import com.quyunshuo.androidbaseframemvvm.common.enums.ConnectStateEnum
 import com.quyunshuo.androidbaseframemvvm.common.ui.BaseActivity
+import com.quyunshuo.androidbaseframemvvm.common.util.FileUtil
 import com.quyunshuo.androidbaseframemvvm.common.util.LanguageUtil
 import com.quyunshuo.androidbaseframemvvm.common.util.LongClickUtils
 import com.quyunshuo.androidbaseframemvvm.common.util.MyContextWrapper
@@ -153,8 +154,12 @@ class SettingActivity : BaseActivity<BackstageActivitySettingBinding, SettingVie
             })
         mBinding.tvSoftwareVersion.text = "软件版本号:"+SBCHeartbeat.softwareVersion
         mBinding.tvCrateVersion.text = "机箱版本号:"+SBCHeartbeat.crateVersion
-//        mBinding.tvDevDogtag.text ="铭牌号:"+ SBCHeartbeat.devDogtag
         mBinding.tvAppVersion.text=  "App版本号:"+packageManager.getPackageInfo(packageName, 0).versionName
+        val deviceId = FileUtil.getDeviceId()
+        if (deviceId.isNotEmpty()) {
+            mBinding.tvDevDogtag.text =
+                UiUtil.getStringRes(R.string.home_dev_id) + deviceId.substring(deviceId.length - 6)
+        }
         mViewModel.getParamData();//读取参数
     }
 
@@ -397,7 +402,7 @@ class SettingActivity : BaseActivity<BackstageActivitySettingBinding, SettingVie
     }
 
     private fun back() {
-        ARouter.getInstance().build(RouteUrl.Main.MainActivity).navigation()
+        ARouter.getInstance().build(MainActivity).navigation()
         finish()
     }
 

+ 1 - 0
module_backstage/src/main/java/com/module/backstage/activity/setting/SettingRepository.kt

@@ -39,6 +39,7 @@ class SettingRepository @Inject constructor() : BaseRepository() {
         params["managerId"] = text!!
         params["gtClientId"] = Heartbeat.clientId!!
         params["equimentType"] = "SBM10"
+//        params["equimentType"] = "P10"
         Log.d(TAG, "initDev1: "+params)
         mApi.initDev(params).run {
             emit(this)

+ 28 - 7
module_backstage/src/main/java/com/module/backstage/adapter/LocalAlarmClockAdapter.kt

@@ -22,18 +22,28 @@ class LocalAlarmClockAdapter(var productList: ArrayList<LocalAlarmClockBean>?) :
 
         fun bind(localAlarmClockBean: LocalAlarmClockBean, position: Int) {
             mBinding.run {
-                tvFunction.text = UiUtil.getStringRes(UiUtil.getResId(localAlarmClockBean.type?.content, R.string::class.java))
-                tvTime.text = localAlarmClockBean.hour+":"+localAlarmClockBean.minute
+                tvFunction.text = UiUtil.getStringRes(
+                    UiUtil.getResId(
+                        localAlarmClockBean.type?.content,
+                        R.string::class.java
+                    )
+                )
+                tvTime.text = localAlarmClockBean.hour + ":" + localAlarmClockBean.minute
                 var weekStr = ""
                 localAlarmClockBean.week?.forEach {
-                    weekStr+=UiUtil.getStringRes(UiUtil.getResId(it.content, R.string::class.java))+" "
+                    weekStr += UiUtil.getStringRes(
+                        UiUtil.getResId(
+                            it.content,
+                            R.string::class.java
+                        )
+                    ) + " "
                 }
                 tvWeek.text = weekStr
                 tvDelete.setOnClickListener {
-                    itemListener?.onClickListener(it,position,DELETE)
+                    itemListener?.onClickListener(it, position, DELETE)
                 }
                 tvUpdate.setOnClickListener {
-                    itemListener?.onClickListener(it,position,UPDATE)
+                    itemListener?.onClickListener(it, position, UPDATE)
 
                 }
             }
@@ -42,7 +52,11 @@ class LocalAlarmClockAdapter(var productList: ArrayList<LocalAlarmClockBean>?) :
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
         val projectVH = MyViewHolder(
-            BackstageItemLocalAlarmClockBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+            BackstageItemLocalAlarmClockBinding.inflate(
+                LayoutInflater.from(parent.context),
+                parent,
+                false
+            )
         )
         return projectVH
     }
@@ -52,10 +66,17 @@ class LocalAlarmClockAdapter(var productList: ArrayList<LocalAlarmClockBean>?) :
     }
 
     override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
-        holder.bind(productList!![position],position)
+        holder.bind(productList!![position], position)
     }
 
     fun setItemListener(itemListener: AdapterClickListener?) {
         this.itemListener = itemListener
     }
+
+    fun setDatas(newproductList: ArrayList<LocalAlarmClockBean>) {
+        newproductList?.let {
+            productList = it
+            notifyDataSetChanged()
+        }
+    }
 }

+ 286 - 46
module_backstage/src/main/java/com/module/backstage/adapter/TestAdapter.kt

@@ -1,23 +1,34 @@
 package com.module.backstage.adapter
 
+import ZtlApi.ZtlManager
+import android.annotation.SuppressLint
 import android.content.Context
+import android.content.Intent
+import android.provider.Settings
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.AdapterView
 import android.widget.AdapterView.OnItemSelectedListener
 import android.widget.ArrayAdapter
+import android.widget.SeekBar
+import androidx.core.content.ContextCompat.startActivity
 import androidx.recyclerview.widget.RecyclerView
 import com.chad.library.adapter4.BaseMultiItemAdapter
 import com.module.backstage.R
+import com.module.backstage.databinding.BackstageItemButtonBinding
 import com.module.backstage.databinding.BackstageItemInputBinding
+import com.module.backstage.databinding.BackstageItemSliderBinding
 import com.module.backstage.databinding.BackstageItemSpinnerBinding
 import com.module.backstage.databinding.BackstageItemSystemSettingsBinding
+import com.module.backstage.databinding.BackstageItemTextBinding
 import com.module.pay.common.OtherEnum
 import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils
+import com.quyunshuo.androidbaseframemvvm.common.constant.MMKVName
 import com.quyunshuo.androidbaseframemvvm.common.listener.AdapterClickListener
 import com.quyunshuo.androidbaseframemvvm.common.util.ToastUtil
 import com.quyunshuo.androidbaseframemvvm.common.util.UiUtil
+import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
 
 class TestAdapter(var productList: MutableList<OtherEnum>) :
     BaseMultiItemAdapter<OtherEnum>(productList) {
@@ -26,56 +37,84 @@ class TestAdapter(var productList: MutableList<OtherEnum>) :
     class ItemVH(val viewBinding: BackstageItemSystemSettingsBinding) :
         RecyclerView.ViewHolder(viewBinding.root)
 
-    // 类型 2 的 viewholder
+    // 类型 2 的 viewholder 输入项
     class HeaderVH(val viewBinding: BackstageItemInputBinding) :
         RecyclerView.ViewHolder(viewBinding.root)
 
-    // 类型 2 的 viewholder
+    // 类型 3 的 viewholder
     class SpinnerVH(val viewBinding: BackstageItemSpinnerBinding) :
         RecyclerView.ViewHolder(viewBinding.root)
 
+    // 类型 4 的 viewholder 滑块
+    class SliderVH(val viewBinding: BackstageItemSliderBinding) :
+        RecyclerView.ViewHolder(viewBinding.root)
+
+    // 类型 5 的 viewholder 文本
+    class TextVH(val viewBinding: BackstageItemTextBinding) :
+        RecyclerView.ViewHolder(viewBinding.root)
+
+    // 类型 6 的 viewholder 按钮
+    class ButtonVH(val viewBinding: BackstageItemButtonBinding) :
+        RecyclerView.ViewHolder(viewBinding.root)
+
     var type3Position: Int = 0 //记录多选值的position
 
     // 在 init 初始化的时候,添加多类型
     init {
-        addItemType(ITEM_TYPE, object : OnMultiItemAdapterListener<OtherEnum, ItemVH> { // 类型 1
-            override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): ItemVH {
-                // 创建 viewholder
-                val viewBinding = BackstageItemSystemSettingsBinding.inflate(
-                    LayoutInflater.from(context), parent, false
-                )
-                return ItemVH(viewBinding)
-            }
+        addItemType(
+            ITEM_TYPE,
+            object : OnMultiItemAdapterListener<OtherEnum, ItemVH> { // 类型 1
+                override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): ItemVH {
+                    // 创建 viewholder
+                    val viewBinding = BackstageItemSystemSettingsBinding.inflate(
+                        LayoutInflater.from(context), parent, false
+                    )
+                    return ItemVH(viewBinding)
+                }
 
-            override fun onBind(holder: ItemVH, position: Int, item: OtherEnum?) {
-                itemListener?.onClickListener(holder.itemView, position, null)
-                // 绑定 item 数据
-                holder.viewBinding.run {
-                    tvName.text = UiUtil.getStringRes(item!!.nameId)
-                    rgSwitch.setOnCheckedChangeListener { group, checkedId ->
-                        when (checkedId) {
-                            R.id.rb_close -> {
-                                SpUtils.putBoolean(item.mmkvName, false)
-                            }
+                override fun onBind(holder: ItemVH, position: Int, item: OtherEnum?) {
+                    itemListener?.onClickListener(holder.itemView, position, null)
+                    // 绑定 item 数据
+                    holder.viewBinding.run {
+                        tvName.text = UiUtil.getStringRes(item!!.nameId)
+                        rgSwitch.setOnCheckedChangeListener { group, checkedId ->
+                            when (checkedId) {
+                                R.id.rb_close -> {
+                                    SpUtils.putBoolean(item.mmkvName, false)
+                                    if (item.mmkvName == MMKVName.WIFI_HOTSPOT) {
+                                        //关闭热点
+                                        ZtlManager.GetInstance().closeAp();
+                                    }
+                                }
 
-                            R.id.rb_open -> {
-                                SpUtils.putBoolean(item.mmkvName, true)
-                            }
+                                R.id.rb_open -> {
+                                    SpUtils.putBoolean(item.mmkvName, true)
+                                    if (item.mmkvName == MMKVName.WIFI_HOTSPOT) {
+                                        //打开热点
+                                        ZtlManager.GetInstance().openAp(
+                                            SpUtils.getString(
+                                                MMKVName.NAME_HOTSPOT,
+                                                "sunzee"
+                                            ), SpUtils.getString(MMKVName.PWD_HOTSPOT, "66666666")
+                                        );
+                                    }
+                                }
 
-                            else -> {}
+                                else -> {}
+                            }
+                        }
+                        var flag = SpUtils.getBoolean(item.mmkvName, item.default as Boolean)
+                        if (flag == true) {
+                            rbOpen.isChecked = true
+                        } else {
+                            rbClose.isChecked = true
                         }
                     }
-                    var flag = SpUtils.getBoolean(item.mmkvName, item.default as Boolean)
-                    if (flag == true) {
-                        rbOpen.isChecked = true
-                    } else {
-                        rbClose.isChecked = true
-                    }
-                }
 
 
-            }
-        }).addItemType(SECTION_TYPE,
+                }
+            }).addItemType(
+            SECTION_TYPE,
             object : OnMultiItemAdapterListener<OtherEnum, HeaderVH> { // 类型 2
                 override fun onCreate(
                     context: Context,
@@ -120,15 +159,15 @@ class TestAdapter(var productList: MutableList<OtherEnum>) :
                     return true;
                 }
 
-            }).addItemType(MULTIPLE_CHOICE_TYPE,
+            }).addItemType(
+            MULTIPLE_CHOICE_TYPE,
             object : OnMultiItemAdapterListener<OtherEnum, SpinnerVH> { // 类型 3
                 override fun onBind(holder: SpinnerVH, position: Int, item: OtherEnum?) {
                     holder.viewBinding.run {
                         tvName.text = UiUtil.getStringRes(item!!.nameId)
-
                         initSpinner(this, item)
                         btnUpdate.setOnClickListener {
-                            SpUtils.putInt(item.mmkvName,this@TestAdapter.type3Position )
+                            SpUtils.putInt(item.mmkvName, this@TestAdapter.type3Position)
                             ToastUtil.switchToastStyleToSuccess("更新成功:" + item.mmkvName)
                         }
                     }
@@ -154,7 +193,7 @@ class TestAdapter(var productList: MutableList<OtherEnum>) :
                         override fun onNothingSelected(parent: AdapterView<*>?) {
                         }
                     })
-                    mBinding.spMultiple.setSelection(SpUtils.getInt(item.mmkvName,0)!!)
+                    mBinding.spMultiple.setSelection(SpUtils.getInt(item.mmkvName, 0)!!)
                 }
 
                 override fun onCreate(
@@ -168,22 +207,223 @@ class TestAdapter(var productList: MutableList<OtherEnum>) :
                     )
                     return SpinnerVH(viewBinding)
                 }
-            }).onItemViewType { position, list -> // 根据数据,返回对应的 ItemViewType
-            if (list[position].type == SECTION_TYPE) {
-                SECTION_TYPE
-            } else if (list[position].type == MULTIPLE_CHOICE_TYPE) {
-                MULTIPLE_CHOICE_TYPE
-            } else {
-                ITEM_TYPE
+            }).addItemType(
+            SLIDER_TYPE,
+            object : OnMultiItemAdapterListener<OtherEnum, SliderVH> { // 类型 2
+                override fun onCreate(
+                    context: Context,
+                    parent: ViewGroup,
+                    viewType: Int,
+                ): SliderVH {
+                    // 创建 viewholder
+                    val viewBinding = BackstageItemSliderBinding.inflate(
+                        LayoutInflater.from(context), parent, false
+                    )
+                    return SliderVH(viewBinding)
+                }
+
+                override fun onBind(holder: SliderVH, position: Int, item: OtherEnum?) {
+                    // 绑定 item 数据
+                    itemListener?.onClickListener(holder.itemView, position, null)
+                    holder.viewBinding.run {
+                        tvName.text = UiUtil.getStringRes(item!!.nameId)
+                        when (item.mmkvName) {
+                            MMKVName.VOLUME -> {
+                                XLogUtil.d("音量:" + ZtlManager.GetInstance().systemMaxVolume + ":" + ZtlManager.GetInstance().systemCurrenVolume)
+                                sbLight.max =
+                                    ZtlManager.GetInstance().systemMaxVolume //maxVolume 为获取到的 Android 系统最大媒体音量值
+                                sbLight.progress =
+                                    ZtlManager.GetInstance().systemCurrenVolume;//currenVolume 为获取到的 Android 系统当前媒体音量值
+                            }
+
+                            MMKVName.LUMINANCE -> {
+                                XLogUtil.d("亮度:" + ZtlManager.GetInstance().systemMaxBrightness + ":" + ZtlManager.GetInstance().systemBrightness)
+                                sbLight.max =
+                                    ZtlManager.GetInstance().systemMaxBrightness //maxBrightness 为 Android 系统最大亮度
+                                sbLight.progress =
+                                    ZtlManager.GetInstance().systemBrightness; //systemBri 为 Android 系统当前亮度
+                            }
+                        }
+
+                        sbLight.setOnSeekBarChangeListener(object :
+                            SeekBar.OnSeekBarChangeListener {
+                            override fun onProgressChanged(
+                                seekBar: SeekBar?,
+                                progress: Int,
+                                fromUser: Boolean,
+                            ) {
+                                //设置进度
+                                setPro(seekBar, progress);
+                            }
+
+                            private fun setPro(seekBar: SeekBar?, progress: Int) {
+                                when (item.mmkvName) {
+                                    MMKVName.VOLUME -> {
+                                        //设置 Android 系统媒体音量值为 10
+                                        ZtlManager.GetInstance().setSystemVolumeIndex(progress);
+                                    }
+
+                                    MMKVName.LUMINANCE -> {
+                                        //设置 Android 系统亮度为 200
+                                        ZtlManager.GetInstance().setBrightness(progress);
+                                    }
+                                }
+
+                            }
+
+                            override fun onStartTrackingTouch(seekBar: SeekBar?) {
+
+                            }
+
+                            override fun onStopTrackingTouch(seekBar: SeekBar?) {
+                            }
+
+                        });
+                    }
+
+                }
+
+                override fun isFullSpanItem(itemType: Int): Boolean {
+                    // 使用GridLayoutManager时,此类型的 item 是否是满跨度
+                    return true;
+                }
+
+            }).addItemType(
+            TEXT_TYPE,
+            object : OnMultiItemAdapterListener<OtherEnum, TextVH> { // 类型 5
+                override fun onCreate(
+                    context: Context,
+                    parent: ViewGroup,
+                    viewType: Int,
+                ): TextVH {
+                    // 创建 viewholder
+                    val viewBinding = BackstageItemTextBinding.inflate(
+                        LayoutInflater.from(context), parent, false
+                    )
+                    return TextVH(viewBinding)
+                }
+
+                @SuppressLint("MissingPermission")
+                override fun onBind(holder: TextVH, position: Int, item: OtherEnum?) {
+                    // 绑定 item 数据
+                    itemListener?.onClickListener(holder.itemView, position, null)
+                    holder.viewBinding.run {
+                        tvName.text = UiUtil.getStringRes(item!!.nameId)
+                        var defaultValue = SpUtils.getString(item.mmkvName, item.default as String)
+                        when (item.mmkvName) {
+                            MMKVName.SIM -> {
+                                try {
+                                    tvValue.text =
+                                        ZtlManager.GetInstance().simTel //simtel 为获取到的 Android 系统 SIM 卡的号码信息
+                                }catch (e:Exception){
+                                    //  throw e
+                                }
+
+
+                            }
+
+                            MMKVName.SIM_IMEI -> {
+                                try {
+                                    tvValue.text =
+                                        ZtlManager.GetInstance().imei
+                                }catch (E:Exception){
+                                    //  throw E
+                                }
+
+
+
+                            }
+                        }
+
+                    }
+                }
+
+                override fun isFullSpanItem(itemType: Int): Boolean {
+                    // 使用GridLayoutManager时,此类型的 item 是否是满跨度
+                    return true;
+                }
+
+            }).addItemType(
+            BUTTON_TYPE,
+            object : OnMultiItemAdapterListener<OtherEnum, ButtonVH> { // 类型 2
+                override fun onCreate(
+                    context: Context,
+                    parent: ViewGroup,
+                    viewType: Int,
+                ): ButtonVH {
+                    // 创建 viewholder
+                    val viewBinding = BackstageItemButtonBinding.inflate(
+                        LayoutInflater.from(context), parent, false
+                    )
+                    return ButtonVH(viewBinding)
+                }
+
+                override fun onBind(holder: ButtonVH, position: Int, item: OtherEnum?) {
+                    // 绑定 item 数据
+                    itemListener?.onClickListener(holder.itemView, position, null)
+                    holder.viewBinding.run {
+
+                        tvName.text = UiUtil.getStringRes(item!!.nameId)
+
+                        var defaultValue = SpUtils.getString(item.mmkvName, item.default as String)
+//                        btnUpdate.text = defaultValue
+                        btnUpdate.setOnClickListener {
+                            if (item.mmkvName == MMKVName.CUT_SYSTEM_SET) {
+                                //打开系统设置界面
+                                startActivity(
+                                    this@TestAdapter.context,
+                                    Intent(Settings.ACTION_SETTINGS),
+                                    null
+                                )
+                                ToastUtil.switchToastStyleToSuccess("打开系统设置界面")
+                            }
+                        }
+                    }
+                }
+
+                override fun isFullSpanItem(itemType: Int): Boolean {
+                    // 使用GridLayoutManager时,此类型的 item 是否是满跨度
+                    return true;
+                }
+
+            })
+
+            .onItemViewType { position, list -> // 根据数据,返回对应的 ItemViewType
+                when (list[position].type) {
+                    SECTION_TYPE -> {
+                        SECTION_TYPE
+                    }
+
+                    MULTIPLE_CHOICE_TYPE -> {
+                        MULTIPLE_CHOICE_TYPE
+                    }
+
+                    SLIDER_TYPE -> {
+                        SLIDER_TYPE
+                    }
+
+                    TEXT_TYPE -> {
+                        TEXT_TYPE
+                    }
+
+                    BUTTON_TYPE -> {
+                        BUTTON_TYPE
+                    }
+
+                    else -> {
+                        ITEM_TYPE
+                    }
+                }
             }
-        }
     }
 
     companion object {
         private const val ITEM_TYPE = 1//开关
         private const val SECTION_TYPE = 2//输入值
         private const val MULTIPLE_CHOICE_TYPE = 3//多选值
-
+        private const val SLIDER_TYPE = 4//滑块
+        private const val TEXT_TYPE = 5//文本
+        private const val BUTTON_TYPE = 6//按钮
     }
 
     private var itemListener: AdapterClickListener? = null

+ 25 - 5
module_backstage/src/main/java/com/module/backstage/fragment/LocalAlarmClockFragment.kt

@@ -23,6 +23,7 @@ import com.quyunshuo.androidbaseframemvvm.common.bean.LocalAlarmClockBean
 import com.quyunshuo.androidbaseframemvvm.common.constant.MMKVName
 import com.quyunshuo.androidbaseframemvvm.common.listener.AdapterClickListener
 import com.quyunshuo.androidbaseframemvvm.common.ui.BaseFragment
+import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
 import dagger.hilt.android.AndroidEntryPoint
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
@@ -67,12 +68,26 @@ class LocalAlarmClockFragment :
             override fun onClickListener(view: View?, position: Int, data: String?) {
                 when (data) {
                     localAdapter?.DELETE -> {
-                        list?.removeAt(position)
-                        localAdapter?.notifyDataSetChanged()
+                        var remove = list?.removeAt(position)
+                        list?.let { localAdapter?.setDatas(it) }
+                        // localAdapter?.notifyDataSetChanged()
                         SpUtils.putString(MMKVName.LOCAL_ALARM_CLOCK, Gson().toJson(list))
+                        Log.d("backinfo", "闹钟:" + Gson().toJson(list))
+                        mViewModel.setAlarmClock(list)
+                        //关闭指定的闹钟。
+                        /*  val number: Int = Integer.valueOf(remove?.id)
+                          for (i in number * 1000 until number * 1000 + remove?.week?.size!!) { //清除所有的闹钟
+                              AlarmManagerUtil.cancelAlarm(
+                                  BaseApplication.context,
+                                  AlarmManagerUtil.ALARM_ACTION,
+                                  i
+                              )
+
+                          }*/
                     }
 
                     localAdapter?.UPDATE -> {
+                        Log.d("backinfo","更新:UPDATE:"+position)
                         showUpdateApp(2, position)
                     }
 
@@ -82,7 +97,7 @@ class LocalAlarmClockFragment :
         })
         rvLocalAlarmClock.adapter = localAdapter
         tvAddLock.setOnClickListener {
-            showUpdateApp(1, list?.size)
+            list?.size?.let { it1 -> showUpdateApp(1, it1) }
         }
         cbOpenLock.isChecked = SpUtils.getBoolean(MMKVName.ALARMCLOCK_TYPE, false)!!
         cbOpenLock.setOnCheckedChangeListener { buttonView, isChecked ->
@@ -103,9 +118,11 @@ class LocalAlarmClockFragment :
         mBinding.rvLocalAlarmClock.adapter = null
         super.onDestroyView()
     }
+    var position=-1
 
-    private fun showUpdateApp(type: Int, id: Int?) {
+    private fun showUpdateApp(type: Int, id: Int) {
         addOrUpdate = type
+        position=id
         if (localAlarmClockDialog == null) {
             localAlarmClockDialog = this@LocalAlarmClockFragment.context?.let {
                 LocalAlarmClockDialog(
@@ -122,7 +139,9 @@ class LocalAlarmClockFragment :
                         }
 
                         localAlarmClockDialog?.update -> {
-                            localAdapter?.notifyDataSetChanged()
+                            list?.set(position, localAlarmClockBean)
+                            Log.d("backinfo","更新:$position"+Gson().toJson(list))
+                            list?.let { localAdapter?.setDatas(it) }
                             SpUtils.putString(MMKVName.LOCAL_ALARM_CLOCK, Gson().toJson(list))
 
                         }
@@ -194,6 +213,7 @@ class LocalAlarmClockFragment :
             removeCallbacksAndMessages(null)
         }
     }
+
     override fun onStop() {
         stopRefreshTime()
         super.onStop()

+ 4 - 5
module_backstage/src/main/java/com/module/backstage/repo/OtherFragmentRepo.kt

@@ -16,18 +16,17 @@ class OtherFragmentRepo @Inject constructor() : BaseRepository() {
     @Inject
     lateinit var mApi: com.module.pay.service.HomeApiService
     var arrayList: MutableList<OtherEnum> = mutableListOf(
+        OtherEnum.MDB_LEVEL,
+        OtherEnum.TTYS_MDB,
+        OtherEnum.BILL_COLLOCATION,
         OtherEnum.AGREEMENT,
         OtherEnum.CHANGE,
-        OtherEnum.CONTACT_NUMBER,
+        OtherEnum.CONTACT_WAY,
         OtherEnum.SHOPPING_TROLLEY,
         OtherEnum.PROMOTION_CODE,
-//        OtherEnum.BILL_COUNTRY,
         OtherEnum.NAYAX_MODE,
         OtherEnum.TTYS_NAYAX,
-        OtherEnum.TTYS_MDB,
         OtherEnum.TTYS_PLC,
-        OtherEnum.BILL_COLLOCATION,
-        OtherEnum.MDB_LEVEL
     )
 
 }

+ 42 - 13
module_backstage/src/main/java/com/module/backstage/repo/SystemSettingsFragmentRepo.kt

@@ -18,35 +18,64 @@ class SystemSettingsFragmentRepo @Inject constructor() : BaseRepository() {
 
     //系统设置
     var arrayList: MutableList<OtherEnum> = Arrays.asList(
-//        OtherEnum.BILL_COUNTRY,
-        OtherEnum.AGREEMENT,
-        OtherEnum.CONTACT_NAME,
-        OtherEnum.CONTACT_NUMBER,
-        OtherEnum.TTYS_NAYAX,
-        OtherEnum.TTYS_MDB,
-        OtherEnum.TTYS_PLC,
-        OtherEnum.NAYAX_MODE,
-        OtherEnum.BILL_COLLOCATION,
-        OtherEnum.MDB_LEVEL
+        OtherEnum.CONTACT,
+        OtherEnum.CONTACT_WAY,
+        OtherEnum.VOLUME,
+        OtherEnum.LUMINANCE,
+        OtherEnum.AUTO_START_HOTSPOT,
+        OtherEnum.NAME_HOTSPOT,
+        OtherEnum.PWD_HOTSPOT,
+        OtherEnum.WIFI_HOTSPOT,
+        OtherEnum.LONG_CLICK_SHOW_STATUS_BAR,
+        OtherEnum.CUT_SYSTEM_SET
     )
 
     //串口设置
     var comSetList: MutableList<OtherEnum> = Arrays.asList(
+        OtherEnum.MDB_LEVEL,
+        OtherEnum.TTYS_MDB,
+        OtherEnum.BILL_COLLOCATION,
+        OtherEnum.TTYS_NAYAX,
+        OtherEnum.NAYAX_MODE,
+        OtherEnum.TTYS_PLC,
+        OtherEnum.MDB_CASH_SALE,
+        OtherEnum.CARD_TEXT,
+        OtherEnum.BILL_TRUST,
+        OtherEnum.MDB_RATE,
+        OtherEnum.AGREEMENT
     )
     //功能开启
     var functionOpenList: MutableList<OtherEnum> = Arrays.asList(
-        OtherEnum.PROMOTION_CODE
+        OtherEnum.STAFF_LOGIN,
     )
     //购物车设置
     var shoppingCartList: MutableList<OtherEnum> = Arrays.asList(
-        OtherEnum.SHOPPING_TROLLEY
+        OtherEnum.SHOPPING_TROLLEY,
+        OtherEnum.DISCOUNT_FUNCTION,
+        OtherEnum.SHOPPING_CART_SIZE,
+        OtherEnum.TWO_PRICE_DISCOUNT,
+        OtherEnum.THREE_PRICE_DISCOUNT,
+        OtherEnum.FIVE_PRICE_DISCOUNT,
+        OtherEnum.TIPS_DISCOUNT_TEXT,
     )
     //找零设置
     var changeSetList: MutableList<OtherEnum> = Arrays.asList(
-        OtherEnum.CHANGE
+        OtherEnum.CHANGE_FUNCTION,
+        OtherEnum.CHANGE_DOLLAR,
+        OtherEnum.CHANGE_BILL,
+        OtherEnum.CHANGE_COIN_REP,
+        OtherEnum.CHANGE_COIN,
+        OtherEnum.CHANGE_ALLOW_NUMBER,
+        OtherEnum.CHANGE_WARNING_NUMBER
     )
     //其他
     var otherSetList: MutableList<OtherEnum> = Arrays.asList(
+        OtherEnum.PROMOTION_CODE,
+        OtherEnum.MAKE_CLEAN_PRICE,
+        OtherEnum.AD_RULE,
+        OtherEnum.AUTO_RETURN_HOME,
+        OtherEnum.SLEEP_TEXT,
+        OtherEnum.LOGO_TEXT
     )
 
 }

+ 24 - 0
module_backstage/src/main/res/drawable/seekbar_progress_drawable.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!-- 整个进度条背景 -->
+    <item android:id="@android:id/background">
+        <shape>
+            <corners android:radius="5dip" />
+            <solid android:color="#ecf7ff"/>
+        </shape>
+    </item>
+    <!-- 省略了二级进度条背景 -->
+
+    <!-- 已完成的进度条背景 -->
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <corners android:radius="5dip" />
+                <solid android:color="#5B9CF3"/>
+            </shape>
+        </clip>
+    </item>
+
+
+</layer-list>

+ 23 - 0
module_backstage/src/main/res/drawable/shape_radio_thumb.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval"
+    android:useLevel="false"
+    >
+
+    <solid android:color="@color/white" />
+
+    <stroke
+        android:width="3dp"
+        android:color="#EDA297" />
+
+    <size android:height="52dp"
+        android:width="52dp"/>
+
+    <corners
+        android:bottomLeftRadius="360dp"
+        android:bottomRightRadius="360dp"
+        android:topLeftRadius="360dp"
+        android:topRightRadius="360dp" />
+
+</shape>

+ 10 - 10
module_backstage/src/main/res/layout/backstage_activity_setting.xml

@@ -93,16 +93,16 @@
                 android:textColor="@color/black"
                 android:textSize="40sp"/>
 
-<!--            <TextView-->
-<!--                android:id="@+id/tv_dev_dogtag"-->
-<!--                android:layout_width="wrap_content"-->
-<!--                android:layout_height="wrap_content"-->
-<!--                android:layout_centerVertical="true"-->
-<!--                android:layout_marginStart="40dp"-->
-<!--                android:gravity="center"-->
-<!--                android:text="铭牌号:"-->
-<!--                android:textColor="@color/black"-->
-<!--                android:textSize="40sp"/>-->
+            <TextView
+                android:id="@+id/tv_dev_dogtag"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                android:layout_marginStart="40dp"
+                android:gravity="center"
+                android:text="@string/home_dev_id"
+                android:textColor="@color/black"
+                android:textSize="40sp"/>
         </LinearLayout>
 
         <TextView

+ 1 - 1
module_backstage/src/main/res/layout/backstage_fragment_price.xml

@@ -19,7 +19,7 @@
         android:layout_width="wrap_content"
         android:orientation="vertical"
         app:layout_constraintBottom_toBottomOf="parent"
-        android:layout_marginBottom="680dp"
+        android:layout_marginBottom="980dp"
         android:gravity="center"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"

+ 36 - 0
module_backstage/src/main/res/layout/backstage_item_button.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="40dp">
+
+    <TextView
+        android:id="@+id/tv_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="@color/black"
+        android:textSize="52sp"
+        android:textStyle="bold"
+        app:layout_constraintBottom_toBottomOf="@+id/btn_update"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/btn_update" />
+
+
+    <Button
+        android:layout_marginStart="20dp"
+        android:id="@+id/btn_update"
+        android:layout_width="185dp"
+        android:layout_height="100dp"
+        android:background="@drawable/home_rectangle_blue_background"
+        android:text="@string/backstage_operate"
+        android:textColor="@color/white"
+        android:textSize="48sp"
+        app:layout_constraintStart_toEndOf="@+id/tv_name"
+        app:layout_constraintTop_toTopOf="parent" />
+
+
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 2 - 1
module_backstage/src/main/res/layout/backstage_item_input.xml

@@ -23,9 +23,9 @@
         android:id="@+id/et_value"
         android:layout_width="320dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="10dp"
         android:layout_marginEnd="8dp"
         android:background="@drawable/backstage_shape_general_param_et"
+        android:layout_marginStart="20dp"
         android:inputType="number"
         android:textSize="50sp"
         android:textColor="@color/black"
@@ -35,6 +35,7 @@
         app:layout_constraintTop_toTopOf="parent" />
 
     <Button
+        android:layout_marginStart="20dp"
         android:id="@+id/btn_update"
         android:layout_width="185dp"
         android:layout_height="100dp"

+ 37 - 0
module_backstage/src/main/res/layout/backstage_item_slider.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="40dp">
+
+    <TextView
+        android:id="@+id/tv_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="@color/black"
+        android:textSize="52sp"
+        android:textStyle="bold"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"/>
+
+    <SeekBar
+        android:id="@+id/sb_light"
+        android:layout_width="620dp"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="20dp"
+        android:max="100"
+        android:progressDrawable="@drawable/seekbar_progress_drawable"
+        android:splitTrack="false"
+        android:thumb="@drawable/shape_radio_thumb"
+        app:layout_constraintStart_toEndOf="@+id/tv_name"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toBottomOf="parent"
+        tools:layout_editor_absoluteY="5dp"
+        tools:ignore="MissingConstraints" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 1
module_backstage/src/main/res/layout/backstage_item_system_settings.xml

@@ -19,8 +19,8 @@
         app:layout_constraintTop_toTopOf="parent" />
 
     <RadioGroup
+        android:layout_marginStart="20dp"
         android:id="@+id/rg_switch"
-        android:layout_marginLeft="20dp"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="horizontal"

+ 38 - 0
module_backstage/src/main/res/layout/backstage_item_text.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="650dp"
+    android:layout_height="wrap_content"
+    android:layout_marginLeft="20dp"
+    android:layout_marginTop="40dp">
+
+    <TextView
+        android:id="@+id/tv_name"
+        android:layout_width="200dp"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="8dp"
+        android:textColor="@color/white"
+        android:textSize="32sp"
+        android:textStyle="bold"
+        app:layout_constraintBottom_toBottomOf="@+id/tv_value"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/tv_value" />
+
+    <TextView
+        android:id="@+id/tv_value"
+        android:layout_width="320dp"
+        android:layout_height="60dp"
+        android:layout_marginStart="10dp"
+        android:layout_marginEnd="8dp"
+        android:background="@drawable/backstage_shape_general_param_et"
+        android:inputType="number"
+        android:gravity="center_vertical"
+        android:textSize="20sp"
+        android:paddingStart="20dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/tv_name"
+        app:layout_constraintTop_toTopOf="parent" />
+
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 2 - 1
module_home/src/main/AndroidManifest.xml

@@ -8,7 +8,8 @@
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <application>
+    <application
+        android:hardwareAccelerated="true">
         <!--  Main 首页  -->
         <activity
             android:name=".activity.main.MainActivity"

+ 26 - 0
module_home/src/main/assets/version_0.json

@@ -0,0 +1,26 @@
+[
+    {
+        "productId": 1,
+        "customImg": "",
+        "productNo": "E01",
+        "customName": "",
+        "imgID": "product_1",
+        "index": 0,
+        "isSelected": true,
+        "nameChinese": "甜味爆米花",
+        "nameId": "base_pro_01",
+        "price": 0.0
+    },
+    {
+        "productId": 2,
+        "customImg": "",
+        "productNo": "E02",
+        "customName": "",
+        "imgID": "product_2",
+        "index": 1,
+        "isSelected": true,
+        "nameChinese": "咸味爆米花",
+        "nameId": "base_pro_02",
+        "price": 0.0
+    }
+]

+ 22 - 19
module_home/src/main/java/com/quyunshuo/module/home/activity/main/MainViewModel.kt

@@ -3,12 +3,14 @@ package com.quyunshuo.module.home.activity.main
 import android.util.Log
 import androidx.lifecycle.MutableLiveData
 import com.google.gson.Gson
+import com.quyunshuo.androidbaseframemvvm.base.BaseApplication
 import com.quyunshuo.androidbaseframemvvm.base.ktx.launchIO
 import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
 import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils
 import com.quyunshuo.androidbaseframemvvm.common.bean.ProductDataBean
 import com.quyunshuo.androidbaseframemvvm.common.constant.MMKVName
 import com.quyunshuo.androidbaseframemvvm.common.util.ProductAbout
+import com.quyunshuo.module.home.utils.CommodityManage
 import dagger.hilt.android.lifecycle.HiltViewModel
 import kotlinx.coroutines.flow.catch
 import javax.inject.Inject
@@ -41,24 +43,25 @@ class MainViewModel @Inject constructor(private val mRepository: MainRepository)
     //初始化商品数据
 
     fun initProductData() {
-        val productDataContains = SpUtils.contains(MMKVName.PRODUCT_DATA)
-        //如果不存在 创建默认的
-        if (!productDataContains!!) {
-            val goodsBeans: ArrayList<ProductDataBean> = ArrayList<ProductDataBean>()
-            for (i in 0 until ProductAbout.namesS.size) {
-                val productDataBean: ProductDataBean = ProductDataBean(
-                    0.0,
-                    ProductAbout.namesS[i],
-                    ProductAbout.imgIdsS[i],
-                    ProductAbout.chineseNameS[i],
-                    true,
-                    "",
-                    i,
-                    ""
-                )
-                goodsBeans.add(productDataBean)
-            }
-            SpUtils.put(MMKVName.PRODUCT_DATA,Gson().toJson(goodsBeans))
-        }
+        CommodityManage.getInstance().init(BaseApplication.context, "version_0.json")
+//        val productDataContains = SpUtils.contains(MMKVName.PRODUCT_DATA)
+//        //如果不存在 创建默认的
+//        if (!productDataContains!!) {
+//            val goodsBeans: ArrayList<ProductDataBean> = ArrayList<ProductDataBean>()
+//            for (i in 0 until ProductAbout.namesS.size) {
+//                val productDataBean: ProductDataBean = ProductDataBean(
+//                    0.0,
+//                    ProductAbout.namesS[i],
+//                    ProductAbout.imgIdsS[i],
+//                    ProductAbout.chineseNameS[i],
+//                    true,
+//                    "",
+//                    i,
+//                    ""
+//                )
+//                goodsBeans.add(productDataBean)
+//            }
+//            SpUtils.put(MMKVName.PRODUCT_DATA,Gson().toJson(goodsBeans))
+//        }
     }
 }

+ 4 - 0
module_home/src/main/java/com/quyunshuo/module/home/bean/PaySuccessBean.kt

@@ -0,0 +1,4 @@
+package com.quyunshuo.module.home.bean
+
+class PaySuccessBean(var payType: String, var payNamber: String) {
+}

+ 62 - 2
module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/BuyFragment.kt

@@ -2,17 +2,24 @@ package com.quyunshuo.module.home.fragment.fragment
 
 import android.content.Intent
 import android.os.Build
+import android.os.Handler
 import android.provider.Settings
+import android.text.format.DateFormat
 import android.util.Log
 import android.view.MotionEvent
 import android.view.View
+import androidx.fragment.app.Fragment
 import androidx.fragment.app.viewModels
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleObserver
+import androidx.lifecycle.OnLifecycleEvent
 import androidx.navigation.fragment.findNavController
 import com.hboxs.serialport.sbc.SBCHeartbeat
 import com.hboxs.serialport.sbc.VBoxMessage
 import com.hboxs.serialport.sbc.VboxSerialPortSendQueue
 import com.hboxs.serialport.sbc.frame.VboxCommand
 import com.hboxs.serialport.sbc.frame.VboxWriteCommand
+import com.quyunshuo.androidbaseframemvvm.base.BaseApplication
 import com.quyunshuo.androidbaseframemvvm.base.utils.RegisterEventBus
 import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils
 import com.quyunshuo.androidbaseframemvvm.common.constant.MMKVName
@@ -22,6 +29,7 @@ import com.quyunshuo.module.home.R
 import com.quyunshuo.module.home.databinding.HomeFragmentBuyBinding
 import com.quyunshuo.module.home.enums.LogoEnum
 import com.quyunshuo.module.home.fragment.vm.BuyFragmentVM
+import com.quyunshuo.module.home.utils.CommodityManage
 import com.quyunshuo.module.home.utils.SimplePlayerUtil
 import dagger.hilt.android.AndroidEntryPoint
 import kotlinx.coroutines.CoroutineScope
@@ -32,6 +40,7 @@ import kotlinx.coroutines.launch
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import java.io.File
+import java.lang.ref.WeakReference
 import java.util.*
 
 
@@ -44,18 +53,22 @@ import java.util.*
 @RegisterEventBus
 @AndroidEntryPoint
 class BuyFragment : BaseFragment<HomeFragmentBuyBinding, BuyFragmentVM>(),
-    View.OnTouchListener {
+    View.OnTouchListener ,LifecycleObserver{
     private val TAG = "BuyFragment"
 
+    private var HANDLE_TIME = 1//设置时间
     private var simplePlayerUtil: SimplePlayerUtil? = null
     override val mViewModel: BuyFragmentVM by viewModels()
     private var playVideos: ArrayList<File>? = null
     override fun createVB() = HomeFragmentBuyBinding.inflate(layoutInflater)
+    private val myHandler: MyHandler =
+        MyHandler(this@BuyFragment)
 
     override fun HomeFragmentBuyBinding.initView() {
+        startRefreshime()
+
         simplePlayerUtil = SimplePlayerUtil(svVideo)
         svVideo.setOnTouchListener(this@BuyFragment)
-
         if (Build.VERSION.SDK_INT >= 23) {
             if (!Settings.canDrawOverlays(this@BuyFragment.context)) {
                 val intent: Intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
@@ -90,7 +103,30 @@ class BuyFragment : BaseFragment<HomeFragmentBuyBinding, BuyFragmentVM>(),
             }
         }
     }
+    internal class MyHandler(fragment: Fragment) : Handler(), LifecycleObserver {
+        var mWeakReference: WeakReference<Fragment> = WeakReference(fragment)
+
+        override fun handleMessage(msg: android.os.Message) {
+            //as用来强转
+            var fragment: BuyFragment? = mWeakReference.get() as BuyFragment
+            when (msg.what) {
+                1 -> {
+                    val sysTime = System.currentTimeMillis() //获取系统时间
+                    val sysTimeStr = DateFormat.format("yyyy-MM-dd HH:mm:ss", sysTime) //时间显示格式
+                    fragment?.mBinding?.tvTime?.text = sysTimeStr //更新时间
+                }
+
+                else -> {
+
+                }
+            }
+        }
 
+        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
+        fun disconnectListener() {
+            removeCallbacksAndMessages(null)
+        }
+    }
     private var jobRestCoin: Job? = null
         get() = field
     private var isRestCoin: Boolean = true
@@ -116,6 +152,8 @@ class BuyFragment : BaseFragment<HomeFragmentBuyBinding, BuyFragmentVM>(),
     }
 
     override fun initObserve() {
+        lifecycle.addObserver(myHandler)
+        lifecycle.addObserver(this)
     }
 
     override fun initRequestData() {
@@ -144,9 +182,31 @@ class BuyFragment : BaseFragment<HomeFragmentBuyBinding, BuyFragmentVM>(),
 
     override fun onDestroyView() {
         super.onDestroyView()
+        jobTimer?.cancel()
         simplePlayerUtil?.onDestroy()
         stopRestCoin()
         Log.d(TAG, "onDestroyView: ")
     }
 
+    private var jobTimer: Job? = null
+
+    /**
+     * 时间日期 隔个一秒执行一次
+     */
+    private fun startRefreshime() {
+        stopRefreshTime()
+        // 启动协程
+        jobTimer = CoroutineScope(Dispatchers.IO).launch {
+            while (true) {
+                myHandler.sendEmptyMessage(HANDLE_TIME)
+                delay(1000) // 每隔1秒重复执行
+            }
+        }
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
+    fun stopRefreshTime() {
+        jobTimer?.cancel()
+        Log.d(TAG, "stopRefreshTime: ")
+    }
 }

+ 252 - 77
module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/HomeFragment.kt

@@ -2,13 +2,16 @@ package com.quyunshuo.module.home.fragment.fragment
 
 import android.annotation.SuppressLint
 import android.graphics.Point
+import android.os.Build
 import android.os.Bundle
 import android.os.Handler
+import android.telephony.SignalStrength
 import android.text.format.DateFormat
 import android.util.Log
 import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
+import androidx.annotation.RequiresApi
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.viewModels
 import androidx.lifecycle.Lifecycle
@@ -29,11 +32,13 @@ import com.hboxs.serialport.sbc.frame.VboxCommand
 import com.hboxs.serialport.sbc.frame.VboxWriteCommand
 import com.module.pay.nayax.CreditCardPresenter
 import com.quyunshuo.androidbaseframemvvm.base.addressenum.ProTypeEnum
+import com.quyunshuo.androidbaseframemvvm.base.bean.Global
 import com.quyunshuo.androidbaseframemvvm.base.ktx.observeLiveData
 import com.quyunshuo.androidbaseframemvvm.base.ktx.setVisible
 import com.quyunshuo.androidbaseframemvvm.base.utils.RegisterEventBus
 import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils
 import com.quyunshuo.androidbaseframemvvm.common.bean.ProductDataBean
+import com.quyunshuo.androidbaseframemvvm.common.bean.ShoppingCartBean
 import com.quyunshuo.androidbaseframemvvm.common.constant.Heartbeat
 import com.quyunshuo.androidbaseframemvvm.common.constant.MMKVName
 import com.quyunshuo.androidbaseframemvvm.common.constant.MqName
@@ -47,6 +52,7 @@ import com.quyunshuo.androidbaseframemvvm.common.util.UiUtil
 import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
 import com.quyunshuo.module.home.R
 import com.quyunshuo.module.home.adapter.HomeProductAdapter
+import com.quyunshuo.module.home.bean.PaySuccessBean
 import com.quyunshuo.module.home.databinding.HomeFragmentHomeBinding
 import com.quyunshuo.module.home.dialog.ContactDialog
 import com.quyunshuo.module.home.dialog.PayChooseDialogFragment
@@ -56,6 +62,10 @@ import com.quyunshuo.module.home.dialog.TipsDialog
 import com.quyunshuo.module.home.enums.LogoEnum
 import com.quyunshuo.module.home.fragment.vm.HomeFragmentVM
 import com.quyunshuo.module.home.weight.NXHooldeIMGView
+import com.quyunshuo.module.home.utils.NetWorkUtils
+import com.quyunshuo.module.home.utils.PhoneStateUtils
+import com.zhanshow.mylibrary.network.NetworkStateReceiver.NetworkStateReceiverListener
+import com.zhanshow.mylibrary.phonestate.MyPhoneStateListener.MyPhoneStateListenerListener
 import dagger.hilt.android.AndroidEntryPoint
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
@@ -78,7 +88,7 @@ import java.math.BigDecimal
 @RegisterEventBus
 @AndroidEntryPoint
 class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), View.OnTouchListener,
-    View.OnClickListener {
+    View.OnClickListener,LifecycleObserver {
 
     private val myHandler: MyHandler = MyHandler(this@HomeFragment)
     private var productList = ArrayList<ProductDataBean>()//传递给make的制作商品list
@@ -97,7 +107,14 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
     private var paySuccessDialog: PaySuccessDialog? = null//支付成功对话框
     private var shoppingCartDialog: ShoppingCartDialogFragment? = null//购物车列表对话框
     private var promotionCode: String? = "" //用户输入的优惠码
-
+    private var networkName = "";//当前的网络状态
+    private var networkLevel = 4;//当前的网络等级
+    private var NETWORK_STATE = 2//网络状态
+    private var NETWORK_LEVEL = 3//网络等级
+    var shopping: WeakReference<ShoppingCartDialogFragment>? = null
+    var payChoose: WeakReference<PayChooseDialogFragment>? = null//支付方式选择对户口
+
+    @RequiresApi(Build.VERSION_CODES.P)
     override fun HomeFragmentHomeBinding.initView() {
         startRefreshime()
         with(homeRvProduct) {
@@ -147,6 +164,36 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         enumByValue?.navId?.let { ivLogo.setImageResource(it) }
         enumByValue?.width?.let { layoutParams.width = it }
         enumByValue?.height?.let { layoutParams.height = it }
+
+        NetWorkUtils.registerLister(
+            this@HomeFragment.activity,
+            object : NetworkStateReceiverListener {
+                override fun networkAvailable(networkName: String) {
+                    Log.e(TAG, "网络 networkAvailable: $networkName")
+                    Global.isNetWork = true
+                    this@HomeFragment.networkName = networkName
+                    myHandler.sendEmptyMessage(NETWORK_STATE)
+
+                }
+
+                override fun networkUnavailable() {
+                    Log.e(TAG, "网络 networkUnavailable: ")
+                    Global.isNetWork = false
+                    networkName = "disconnect"
+                    myHandler.sendEmptyMessage(NETWORK_STATE)
+                }
+            })
+
+        PhoneStateUtils.registerPhoneStateListener(
+            this@HomeFragment.activity,
+            object : MyPhoneStateListenerListener {
+
+                override fun onSignalStrengthsChanged(p0: SignalStrength?) {
+                    Log.e(TAG, "网络  currentSignalStrength: " + p0?.level)
+                    this@HomeFragment.networkLevel = p0?.level!!
+                    myHandler.sendEmptyMessage(NETWORK_LEVEL)
+                }
+            })
     }
 
     //设置字体文件
@@ -174,6 +221,7 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         observeLiveData(mViewModel.coinValue, ::getCoinValue)
         lifecycle.addObserver(mViewModel.threadHomeParam)
         lifecycle.addObserver(myHandler)
+        lifecycle.addObserver(this)
     }
     var lastCoin: BigDecimal  = BigDecimal.ZERO.setScale(2, java.math.RoundingMode.HALF_UP);
 
@@ -205,15 +253,7 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         product = productList[position]
         Log.d(TAG, "clickProduct: "+product)
         //点击前校验 有没有开机、有没有选择支付方式等。
-        val deviceStatusCheck = mViewModel.deviceStatusCheck()//是否开机
-        if (deviceStatusCheck != "02") {
-            showTipsDialog(deviceStatusCheck)
-            return
-        }
-//        if (product?.price!! <= 0 && !Heartbeat.isForeign) {
-//            showTipsDialog("价格低于0元,不能购买")
-//            return
-//        }
+        if (checkToBuy()) return//是否开机
 
 //        selectProductDataBean = ProTypeEnum.getEnumByValue(product!!.nameChinese)
         //todo 测试做糖 传递价格等信息过去。
@@ -234,33 +274,58 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         }
     }
 
+    private fun checkToBuy(): Boolean {
+        val deviceStatusCheck = mViewModel.deviceStatusCheck()
+        if (deviceStatusCheck != "02") {
+            showTipsDialog(deviceStatusCheck)
+            return true
+        }
+        //        if (product?.price!! <= 0 && !Heartbeat.isForeign) {
+        //            showTipsDialog("价格低于0元,不能购买")
+        //            return
+        //        }
+        return false
+    }
+
     /**
      * 去付款
      * 选择支付方式对话框
      */
     private fun openPayDialog() {
-        if (payChooseDialogFragment == null) {
-            payChooseDialogFragment = PayChooseDialogFragment()
-            lifecycle.addObserver(payChooseDialogFragment!!)
-            payChooseDialogFragment?.setListener(object : DialogClickListener {
-                override fun onClickListener(type: Int, text: String?) {
-                    when (type) {
-                        payChooseDialogFragment?.typeBack -> {
-                            pauseTime = true
-                            //点击取消的时候发送一个event,这样统一一点,因为mdb刷卡器也可以取消,nayax也可以取消。。
-                            EventBus.getDefault().post(ApiMessageEvent(PayName.CANCEL_PAY,""))
-                        }
-
-                        else -> {}
+        if (payChoose?.get()?.let { isShow(it) } == true) {
+            return
+        }
+        payChoose = WeakReference(PayChooseDialogFragment())
+        payChoose?.get()?.setListener(object : DialogClickListener {
+            override fun onClickListener(type: Int, text: String?) {
+                when (type) {
+                    payChoose?.get()?.typeBack -> {
+                        pauseTime = true
+                        startRefreshime()
+                        //点击取消的时候发送一个event,这样统一一点,因为mdb刷卡器也可以取消,nayax也可以取消。。
+                        EventBus.getDefault().post(ApiMessageEvent(PayName.CANCEL_PAY, ""))
                     }
+
+                    else -> {}
                 }
-            })
-            lifecycle.addObserver(payChooseDialogFragment!!)
-        }
-        //携带购物车内容、优惠码过去。
-        payChooseDialogFragment?.setData(mViewModel.getShoppingTrolleyList(), promotionCode, mViewModel.shoppingTrolleySumPrice())
-        payChooseDialogFragment?.show(parentFragmentManager, payChooseDialogFragment?.tag)
+            }
+        })
+        payChoose?.get()?.setData(
+            mViewModel.getShoppingTrolleyList(),
+            promotionCode,
+            mViewModel.shoppingTrolleySumPrice()
+        )
+        payChoose?.get()?.show(parentFragmentManager, payChooseDialogFragment?.tag)
+    }
 
+    fun isShow(dialogFragment: PayChooseDialogFragment): Boolean {
+        if (dialogFragment != null && dialogFragment.getDialog() != null && dialogFragment.getDialog()!!
+                .isShowing()
+        ) {
+            return true
+        } else {
+            return false
+        }
     }
 
     override fun initRequestData() {
@@ -271,15 +336,12 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         mViewModel.getArticleData()
     }
 
-    override fun onStop() {
-        Log.d(TAG, "onStop: ")
-        stopRefreshTime()
-        super.onStop()
-    }
 
     override fun onDestroyView() {
         Log.d(TAG, "onDestroyView: ")
         mBinding.homeRvProduct.adapter = null //为什么要手动呢?。。。。。
+        NetWorkUtils.unRegisterNetWork(activity)
+        PhoneStateUtils.unRegisterPhoneStateListener(activity)
         super.onDestroyView()
     }
 
@@ -306,10 +368,11 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         when (message.name) {
             MqName.PAY_SUCCESS -> {
                 Log.d(TAG, "event: 收到了支付成功")
+                payChoose?.get()?.dismiss()
                 showPaySuccessDialog()
                 lifecycleScope.launch {
                     delay(2000)
-                    gotoMake(message.name,message.data as String)
+                    gotoMake(message.name,message.data as PaySuccessBean)
                 }
             }
             PayName.ACCEPT_BILL->{
@@ -324,12 +387,11 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         mViewModel.disposeData(messageEvent)
     }
 
+    var makeList: List<ShoppingCartBean>? = null
 
-
-    private fun gotoMake(name: String, payType: String) {
-
+    private fun gotoMake(name: String, payInfo: PaySuccessBean) {
         Log.d(TAG, "gotoMake: "+mViewModel.getShoppingTrolleyList())
-       var selectProductDataBean = ProTypeEnum.getEnumByValue(name) //上线需要使用这个。
+//       var selectProductDataBean = ProTypeEnum.getEnumByValue(name) //上线需要使用这个。
         if (product != null) {
             val findNavController = findNavController()
             var bundle = Bundle()
@@ -338,7 +400,17 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
             bundle.putString("SELECT_PRO", Gson().toJson(mViewModel.getShoppingTrolleyList()))
             bundle.putDouble("PRICE", mViewModel.shoppingTrolleySumPrice())
             bundle.putString("PROMOTION_CODE", promotionCode)
-            bundle.putString("PAY_TYPE",payType)
+            makeList = splitProductsByCount(mViewModel.getShoppingTrolleyList())
+            makeList?.let {
+                val allPrice = calculateTotal(it)
+                val name = 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)
+                }
+            }
             try {
                 findNavController.navigate(
                     R.id.home_action_home_homefragment_to_home_makefragment,
@@ -348,26 +420,129 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
                 Log.d(TAG, "gotoMake: "+e.message)
             }
         }
-        XLog.d("payType:$payType")
+        XLog.d("payType:$payInfo")
+    }
+
+
+    fun calculateTotal(cartItems: List<ShoppingCartBean>): Double {
+        return cartItems.sumOf { it.price }
+    }
+
+    // 生成名称拼接字符串
+    fun buildNameString(items: List<ShoppingCartBean>): String {
+        return items
+            .map { bean ->
+                // 优先取非空中文名,否则用ID
+                bean.nameChinese.takeIf { !it.isNullOrBlank() } ?: bean.nameId
+            }
+            .joinToString(separator = ", ") // 添加逗号和空格
+    }
+
+    fun splitProductsByCount(originalList: List<ShoppingCartBean>): List<ShoppingCartBean> {
+        val resultList: MutableList<ShoppingCartBean> = ArrayList<ShoppingCartBean>()
+
+        for (product in originalList) {
+            val count: Int = product.count
+            if (count <= 0) continue  // 跳过无效count
+            // 根据count生成新对象
+            for (i in 0 until count) {
+                val newItem: ShoppingCartBean = ShoppingCartBean(
+                    product.productNo,
+                    product.price,
+                    product.nameId,
+                    product.imgID,
+                    product.nameChinese,
+                    product.index,
+                    1
+                )
+                resultList.add(newItem)
+            }
+        }
+        return resultList
     }
 
+
     internal class MyHandler(fragment: Fragment) : Handler(), LifecycleObserver {
         var mWeakReference: WeakReference<Fragment> = WeakReference(fragment)
 
         override fun handleMessage(msg: android.os.Message) {
             //as用来强转
-            var fragment: HomeFragment = mWeakReference.get() as HomeFragment
+            var fragment: HomeFragment? = mWeakReference.get() as HomeFragment
             when (msg.what) {
-                fragment.HANDLE_TIME -> {
+                fragment?.HANDLE_TIME -> {
                     setTimeDate(fragment)
                 }
 
+                fragment?.NETWORK_STATE -> {
+                    setNetwork(fragment)
+                }
+
+                fragment?.NETWORK_LEVEL -> {
+                    setNetworkLevel(fragment)
+
+                }
+
+                else -> {
+
+                }
+            }
+        }
+
+        private fun setNetworkLevel(fragment: HomeFragment) {
+            XLogUtil.d("fragment.networkLevel:" + fragment.networkLevel)
+            when (fragment.networkLevel) {
+                1 -> {
+                    fragment.mBinding.iv4g.setImageResource(R.drawable.leven1)
+                }
+
+                2 -> {
+                    fragment.mBinding.iv4g.setImageResource(R.drawable.leven2)
+                }
+
+                3 -> {
+                    fragment.mBinding.iv4g.setImageResource(R.drawable.leven3)
+                }
+
+                4 -> {
+                    fragment.mBinding.iv4g.setImageResource(R.drawable.leven4)
+                }
+
+                5 -> {
+                    fragment.mBinding.iv4g.setImageResource(R.drawable.leven4)
+                }
+
                 else -> {
+                    fragment.mBinding.iv4g.setImageResource(R.drawable.leven0)
 
                 }
             }
         }
 
+        private fun setNetwork(fragment: HomeFragment) {
+            XLogUtil.d("fragment.networkName:" + fragment.networkName)
+            when (fragment.networkName) {
+                "4g" -> {
+                    fragment.mBinding.iv4g.setVisible(true)
+                    fragment.mBinding.ivWifi.setVisible(false)
+
+                }
+
+                "wifi" -> {
+                    fragment.mBinding.ivWifi.setImageResource(R.drawable.wifi)
+                    fragment.mBinding.ivWifi.setVisible(true)
+                    fragment.mBinding.iv4g.setVisible(false)
+                }
+
+                "disconnect" -> {
+                    fragment.mBinding.ivWifi.setImageResource(R.drawable.leven0)
+                    fragment.mBinding.ivWifi.setVisible(true)
+                    fragment.mBinding.iv4g.setVisible(false)
+                }
+
+                else -> {}
+            }
+        }
+
         /**
          * 设置时间
          */
@@ -376,10 +551,10 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
             val sysTime = System.currentTimeMillis() //获取系统时间
             val sysTimeStr = DateFormat.format("yyyy-MM-dd HH:mm:ss", sysTime) //时间显示格式
             fragment.mBinding.tvTime.text = sysTimeStr //更新时间
-            fragment.mBinding.tvWendu.text = SBCHeartbeat.outsideTemp+"°C"
-            fragment.mBinding.tvShidu.text = SBCHeartbeat.outsideHumidity+"%"
-            fragment.mBinding.tvLutou.text = SBCHeartbeat.headTemp+"°C"
-            fragment.mBinding.tvFashengqi.text = SBCHeartbeat.steamTemp+"°C"
+            fragment.mBinding.tvWendu.text = SBCHeartbeat.outsideTemp + "°C"
+            fragment.mBinding.tvShidu.text = SBCHeartbeat.outsideHumidity + "%"
+            fragment.mBinding.tvLutou.text = SBCHeartbeat.headTemp + "°C"
+            fragment.mBinding.tvFashengqi.text = SBCHeartbeat.steamTemp + "°C"
 
             if (fragment.pauseTime) {
                 fragment.backTime--
@@ -390,6 +565,7 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
             }
         }
 
+
         @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
         fun disconnectListener() {
             removeCallbacksAndMessages(null)
@@ -412,7 +588,8 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
         }
     }
 
-    private fun stopRefreshTime() {
+    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
+    fun stopRefreshTime() {
         jobTimer?.cancel()
     }
 
@@ -496,8 +673,8 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
 //                gotoMake("","")
             }
             R.id.btn_cif -> {
-                val name=SpUtils.getString(MMKVName.CONTACT_NAME,"")
-                val way=SpUtils.getString(MMKVName.CONTACT_NUMBER,"")
+                val name=SpUtils.getString(MMKVName.CONTACT,"")
+                val way=SpUtils.getString(MMKVName.CONTACT_WAY,"")
                 showContactDialog(name,way)
             }
             else -> {}
@@ -526,34 +703,32 @@ class HomeFragment : BaseFragment<HomeFragmentHomeBinding, HomeFragmentVM>(), Vi
             return
         }
         stopTimeReturn()
-        if (shoppingCartDialog == null) {
-            shoppingCartDialog = ShoppingCartDialogFragment()
-            shoppingCartDialog?.setListener(object : DialogClickListener {
-                override fun onClickListener(type: Int, text: String?) {
-                    when (type) {
-                        shoppingCartDialog?.type1 -> {
-                            startTimerReturn()
-                        }
-
-                        R.id.btn_pay -> {
-                            promotionCode = text
-                            pay()
-                        }
-
-                        else -> {}
+        shopping = WeakReference(ShoppingCartDialogFragment())
+        shopping?.get()?.setListener(object : DialogClickListener {
+            override fun onClickListener(type: Int, text: String?) {
+
+
+                when (type) {
+                    shopping?.get()?.type1 -> {
+                        Log.d(
+                            "backinfo",
+                            "onClickListeneronClickListeneronClickListeneronClickListener"
+                        )
+                        startTimerReturn()
+                        startRefreshime()
                     }
+
+                    R.id.btn_pay -> {
+                        promotionCode = text
+                        pay()
+                    }
+
+                    else -> {}
                 }
-            })
-            lifecycle.addObserver(shoppingCartDialog!!)
-        }
-//        shoppingCartDialog?.show(this.parentFragmentManager,"shoppingCartDialog")
-        getParentFragmentManager().let {
-            shoppingCartDialog!!.show(
-                it,
-                "shoppingCartDialog"
-            )
-        }
-        shoppingCartDialog?.setData(mViewModel)
+            }
+        })
+        shopping?.get()?.show(this.parentFragmentManager, "shoppingCartDialog")
+        shopping?.get()?.setData(mViewModel)
     }
 
     /**

+ 3 - 15
module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/MakeFragment.kt

@@ -59,7 +59,7 @@ import java.util.UUID
  */
 @RegisterEventBus
 @AndroidEntryPoint
-class MakeFragment : BaseFragment<HomeFragmentMakeBinding, MakeFragmentVM>() {
+class MakeFragment : BaseFragment<HomeFragmentMakeBinding, MakeFragmentVM>(),LifecycleObserver {
 
     private val TAG = "MakeFragment"
     private var simplePlayerUtil: SimplePlayerUtil? = null
@@ -113,7 +113,7 @@ class MakeFragment : BaseFragment<HomeFragmentMakeBinding, MakeFragmentVM>() {
         //硬币清零
         restCoin()
 
-        val logoIcon = SpUtils.getString(MMKVName.LOGO_TEXT, "1")
+        val logoIcon = SpUtils.getString(MMKVName.LOGO_TEXT, "7777")
         val enumByValue = LogoEnum.getEnumByValue(logoIcon!!)
         val layoutParams = ivLogo.layoutParams
         enumByValue?.navId?.let { ivLogo.setImageResource(it) }
@@ -132,6 +132,7 @@ class MakeFragment : BaseFragment<HomeFragmentMakeBinding, MakeFragmentVM>() {
         observeLiveData(mViewModel.D170Value, ::dataChange)
         lifecycle.addObserver(mViewModel.threadHomeParam)
         lifecycle.addObserver(myHandler)
+        lifecycle.addObserver(this)
     }
 
     private fun dataChange(value: String) {
@@ -152,22 +153,9 @@ class MakeFragment : BaseFragment<HomeFragmentMakeBinding, MakeFragmentVM>() {
 
     override fun initRequestData() {
         val promotionCodes = arguments?.getString("PROMOTION_CODE")
-        val price = arguments!!.getDouble("PRICE",0.00)
-        val payType = arguments!!.getString("PAY_TYPE","0")
-        val sysTime = System.currentTimeMillis() //获取系统时间
-        val sn = UUID.randomUUID().toString().replace("-", "")
-        val sysTimeStr = DateFormat.format("yyyy-MM-dd HH:mm:ss", sysTime) //时间显示格式
-        val localOrderBean = LocalOrderBean(
-            price = price,
-            payType = payType,
-            sn = sn,
-            time = sysTimeStr.toString(),
-            name=""
-        )
         mViewModel.getArticleData()
         //todo 优惠码处理
         mViewModel.usePromotionCode(promotionCodes)
-        mViewModel.saveOrder(localOrderBean)
     }
 
     override fun onDestroy() {

+ 15 - 3
module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/pay/BillCoinFragment.kt

@@ -11,8 +11,11 @@ import com.quyunshuo.androidbaseframemvvm.common.constant.event.ApiMessageEvent
 import com.quyunshuo.androidbaseframemvvm.common.ui.BaseFragment
 import com.quyunshuo.androidbaseframemvvm.common.util.UiUtil
 import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
+import com.quyunshuo.module.home.R
+import com.quyunshuo.module.home.bean.PaySuccessBean
 import com.quyunshuo.module.home.databinding.HomeFragmentBillCoinBinding
 import com.quyunshuo.module.home.fragment.vm.BuyFragmentVM
+import com.quyunshuo.module.home.utils.OrderNumberGenerator
 import dagger.hilt.android.AndroidEntryPoint
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
@@ -50,19 +53,28 @@ class BillCoinFragment : BaseFragment<HomeFragmentBillCoinBinding, BuyFragmentVM
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun event(message: ApiMessageEvent) {
         when (message.name) {
-            PayName.ACCEPT_BILL,PayName.COIN_DATA -> {
+            PayName.ACCEPT_BILL, PayName.COIN_DATA -> {
                 settlement()
             }
+
             else -> {}
         }
     }
 
     //金额结算
     private fun settlement() {
-        var price = sumPrice?.subtract(Heartbeat.acceptBill+Heartbeat.coinData)
+        var price = sumPrice?.subtract(Heartbeat.acceptBill + Heartbeat.coinData)
         if (price!!.toDouble() <= 0.0) {
             //如果支付成功,通知前台。
-            EventBus.getDefault().post(ApiMessageEvent(MqName.PAY_SUCCESS, UiUtil.getStringRes(PayEnum.BILL_COIN.nameId)))
+            EventBus.getDefault().post(
+                ApiMessageEvent(
+                    MqName.PAY_SUCCESS, PaySuccessBean(
+                        UiUtil.getStringRes(
+                            R.string.base_bill_coin
+                        ), OrderNumberGenerator.generateOrderNumber()
+                    )
+                )
+            )
             return
         }
         price = price.setScale(2, RoundingMode.HALF_UP)

+ 13 - 1
module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/pay/FreeMakeFragment.kt

@@ -11,9 +11,12 @@ import com.quyunshuo.androidbaseframemvvm.common.constant.event.ApiMessageEvent
 import com.quyunshuo.androidbaseframemvvm.common.ui.BaseFragment
 import com.quyunshuo.androidbaseframemvvm.common.util.UiUtil
 import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
+import com.quyunshuo.module.home.R
+import com.quyunshuo.module.home.bean.PaySuccessBean
 import com.quyunshuo.module.home.databinding.HomeFragmentBillCoinBinding
 import com.quyunshuo.module.home.databinding.HomeFragmentFreeMakeBinding
 import com.quyunshuo.module.home.fragment.vm.BuyFragmentVM
+import com.quyunshuo.module.home.utils.OrderNumberGenerator
 import dagger.hilt.android.AndroidEntryPoint
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
@@ -38,8 +41,17 @@ class FreeMakeFragment : BaseFragment<HomeFragmentFreeMakeBinding, BuyFragmentVM
         sumPrice = BigDecimal(arguments?.getDouble("PRICE", 0.0)!!)
         XLogUtil.d("price:" + sumPrice + Heartbeat.acceptBill)
         tvStartMake.setOnClickListener {
+            XLogUtil.d("开始免费制作")
             //传递支付方式。
-            EventBus.getDefault().post(ApiMessageEvent(MqName.PAY_SUCCESS, UiUtil.getStringRes(PayEnum.FREE.nameId)))
+            EventBus.getDefault().post(
+                ApiMessageEvent(
+                    MqName.PAY_SUCCESS, PaySuccessBean(
+                        UiUtil.getStringRes(
+                            R.string.base_free_pay
+                        ), OrderNumberGenerator.generateOrderNumber()
+                    )
+                )
+            )
         }
     }
 

+ 26 - 14
module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/pay/MDBCardFragment.kt

@@ -22,9 +22,12 @@ import com.quyunshuo.androidbaseframemvvm.common.constant.event.ApiMessageEvent
 import com.quyunshuo.androidbaseframemvvm.common.ui.BaseFragment
 import com.quyunshuo.androidbaseframemvvm.common.util.UiUtil
 import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
+import com.quyunshuo.module.home.R
+import com.quyunshuo.module.home.bean.PaySuccessBean
 import com.quyunshuo.module.home.databinding.HomeFragmentMdbCardBinding
 import com.quyunshuo.module.home.databinding.HomeFragmentNayaxCardBinding
 import com.quyunshuo.module.home.fragment.vm.BuyFragmentVM
+import com.quyunshuo.module.home.utils.OrderNumberGenerator
 import dagger.hilt.android.AndroidEntryPoint
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
@@ -42,13 +45,13 @@ import org.greenrobot.eventbus.ThreadMode
  */
 @RegisterEventBus
 @AndroidEntryPoint
-class MDBCardFragment : BaseFragment<HomeFragmentMdbCardBinding, BuyFragmentVM>()  {
+class MDBCardFragment : BaseFragment<HomeFragmentMdbCardBinding, BuyFragmentVM>() {
 
     override val mViewModel: BuyFragmentVM by viewModels()
     override fun createVB() = HomeFragmentMdbCardBinding.inflate(layoutInflater)
-    private var selectPro:String?= null//传递过来的购物车内容
+    private var selectPro: String? = null//传递过来的购物车内容
     var createStrategy = PaySendDataFactory.createStrategy(StrategyType.MDB)
-    var productNumber ="0"
+    var productNumber = "0"
     var price = 0.0
 
     override fun HomeFragmentMdbCardBinding.initView() {
@@ -59,15 +62,15 @@ class MDBCardFragment : BaseFragment<HomeFragmentMdbCardBinding, BuyFragmentVM>(
         )
 
         arrayList.forEach {
-            price+= it.count * it.price
+            price += it.count * it.price
             productNumber = it.index.toString()
         }
         //发起交易
-        createStrategy.creditCardPay(price,productNumber)
+        createStrategy.creditCardPay(price, productNumber)
         XLogUtil.d("发起交易:$price")
 
         tvReset.setOnClickListener {
-            createStrategy.creditCardPay(price,productNumber)
+            createStrategy.creditCardPay(price, productNumber)
             tvReset.setVisible(false)
             ivCardIcon.setVisible(true)
             tvCardTips1.setVisible(true)
@@ -80,7 +83,7 @@ class MDBCardFragment : BaseFragment<HomeFragmentMdbCardBinding, BuyFragmentVM>(
         super.onDestroyView()
     }
 
-    fun canselPay(){
+    fun canselPay() {
         //如果是支付成功,那么取消肯定是没有的。
         //取消信用卡的本次操作
         createStrategy.creditCardCancel()
@@ -100,27 +103,36 @@ class MDBCardFragment : BaseFragment<HomeFragmentMdbCardBinding, BuyFragmentVM>(
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun event(message: ApiMessageEvent) {
         when (message.name) {
-            PayName.CANCEL_PAY->{
+            PayName.CANCEL_PAY -> {
                 canselPay()
             }
-            PayName.MDB_CARD_SUCCESS->{
+
+            PayName.MDB_CARD_SUCCESS -> {
                 CoroutineScope(Dispatchers.IO).launch {
                     createStrategy.creditCardVendSuccess(productNumber)
                     delay(500)
                     createStrategy.creditCardSessionComplete()
                     delay(500)
-                    createStrategy.creditCardCashSale(price,productNumber)
-                    EventBus.getDefault().post(ApiMessageEvent(MqName.PAY_SUCCESS, UiUtil.getStringRes(PayEnum.MDB_NO_CASH.nameId)))
-
+                    createStrategy.creditCardCashSale(price, productNumber)
+                    EventBus.getDefault().post(
+                        ApiMessageEvent(
+                            MqName.PAY_SUCCESS, PaySuccessBean(
+                                UiUtil.getStringRes(
+                                    R.string.base_mdb_no_cash
+                                ), OrderNumberGenerator.generateOrderNumber()
+                            )
+                        )
+                    )
                 }
-
             }
-            PayName.MDB_CARD_DENIED->{
+
+            PayName.MDB_CARD_DENIED -> {
                 mBinding.tvReset.setVisible(true)
                 mBinding.ivCardIcon.setVisible(false)
                 mBinding.tvCardTips1.setVisible(false)
                 mBinding.tvCardTips2.setVisible(false)
             }
+
             else -> {}
         }
     }

+ 24 - 10
module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/pay/NayaxCardFragment.kt

@@ -19,8 +19,11 @@ import com.quyunshuo.androidbaseframemvvm.common.constant.event.ApiMessageEvent
 import com.quyunshuo.androidbaseframemvvm.common.ui.BaseFragment
 import com.quyunshuo.androidbaseframemvvm.common.util.UiUtil
 import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
+import com.quyunshuo.module.home.R
+import com.quyunshuo.module.home.bean.PaySuccessBean
 import com.quyunshuo.module.home.databinding.HomeFragmentNayaxCardBinding
 import com.quyunshuo.module.home.fragment.vm.BuyFragmentVM
+import com.quyunshuo.module.home.utils.OrderNumberGenerator
 import dagger.hilt.android.AndroidEntryPoint
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
@@ -36,12 +39,12 @@ import org.greenrobot.eventbus.ThreadMode
  */
 @RegisterEventBus
 @AndroidEntryPoint
-class NayaxCardFragment : BaseFragment<HomeFragmentNayaxCardBinding, BuyFragmentVM>()  {
+class NayaxCardFragment : BaseFragment<HomeFragmentNayaxCardBinding, BuyFragmentVM>() {
 
     override val mViewModel: BuyFragmentVM by viewModels()
     override fun createVB() = HomeFragmentNayaxCardBinding.inflate(layoutInflater)
     var cardPresenter = CreditCardPresenter.getCreditCardContract()
-    private var selectPro:String?= null//传递过来的购物车内容
+    private var selectPro: String? = null//传递过来的购物车内容
     private val TAG = "NayaxCardFragment"
 
     override fun HomeFragmentNayaxCardBinding.initView() {
@@ -59,11 +62,11 @@ class NayaxCardFragment : BaseFragment<HomeFragmentNayaxCardBinding, BuyFragment
         )
         var price = 0.0
         arrayList.forEach {
-            price+= it.count * it.price
+            price += it.count * it.price
         }
         //发起交易
-        cardPresenter.setNameAndPrice(price*100,0)
-        if (SpUtils.getBoolean(MMKVName.NAYAX_MODE,false)!!){
+        cardPresenter.setNameAndPrice(price * 100, 0)
+        if (SpUtils.getBoolean(MMKVName.NAYAX_MODE, false)!!) {
             cardPresenter.vendRequest();
         }
     }
@@ -72,7 +75,7 @@ class NayaxCardFragment : BaseFragment<HomeFragmentNayaxCardBinding, BuyFragment
         super.onDestroyView()
     }
 
-    fun canselPay(){
+    fun canselPay() {
         //如果是支付成功,那么取消肯定是没有的。
         //取消信用卡的本次操作
         if (cardPresenter.is_ready()) {
@@ -94,23 +97,34 @@ class NayaxCardFragment : BaseFragment<HomeFragmentNayaxCardBinding, BuyFragment
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun event(message: ApiMessageEvent) {
         when (message.name) {
-            PayName.CANCEL_PAY->{
+            PayName.CANCEL_PAY -> {
                 canselPay()
             }
+
             else -> {}
         }
     }
+
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun event(message: CreditCardMessage) {
         when (message.type) {
-            CreditCardMessage.Type.invalid->{
+            CreditCardMessage.Type.invalid -> {
                 //卡无效或者余额不足的情况。 取消也会调用。
 //                payChooseDialogFragment?.dismiss()
             }
-            CreditCardMessage.Type.success->{
+
+            CreditCardMessage.Type.success -> {
                 //支付成功
                 //如果支付成功,通知前台。
-                EventBus.getDefault().post(ApiMessageEvent(MqName.PAY_SUCCESS, UiUtil.getStringRes(PayEnum.NAYAX.nameId)))
+                EventBus.getDefault().post(
+                    ApiMessageEvent(
+                        MqName.PAY_SUCCESS, PaySuccessBean(
+                            UiUtil.getStringRes(
+                                R.string.base_nayax
+                            ), OrderNumberGenerator.generateOrderNumber()
+                        )
+                    )
+                )
             }
             else -> {}
         }

+ 17 - 18
module_home/src/main/java/com/quyunshuo/module/home/fragment/fragment/pay/QrCodeFragment.kt

@@ -9,7 +9,6 @@ import android.view.View
 import androidx.fragment.app.viewModels
 import com.google.gson.Gson
 import com.google.gson.reflect.TypeToken
-import com.quyunshuo.androidbaseframemvvm.base.addressenum.PayEnum
 import com.quyunshuo.androidbaseframemvvm.base.ktx.observeLiveData
 import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils
 import com.quyunshuo.androidbaseframemvvm.common.bean.ShoppingCartBean
@@ -18,7 +17,6 @@ import com.quyunshuo.androidbaseframemvvm.common.constant.MqName
 import com.quyunshuo.androidbaseframemvvm.common.constant.event.ApiMessageEvent
 import com.quyunshuo.androidbaseframemvvm.common.ui.BaseFragment
 import com.quyunshuo.androidbaseframemvvm.common.util.ToastUtil
-import com.quyunshuo.androidbaseframemvvm.common.util.UiUtil
 import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
 import com.quyunshuo.module.home.databinding.HomeFragmentQrCodeBinding
 import com.quyunshuo.module.home.fragment.vm.QrCodeFragmentVM
@@ -32,32 +30,32 @@ import org.greenrobot.eventbus.EventBus
  * @since 2021/8/1 11:46 下午
  */
 @AndroidEntryPoint
-class QrCodeFragment : BaseFragment<HomeFragmentQrCodeBinding, QrCodeFragmentVM>()  {
+class QrCodeFragment : BaseFragment<HomeFragmentQrCodeBinding, QrCodeFragmentVM>() {
 
     override val mViewModel: QrCodeFragmentVM by viewModels()
     override fun createVB() = HomeFragmentQrCodeBinding.inflate(layoutInflater)
 
-    private var selectPro:String?= null//传递过来的购物车内容
-    private var promotionCode:String?=null//传递过来的优惠码
+    private var selectPro: String? = null//传递过来的购物车内容
+    private var promotionCode: String? = null//传递过来的优惠码
 
     override fun HomeFragmentQrCodeBinding.initView() {
-        with(ivReset){
+        with(ivReset) {
             setOnClickListener {
                 mViewModel.twoPayCode(selectPro)
                 visibility = View.GONE
-                pbQrLoading.visibility =View.VISIBLE
+                pbQrLoading.visibility = View.VISIBLE
 
             }
         }
     }
 
     override fun initObserve() {
-        observeLiveData(mViewModel.qrCode,::showQrCode)
+        observeLiveData(mViewModel.qrCode, ::showQrCode)
     }
 
     private fun showQrCode(qrCode: String) {
         mBinding.pbQrLoading.visibility = View.GONE
-        if (qrCode=="") {
+        if (qrCode == "") {
             mBinding.ivReset.visibility = View.VISIBLE
             ToastUtil.switchToastStyleToWarn("网络不好,请重试")
             return
@@ -65,11 +63,11 @@ class QrCodeFragment : BaseFragment<HomeFragmentQrCodeBinding, QrCodeFragmentVM>
         if (isBase64Img(qrCode)) {
             val bitmap: Bitmap = stringToBitmap(qrCode)
             mBinding.ivQrCode.setImageBitmap(bitmap)
-        }else if("0"==qrCode) {
+        } else if ("0" == qrCode) {
             // 优惠码支付成功
-            EventBus.getDefault().post(ApiMessageEvent(MqName.PAY_SUCCESS, UiUtil.getStringRes(PayEnum.TWO_CODE.nameId)))
+            EventBus.getDefault().post(ApiMessageEvent(MqName.PAY_SUCCESS, ""))
             return
-        }else{
+        } else {
             mBinding.ivReset.visibility = View.VISIBLE
             ToastUtil.switchToastStyleToWarn(qrCode)
             return
@@ -80,16 +78,17 @@ class QrCodeFragment : BaseFragment<HomeFragmentQrCodeBinding, QrCodeFragmentVM>
     override fun initRequestData() {
         selectPro = arguments?.getString("SELECT_PRO")
         promotionCode = arguments?.getString("PROMOTION_CODE")
+        Log.d("backinfo", "选择的商品:" + selectPro)
         //是否为购物车模式  不管是否为购物车模式,都使用twoPayCodeShoppingCart  因为单选其实就是限制购物车只能一个。
 //        val isShoppingTrolley = SpUtils.getBoolean(MMKVName.SHOPPING_TROLLEY, true)
 //        if (isShoppingTrolley!!){
-            val arrayList: ArrayList<ShoppingCartBean> = Gson().fromJson(
-                selectPro,
-                object : TypeToken<ArrayList<ShoppingCartBean?>?>() {}.type
-            )
-            mViewModel.twoPayCodeShoppingCart(arrayList,promotionCode)
+        val arrayList: ArrayList<ShoppingCartBean> = Gson().fromJson(
+            selectPro,
+            object : TypeToken<ArrayList<ShoppingCartBean?>?>() {}.type
+        )
+        mViewModel.twoPayCodeShoppingCart(arrayList, promotionCode)
 //        }else{
-            //
+        //
 //            mViewModel.twoPayCode(selectPro,promotionCode)
 //        }
 

+ 0 - 5
module_home/src/main/java/com/quyunshuo/module/home/fragment/repo/MakeFragmentRepo.kt

@@ -29,9 +29,4 @@ class MakeFragmentRepo @Inject constructor() : BaseRepository() {
             emit(this)
         }
     }
-
-    suspend fun saveOrder(localOrderBean:LocalOrderBean){
-        val orderBeanDao= SZDatabase.getDatabase(BaseApplication.context).getLocalOrderDao()
-        orderBeanDao.insert(localOrderBean)
-    }
 }

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

@@ -1,5 +1,6 @@
 package com.quyunshuo.module.home.fragment.vm
 
+import android.text.format.DateFormat
 import android.util.Log
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
@@ -11,6 +12,9 @@ import com.hboxs.serialport.plc.util.AsciiUtils
 import com.hboxs.serialport.plc.util.HexadecimalUtil
 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.quyunshuo.androidbaseframemvvm.base.BaseApplication
 import com.quyunshuo.androidbaseframemvvm.base.addressenum.PlcHomeAddressEnum
 import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
 import com.quyunshuo.androidbaseframemvvm.common.bean.ProductDataBean
@@ -45,6 +49,7 @@ class HomeFragmentVM @Inject constructor(private val mRepo: HomeFragmentRepo) :
     val shoppingCarSize: LiveData<Int> get() = _shoppingCarSize
     private val _shoppingCarSumPrice = MutableLiveData<Double>()
     val shoppingCarSumPrice: LiveData<Double> get() = _shoppingCarSumPrice
+    private val localOrderDao = SZDatabase.getDatabase(BaseApplication.context).getLocalOrderDao()
 
     private val _coinValue = MutableLiveData<String>()
     val coinValue: LiveData<String> get() = _coinValue
@@ -62,6 +67,20 @@ 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) //时间显示格式
+        localOrderDao.insert(
+            LocalOrderBean(
+                price = price,
+                payType = payType,
+                sn = sn,
+                time = sysTimeStr.toString(),
+                name = name
+            )
+        )
+    }
+
     /**
      * 获取 banner 数据
      */
@@ -221,6 +240,7 @@ class HomeFragmentVM @Inject constructor(private val mRepo: HomeFragmentRepo) :
         } else {
             // 如果不存在,添加新项
             val newItem = ShoppingCartBean(
+                productDataBean.productNo,
                 productDataBean.price,
                 productDataBean.nameId,
                 productDataBean.imgID,

+ 0 - 6
module_home/src/main/java/com/quyunshuo/module/home/fragment/vm/MakeFragmentVM.kt

@@ -181,10 +181,4 @@ class MakeFragmentVM @Inject constructor(private val mRepo: MakeFragmentRepo) :
         }
 
     }
-
-    fun saveOrder(localOrderBean: LocalOrderBean) {
-        viewModelScope.launch(Dispatchers.IO) {
-            mRepo.saveOrder(localOrderBean)
-        }
-    }
 }

+ 1 - 1
module_home/src/main/java/com/quyunshuo/module/home/fragment/vm/QrCodeFragmentVM.kt

@@ -112,7 +112,7 @@ class QrCodeFragmentVM @Inject constructor(private val mRepo: QrCodeFragmentRepo
                     }
                     shoppingCartNumber++
                 }
-                map[""+it.nameChinese+"-"+it.count] = Gson().toJson(codes)
+                map[""+it.productNo+"-"+it.count] = Gson().toJson(codes)
             }
             Log.d(TAG, "twoPayCodeShoppingCart: "+Gson().toJson(map))
             paymentStrategy.pay(map).catch {

+ 1 - 1
module_home/src/main/java/com/quyunshuo/module/home/pay/WeChatAlipayPayMent.kt

@@ -62,7 +62,7 @@ class WeChatAlipayPayMent @Inject constructor() : DefultPayMentStrategy() {
     private suspend fun carsPay(productName: String)= request<String> {
         val body: RequestBody =
             RequestBody.create("application/json;charset=utf-8".toMediaTypeOrNull(), productName)
-        val url:String ="/PAY-SERVER/tOrder/carsPay?="+Heartbeat.deviceId!!
+        val url:String ="/PAY-SERVER/tOrder/newCarsPay?="+Heartbeat.deviceId!!
         mApi.carsPay(url,body).run {
             emit(this)
         }

+ 1 - 1
module_home/src/main/java/com/quyunshuo/module/home/pay/WeChatAlipayPayShoppingCartMent.kt

@@ -61,7 +61,7 @@ class WeChatAlipayPayShoppingCartMent @Inject constructor() : DefultPayMentStrat
     private suspend fun carsPay(productName: String)= request<String> {
         val body: RequestBody =
             RequestBody.create("application/json;charset=utf-8".toMediaTypeOrNull(), productName)
-        val url:String ="/PAY-SERVER/tOrder/carsPay?clientId="+Heartbeat.deviceId!!
+        val url:String ="/PAY-SERVER/tOrder/newCarsPay?clientId="+Heartbeat.deviceId!!
         Log.d(TAG, "carsPay: "+url)
         mApi.carsPay(url,body).run {
             emit(this)

+ 10 - 4
module_home/src/main/java/com/quyunshuo/module/home/receiver/MqttHelper.kt

@@ -2,8 +2,9 @@ package com.quyunshuo.module.home.receiver
 
 import android.content.Context
 import com.google.gson.Gson
+
 import com.module.pay.service.HomeApiService
-import com.quyunshuo.androidbaseframemvvm.base.BaseApplication
+
 import com.quyunshuo.androidbaseframemvvm.common.constant.Heartbeat
 import com.quyunshuo.module.home.service.ManageMqtt
 import javax.inject.Inject
@@ -24,16 +25,21 @@ class MqttHelper @Inject constructor() {
      */
     fun register(context: Context?) {
         mqtt.init(context)
+
+    }
+
+    fun isMqConnected(): Boolean {
+        return mqtt.isMqConnected
     }
 
     /**
      * 发送数据
      */
-    fun sendData(data: String) {
+    fun sendData(topic: String, data: String) {
         //{"kindData:1","kindId:openDev"}
-        if (""!=(Heartbeat.deviceId)) {
+        if ("" != (Heartbeat.deviceId)) {
             if (mqtt != null && mqtt.isMqConnected) {
-                Heartbeat.deviceId?.let { mqtt.publish(it, Gson().toJson(data)) }
+                Heartbeat.deviceId?.let { mqtt.publish(topic, data) }
 
             }
         }

+ 170 - 0
module_home/src/main/java/com/quyunshuo/module/home/service/ForceBackToAppService.kt

@@ -0,0 +1,170 @@
+package com.quyunshuo.module.home.service
+
+import ZtlApi.ZtlManager
+import android.annotation.SuppressLint
+import android.app.ActivityManager
+import android.app.AlarmManager
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.os.Build
+import android.os.IBinder
+import android.os.Process
+import android.util.Log
+import android.view.WindowManager
+import com.elvishew.xlog.XLog
+import com.hboxs.serialport.plc.DialogClickListener
+import com.hboxs.serialport.sbc.SBCHeartbeat.initIsSuccess
+import com.hboxs.serialport.sbc.VBoxMessage
+import com.hboxs.serialport.sbc.VboxSerialPortDevice
+import com.hboxs.serialport.sbc.VboxSerialPortManager
+import com.hjq.http.lifecycle.LifecycleService
+import com.module.pay.common.PayAgreementUtil
+import com.module.pay.nayax.CreditCardPresenter
+import com.module.pay.strategy.PaySendDataFactory
+import com.quyunshuo.androidbaseframemvvm.base.BaseApplication
+import com.quyunshuo.androidbaseframemvvm.base.ktx.observeLiveData
+import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils
+import com.quyunshuo.androidbaseframemvvm.common.constant.MMKVName
+import com.quyunshuo.androidbaseframemvvm.common.constant.MqName
+import com.quyunshuo.androidbaseframemvvm.common.constant.event.ApiMessageEvent
+import com.quyunshuo.androidbaseframemvvm.common.util.LogUtil
+import com.quyunshuo.androidbaseframemvvm.common.util.ToastUtil
+import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
+import com.quyunshuo.module.home.activity.main.MainActivity
+import com.quyunshuo.module.home.dialog.CountDownDialogFragment
+import com.quyunshuo.module.home.dialog.WarringDialog
+import com.tencent.mmkv.MMKV
+import dagger.hilt.android.AndroidEntryPoint
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
+import javax.inject.Inject
+
+/**
+ * 强制返回App服务:用与解决闪退自回复的功能
+ */
+@AndroidEntryPoint
+class ForceBackToAppService : LifecycleService() {
+    private val TAG = "GlobalService"
+
+    private val NOTIFICATION_ID = "1"
+    private val NOTIFICATION_NAME: CharSequence = "GlobalService"
+    //强制返回App的携程
+    var forceBackToAppJob: Job? = null
+
+    //这个必须加,不能设置为null
+    private fun getNotification(): Notification {
+        val builder: Notification.Builder = Notification.Builder(this)
+            .setContentTitle("GlobalService")
+            .setContentText("我正在运行") //标题和内容可以不加
+        //设置Notification的ChannelID,否则不能正常显示
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            builder.setChannelId(NOTIFICATION_ID)
+        }
+        val notification = builder.build()
+        return notification
+    }
+
+
+    @SuppressLint("ForegroundServiceType")
+    override fun onCreate() {
+        super.onCreate()
+        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
+
+        //创建NotificationChannel
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            val channel = NotificationChannel(
+                NOTIFICATION_ID,
+                NOTIFICATION_NAME,
+                NotificationManager.IMPORTANCE_HIGH
+            )
+            notificationManager.createNotificationChannel(channel)
+            startForeground(1, getNotification())
+        }
+        XLog.init()
+        forceBackToApp()
+    }
+
+    /**
+     * 强制跳回App
+     */
+    fun forceBackToApp() {
+        if (forceBackToAppJob == null) {
+            forceBackToAppJob = CoroutineScope(Dispatchers.IO).launch {
+                while (isActive) {//在协程中使用 isActive 可以确保协程在取消时能够及时退出循环或停止任务,避免资源浪费。
+                    delay(10000)
+                    //判断程序是否在运行
+                    val isRunning: Boolean = isServiceStarted(
+                        BaseApplication.context,
+                        "com.quyunshuo.androidbaseframemvvm"
+                    )
+                    XLogUtil.d("MyTestService,Build.MODEL onReceive:程序未开启============$isRunning")
+                    //运行中,跳过他。
+                    if (isRunning) {
+                        continue
+                    }
+                    val intent: Intent = Intent(
+                        BaseApplication.context,
+                        MainActivity::class.java
+                    ) //此处我是根据需要重新启动时先进入欢迎页
+                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) //关掉所要到的界面中间的activity
+
+                    @SuppressLint("WrongConstant") val restartIntent = PendingIntent.getActivity(
+                        BaseApplication.context, 0, intent,
+                        Intent.FLAG_ACTIVITY_NEW_TASK or PendingIntent.FLAG_IMMUTABLE
+                    )
+
+                    //退出程序
+                    val mgr = BaseApplication.context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
+                    mgr[AlarmManager.RTC, System.currentTimeMillis() + 1000] =
+                        restartIntent // 1秒钟后重启应用,这个可以根据需要自己定义
+
+                    //干掉当前的程序
+                    LogUtil.d("MyTestService", "uncaughtException2: ")
+                    Process.killProcess(Process.myPid())
+                    System.exit(0)
+
+                }
+
+            }
+        }
+
+    }
+
+    /**
+     * 关掉强制跳回App
+     */
+    fun stopForceBackToApp(){
+        forceBackToAppJob?.cancel()
+        forceBackToAppJob = null
+    }
+
+    /**
+     * 检测一个android程序是否在运行
+     *
+     * @param context
+     * @param PackageName
+     * @return
+     */
+    fun isServiceStarted(context: Context, packageName: String): Boolean {
+        val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+        val runningProcesses = am.runningAppProcesses
+        for (processInfo in runningProcesses) {
+            if (processInfo.processName == packageName) {
+                return true
+            }
+        }
+        return false
+    }
+
+}

+ 24 - 7
module_home/src/main/java/com/quyunshuo/module/home/service/ManageMqtt.kt

@@ -8,6 +8,9 @@ import android.net.ConnectivityManager
 import android.net.wifi.WifiManager
 import android.util.Log
 import com.quyunshuo.androidbaseframemvvm.common.constant.Heartbeat
+import com.hboxs.serialport.plc.message.MqttMessageBean
+import com.hboxs.serialport.sbc.SBCHeartbeat
+import com.quyunshuo.androidbaseframemvvm.common.constant.MqName
 import org.eclipse.paho.android.service.MqttAndroidClient
 import org.eclipse.paho.client.mqttv3.IMqttActionListener
 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken
@@ -23,7 +26,7 @@ import javax.inject.Singleton
  * 测试环境的设备管理系统
  */
 @Singleton
-class ManageMqtt @Inject constructor(){
+class ManageMqtt @Inject constructor() {
 
     private var context: Context? = null
     private var TAG = "MQTT"
@@ -55,7 +58,11 @@ class ManageMqtt @Inject constructor(){
             // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
             options.keepAliveInterval = 90
 
-            client = MqttAndroidClient(context, "tcp://112.74.33.65:1883", Heartbeat.deviceId)//在管理里面显示的名称
+            client = MqttAndroidClient(
+                context,
+                "tcp://112.74.33.65:1883",
+                Heartbeat.deviceId
+            )//在管理里面显示的名称
             //设置连接的用户名
             options.userName = "sunzeeUser"
             //设置连接的密码
@@ -65,10 +72,10 @@ class ManageMqtt @Inject constructor(){
             //设置回调
             client?.setCallback(object : MqttCallbackExtended {
                 override fun connectComplete(reconnect: Boolean, serverURI: String) {
-                    log("已连接mq")
+                    log("已连接mq"+Heartbeat.deviceId)
                     isMqConnected = true
                     //连接成功,我们要进行订阅
-                    subscribe("15018460394")
+                    Heartbeat.deviceId?.let { subscribe(it) }
                 }
 
                 override fun connectionLost(cause: Throwable) {
@@ -91,6 +98,15 @@ class ManageMqtt @Inject constructor(){
                     try {
                         //todo 收到消息,要进行一些处理的。 Eventbus
                         log("收到消息:$topicName     $message")
+                        val str1: String = String(message.getPayload())
+                        org.greenrobot.eventbus.EventBus.getDefault()
+                            .post(
+                                MqttMessageBean(
+                                    topicName,
+                                    MqName.messageArrived,
+                                    str1
+                                )
+                            )
                     } catch (e: Exception) {
                         log("异常:$e")
                     }
@@ -105,7 +121,7 @@ class ManageMqtt @Inject constructor(){
         intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
         intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
         intentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION)
-        context?.registerReceiver(netWorkBroadCastReciver,intentFilter)
+        context?.registerReceiver(netWorkBroadCastReciver, intentFilter)
     }
 
     //进行链接
@@ -202,6 +218,7 @@ class ManageMqtt @Inject constructor(){
 
 
     private var networkState = 100
+
     //断网重连查询
     fun isNetConnected(context: Context): Boolean {
         Log.d(TAG, "isNetConnected: ")
@@ -232,10 +249,10 @@ class ManageMqtt @Inject constructor(){
         return false
     }
 
-    var netWorkBroadCastReciver = object :BroadcastReceiver() {
+    var netWorkBroadCastReciver = object : BroadcastReceiver() {
         override fun onReceive(context: Context, intent: Intent?) {
             isNetConnected(context)
-            log( "NetWorkBroadCastReciver: ")
+            log("NetWorkBroadCastReciver: ")
         }
     }
 

+ 30 - 4
module_home/src/main/java/com/quyunshuo/module/home/service/MqService.kt

@@ -12,11 +12,17 @@ import android.os.Handler
 import android.os.IBinder
 import android.os.Message
 import android.util.Log
+import com.hboxs.serialport.plc.message.MqttMessageBean
 import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils
 import com.quyunshuo.androidbaseframemvvm.common.constant.Heartbeat
 import com.quyunshuo.androidbaseframemvvm.common.constant.MMKVName
+import com.quyunshuo.androidbaseframemvvm.common.constant.MqName
+import com.quyunshuo.androidbaseframemvvm.common.constant.SavaAddress
 import com.quyunshuo.androidbaseframemvvm.common.enums.ConnectStateEnum
 import com.quyunshuo.androidbaseframemvvm.common.util.FileUtil
+import com.quyunshuo.androidbaseframemvvm.common.util.ToastUtil
+import com.quyunshuo.androidbaseframemvvm.common.util.UiUtil
+import com.quyunshuo.module.home.R
 import com.quyunshuo.module.home.receiver.MqttHelper
 import com.rabbitmq.client.AMQP
 import com.rabbitmq.client.Channel
@@ -29,6 +35,9 @@ import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
+import org.greenrobot.eventbus.EventBus
+import org.greenrobot.eventbus.Subscribe
+import org.greenrobot.eventbus.ThreadMode
 import java.io.IOException
 import javax.inject.Inject
 
@@ -39,6 +48,7 @@ class MqService : Service() {
     private val userName = "admin"
     private val passWord = "admin"
     private val hostName = "112.74.63.148"
+    private val portNum = 5672
 
     @Inject
     lateinit var mqServiceViewModel: MqServiceViewModel
@@ -47,7 +57,7 @@ class MqService : Service() {
     lateinit var mqttHelper: MqttHelper
 
     //    private String hostName = "192.168.0.184";//
-    private val portNum = 5672
+
     private var queueName: String = Heartbeat.deviceId!! //队列
 
     @Volatile
@@ -68,6 +78,7 @@ class MqService : Service() {
     override fun onCreate() {
         super.onCreate()
         Log.d(TAG, "onCreate......")
+        EventBus.getDefault().register(this)
         //连接设置
         setupConnectionFactory()
         //开启消费者线程
@@ -84,7 +95,7 @@ class MqService : Service() {
         mqttHelper.register(this)
         CoroutineScope(Dispatchers.IO).launch {
             delay(10000)
-            mqttHelper.sendData("asdfasdf")
+            //  mqttHelper.sendData("asdfasdf")
             Log.d(TAG, "mqttHelper.sendData: ")
 
         }
@@ -94,6 +105,7 @@ class MqService : Service() {
     override fun onDestroy() {
         super.onDestroy()
         unregisterReceiver(mNetWorkBroadCastReciver)
+        EventBus.getDefault().unregister(this)
     }
 
     /**
@@ -132,6 +144,20 @@ class MqService : Service() {
         return super.onStartCommand(intent, flags, startId)
     }
 
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    fun event(message: MqttMessageBean) {
+        when (message.topicType) {
+            MqName.SENDPRICE -> {
+                if (mqttHelper.isMqConnected()){
+                    Log.d("backinfo", "要发送修改设备价格的数据:" + message.content)
+                    mqttHelper.sendData(message.topic, message.content)
+                }else{
+                    ToastUtil.switchToastStyleToWarn(UiUtil.getStringRes(com.quyunshuo.androidbaseframemvvm.base.R.string.mqtt_con_state))
+                }
+            }
+        }
+    }
+
     //旧方法
     private fun initView() {
         var data = SpUtils.getString(MMKVName.QUEUE_DATA, "") as String //连接设备id
@@ -141,7 +167,7 @@ class MqService : Service() {
         if (("" == updateMaterialStatus)) { //因为脱离系统了,那么就清空,重新创建
             data = ""
         }
-        val machineType: String = SpUtils.getString(MMKVName.MACHINE_TYPE, "SBM10")!!
+        val machineType: String = SpUtils.getString(MMKVName.MACHINE_TYPE, SavaAddress.MACHINE_TYPE)!!
         Log.d(TAG, "$data: mq getAddQueue: $machineType")
         // SharedPreferencesUtils.setParam(Name.QUEUE_DATA, data);
         if (("" == Heartbeat.deviceId)) {
@@ -176,7 +202,7 @@ class MqService : Service() {
     private fun initView1() {
         val data = SpUtils.getString(MMKVName.QUEUE_DATA, "") as String //连接设备id
         Log.d(TAG, "1data initView: $data")
-        val machineType: String = SpUtils.getString(MMKVName.MACHINE_TYPE, "SBM10")!!
+        val machineType: String = SpUtils.getString(MMKVName.MACHINE_TYPE, SavaAddress.MACHINE_TYPE)!!
         Log.d(TAG, "$data: mq getAddQueue: $machineType")
         // SharedPreferencesUtils.setParam(Name.QUEUE_DATA, data);
         if (("" == FileUtil.getDeviceId())) {

+ 2 - 1
module_home/src/main/java/com/quyunshuo/module/home/service/MqServiceRepository.kt

@@ -6,6 +6,7 @@ import com.quyunshuo.androidbaseframemvvm.base.mvvm.m.BaseRepository
 import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils
 import com.quyunshuo.androidbaseframemvvm.common.constant.Heartbeat
 import com.quyunshuo.androidbaseframemvvm.common.constant.MMKVName
+import com.quyunshuo.androidbaseframemvvm.common.constant.SavaAddress
 import javax.inject.Inject
 
 /**
@@ -36,7 +37,7 @@ class MqServiceRepository @Inject constructor() : BaseRepository() {
     suspend fun getAddQueue() = request<String> {
         val params= HashMap<String, Any>()
         Log.d(TAG, "Heartbeat.deviceId-->" + Heartbeat.deviceId)
-        val machineType: String = SpUtils.getString(MMKVName.MACHINE_TYPE, "SBM10")!!
+        val machineType: String = SpUtils.getString(MMKVName.MACHINE_TYPE, SavaAddress.MACHINE_TYPE)!!
         params["exchange"] = machineType //交换机的名称,机型
         params["queue"] = Heartbeat.deviceId!! //队列的名称,机器的设备编码
         params["routingKey"] = Heartbeat.deviceId!! //队列的key,机器的设备编码

+ 63 - 0
module_home/src/main/java/com/quyunshuo/module/home/utils/AssetManager.kt

@@ -0,0 +1,63 @@
+package com.quyunshuo.module.home.utils
+
+import android.content.Context
+import com.google.common.base.CharMatcher.`is`
+
+
+object AssetManager {
+    @Volatile
+    private var singleton: AssetManager? = null
+
+    val instance: AssetManager?
+        get() {
+            if (singleton == null) {
+                synchronized(AssetManager::class.java) {
+                    if (singleton == null) {
+                        singleton = AssetManager
+                    }
+                }
+            }
+            return singleton
+        }
+
+    fun readJsonFromAssets(context: Context, fileName: String): String? {
+        /* return try {
+             // 通过 AssetManager 打开文件流
+             context.assets.open(fileName).bufferedReader().use {
+                 it.readText()
+             }
+         } catch (e: IOException) {
+             ""
+         }*/
+        try {
+            var input = context.assets.open(fileName)
+            var size = input.available();
+            val buffer = ByteArray(size)
+            input.read(buffer)
+            input.close()
+            val json = String(buffer, charset("UTF-8"))
+            return json.replace("\r","").replace("\n","").replace(" ","").replace("\\\"", "\"")
+        } catch (e: Exception) {
+            return ""
+        }
+    }
+
+    /* fun readJsonFromAssets(context: Context, fileName: String?): String {
+         val jsonContent = StringBuilder()
+
+         try {
+             val assetManager: AssetManager = context.assets
+             assetManager.open(fileName).use { inputStream ->
+                 BufferedReader(InputStreamReader(inputStream)).use { reader ->
+                     var line: String?
+                     while ((reader.readLine().also { line = it }) != null) {
+                         jsonContent.append(line) // readLine()自动去除行尾换行符
+                     }
+                 }
+             }
+         } catch (e: IOException) {
+             e.printStackTrace()
+         }
+         return jsonContent.toString().replace("\r\n", "") // 全局替换剩余换行符
+     }*/
+}

+ 133 - 0
module_home/src/main/java/com/quyunshuo/module/home/utils/CommodityManage.java

@@ -0,0 +1,133 @@
+package com.quyunshuo.module.home.utils;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils;
+import com.quyunshuo.androidbaseframemvvm.common.bean.ProductDataBean;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class CommodityManage {
+
+    private static volatile CommodityManage singleton;
+
+    private CommodityManage() {
+    }
+
+    public static CommodityManage getInstance() {
+        if (singleton == null) {
+            synchronized (CommodityManage.class) {
+                if (singleton == null) {
+                    singleton = new CommodityManage();
+                }
+            }
+        }
+        return singleton;
+    }
+
+    public void init(Context context, String CommodityName) {
+        String assetsJson = AssetManager.INSTANCE.getInstance().readJsonFromAssets(context, CommodityName);
+        // Log.d("backinfo", "assetsJson:" + assetsJson);
+        Boolean productData = SpUtils.INSTANCE.contains("PRODUCT_DATA");
+        if (assetsJson.isEmpty()) {//代表app没有更新
+            if (!productData) {//代表没有存入过
+                String productList = AssetManager.INSTANCE.getInstance().readJsonFromAssets(context, "version_0.json");
+                //    Log.d("backinfo", "productList:" + productList);
+                SpUtils.INSTANCE.put("PRODUCT_DATA", productList);
+            }
+
+        } else {//代表app已经更新
+            if (!productData) {//代表没有存入过
+                SpUtils.INSTANCE.put("PRODUCT_DATA", assetsJson);
+            } else {
+                String loction = SpUtils.INSTANCE.getString("PRODUCT_DATA", "");
+
+                // Log.d("backinfo", "loction:" + loction);
+                Gson gson = new Gson();
+                List<ProductDataBean> list = gson.fromJson(loction, new TypeToken<List<ProductDataBean>>() {
+                }.getType());
+                List<ProductDataBean> newlist = gson.fromJson(assetsJson, new TypeToken<List<ProductDataBean>>() {
+                }.getType());
+                boolean isnewProduct = isNewLists(list, newlist);
+                if (isnewProduct) {
+                    Log.d("backinfo", "有新的商品");
+                    List<ProductDataBean> newProduct = mergeLists(list, newlist);
+                    SpUtils.INSTANCE.put("PRODUCT_DATA", gson.toJson(newProduct));
+                } else {
+                    Log.d("backinfo", "没有新的商品");
+                }
+
+            }
+        }
+
+
+    }
+
+
+    private boolean isNewLists(List<ProductDataBean> list1, List<ProductDataBean> list2) {
+        // 创建新列表避免修改原始数据
+        List<ProductDataBean> mergedList = new ArrayList<>(list1);
+        Set<Integer> existingIds = new HashSet<>();
+
+        // 收集第一个列表的所有 productId
+        for (ProductDataBean bean : list1) {
+            existingIds.add(bean.getProductId());
+        }
+
+        // 遍历第二个列表,添加不重复的项
+        for (ProductDataBean bean : list2) {
+            if (!existingIds.contains(bean.getProductId())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private List<ProductDataBean> mergeLists(List<ProductDataBean> list1, List<ProductDataBean> list2) {
+        // 创建新列表避免修改原始数据
+        List<ProductDataBean> mergedList = new ArrayList<>(list1);
+        Set<Integer> existingIds = new HashSet<>();
+
+        // 收集第一个列表的所有 productId
+        for (ProductDataBean bean : list1) {
+            existingIds.add(bean.getProductId());
+        }
+
+        // 遍历第二个列表,添加不重复的项
+        for (ProductDataBean bean : list2) {
+            if (!existingIds.contains(bean.getProductId())) {
+                double price = findMaxPrice(list1);
+                bean.setPrice(price);
+                mergedList.add(bean);
+                existingIds.add(bean.getProductId()); // 避免重复添加
+            }
+        }
+
+        return mergedList;
+    }
+
+    private double findMaxPrice(List<ProductDataBean> productList) {
+        double maxPrice = 0;
+
+
+        for (int i = 0; i < productList.size(); i++) {
+
+            double currentPrice = productList.get(i).getPrice();
+
+            if (currentPrice > maxPrice) {
+                maxPrice = currentPrice;
+            }
+        }
+
+
+        // 处理所有价格都是负数的情况
+        return maxPrice;
+    }
+}

+ 156 - 0
module_home/src/main/java/com/quyunshuo/module/home/utils/NetWorkUtils.java

@@ -0,0 +1,156 @@
+package com.quyunshuo.module.home.utils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkInfo;
+import android.net.NetworkRequest;
+import android.net.Proxy;
+import android.os.Build.VERSION;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.zhanshow.mylibrary.network.LibraryConfig;
+import com.zhanshow.mylibrary.network.NetworkStateReceiver;
+
+public class NetWorkUtils {
+    public static final String NETWORK_TYPE_WIFI = "wifi";
+    public static final String NETWORK_TYPE_3G = "3g";
+    public static final String NETWORK_TYPE_4G = "4g";
+    public static final String NETWORK_TYPE_2G = "2g";
+    public static final String NETWORK_TYPE_WAP = "wap";
+    public static final String NETWORK_TYPE_UNKNOWN = "unknown";
+    public static final String NETWORK_TYPE_DISCONNECT = "disconnect";
+    private static NetworkStateReceiver mNetworkStateReceiver;
+    private static ConnectivityManager connectivityManager;
+    private static ConnectivityManager.NetworkCallback networkCallback;
+    public NetWorkUtils() {
+    }
+
+    private static int getNetworkType(Context context) {
+        ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService("connectivity");
+        NetworkInfo networkInfo = connectivityManager == null ? null : connectivityManager.getActiveNetworkInfo();
+        return networkInfo == null ? -1 : networkInfo.getType();
+    }
+
+    public static String getNetworkTypeName(Context context) {
+        ConnectivityManager manager = (ConnectivityManager)context.getSystemService("connectivity");
+        String type = "disconnect";
+        NetworkInfo networkInfo;
+        if (manager != null && (networkInfo = manager.getActiveNetworkInfo()) != null) {
+            if (networkInfo.isConnected()) {
+                String typeName = networkInfo.getTypeName();
+                if ("WIFI".equalsIgnoreCase(typeName)) {
+                    type = "wifi";
+                } else if ("MOBILE".equalsIgnoreCase(typeName)) {
+                    String proxyHost = Proxy.getDefaultHost();
+                    type = TextUtils.isEmpty(proxyHost) ? (is4GNetwork(context) ? "4g" : (isFastMobileNetwork(context) ? "3g" : "2g")) : "wap";
+                } else {
+                    type = "unknown";
+                }
+            }
+
+            return type;
+        } else {
+            return type;
+        }
+    }
+
+    private static boolean isFastMobileNetwork(Context context) {
+        TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService("phone");
+        if (telephonyManager == null) {
+            return false;
+        } else {
+            switch (telephonyManager.getNetworkType()) {
+                case 0:
+                    return false;
+                case 1:
+                    return false;
+                case 2:
+                    return false;
+                case 3:
+                    return true;
+                case 4:
+                    return false;
+                case 5:
+                    return true;
+                case 6:
+                    return true;
+                case 7:
+                    return false;
+                case 8:
+                    return true;
+                case 9:
+                    return true;
+                case 10:
+                    return true;
+                case 11:
+                    return false;
+                case 12:
+                    return true;
+                case 13:
+                    return true;
+                case 14:
+                    return true;
+                case 15:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    }
+
+    private static boolean is4GNetwork(Context context) {
+        TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService("phone");
+        if (telephonyManager == null) {
+            return false;
+        } else {
+            switch (telephonyManager.getNetworkType()) {
+                case 13:
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    }
+
+    public static void registerLister(final Activity activity, NetworkStateReceiver.NetworkStateReceiverListener listener) {
+        LibraryConfig.getInstance().initApplication(activity);
+        mNetworkStateReceiver = new NetworkStateReceiver();
+        mNetworkStateReceiver.addListener(listener);
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
+        intentFilter.addAction("com.example.CONNECTIVITY_ACTION_LOLLIPOP");
+        activity.registerReceiver(mNetworkStateReceiver, intentFilter);
+        if (VERSION.SDK_INT >= 21) {
+            connectivityManager = (ConnectivityManager)activity.getSystemService("connectivity");
+            NetworkRequest.Builder builder = new NetworkRequest.Builder();
+            networkCallback = new ConnectivityManager.NetworkCallback() {
+                public void onAvailable(Network network) {
+                    Intent intent = new Intent("com.example.CONNECTIVITY_ACTION_LOLLIPOP");
+                    intent.putExtra("noConnectivity", false);
+                    activity.sendBroadcast(intent);
+                }
+
+                public void onLost(Network network) {
+                    Intent intent = new Intent("com.example.CONNECTIVITY_ACTION_LOLLIPOP");
+                    intent.putExtra("noConnectivity", true);
+                    activity.sendBroadcast(intent);
+                }
+            };
+            connectivityManager.registerNetworkCallback(builder.build(), networkCallback);
+        }
+    }
+
+    public static void unRegisterNetWork(Activity activity) {
+        activity.unregisterReceiver(mNetworkStateReceiver);
+        mNetworkStateReceiver.removeListeners();
+        connectivityManager.unregisterNetworkCallback(networkCallback);
+        networkCallback = null;
+        mNetworkStateReceiver= null;
+
+    }
+}

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

@@ -0,0 +1,29 @@
+package com.quyunshuo.module.home.utils;
+
+import java.security.SecureRandom;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+public class OrderNumberGenerator {
+    public static String generateOrderNumber() {
+        // 1. 时间戳部分(精确到毫秒)
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS", Locale.getDefault());
+        String timestamp = sdf.format(new Date());
+
+        // 2. 随机数部分(4位字母数字)
+        String randomString = generateRandomNumber(6);
+
+        // 3. 组合成订单号(可添加业务前缀,如商户ID)
+        return timestamp + randomString; // ORD 为示例前缀
+    }
+
+    private static String generateRandomNumber(int length) {
+        SecureRandom random = new SecureRandom();
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < length; i++) {
+            sb.append(random.nextInt(10)); // 仅生成0-9
+        }
+        return sb.toString();
+    }
+}

+ 30 - 0
module_home/src/main/java/com/quyunshuo/module/home/utils/PhoneStateUtils.java

@@ -0,0 +1,30 @@
+package com.quyunshuo.module.home.utils;
+
+import android.app.Activity;
+import android.telephony.TelephonyManager;
+
+import com.zhanshow.mylibrary.phonestate.MyPhoneStateListener;
+
+/**
+ * 没有内存泄漏的版本。
+ */
+public class PhoneStateUtils {
+    private static MyPhoneStateListener myPhoneStateListener;
+
+    public PhoneStateUtils() {
+    }
+
+    public static void registerPhoneStateListener(Activity activity, MyPhoneStateListener.MyPhoneStateListenerListener listener) {
+        myPhoneStateListener = new MyPhoneStateListener();
+        myPhoneStateListener.addListener(listener);
+        TelephonyManager telephonyManager = (TelephonyManager)activity.getSystemService("phone");
+        telephonyManager.listen(myPhoneStateListener, 256);
+    }
+
+    public static void unRegisterPhoneStateListener(Activity activity) {
+        TelephonyManager telephonyManager = (TelephonyManager)activity.getSystemService("phone");
+        telephonyManager.listen(myPhoneStateListener, 0);
+        myPhoneStateListener.removeListeners();
+        myPhoneStateListener = null;
+    }
+}

+ 141 - 58
module_home/src/main/java/com/quyunshuo/module/home/utils/RemotePushUtil.kt

@@ -6,8 +6,6 @@ import android.util.Log
 import com.google.gson.Gson
 import com.hboxs.serialport.plc.message.Message
 import com.hboxs.serialport.plc.thread.ThreadSettingParam
-import com.hboxs.serialport.sbc.VBoxMessage
-import com.hboxs.serialport.sbc.frame.VboxCommand
 import com.quyunshuo.androidbaseframemvvm.base.BaseApplication
 import com.quyunshuo.androidbaseframemvvm.base.addressenum.PlcSettingAddressEnum
 import com.quyunshuo.androidbaseframemvvm.base.utils.SpUtils
@@ -16,11 +14,14 @@ import com.quyunshuo.androidbaseframemvvm.common.constant.Heartbeat
 import com.quyunshuo.androidbaseframemvvm.common.constant.MMKVName
 import com.quyunshuo.androidbaseframemvvm.common.constant.MqName
 import com.quyunshuo.androidbaseframemvvm.common.constant.event.ApiMessageEvent
-import com.quyunshuo.androidbaseframemvvm.common.enums.ConnectStateEnum
-import com.quyunshuo.module.home.bean.AlarmClockBean
 import com.quyunshuo.androidbaseframemvvm.common.enums.AlarmClockEnum
+import com.quyunshuo.androidbaseframemvvm.common.enums.ConnectStateEnum
 import com.quyunshuo.androidbaseframemvvm.common.util.AlarmManagerUtil
-import com.quyunshuo.androidbaseframemvvm.common.util.XLogUtil
+import com.quyunshuo.androidbaseframemvvm.common.util.ToastUtil
+import com.quyunshuo.androidbaseframemvvm.common.util.UiUtil
+import com.quyunshuo.module.home.R
+import com.quyunshuo.module.home.bean.AlarmClockBean
+import com.quyunshuo.module.home.bean.PaySuccessBean
 import com.quyunshuo.module.home.getui.BaseBean
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
@@ -29,15 +30,24 @@ import kotlinx.coroutines.launch
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
+import java.io.ByteArrayOutputStream
+import java.io.DataInputStream
+import java.io.File
+import java.io.FileInputStream
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
+import java.net.HttpURLConnection
+import java.net.URL
 import java.text.ParseException
 import java.text.SimpleDateFormat
 import java.util.Calendar
 import javax.inject.Inject
 
 class RemotePushUtil @Inject constructor() {
-    private  val TAG = "RemotePushUtil"
+    private val TAG = "RemotePushUtil"
     @Inject
-    lateinit var  threadSettingParam: ThreadSettingParam
+    lateinit var threadSettingParam: ThreadSettingParam
     init {
         registerToEventBus()
     }
@@ -60,7 +70,7 @@ class RemotePushUtil @Inject constructor() {
             Message.Type.ack -> {
                 ack(messageEvent)
             }
-            Message.Type.response -> { }
+            Message.Type.response -> {}
             Message.Type.connected -> {}
             Message.Type.disconnected -> {}
             Message.Type.sendError -> {}
@@ -70,7 +80,7 @@ class RemotePushUtil @Inject constructor() {
 
     private fun ack(messageEvent: Message) {
         val name = messageEvent.name
-        Log.d(TAG, "ack: "+name)
+        Log.d(TAG, "ack: " + name)
         when (name) {
             PlcSettingAddressEnum.M3.address -> {
                 threadSettingParam.stopUp()
@@ -79,7 +89,7 @@ class RemotePushUtil @Inject constructor() {
                     threadSettingParam.startRstM3()
                 }
             }
-            PlcSettingAddressEnum.RM3.address->{
+            PlcSettingAddressEnum.RM3.address -> {
                 threadSettingParam.stopRstM3()
             }
 
@@ -149,14 +159,123 @@ class RemotePushUtil @Inject constructor() {
                 openOrCloseDev(baseBean)
             }
 
+            MqName.PUSHTIMERULE -> {
+                pushtimeRule(baseBean, kind)
+            }
+
+            MqName.log -> {
+                //远程上传日志文件
+                uploadLogApi(baseBean.kind_data)
+            }
+
             else -> {}
         }
     }
 
-    private fun openOrCloseDev( baseBean: BaseBean) {
+    /**
+     * 远程上传日志文件
+     *
+     * @param kindData
+     */
+    fun uploadLogApi(kindData: String) {
+        Thread {
+            val file = File("/storage/emulated/0/logdata/$kindData.txt")
+            if (file.exists()) {
+                if (file.isFile) {
+                    var `in`: DataInputStream? = null
+                    var out: OutputStream? = null
+                    var conn: HttpURLConnection? = null
+                    var ins: InputStream? = null
+                    var outStream: ByteArrayOutputStream? = null
+                    try {
+                        val url =
+                            URL("http://app.sunzee.com.cn" + "/api/app_equipment/index/sendLog.htm?fileName=" + kindData)
+
+                        conn = url.openConnection() as HttpURLConnection
+                        // 发送POST请求必须设置如下两行
+                        conn!!.doOutput = true
+                        conn!!.useCaches = false
+                        conn!!.requestMethod = "POST"
+                        conn!!.setRequestProperty("Content-Type", "text/html")
+                        conn!!.setRequestProperty("Cache-Control", "no-cache")
+                        conn!!.setRequestProperty("Charsert", "UTF-8")
+                        conn!!.connect()
+                        conn!!.connectTimeout = 10000
+                        out = conn!!.outputStream
+                        `in` = DataInputStream(FileInputStream(file))
+
+                        var bytes = 0
+                        val buffer = ByteArray(1024)
+                        while ((`in`.read(buffer).also { bytes = it }) != -1) {
+                            out.write(buffer, 0, bytes)
+                        }
+
+                        out.flush()
+
+                        // 返回流
+                        if (conn!!.responseCode == HttpURLConnection.HTTP_OK) {
+                            ins = conn!!.inputStream
+                            outStream = ByteArrayOutputStream()
+                            val data = ByteArray(1024)
+                            var count = -1
+                            while ((ins.read(data, 0, 1024).also { count = it }) != -1) {
+                                outStream.write(data, 0, count)
+
+                            }
+                        } else {
+
+                        }
+                    } catch (e: java.lang.Exception) {
+                        e.printStackTrace()
+
+                    } finally {
+                        if (`in` != null) {
+                            try {
+                                `in`.close()
+                            } catch (e: IOException) {
+                                e.printStackTrace()
+                            }
+                        }
+                        if (out != null) {
+                            try {
+                                out.close()
+                            } catch (e: IOException) {
+                                e.printStackTrace()
+                            }
+                        }
+                        if (ins != null) {
+                            try {
+                                ins.close()
+                            } catch (e: IOException) {
+                                e.printStackTrace()
+                            }
+                        }
+                        if (outStream != null) {
+                            try {
+                                outStream.close()
+                            } catch (e: IOException) {
+                                e.printStackTrace()
+                            }
+                        }
+                        conn?.disconnect()
+                    }
+                }
+            }
+        }.start()
+    }
+
+    private fun pushtimeRule(baseBean: BaseBean, kind: String) {
+        if (baseBean.kind_data == null) {
+            ToastUtil.switchToastStyleToWarn("广告规则数据无效")
+            return
+        }
+        EventBus.getDefault().post(ApiMessageEvent(kind, baseBean.kind_data))
+    }
+
+    private fun openOrCloseDev(baseBean: BaseBean) {
         val kind_data: String = baseBean.kind_data
         //没有关机
-       if (kind_data == "1") {
+        if (kind_data == "1") {
             //开机
            threadSettingParam.startUp()
         }
@@ -255,7 +374,7 @@ class RemotePushUtil @Inject constructor() {
     }
 
     private fun devSleep(kind: String, data: String) {
-        Log.d(TAG, "devSleep: "+kind+":"+data)
+        Log.d(TAG, "devSleep: " + kind + ":" + data)
         EventBus.getDefault().post(ApiMessageEvent(kind, data))
     }
 
@@ -264,7 +383,15 @@ class RemotePushUtil @Inject constructor() {
         val json: String = baseBean.kind_data
         val paySucessBean: PaySucessBean = gson.fromJson(json, PaySucessBean::class.java)
         //LogUtils.logWrite("第一步:存儲信息,支付成功")
-        EventBus.getDefault().post(ApiMessageEvent(kind, paySucessBean))
+        EventBus.getDefault().post(
+            ApiMessageEvent(
+                kind, PaySuccessBean(
+                    UiUtil.getStringRes(
+                        R.string.base_two_code
+                    ), paySucessBean.sn
+                )
+            )
+        )
     }
 
     /**
@@ -407,48 +534,4 @@ class RemotePushUtil @Inject constructor() {
         Log.d(TAG, "setAlarmClock: $numberCount")
         return numberCount
     }
-
-    @Subscribe(threadMode = ThreadMode.MAIN)
-    fun event(messageEvent: VBoxMessage) {
-        XLogUtil.d(messageEvent.cmd+":messageEvent.data:"+messageEvent.data)
-        when (messageEvent.cmd) {
-            VboxCommand.CMD_HEARTBEAT ->{
-                cmdHeartbeat(messageEvent)
-            }
-            else -> {}
-        }
-    }
-
-    private fun cmdHeartbeat(messageEvent: VBoxMessage) {
-        val deviceState = messageEvent.data.substring(0, 2)//机器状态码
-        Log.d(TAG, "deviceState:1 "+messageEvent.data)
-        Log.d(TAG, "deviceState:2 "+deviceState)
-        when(deviceState){
-            "00"->{//刚上电
-
-            }
-            "01"->{//开机中
-
-            }
-            "02"->{//就绪待机,可以选购或制作下一杯
-
-            }
-            "03"->{//报警中
-
-            }
-            "04"->{//开始制作
-
-            }
-            "05"->{//下玉米完毕
-
-            }
-            "07"->{//玉米爆开
-
-            }
-            "10"->{//制作完成
-
-            }
-            else->{}
-        }
-    }
 }

+ 14 - 128
module_home/src/main/java/com/quyunshuo/module/home/utils/SimplePlayerUtil.kt

@@ -1,28 +1,20 @@
 package com.quyunshuo.module.home.utils
 
 import android.annotation.SuppressLint
-import android.graphics.Bitmap
-import android.graphics.SurfaceTexture
 import android.media.MediaPlayer
 import android.media.MediaPlayer.OnCompletionListener
 import android.media.MediaPlayer.OnPreparedListener
 import android.os.Build
 import android.os.CountDownTimer
 import android.util.Log
-import android.view.Surface
 import android.view.SurfaceHolder
 import android.view.SurfaceView
-import android.view.TextureView
-import android.view.TextureView.SurfaceTextureListener
-import android.view.animation.AlphaAnimation
 import androidx.annotation.RequiresApi
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 
-class SimplePlayerUtil : OnPreparedListener, OnCompletionListener, MediaPlayer.OnErrorListener,
-    SurfaceHolder.Callback {
-    private var surface: Surface? = null
-    private var textureView: TextureView? = null
+class SimplePlayerUtil : OnPreparedListener, OnCompletionListener,
+    MediaPlayer.OnErrorListener, SurfaceHolder.Callback {
     private var surfaceView: SurfaceView? = null
     private var url: String? = null
     private var onPreparedListener: OnPreparedListener? = null
@@ -31,27 +23,12 @@ class SimplePlayerUtil : OnPreparedListener, OnCompletionListener, MediaPlayer.O
     var player: MediaPlayer? = null
         private set
     var size: Float = 1f
-    private var fadeInAnimation: AlphaAnimation? = null
-    private var fadeOutAnimation: AlphaAnimation? = null
 
     //渐强的时长,单位:毫秒;默认2秒
     val duration: Long = 2000
 
     //音量调节的时间间隔1
     var interval: Long = duration / 10
-
-    constructor(textureView: TextureView?) {
-        this.textureView = textureView
-        // 创建一个淡入动画,从完全透明到不透明
-        fadeInAnimation = AlphaAnimation(0f, 1f)
-        fadeInAnimation!!.duration = 500 // 设置动画时长为0.5秒
-
-        // 创建一个淡出动画,从不透明到完全透明
-        fadeOutAnimation = AlphaAnimation(1f, 0f)
-        fadeOutAnimation!!.duration = 500 // 设置动画时长为0.5秒
-        setup()
-    }
-
     fun setVolume() {
         if (size <= 0) {
             player!!.setVolume(size, size)
@@ -60,13 +37,13 @@ class SimplePlayerUtil : OnPreparedListener, OnCompletionListener, MediaPlayer.O
         object : CountDownTimer(duration, interval) {
             override fun onTick(millisUntilFinished: Long) {
                 val volume = 1f - millisUntilFinished * 1.0f / duration
-                if (this@SimplePlayerUtil.player != null) {
+                if (player != null) {
                     player!!.setVolume(volume, volume)
                 }
             }
 
             override fun onFinish() {
-                if (this@SimplePlayerUtil.player != null) {
+                if (player != null) {
                     player!!.setVolume(1f, 1f)
                 }
             }
@@ -80,64 +57,13 @@ class SimplePlayerUtil : OnPreparedListener, OnCompletionListener, MediaPlayer.O
 
     constructor(surfaceView: SurfaceView?) {
         this.surfaceView = surfaceView
-        // 创建一个淡入动画,从完全透明到不透明
-        fadeInAnimation = AlphaAnimation(0f, 1f)
-        fadeInAnimation!!.duration = 500 // 设置动画时长为0.5秒
-
-        // 创建一个淡出动画,从不透明到完全透明
-        fadeOutAnimation = AlphaAnimation(1f, 0f)
-        fadeOutAnimation!!.duration = 500 // 设置动画时长为0.5秒
         setup()
     }
 
 
     private fun setup() {
         player = MediaPlayer()
-        if (textureView != null) {
-            textureView!!.surfaceTextureListener = object : SurfaceTextureListener {
-                override fun onSurfaceTextureAvailable(
-                    surfaceTexture: SurfaceTexture,
-                    i: Int,
-                    i1: Int
-                ) {
-                    surface = Surface(surfaceTexture)
-                    //                    textureView.setSurfaceTexture(surfaceTexture);
-                    player!!.setSurface(surface)
-                    Log.d(
-                        TAG,
-                        "iMediaPlayer1 onSurfaceTextureAvailable: $surface"
-                    )
-                }
-
-
-                override fun onSurfaceTextureSizeChanged(
-                    surfaceTexture: SurfaceTexture,
-                    i: Int,
-                    i1: Int
-                ) {
-                }
-
-
-                override fun onSurfaceTextureDestroyed(surfaceTexture: SurfaceTexture): Boolean {
-                    error = true
-                    if (this@SimplePlayerUtil.player != null) {
-                        //                        iMediaPlayer.reset();//进入闲置状态
-                        player!!.release() //进入闲置状态后,进入 End (结束) 状态(涉及到资源的释放),不能转换为其他状态
-                        this@SimplePlayerUtil.player = null
-                        Log.d(TAG, "iMediaPlayer2 onDestroy: ")
-                    }
-                    if (surface != null) {
-                        surface!!.release()
-                        surface = null
-                    }
-                    return true
-                }
-
-
-                override fun onSurfaceTextureUpdated(surfaceTexture: SurfaceTexture) {
-                }
-            }
-        } else if (surfaceView != null) {
+        if (surfaceView != null) {
             surfaceView!!.holder.addCallback(this)
         }
 
@@ -159,30 +85,11 @@ class SimplePlayerUtil : OnPreparedListener, OnCompletionListener, MediaPlayer.O
         //        });
     }
 
-    var playPosition: Int = 0
 
     override fun onPrepared(mediaPlayer: MediaPlayer) {
-        Log.d(TAG, fadeInAnimation.toString() + "onPrepared: " + surfaceView)
-        if (surfaceView != null) {
-            surfaceView!!.startAnimation(fadeInAnimation) // 淡入动画
-        }
-        if (textureView != null) {
-            textureView!!.startAnimation(fadeInAnimation) // 淡入动画
-        }
-
-        // 准备就绪了,开始播放
-
-//        if (getPlayPosition() != 0 && !"5121".equals(Hawk.get("logo",1))) {
-//            int duration = mediaPlayer.getDuration();
-//            Log.d(TAG, duration + ":playTime: " + getPlayPosition());
-//            if (duration >= getPlayPosition()) {
-//                iMediaPlayer.seekTo(getPlayPosition());
-//            }
-//        }
+        //准备就绪了,开始播放
         player!!.start()
 
-        playPosition = 0
-
         //        iMediaPlayer.setVolume(0,0);
         if (onPreparedListener != null) {
             onPreparedListener!!.onPrepared(player)
@@ -193,7 +100,7 @@ class SimplePlayerUtil : OnPreparedListener, OnCompletionListener, MediaPlayer.O
     private var error = false
 
 
-    fun setUrl(url: String?) {
+    fun setUrl(url: String) {
         this.url = url
         playVideo()
     }
@@ -222,7 +129,6 @@ class SimplePlayerUtil : OnPreparedListener, OnCompletionListener, MediaPlayer.O
                 onError(null, 0, 0)
             }
         }
-
     }
 
 
@@ -233,27 +139,12 @@ class SimplePlayerUtil : OnPreparedListener, OnCompletionListener, MediaPlayer.O
 
     fun onDestroy() {
         error = true
-        Log.d(TAG, surface.toString() + "iMediaPlayer1 onDestroy: " + player)
         if (player != null) {
-            if (player!!.isPlaying) {
-                player!!.stop()
-                Log.d(TAG, "onDestroy: ")
-            }
-            //            iMediaPlayer.reset();//进入闲置状态
+//            iMediaPlayer.reset();//进入闲置状态
             player!!.release() //进入闲置状态后,进入 End (结束) 状态(涉及到资源的释放),不能转换为其他状态
-            //            iMediaPlayer = null;
-        }
-        if (surface != null) {
-            surface!!.release()
-            surface = null
-        }
-    }
-
-    fun snipping(): Bitmap? {
-        if (textureView != null) {
-            return textureView!!.bitmap
+            player = null
         }
-        return null
+        Log.d(TAG, "iMediaPlayer1 onDestroy: ")
     }
 
 
@@ -273,13 +164,6 @@ class SimplePlayerUtil : OnPreparedListener, OnCompletionListener, MediaPlayer.O
 
 
     override fun onCompletion(mediaPlayer: MediaPlayer) {
-//        surfaceView.startAnimation(fadeOutAnimation); // 淡出动画
-        if (surfaceView != null) {
-            surfaceView!!.startAnimation(fadeInAnimation) // 淡入动画
-        }
-        if (textureView != null) {
-            textureView!!.startAnimation(fadeOutAnimation) // 淡入动画
-        }
         if (onCompletionListener != null) {
             onCompletionListener!!.onCompletion(player)
         } else {
@@ -323,13 +207,15 @@ class SimplePlayerUtil : OnPreparedListener, OnCompletionListener, MediaPlayer.O
             player!!.reset() //进入闲置状态
             player!!.release() //进入闲置状态后,进入 End (结束) 状态(涉及到资源的释放),不能转换为其他状态
             player = null
-            surfaceView = null
             Log.d(TAG, "iMediaPlayer2 onDestroy: ")
         }
+        if (holder != null) {
+            holder.removeCallback(this)
+        }
         Log.d(TAG, "iMediaPlayer2 onDestroy: ")
     }
 
     companion object {
         private const val TAG = "SimplePlayer"
     }
-}
+}

TEMPAT SAMPAH
module_home/src/main/res/drawable/leven0.png


TEMPAT SAMPAH
module_home/src/main/res/drawable/leven1.png


TEMPAT SAMPAH
module_home/src/main/res/drawable/leven2.png


TEMPAT SAMPAH
module_home/src/main/res/drawable/leven3.png


TEMPAT SAMPAH
module_home/src/main/res/drawable/leven4.png


TEMPAT SAMPAH
module_home/src/main/res/drawable/wifi.png


+ 34 - 3
module_home/src/main/res/layout/home_fragment_buy.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
@@ -39,6 +39,37 @@
         android:id="@+id/iv_buy_icon"
         android:layout_width="400dp"
         android:layout_height="400dp"
-        android:src="@drawable/btn_goumai" />
+        android:src="@drawable/btn_goumai"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="@+id/sv_video" />
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/cl_home_time"
+        android:layout_width="550dp"
+        android:layout_height="250dp"
+        android:layout_marginTop="20dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <TextView
+            android:id="@+id/tv_time"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="2024-07-21 21:06:23"
+            android:textColor="@color/black"
+            android:textSize="50sp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/tv_clientId"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/home_dev_id"
+            android:textColor="@color/black"
+            android:textSize="50sp"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@+id/tv_time" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
 
-</RelativeLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 31 - 10
module_home/src/main/res/layout/home_fragment_home.xml

@@ -17,6 +17,26 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
 
+    <ImageView
+        android:id="@+id/iv_4g"
+        android:layout_width="150dp"
+        android:layout_height="150dp"
+        android:layout_marginTop="20dp"
+        android:src="@drawable/leven0"
+        android:visibility="gone"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <ImageView
+        android:id="@+id/iv_wifi"
+        android:layout_width="150dp"
+        android:layout_height="150dp"
+        android:layout_marginTop="20dp"
+        android:src="@drawable/wifi"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
     <!--    <TextView-->
     <!--        android:id="@+id/tv_back_time"-->
     <!--        android:layout_width="wrap_content"-->
@@ -99,7 +119,6 @@
     </androidx.constraintlayout.widget.ConstraintLayout>
 
     <Button
-        android:visibility="gone"
         android:id="@+id/btn_language_switch"
         android:layout_width="200dp"
         android:layout_height="150dp"
@@ -111,6 +130,7 @@
         android:textColor="@color/black"
         android:textSize="40sp"
         android:textStyle="bold"
+        android:visibility="gone"
         app:layout_constraintEnd_toStartOf="@id/btn_cif"
         app:layout_constraintTop_toTopOf="parent" />
 
@@ -153,8 +173,8 @@
 
         <LinearLayout
             android:layout_width="wrap_content"
-            android:layout_weight="1"
-            android:layout_height="wrap_content">
+            android:layout_height="wrap_content"
+            android:layout_weight="1">
 
             <TextView
                 android:id="@+id/tv_aacpe_bill_tip"
@@ -180,8 +200,8 @@
 
         <LinearLayout
             android:layout_width="wrap_content"
-            android:layout_weight="1"
-            android:layout_height="wrap_content">
+            android:layout_height="wrap_content"
+            android:layout_weight="1">
 
             <TextView
                 android:id="@+id/tv_aacpe_coin_tip"
@@ -290,9 +310,9 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
+        android:background="@drawable/userbottom_bg"
         android:gravity="center"
         android:orientation="horizontal"
-        android:background="@drawable/userbottom_bg"
         app:layout_constraintBottom_toTopOf="@+id/home_guideline2"
         app:layout_constraintEnd_toStartOf="@+id/home_guideline"
         app:layout_constraintStart_toStartOf="@+id/home_guideline">
@@ -378,21 +398,22 @@
         </RelativeLayout>
 
         <RelativeLayout
-            android:layout_marginTop="15dp"
-            android:layout_marginBottom="15dp"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content">
+            android:layout_height="wrap_content"
+            android:layout_marginTop="15dp"
+            android:layout_marginBottom="15dp">
 
             <ImageView
                 android:id="@+id/iv_lutou"
                 android:layout_width="120dp"
                 android:layout_height="120dp"
                 android:src="@drawable/icon_fashengqi" />
+
             <LinearLayout
-                android:gravity="center"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_toRightOf="@id/iv_lutou"
+                android:gravity="center"
                 android:orientation="vertical">
 
                 <TextView

+ 47 - 7
module_pay/src/main/java/com/module/pay/common/OtherEnum.kt

@@ -15,21 +15,61 @@ import com.quyunshuo.androidbaseframemvvm.common.util.AmountMoney
  * type:类型 1  开关 2 输入类 3 多选项值(国家,语言,通讯)
  * mmkvName:保存key
  */
-enum class OtherEnum(var nameId:Int, var nameS:String, var category:String, var default:Any, var type:Int, var mmkvName: String) {
+enum class OtherEnum(var nameId:Int,var nameS:String,var category:String,var default:Any,var type:Int,var mmkvName: String) {
+    CONTACT_WAY(R.string.contact_way,"联系方式","系统设置","123456", 2,MMKVName.CONTACT_WAY),
+    CONTACT(R.string.contact,"联系名字","系统设置","联系人", 2,MMKVName.CONTACT),
+    AUTO_START_HOTSPOT(R.string.auto_start_hotspot,"开启自启热点","系统设置",false,1, MMKVName.AUTO_START_HOTSPOT),
+    NAME_HOTSPOT(R.string.name_hotspot,"热点名称","系统设置","sunzee",2, MMKVName.NAME_HOTSPOT),
+    PWD_HOTSPOT(R.string.pwd_hotspot,"热点密码","系统设置","66666666",2, MMKVName.PWD_HOTSPOT),
+    LONG_CLICK_SHOW_STATUS_BAR(R.string.long_click_show_status_bar,"登录页长按显示状态栏","系统设置",true,1, MMKVName.LONG_CLICK_SHOW_STATUS_BAR),
+    VOLUME(R.string.volume,"音量","系统设置",true,4, MMKVName.VOLUME),
+    LUMINANCE(R.string.luminance, "亮度", "系统设置", true, 4, MMKVName.LUMINANCE),
+//    SIM(R.string.sim, "SIM", "系统设置", "", 5, MMKVName.SIM),
+//    SIM_IMEI(R.string.sim_imei, "SIM IMEI", "系统设置", "", 5, MMKVName.SIM_IMEI),
+    CUT_SYSTEM_SET(R.string.cut_system_set, "切换系统设置", "系统设置", "", 6, MMKVName.CUT_SYSTEM_SET),
+    WIFI_HOTSPOT(R.string.wifi_hotspot, "Wifi热点", "系统设置", false, 1, MMKVName.WIFI_HOTSPOT),
+
+
     AGREEMENT(R.string.agreement,"通讯协议","串口设置", PayAgreementUtil.MDB_ICT, 3,MMKVName.ICT),//ArrayList<String>(listOf("MDB","ICT","WMDB"))
     CHANGE(R.string.change,"找零功能","找零设置",false, 1,MMKVName.CHANGE),
-    SHOPPING_TROLLEY(R.string.shopping_trolley,"购物车","购物车设置",true, 1,MMKVName.SHOPPING_TROLLEY),
-    PROMOTION_CODE(R.string.promotion_code,"优惠码","功能开启",false, 1,MMKVName.PROMOTION_CODE),
-//    BILL_COUNTRY(R.string.bill_country,"国家纸币选择","串口设置",/*ArrayList<String>(listOf("MDB","ICT"))*/AmountMoney.language, 3,MMKVName.BILL_COUNTRY),
+    //    BILL_COUNTRY(R.string.bill_country,"国家纸币选择","串口设置",ArrayList<String>(listOf("MDB","ICT")), 3,MMKVName.BILL_COUNTRY),
     NAYAX_MODE(R.string.nayax_mode,"Nayax闲置模式","串口设置",false,1,MMKVName.NAYAX_MODE),
     TTYS_NAYAX(R.string.ttys_nayax,"Nayax 串口","串口设置","ttyS3",2,MMKVName.TTYS_NAYAX),
     TTYS_MDB(R.string.ttys_mdb,"MDB 串口","串口设置","ttyS5",2,MMKVName.TTYS_MDB),
     TTYS_PLC(R.string.ttys_plc,"PLC 串口","串口设置","ttyS7",2,MMKVName.TTYS_PLC),
     BILL_COLLOCATION(R.string.bill_collocation,"MDB 纸币托管","通讯设置",false,1,MMKVName.BILL_COLLOCATION),
     MDB_LEVEL(R.string.mdb_level,"MDB L3级别","通讯设置",true,1,MMKVName.MDB_LEVEL),
-    CONTACT_NAME(R.string.way_contacts,"联系人","系统设置","名字", 2,MMKVName.CONTACT_NAME),
-    CONTACT_NUMBER(R.string.way_contacts,"联系方式","系统设置","123456", 2,MMKVName.CONTACT_NUMBER),
+    MDB_RATE(R.string.mdb_rate,"MDB 倍率","串口设置","100",2,MMKVName.MDB_RATE),
+    CARD_TEXT(R.string.card_text,"指引消费者刷卡文本","串口设置","",2,MMKVName.CARD_TEXT),
+    BILL_TRUST(R.string.bill_trust,"纸币托管","串口设置",false,1,MMKVName.BILL_TRUST),
+    MDB_CASH_SALE(R.string.mdb_cash_sale,"MDB Cash Sale","串口设置",true,1,MMKVName.MDB_CASH_SALE),
+
+
+    PROMOTION_CODE(R.string.promotion_code,"优惠码","功能开启",false, 1,MMKVName.PROMOTION_CODE),
+    MAKE_CLEAN_PRICE(R.string.make_clean_price,"制作后清零金额","功能开启",false, 1,MMKVName.MAKE_CLEAN_PRICE),
+    STAFF_LOGIN(R.string.staff_login,"员工登录","功能开启",false, 1,MMKVName.STAFF_LOGIN),
+    //提示没有退币功能。
+    AD_RULE(R.string.ad_rule,"广告规则","其他",true, 1,MMKVName.AD_RULE),
+    AUTO_RETURN_HOME(R.string.auto_return_home,"自动返回首页(分钟)","其他","10", 2,MMKVName.AUTO_RETURN_HOME),
+    SLEEP_TEXT(R.string.sleep_text,"休眠中文本","其他","", 2,MMKVName.SLEEP_TEXT),
+    LOGO_TEXT(R.string.logo_text,"图标变更","其他","7777", 2,MMKVName.LOGO_TEXT),
+
+
+    SHOPPING_TROLLEY(R.string.shopping_trolley,"购物车功能","购物车设置",true, 1,MMKVName.SHOPPING_TROLLEY),
+    SHOPPING_CART_SIZE(R.string.shopping_cart_size,"购物车可添加数量","购物车设置","5", 2,MMKVName.SHOPPING_CART_SIZE),
+    TWO_PRICE_DISCOUNT(R.string.two_price_discount,"第二件折扣","购物车设置","10", 2,MMKVName.TWO_PRICE_DISCOUNT),
+    THREE_PRICE_DISCOUNT(R.string.three_price_discount,"第三件折扣","购物车设置","10", 2,MMKVName.THREE_PRICE_DISCOUNT),
+    FIVE_PRICE_DISCOUNT(R.string.five_price_discount,"第五件折扣","购物车设置","10", 2,MMKVName.FIVE_PRICE_DISCOUNT),
+    TIPS_DISCOUNT_TEXT(R.string.tips_discount_text,"折扣提示文本","购物车设置","", 2,MMKVName.TIPS_DISCOUNT_TEXT),
+    DISCOUNT_FUNCTION(R.string.discount_function,"折扣功能","找零设置",false, 1,MMKVName.DISCOUNT_FUNCTION),
 
-    LOGO_TEXT(R.string.logo_text,"图标变更","功能开启","7777", 2,MMKVName.LOGO_TEXT),
+    CHANGE_FUNCTION(R.string.change_function,"找零功能","找零设置",false, 1,MMKVName.CHANGE_FUNCTION),
+    CHANGE_BILL(R.string.change_bill,"找零纸币","找零设置",false, 1,MMKVName.CHANGE_BILL),
+    CHANGE_COIN(R.string.change_coin,"找零硬币","找零设置",false, 1,MMKVName.CHANGE_COIN),
+    //找零类型
+    CHANGE_DOLLAR(R.string.change_dollar,"币值设置(一枚硬币等于的金额)","找零设置","1", 2,MMKVName.CHANGE_DOLLAR),
+    CHANGE_COIN_REP(R.string.change_coin_rep,"找零硬币库存","找零设置","200", 2,MMKVName.CHANGE_COIN_REP),
+    CHANGE_ALLOW_NUMBER(R.string.change_allow_number,"允许一次找零个数","找零设置","7", 2,MMKVName.CHANGE_ALLOW_NUMBER),
+    CHANGE_WARNING_NUMBER(R.string.change_warning_number,"找零预警库存","找零设置","100", 2,MMKVName.CHANGE_WARNING_NUMBER),
 
 }

+ 3 - 2
module_pay/src/main/java/com/module/pay/strategy/PaySendDataMDBStrategy.kt

@@ -113,11 +113,12 @@ object PaySendDataMDBStrategy : PaySendDataStrategy {
 
     override fun creditCardVendSuccess(number: String) {
         serialPortUtil?.sendSerialPort("1302"+ByteUtils.decimal2fitHex(number.toLong(),4))
-
     }
 
     override fun creditCardCashSale(price: Double, number: String) {
+        if (SpUtils.getBoolean(MMKVName.MDB_CASH_SALE, true) == false) {
+            return
+        }
         serialPortUtil?.sendSerialPort("1305"+ByteUtils.decimal2fitHex((price*100).toLong(),4)+ByteUtils.decimal2fitHex(number.toLong(),4))
-
     }
 }

+ 25 - 0
serialport-api/src/main/java/com/hboxs/serialport/plc/message/MqttMessageBean.java

@@ -0,0 +1,25 @@
+package com.hboxs.serialport.plc.message;
+
+public class MqttMessageBean {
+    private String topic;
+    private String topicType;
+    private String content;
+
+    public MqttMessageBean(String topic, String topicType, String content) {
+        this.topic = topic;
+        this.topicType = topicType;
+        this.content = content;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+
+    public String getTopicType() {
+        return topicType;
+    }
+
+    public String getContent() {
+        return content;
+    }
+}