左晓为主开发手持机充值管理机
generallibrary/src/main/java/com/dayu/general/activity/MainActivity.kt
@@ -1,28 +1,366 @@
package com.dayu.general.activity
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.KeyEvent
import android.view.LayoutInflater
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.dayu.baselibrary.net.subscribers.SubscriberListener
import com.dayu.baselibrary.utils.ToastUtil
import com.dayu.general.BaseApplication
import com.dayu.general.R
import com.dayu.general.adapter.TabAdapter
import com.dayu.general.bean.net.UserInfoResult
import com.dayu.general.bean.net.WaterPriceResult
import com.dayu.general.dao.BaseDaoSingleton
import com.dayu.general.databinding.ActivityMainBinding
import com.dayu.general.net.ApiManager
import com.dayu.general.net.BaseResponse
import com.dayu.general.tool.CardOperationType
import com.tencent.bugly.crashreport.CrashReport
import kotlinx.coroutines.launch
class MainActivity : BaseActivity(){
class MainActivity : BaseNfcActivity() {
    var binding: ActivityMainBinding? = null
    private val fragments: ArrayList<Fragment> = ArrayList()
    var mExitTime: Long = 0
    private val handler = Handler(Looper.getMainLooper())
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setupFragments();
        binding = ActivityMainBinding.inflate(LayoutInflater.from(this))
        setContentView(binding?.root)
        // 注册MainActivity实例到BaseApplication
        BaseApplication.setMainActivity(this)
        setupFragments()
        initView()
        initTab()
        getUserInfo()
        // 延时20秒后获取水价
        handler.postDelayed({
            getWaterPriceFromActivity()
        }, 20000) // 20秒延时
    }
    override fun onDestroy() {
        super.onDestroy()
        // 清理Handler回调,防止内存泄漏
        handler.removeCallbacksAndMessages(null)
        // 清理BaseApplication中的MainActivity引用
        BaseApplication.setMainActivity(null)
    }
    override fun onNfcBack(intent: Intent) {
        intent.let { nfcIntent ->
            // 获取当前显示的Fragment
            val currentFragment = fragments[binding?.viewPager?.currentItem ?: 0]
            // 如果当前显示的是充值Fragment,则将NFC信息传递给它处理
            if (currentFragment is RechargeFragment) {
                currentFragment.handleNfcIntent(nfcIntent)
            }
        }
    }
    /**
     * 获取水价信息 - 公开方法供其他地方调用
     */
    fun getWaterPriceFromActivity() {
        // 如果水价已存在且大于0,则不重复获取
        if (BaseApplication.waterPrice > 0.0) {
            return
        }
        ApiManager.getInstance().requestGetHideLoading(
            this,
            "terminal/client/getWaterPrice",
            WaterPriceResult::class.java,
            null,
            object : SubscriberListener<BaseResponse<WaterPriceResult>>() {
                override fun onNext(response: BaseResponse<WaterPriceResult>) {
                    if (response.success && response.code == "0001") {
                        // 获取水价成功,保存到BaseApplication
                        response.content?.let { waterPriceResult ->
                            BaseApplication.waterPrice = waterPriceResult.price
                        }
                    }
                }
                override fun onError(e: Throwable?) {
                    super.onError(e)
                    // 网络异常时不显示错误信息,避免影响用户体验
                }
            }
        )
    }
    private fun getUserInfo() {
        // 使用正确的类型参数
        ApiManager.getInstance().requestGetLoading(
            this,
            "base/user/getUserInfos/" + BaseApplication.userId,
            UserInfoResult::class.java,
            null,
            object : SubscriberListener<BaseResponse<UserInfoResult>>() {
                override fun onNext(t: BaseResponse<UserInfoResult>) {
                    if (t.success) {
                        BaseApplication.userName = t.content?.userName ?: ""
                        BaseApplication.userPhone = t.content?.phone ?: ""
                        BaseApplication.blockName = t.content?.blockName ?: ""
                    } else {
                        // 处理搜索失败的情况
                        ToastUtil.show(t.msg)
                    }
                }
                override fun onError(e: Throwable?) {
                    super.onError(e)
                    ToastUtil.show("搜索失败: ${e?.message ?: "未知错误"}")
                }
            }
        )
    }
    private fun initView() {
        binding!!.BSCardLL.setOnClickListener {  changeBottomState(Tab.BSC) }
        binding!!.myLL.setOnClickListener { changeBottomState(Tab.MY) }
        binding!!.rechargeLL.setOnClickListener { changeBottomState(Tab.RECHARGE) }
    }
    private fun setupFragments() {
        fragments.add(BSCardFragment())
        fragments.add(RechargeFragment())
        fragments.add(BSCardFragment())
        fragments.add(MyFragment())
    }
    private fun initTab() {
        binding?.viewPager?.adapter = TabAdapter(this, fragments)
        binding?.viewPager?.currentItem = (1)
        binding?.viewPager?.offscreenPageLimit = 3
        binding?.viewPager?.isUserInputEnabled = false
    }
    private enum class Tab {
        BSC, RECHARGE, MY
    }
    /**
     * 修改底部状态
     */
    private fun changeBottomState(tab: Tab) {
        resetTabState()
        when (tab) {
            Tab.BSC -> updateTabUI(0, R.drawable.bottom_card_white, R.color.white)
            Tab.RECHARGE -> updateTabUI(1, R.drawable.bottom_recharge_white, R.color.white)
            Tab.MY -> updateTabUI(2, R.drawable.bottom_my_white, R.color.white)
        }
    }
    /**
     * 重置所有 Tab 的默认状态
     */
    private fun resetTabState() {
        binding!!.BSCardImg.setImageDrawable(
            ContextCompat.getDrawable(
                this,
                R.drawable.bottom_card_black
            )
        )
        binding!!.BSCardText.setTextColor(ContextCompat.getColor(this, R.color.black))
        binding!!.rechargeImg.setImageDrawable(
            ContextCompat.getDrawable(
                this,
                R.drawable.bottom_recharge_black
            )
        )
        binding!!.rechargeText.setTextColor(ContextCompat.getColor(this, R.color.black))
        binding!!.myImg.setImageDrawable(
            ContextCompat.getDrawable(
                this,
                R.drawable.bottom_my_black
            )
        )
        binding!!.myText.setTextColor(ContextCompat.getColor(this, R.color.black))
    }
    /**
     * 更新某个 Tab 的 UI 状态
     */
    private fun updateTabUI(position: Int, iconResId: Int, textColorResId: Int) {
        if (position == 1) {
            binding!!.viewPager.setCurrentItem(position, true)
        } else {
            binding!!.viewPager.setCurrentItem(position, false)
        }
        when (position) {
            0 -> {
                binding!!.BSCardImg.setImageDrawable(ContextCompat.getDrawable(this, iconResId))
                binding!!.BSCardText.setTextColor(ContextCompat.getColor(this, textColorResId))
            }
            1 -> {
                binding!!.rechargeImg.setImageDrawable(ContextCompat.getDrawable(this, iconResId))
                binding!!.rechargeText.setTextColor(ContextCompat.getColor(this, textColorResId))
            }
            2 -> {
                binding!!.myImg.setImageDrawable(ContextCompat.getDrawable(this, iconResId))
                binding!!.myText.setTextColor(ContextCompat.getColor(this, textColorResId))
            }
        }
    }
    //点击两次退出程序 有时间间隔 间隔内点击则退出程序 否则 则提示
    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if ((System.currentTimeMillis() - mExitTime) > 2000) {
                Toast.makeText(this@MainActivity, "再按一次退出程序", Toast.LENGTH_SHORT)
                    .show()
                mExitTime = System.currentTimeMillis()
            } else {
                this@MainActivity.finish()
            }
            return true
        }
        return super.onKeyDown(keyCode, event)
    }
    /**
     * 向服务器上报写卡操作结果
     * 写卡成功后调用此方法通知服务器操作完成,成功后更新本地数据库isReported为true
     *
     * @param cardAddr 卡地址/卡号
     * @param operationTypeCode 操作类型代码
     * @param orderNumber 订单号
     * @param regionNumber 区域号
     * @param projectNumber 项目号
     */
    fun postCardData(
        cardAddr: String,
        operationTypeCode: Int,
        orderNumber: String = "",
        regionNumber: String = "",
        projectNumber: String = ""
    ) {
        val map = mutableMapOf<String, Any>()
        // 添加卡地址参数
        if (cardAddr.isNotEmpty()) {
            map["cardAddr"] = cardAddr
        }
        // 添加操作类型参数
        // 判断是否为管理卡制作操作类型(100-108),如果是则传递MANAGEMENT_CARD_WRITE的值(7)
        val operateTypeToSend = if (operationTypeCode in 100..108) {
            CardOperationType.MANAGEMENT_CARD_WRITE.code
        } else {
            operationTypeCode
        }
        map["operateType"] = operateTypeToSend
        // 添加订单号参数(如果存在)
        if (orderNumber.isNotEmpty()) {
            map["orderNumber"] = orderNumber
        }
        // 添加区域号和项目号参数
        if (regionNumber.isNotEmpty()) {
            map["regionNumber"] = regionNumber
        }
        if (projectNumber.isNotEmpty()) {
            map["projectNumber"] = projectNumber
        }
        // 调用服务器接口上报操作结果
        ApiManager.getInstance().requestPostHideLoading(
            this,
            "terminal/card/termCallBack", // 终端写卡回调接口
            String::class.java,
            map,
            object : SubscriberListener<BaseResponse<String>>() {
                override fun onNext(t: BaseResponse<String>) {
                    if (t.success) {
                        // 上报成功,更新本地数据库isReported为true
                        updateCardReportedStatus(cardAddr, orderNumber, operationTypeCode)
                    } else {
                        // 上报失败,记录错误但不影响用户操作
                        CrashReport.postCatchedException(Exception("上报写卡结果失败: ${t.msg}"))
                    }
                }
                override fun onError(e: Throwable?) {
                    super.onError(e)
                    // 网络错误,记录错误但不影响用户操作
                    CrashReport.postCatchedException(e ?: Exception("上报写卡结果网络错误"))
                }
            }
        )
    }
    /**
     * 更新本地数据库中的上报状态
     * 根据操作类型判断是更新ManagerCardBean还是CardRegistrationBean的isReported状态为true
     *
     * @param cardNumber 卡号
     * @param orderNumber 订单号
     * @param operationTypeCode 操作类型代码
     */
    private fun updateCardReportedStatus(cardNumber: String, orderNumber: String = "", operationTypeCode: Int = -1) {
        lifecycleScope.launch {
            try {
                val baseDaoSingleton = BaseDaoSingleton.getInstance(this@MainActivity)
                // 根据操作类型判断是管理卡还是用户卡操作
                val isManagerCardOperation = operationTypeCode in 100..108
                if (isManagerCardOperation) {
                    // 管理卡制作操作类型,查询和更新ManagerCardBean
                    val managerCardDao = baseDaoSingleton.managerCardDao()
                    val managerCard = if (orderNumber.isNotEmpty()) {
                        managerCardDao.getByOrderId(orderNumber)
                    } else {
                        managerCardDao.getByCardAddress(cardNumber)
                    }
                    if (managerCard != null) {
                        val updatedManagerCard = managerCard.copy(isReported = true)
                        managerCardDao.update(updatedManagerCard)
                    }
                } else {
                    // 用户卡操作类型,查询和更新CardRegistrationBean
                    val cardRegistrationDao = baseDaoSingleton.cardRegistrationDao()
                    val cardRegistration = if (orderNumber.isNotEmpty()) {
                        cardRegistrationDao.getByOrderId(orderNumber)
                    } else {
                        // 如果没有订单号,则通过卡号查找
                        cardRegistrationDao.getByCardNumber(cardNumber)
                    }
                    if (cardRegistration != null) {
                        // 创建更新后的CardRegistrationBean对象,将isReported设置为true
                        val updatedCardRegistration = cardRegistration.copy(isReported = true)
                        // 更新数据库记录
                        cardRegistrationDao.update(updatedCardRegistration)
                    }
                }
            } catch (e: Exception) {
                // 记录异常信息,但不影响用户操作
                CrashReport.postCatchedException(e)
                e.printStackTrace()
            }
        }
    }
}