左晓为主开发手持机充值管理机
generallibrary/src/main/java/com/dayu/general/activity/CardReplaceActivity.kt
@@ -3,23 +3,17 @@
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.TypedValue
import android.view.View
import android.widget.RadioButton
import android.widget.Toast
import com.dayu.baselibrary.net.subscribers.SubscriberListener
import com.dayu.baselibrary.utils.MornyUtil
import com.dayu.baselibrary.utils.ToastUtil
import com.dayu.baselibrary.view.TipDialog
import com.dayu.baselibrary.view.TitleBar
import com.dayu.general.BaseApplication
import com.dayu.general.R
import com.dayu.general.bean.card.UserCard
import com.dayu.general.bean.net.CardInfoResult
import com.dayu.general.bean.net.CardInfoByClientResult
import com.dayu.general.bean.net.CardInfoResult
import com.dayu.general.bean.net.CardReplaceResult
import com.dayu.general.bean.net.PaymentMethod
import com.dayu.general.bean.net.PaymentMethodResponse
import com.dayu.general.databinding.ActivityCardReplaceBinding
import com.dayu.general.net.ApiManager
import com.dayu.general.net.BaseResponse
@@ -38,23 +32,21 @@
    private var cardInfo: CardInfoResult? = null
    private var cardInfoByClient: CardInfoByClientResult? = null
    private var userCard: UserCard? = null
    private var clientNum: String? = null
    private var cardNum: String? = null
    private var newCardNumber: String? = null // 新卡卡号
    // 支付方式相关属性
    private var paymentMethod: String = "现金"
    private var paymentId: Long = 0
    private var paymentId: String = ""
    private var paymentMethodList: List<PaymentMethod> = listOf()
    companion object {
        /**
         * 启动补卡Activity
         */
        fun start(context: Context, clientNum: String? = null) {
        fun start(context: Context, clientNum: String) {
            val intent = Intent(context, CardReplaceActivity::class.java)
            clientNum?.let {
                intent.putExtra("clientNum", it)
            }
            intent.putExtra("cardNum", clientNum)
            context.startActivity(intent)
        }
    }
@@ -65,12 +57,10 @@
        setContentView(binding.root)
        // 获取传递的clientNum参数
        clientNum = intent.getStringExtra("clientNum")
        cardNum = intent.getStringExtra("cardNum")
        initView()
        // 获取支付方式
        getPaymentMethods()
        // 无论是否有clientNum,都先显示读卡界面,等待用户刷新卡
        resetToReadingState()
    }
@@ -87,100 +77,8 @@
        }
    }
    /**
     * 获取支付方式列表
     */
    private fun getPaymentMethods() {
        ApiManager.getInstance().requestGetLoading(
            this,
            "sell/paymentmethod/get",
            PaymentMethodResponse::class.java,
            null,
            object : SubscriberListener<BaseResponse<PaymentMethodResponse>>() {
                override fun onNext(response: BaseResponse<PaymentMethodResponse>) {
                    if (response.success) {
                        // 获取支付方式列表
                        val paymentMethods = response.content?.obj ?: listOf()
                        if (paymentMethods.isNotEmpty()) {
                            paymentMethodList = paymentMethods
                            // 更新支付方式显示
                            updatePaymentMethodRadioGroup()
                        }
                    } else {
                        Toast.makeText(
                            this@CardReplaceActivity,
                            "获取支付方式失败: ${response.msg}",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
                override fun onError(e: Throwable?) {
                    super.onError(e)
                    Toast.makeText(
                        this@CardReplaceActivity,
                        "获取支付方式失败: ${e?.message ?: "网络异常"}",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        )
    }
    /**
     * 更新支付方式RadioGroup
     */
    private fun updatePaymentMethodRadioGroup() {
        // 清空原有RadioButton
        binding.paymentMethodGroup.removeAllViews()
        // 动态添加RadioButton
        paymentMethodList.forEachIndexed { index, method ->
            val radioButton = RadioButton(this)
            radioButton.id = View.generateViewId() // 生成唯一ID
            radioButton.layoutParams = android.widget.LinearLayout.LayoutParams(
                0,
                resources.getDimensionPixelSize(R.dimen.dimen_40),
                1.0f
            )
            // 如果不是最后一个按钮,添加右边距
            if (index < paymentMethodList.size - 1) {
                (radioButton.layoutParams as android.widget.LinearLayout.LayoutParams).rightMargin =
                    resources.getDimensionPixelSize(R.dimen.dimen_15)
            }
            radioButton.text = method.name
            radioButton.background = resources.getDrawable(R.drawable.radio_selector)
            radioButton.buttonDrawable = null
            radioButton.gravity = android.view.Gravity.CENTER
            radioButton.setTextColor(resources.getColorStateList(R.color.radio_button_text_color))
            radioButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
            // 添加到RadioGroup
            binding.paymentMethodGroup.addView(radioButton)
            // 默认选中第一个
            if (index == 0) {
                radioButton.isChecked = true
                paymentMethod = method.name
                paymentId = method.id
            }
        }
        // 设置支付方式选择监听
        binding.paymentMethodGroup.setOnCheckedChangeListener { group, checkedId ->
            // 根据选中的ID获取支付方式
            for (i in 0 until group.childCount) {
                val radioButton = group.getChildAt(i) as RadioButton
                if (radioButton.id == checkedId) {
                    paymentMethod = radioButton.text.toString()
                    paymentId = paymentMethodList[i].id
                    break
                }
            }
        }
    }
    /**
     * 重置到读卡状态
@@ -194,7 +92,7 @@
        cardInfoByClient = null
        newCardNumber = null
        binding.etCardCost.setText("")
        binding.etReturnAmount.setText("0")
        binding.etReturnAmount.setText("")
    }
    /**
@@ -244,7 +142,7 @@
            }
            val readCardNumber = parts[0]
            val cardType = parts[1]
            if (readCardNumber.isBlank()) {
                showConfirmDialog("卡号为空,无法进行操作,请重新刷卡") {
                }
@@ -254,27 +152,35 @@
            // 保存新卡卡号
            this.newCardNumber = readCardNumber
            // 根据是否有clientNum参数决定获取卡信息的方式
            if (clientNum != null) {
                // 如果有clientNum,使用clientNum获取卡信息
                getCardInfoByClientNum(clientNum!!)
            } else {
                // 如果没有clientNum,根据卡片类型进行处理
                when (cardType) {
                    CardCommon.USER_CARD_TYPE_1,
                    CardCommon.USER_CARD_TYPE_2,
                    CardCommon.USER_CARD_TYPE_3 -> {
                        // 用户卡:解析卡内数据并调用接口
                        showConfirmDialog("该卡片类型不支持补卡操作") {
            when (cardType) {
                "00" -> {
                    // 白卡才可以补卡
                    if (cardNum != null) {
                        // 如果有clientNum,使用clientNum获取卡信息
                        getCardInfoByClientNum(cardNum!!)
                    } else {
                        showConfirmDialog("获取旧卡信息数据失败") {
                            resetToReadingState()
                        }
                    }
                    else -> {
                        // 管理类卡不支持补卡
                        handleUserCard(readCardNumber, cardType, nfcAdapter)
                }
                CardCommon.USER_CARD_TYPE_1,
                CardCommon.USER_CARD_TYPE_2,
                CardCommon.USER_CARD_TYPE_3 -> {
                    // 用户卡:解析卡内数据并调用接口
                    showConfirmDialog("用户卡不支持补卡") {
                        resetToReadingState()
                    }
                }
                else -> {
                    showConfirmDialog("当前非白卡") {
                        resetToReadingState()
                    }
                }
            }
        } catch (e: Exception) {
            showConfirmDialog("读卡异常:${e.message}") {
            }
@@ -282,102 +188,6 @@
        }
    }
    /**
     * 处理用户卡
     */
    private fun handleUserCard(cardNumber: String, cardType: String, nfcAdapter: NfcReadHelper) {
        // 解析用户卡数据
        val userCard = nfcAdapter.getUserCardData()
        if (userCard == null) {
            showConfirmDialog("解析卡片数据失败,请重新刷卡") {
            }
            return
        }
        // 输出用户卡内所有信息到日志
        android.util.Log.d("CardReplaceActivity", "=== 用户卡信息 ===")
        android.util.Log.d("CardReplaceActivity", "卡号: $cardNumber")
        android.util.Log.d("CardReplaceActivity", "卡片类型: $cardType")
        android.util.Log.d("CardReplaceActivity", "卡内余额: ${userCard.balance}")
        android.util.Log.d("CardReplaceActivity", "==================")
        this.userCard = userCard
        // 根据卡号获取卡片详细信息
        getCardInfo(cardNumber, cardType, userCard)
    }
    /**
     * 获取卡片详细信息(用户卡专用)
     */
    private fun getCardInfo(cardNumber: String, cardType: String, userCard: UserCard) {
        val map = mutableMapOf<String, Any>()
        map["cardAddr"] = cardNumber
        ApiManager.getInstance().requestGetLoading(
            this,
            "terminal/card/readCard",
            CardInfoResult::class.java,
            map,
            object : SubscriberListener<BaseResponse<CardInfoResult>>() {
                override fun onNext(t: BaseResponse<CardInfoResult>) {
                    if (t.success) {
                        // 读卡成功,显示用户卡详细信息
                        showUserCardInfo(t.content, cardNumber, cardType, userCard)
                    } else {
                        // 处理获取失败的情况
                        handleCardInfoError(t.code, t.msg)
                    }
                }
                override fun onError(e: Throwable?) {
                    super.onError(e)
                    showConfirmDialog("获取卡信息失败: ${e?.message ?: "网络异常,请检查网络连接"}") {
                    }
                }
            }
        )
    }
    /**
     * 显示用户卡片信息(包含卡内数据和接口返回数据)
     */
    private fun showUserCardInfo(
        cardInfo: CardInfoResult?,
        cardNumber: String,
        cardType: String,
        userCard: UserCard
    ) {
        // 隐藏读卡提示,显示信息区域和底部按钮
        binding.scrollReadCard.visibility = android.view.View.GONE
        binding.cardInfoContainer.visibility = android.view.View.VISIBLE
        binding.bottomButtonContainer.visibility = android.view.View.VISIBLE
        this.cardInfo = cardInfo
        this.cardNumber = cardNumber
        // 显示新卡卡号
        binding.tvCurrentCardAddress.text = newCardNumber ?: cardNumber
        // 显示服务器数据
        cardInfo?.let { info ->
            binding.tvUserName.text = info.userName ?: "未知"
            binding.tvPhone.text = info.phone ?: "未绑定"
            // 根据state字段显示状态
            val (statusText, statusColor) = when (info.state) {
                1 -> Pair("正常", android.graphics.Color.parseColor("#4CAF50")) // 绿色
                2 -> Pair("已注销", android.graphics.Color.parseColor("#FF5722")) // 深橙色
                3 -> Pair("已挂失", android.graphics.Color.parseColor("#FF9800")) // 橙色
                4 -> Pair("无效卡片", android.graphics.Color.parseColor("#F44336")) // 红色
                else -> Pair("未知状态", android.graphics.Color.parseColor("#9E9E9E")) // 灰色
            }
            binding.tvCardStatus.text = statusText
            binding.tvCardStatus.setTextColor(statusColor)
        }
        userCard.let { card ->
            // 余额转换为元(原始数据可能是分)
            binding.tvCardBalance.text = MornyUtil.changeF2Y(card.balance) + "元"
        }
    }
    /**
     * 处理卡信息获取错误
@@ -463,7 +273,7 @@
        val map = mutableMapOf<String, Any>()
        map["cardAddr"] = newCardNumber!! // 使用新卡卡号
        // 根据数据源选择cardNum参数
        val cardNum = when {
            cardInfo != null -> cardInfo!!.cardNum.toString()
@@ -471,7 +281,7 @@
            else -> cardNumber ?: newCardNumber!!
        }
        map["cardNum"] = cardNum
        map["cardCost"] = cardCost
        map["returnAmount"] = returnAmount  // 使用返回金额
        map["paymentId"] = paymentId // 使用选中的支付方式ID
@@ -488,7 +298,12 @@
                override fun onNext(t: BaseResponse<CardReplaceResult>) {
                    if (t.success && t.content != null) {
                        // 补卡成功,跳转到写卡界面
                        startWriteCardActivity(t.content!!, cardCost, returnAmount, createUserCardFromData())
                        startWriteCardActivity(
                            t.content!!,
                            cardCost,
                            returnAmount,
                            createUserCardFromData()
                        )
                    } else {
                        // 补卡失败
                        val errorMsg = if (t.msg.isNullOrBlank()) "补卡失败,请重试" else t.msg
@@ -520,6 +335,7 @@
                    phoneNumber = cardInfoByClient!!.phone.toString()
                }
            }
            else -> UserCard() // 返回空的UserCard对象
        }
    }
@@ -568,13 +384,13 @@
    /**
     * 根据客户编号获取卡信息
     */
    private fun getCardInfoByClientNum(clientNum: String) {
    private fun getCardInfoByClientNum(cardNum: String) {
        val map = mutableMapOf<String, Any>()
        map["clientNum"] = clientNum
        map["cardNum"] = cardNum
        ApiManager.getInstance().requestGetLoading(
            this,
            "terminal/card/getcardbyclientnum",
            "terminal/card/getcardbycardnum",
            CardInfoByClientResult::class.java,
            map,
            object : SubscriberListener<BaseResponse<CardInfoByClientResult>>() {
@@ -610,11 +426,17 @@
        binding.bottomButtonContainer.visibility = android.view.View.VISIBLE
        // 显示新卡卡号(如果已读取到新卡)
        binding.tvCurrentCardAddress.text = newCardNumber ?: cardInfo.cardNum
        binding.tvCurrentCardAddress.text = newCardNumber ?: ""
        // 显示卡信息
        binding.tvUserName.text = cardInfo.clientName
        binding.tvPhone.text = cardInfo.phone.toString()
        // 显示卡号
        binding.tvCardNumber.text = cardInfo.cardNum ?: "--"
        // 显示客户编号
        binding.tvCustomerId.text = cardInfo.clientNum ?: "--"
        // 根据cardState字段显示状态
        val (statusText, statusColor) = when (cardInfo.cardState) {
@@ -629,7 +451,7 @@
        // 显示余额
        binding.tvCardBalance.text = "${cardInfo.money}元"
        // 设置cardNumber用于后续API调用
        cardNumber = cardInfo.cardNum
    }