feat(general): 新增卡片操作类型并优化写卡逻辑
- 新增 CardOperationType 密封类,用于区分不同的卡片操作类型
- 修改工本费输入类型为整数,提高用户体验
- 优化用户卡数据写入逻辑,确保数据长度正确
-修复清零卡和开卡的写卡流程,增加订单号和操作类型支持
- 优化数据传输格式,提高系统稳定性
 
	
	
	
	
	
	
	
	
	
	
	
	
	
 |  |  | 
 |  |  |                         mfc.connect(); | 
 |  |  |                         // 验证扇区密码 | 
 |  |  |                         boolean isOpen = false; | 
 |  |  |                         for (int i = 0; i < listKeyA.size(); i++) { | 
 |  |  |                             if (mfc.authenticateSectorWithKeyA(a, listKeyA.get(i))) { | 
 |  |  |                                 isOpen = true; | 
 |  |  |                                 if (listKeyA.get(i).equals(defauleKey)) { | 
 |  |  |                                     // 当前为默认白卡密码时写卡时修改密码 | 
 |  |  |                                     changePasword(a, mfc); | 
 |  |  |  | 
 |  |  |                         if (listKeyA.size() != 0) { | 
 |  |  |                             for (int i = 0; i < listKeyA.size(); i++) { | 
 |  |  |                                 if (mfc.authenticateSectorWithKeyA(a, listKeyA.get(i))) { | 
 |  |  |                                     isOpen = true; | 
 |  |  |                                     if (listKeyA.get(i).equals(defauleKey)) { | 
 |  |  |                                         // 当前为默认白卡密码时写卡时修改密码 | 
 |  |  |                                         changePasword(a, mfc); | 
 |  |  |                                     } | 
 |  |  |                                     break; | 
 |  |  |                                 } | 
 |  |  |                                 break; | 
 |  |  |                             } | 
 |  |  |                         } else if (listA_PS.size() != 0 && listA_PS.size() > a) { | 
 |  |  |                             if (mfc.authenticateSectorWithKeyA(a, defauleKey)) { | 
 |  |  |                                 isOpen = true; | 
 |  |  |  | 
 |  |  |                             } else if (mfc.authenticateSectorWithKeyA(a, listA_PS.get(a))) { | 
 |  |  |                                 isOpen = true; | 
 |  |  |                             } | 
 |  |  |                         } | 
 |  |  |                         if (isOpen) { | 
 |  |  | 
 |  |  |                         boolean isOpen = false; | 
 |  |  |                         if (listKeyA.size() != 0) { | 
 |  |  |                             for (int i = 0; i < listKeyA.size(); i++) { | 
 |  |  |                                 if (mfc.authenticateSectorWithKeyA(0, listKeyA.get(i))) { | 
 |  |  |                                 if (mfc.authenticateSectorWithKeyA(a, listKeyA.get(i))) { | 
 |  |  |                                     isOpen = true; | 
 |  |  |                                     if (listKeyA.get(i).equals(defauleKey)) { | 
 |  |  |                                         // 当前为默认白卡密码时写卡时修改密码 | 
 |  |  | 
 |  |  |     /** | 
 |  |  |      * 修改密码 | 
 |  |  |      * | 
 |  |  |      * @param 书写的扇区 | 
 |  |  |      * @param passWord 密码 | 
 |  |  |      * @return | 
 |  |  |      */ | 
 
 |  |  | 
 |  |  | import com.dayu.baselibrary.view.TitleBar.ClickType_LEFT_IMAGE | 
 |  |  | import com.dayu.general.databinding.ActivityManageListGeBinding | 
 |  |  | import com.dayu.general.tool.CardCommon | 
 |  |  | import com.dayu.general.tool.CardOperationType | 
 |  |  |  | 
 |  |  | class ManageListActivity : BaseActivity() { | 
 |  |  |  | 
 |  |  | 
 |  |  |         binding?.tvCleanCard?.setOnClickListener { | 
 |  |  |             var intent = Intent(this, ManagerReadActivity::class.java).apply { | 
 |  |  |                 putExtra("cardType", CardCommon.CLEAN_CARD_TYPE) | 
 |  |  |                 putExtra("operationTypeCode", CardOperationType.CleanCard.code) | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             startActivity(intent) | 
 |  |  |         } | 
 |  |  |         binding?.tvCheckCard?.setOnClickListener { | 
 |  |  |             var intent = Intent(this, ManagerReadActivity::class.java).apply { | 
 |  |  |                 putExtra("cardType", CardCommon.CHECK_CARD) | 
 |  |  |                 putExtra("operationTypeCode", CardCommon.CHECK_CARD) | 
 |  |  |                 putExtra("operationTypeCode", CardOperationType.CheckCard.code) | 
 |  |  |             } | 
 |  |  |             startActivity(intent) | 
 |  |  |         } | 
 
 |  |  | 
 |  |  | import android.widget.Toast | 
 |  |  | import androidx.lifecycle.lifecycleScope | 
 |  |  | import com.dayu.baselibrary.net.subscribers.SubscriberListener | 
 |  |  | import com.dayu.baselibrary.utils.MornyUtil | 
 |  |  | import com.dayu.baselibrary.view.TitleBar.ClickType_LEFT_IMAGE | 
 |  |  | import com.dayu.general.BaseApplication | 
 |  |  | import com.dayu.general.R | 
 |  |  | 
 |  |  | import com.dayu.general.net.ApiManager | 
 |  |  | import com.dayu.general.net.BaseResponse | 
 |  |  | import com.dayu.general.tool.CardCommon.Companion.USER_CARD_TYPE_1 | 
 |  |  | import com.dayu.general.tool.CardOperationType | 
 |  |  | import com.dayu.general.tool.NfcReadHelper | 
 |  |  | import com.dayu.general.tool.NfcWreatHelper | 
 |  |  | import com.dayu.general.utils.DateUtils | 
 |  |  | 
 |  |  |  | 
 |  |  |         // 获取工本费 | 
 |  |  |         val cardFeeStr = binding.newCardCardFee.text.toString() | 
 |  |  |         val cardFee = if (cardFeeStr.isEmpty()) 0.0 else cardFeeStr.toDouble() | 
 |  |  |  | 
 |  |  |         // 格式化金额为两位小数 | 
 |  |  |         val formattedRechargeAmount = String.format("%.2f", rechargeAmount) | 
 |  |  |         val formattedCardFee = String.format("%.2f", cardFee) | 
 |  |  |         val cardFee = if (cardFeeStr.isEmpty()) 0 else cardFeeStr.toInt() | 
 |  |  |  | 
 |  |  |         val remark = binding.newCardRemark.text.toString() | 
 |  |  |  | 
 |  |  | 
 |  |  |                                     putExtra("orderId", orderId) | 
 |  |  |                                     putExtra("cardAddr", cardPhysicalId) | 
 |  |  |                                     var userCard = UserCard() | 
 |  |  |                                     userCard.areaNumber =clientInfo.districtNum | 
 |  |  |                                     userCard.areaNumber = response.content?.cardNum?.substring(0, 12).toString() | 
 |  |  |                                     userCard.userCode =clientInfo.clientNum | 
 |  |  |                                     userCard.phoneNumber =clientInfo.phone | 
 |  |  |                                     userCard.userCodeNumber = response.content?.cardNum?.toInt()!! | 
 |  |  |                                     userCard.projectCode = response.content?.projectNo?.toInt()!! | 
 |  |  |                                     userCard.balance = response.content?.balance?.toInt()!! | 
 |  |  |                                     userCard.userCodeNumber = response.content?.cardNum?.substring(12)?.toInt()!! | 
 |  |  |                                     userCard.projectCode = response.content?.projectNo!! | 
 |  |  |                                     userCard.balance = MornyUtil.changeY2F(response.content?.balance) | 
 |  |  | //                                    userCard.surplusWater = response.content?.surplusWater?.toInt()!! | 
 |  |  |                                     userCard.waterPrice = response.content?.waterPrice?.toFloat()!! | 
 |  |  | //                                    userCard.electricPrice = response.content?.electricPrice?.toFloat()!! | 
 |  |  |                                     userCard.rechargeDate = DateUtils.parseStringToCalendar(response.content?.time) | 
 |  |  |                                     putExtra("userCard", userCard) | 
 |  |  |                                     putExtra("operationTypeCode", CardOperationType.OpenCard.code) | 
 |  |  |                                     putExtra("orderNumber", response.content?.orderNo) | 
 |  |  |                                     putExtra("cardFee", cardFee) | 
 |  |  |                                     startActivity(this) | 
 |  |  |                                 } | 
 |  |  |                             } catch (e: Exception) { | 
 
 |  |  | 
 |  |  | import com.dayu.general.bean.card.ClearCard | 
 |  |  | import com.dayu.general.bean.card.UserCard | 
 |  |  | import com.dayu.general.tool.CardCommon | 
 |  |  | import com.dayu.general.tool.CardOperationType | 
 |  |  | import com.dayu.general.databinding.ActivityNfcWriteGeBinding | 
 |  |  | import com.dayu.general.net.ApiManager | 
 |  |  | import com.dayu.general.net.BaseResponse | 
 |  |  | 
 |  |  | import com.dayu.general.dao.BaseDaoSingleton | 
 |  |  | import com.tencent.bugly.crashreport.CrashReport | 
 |  |  | import kotlinx.coroutines.launch | 
 |  |  | import java.lang.StringBuilder | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * @author: zuo | 
 |  |  | 
 |  |  |     var cardType = "" | 
 |  |  |     var orderId = "" | 
 |  |  |     var cardAddr = "" | 
 |  |  |     var cardFee = 0 | 
 |  |  |  | 
 |  |  |     //订单编号 | 
 |  |  |     var orderNumber = "" | 
 |  |  |     private lateinit var userCard: UserCard | 
 |  |  |     private var operationTypeCode = -1; | 
 |  |  |     private var operationType: CardOperationType? = null | 
 |  |  |  | 
 |  |  |     override fun onCreate(savedInstanceState: Bundle?) { | 
 |  |  |         super.onCreate(savedInstanceState) | 
 |  |  | 
 |  |  |         cardType = intent?.getStringExtra("cardType") ?: "" | 
 |  |  |         orderId = intent?.getStringExtra("orderId") ?: "" | 
 |  |  |         cardAddr = intent?.getStringExtra("cardAddr") ?: "" | 
 |  |  |         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) { | 
 |  |  |             userCard = intent?.getSerializableExtra("userCard", UserCard::class.java)!! | 
 |  |  |         } else { | 
 |  |  |             userCard = (intent?.getSerializableExtra("userCard") as? UserCard)!! | 
 |  |  |         operationTypeCode = intent?.getIntExtra("operationTypeCode", -1) ?: -1 | 
 |  |  |         operationType = CardOperationType.fromCode(operationTypeCode) | 
 |  |  |         if (intent?.hasExtra("cardFee") == true) { | 
 |  |  |             cardFee = intent?.getIntExtra("cardFee", 0) ?: 0 | 
 |  |  |         } | 
 |  |  |         if (intent?.hasExtra("userCard") == true) { | 
 |  |  |             if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) { | 
 |  |  |                 userCard = intent?.getSerializableExtra("userCard", UserCard::class.java)!! | 
 |  |  |             } else { | 
 |  |  |                 userCard = (intent?.getSerializableExtra("userCard") as? UserCard)!! | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |         if (cardType.isNotEmpty()) { | 
 |  |  |             when (cardType) { | 
 |  |  |                 CardCommon.CLEAN_CARD_TYPE -> { | 
 |  |  |         } | 
 |  |  |         if (operationTypeCode != -1) { | 
 |  |  |             when (operationType) { | 
 |  |  |                 CardOperationType.CleanCard -> { | 
 |  |  |                     binding?.cardData?.text = "清零卡写卡" | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 CardOperationType.OpenCard -> { | 
 |  |  |                     var textData = StringBuilder() | 
 |  |  |                     textData.append("用户开卡\n") | 
 |  |  |                     if (cardFee != 0) { | 
 |  |  |                         textData.append("工本费:" + cardFee + "元\n") | 
 |  |  |                     } | 
 |  |  |                     if (userCard.balance != 0) { | 
 |  |  |                         textData.append("充值金额:" + userCard.balance + "元") | 
 |  |  |                     } | 
 |  |  |  | 
 |  |  |                     binding?.cardData?.text = textData.toString() | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 CardOperationType.CancelCard -> TODO() | 
 |  |  |                 CardOperationType.CheckCard -> TODO() | 
 |  |  |                 CardOperationType.DeductCard -> TODO() | 
 |  |  |                 CardOperationType.Recharge -> TODO() | 
 |  |  |                 CardOperationType.ReplaceCard -> TODO() | 
 |  |  |                 null -> TODO() | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  | 
 |  |  |  | 
 |  |  |     override fun onNfcBack(intent: Intent) { | 
 |  |  |         val nfcReadHelper = NfcReadHelper.getInstance(intent, this) | 
 |  |  |         val cardNumber = nfcReadHelper.getCardNumberNoClose() | 
 |  |  |         // 使用正常的getCardNumber()方法,它会自动关闭连接 | 
 |  |  |         val cardNumber = nfcReadHelper.getCardNumber() | 
 |  |  |          | 
 |  |  |         if (cardNumber.isNotEmpty() && cardNumber == cardAddr) { | 
 |  |  |             val nfcWreatHelper = NfcWreatHelper.getInstance(intent, this) | 
 |  |  |             when (cardType) { | 
 |  |  |                 CardCommon.CLEAN_CARD_TYPE -> { | 
 |  |  |             when (operationType) { | 
 |  |  |                 CardOperationType.CleanCard -> { | 
 |  |  |                     var clearCard = ClearCard() | 
 |  |  |                     nfcWreatHelper.writeData(clearCard.getZeroBytes(), 7, 0) { success, message -> | 
 |  |  |                         if (success) { | 
 |  |  |                             postCardData(cardType, cardAddr, "") | 
 |  |  |                             // 写卡成功后更新数据库中的isCardWritten状态 | 
 |  |  |                             updateCardWrittenStatus(cardAddr) | 
 |  |  |                             ToastUtil.show("写卡成功!") | 
 |  |  |                             // 处理写卡成功的情况 | 
 |  |  |                         } else { | 
 |  |  |                             // 处理写卡失败的情况 | 
 |  |  |                             ToastUtil.show(message) | 
 |  |  |                         // 确保Toast在主线程中调用 | 
 |  |  |                         runOnUiThread { | 
 |  |  |                             if (success) { | 
 |  |  |                                 postCardData(cardType, cardAddr) | 
 |  |  |                                 // 写卡成功后更新数据库中的isCardWritten状态 | 
 |  |  |                                 updateCardWrittenStatus(cardAddr) | 
 |  |  |                                 ToastUtil.show("写卡成功!") | 
 |  |  |                                 // 处理写卡成功的情况 | 
 |  |  |                             } else { | 
 |  |  |                                 // 处理写卡失败的情况 | 
 |  |  |                                 ToastUtil.show(message) | 
 |  |  |                             } | 
 |  |  |                         } | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 CardCommon.USER_CARD_TYPE_1 -> { | 
 |  |  |                     binding?.cardData?.text = "写用户卡" | 
 |  |  |                 CardOperationType.OpenCard -> { | 
 |  |  |                     nfcWreatHelper.writeUserDataAsync(userCard, object : NFCCallBack { | 
 |  |  |                         override fun isSusses(flag: Boolean, msg: String?) { | 
 |  |  |                             if (flag) { | 
 |  |  |                                 // 写卡成功后更新数据库中的isCardWritten状态 | 
 |  |  |                                 updateCardWrittenStatus(cardAddr) | 
 |  |  |                                 ToastUtil.show("写卡成功!") | 
 |  |  |                             } else { | 
 |  |  |                                 ToastUtil.show("写卡失败: ${msg ?: "未知错误"}") | 
 |  |  |                             // 确保Toast在主线程中调用 | 
 |  |  |                             runOnUiThread { | 
 |  |  |                                 if (flag) { | 
 |  |  |                                     // 写卡成功后更新数据库中的isCardWritten状态 | 
 |  |  |                                     updateCardWrittenStatus(cardAddr) | 
 |  |  |                                     ToastUtil.show("写卡成功!") | 
 |  |  |                                 } else { | 
 |  |  |                                     ToastUtil.show("写卡失败: ${msg ?: "未知错误"}") | 
 |  |  |                                 } | 
 |  |  |                             } | 
 |  |  |                         } | 
 |  |  |                     }) | 
 |  |  |  | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 CardOperationType.CancelCard -> TODO() | 
 |  |  |                 CardOperationType.CheckCard -> TODO() | 
 |  |  |                 CardOperationType.DeductCard -> TODO() | 
 |  |  |                 CardOperationType.Recharge -> TODO() | 
 |  |  |                 CardOperationType.ReplaceCard -> TODO() | 
 |  |  |                 null -> TODO() | 
 |  |  |             } | 
 |  |  |         } else { | 
 |  |  |             ToastUtil.show("卡片错误,当前刷的卡与刚刚的卡不一致") | 
 |  |  | 
 |  |  |             try { | 
 |  |  |                 val cardRegistrationDao = BaseDaoSingleton.getInstance(this@NfcWreatActivity) | 
 |  |  |                     .cardRegistrationDao() | 
 |  |  |                  | 
 |  |  |  | 
 |  |  |                 // 根据卡号查找CardRegistrationBean记录 | 
 |  |  |                 val cardRegistration = cardRegistrationDao.getByCardNumber(cardNumber) | 
 |  |  |                 if (cardRegistration != null) { | 
 |  |  | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     fun postCardData(cardType: String, cardAddr: String, remark: String) { | 
 |  |  |     fun postCardData(cardType: String, cardAddr: String) { | 
 |  |  |         when (cardType) { | 
 |  |  |             CardCommon.CHECK_CARD -> { | 
 |  |  |                 binding?.cardData?.text = "写用户卡" | 
 |  |  | 
 |  |  |             map["cardAddr"] = cardAddr | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         if (cardType.isNotEmpty()) { | 
 |  |  | //            map["cardType"] = cardType | 
 |  |  |             map["operateType"] = "1" | 
 |  |  |         } | 
 |  |  |         if (remark.isNotEmpty()) { | 
 |  |  |             map["remarks"] = remark | 
 |  |  |         map["operateType"] = operationTypeCode | 
 |  |  |         if (orderNumber.isNotEmpty()) { | 
 |  |  |             map["orderNumber"] = orderNumber | 
 |  |  |         } | 
 |  |  |         // 使用正确的类型参数 | 
 |  |  |         ApiManager.getInstance().requestPostLoading( | 
 |  |  |             this, | 
 |  |  |             "/sell/card/call_back", | 
 |  |  |             "terminal/card/termCallBack", | 
 |  |  |             String::class.java, | 
 |  |  |             map, | 
 |  |  |             object : SubscriberListener<BaseResponse<String>>() { | 
 
 |  |  | 
 |  |  |             val data = ByteArray(16) | 
 |  |  |             try { | 
 |  |  |                 // 设置国家行政区域号(BCD格式,6字节,0-5位) | 
 |  |  |                 val areaCodeBytes = BcdUtil.strToBcd(String.format("%012d", areaNumber)) | 
 |  |  |                 System.arraycopy(areaCodeBytes, 0, data, 0, 6) | 
 |  |  |                 val areaNumberStr = if (areaNumber.isBlank() || !areaNumber.all { it.isDigit() }) { | 
 |  |  |                     "000000000000" | 
 |  |  |                 } else { | 
 |  |  |                     areaNumber.padStart(12, '0') | 
 |  |  |                 } | 
 |  |  |                 val areaCodeBytes = BcdUtil.strToBcd(areaNumberStr) | 
 |  |  |                 System.arraycopy(areaCodeBytes, 0, data, 0, minOf(areaCodeBytes.size, 6)) | 
 |  |  |  | 
 |  |  |                 // 设置用户卡编号(HEX格式,2字节,6-7位) | 
 |  |  |                 // 设置用户卡编号(HEX格式,2字节,6-7位) - 修复:确保数组长度正确 | 
 |  |  |                 val userCodeBytes = HexUtil.hexToByteArray(HexUtil.get10To16LowHigh(userCodeNumber)) | 
 |  |  |                 System.arraycopy(userCodeBytes, 0, data, 6, 2) | 
 |  |  |                 val userCodePadded = ByteArray(2) | 
 |  |  |                 System.arraycopy(userCodeBytes, 0, userCodePadded, 0, minOf(userCodeBytes.size, 2)) | 
 |  |  |                 System.arraycopy(userCodePadded, 0, data, 6, 2) | 
 |  |  |  | 
 |  |  |                 // 设置卡类型(8位) | 
 |  |  |                 data[8] = HexUtil.hexToByte(cardType) | 
 |  |  |  | 
 |  |  |                 // 设置手机号(BCD格式,6字节,9-14位) | 
 |  |  |                 val phoneBytes = BcdUtil.strToBcd(phoneNumber.padStart(12, '0')) | 
 |  |  |                 System.arraycopy(phoneBytes, 0, data, 9, 6) | 
 |  |  |                 System.arraycopy(phoneBytes, 0, data, 9, minOf(phoneBytes.size, 6)) | 
 |  |  |  | 
 |  |  |                 // 设置校验和(15位) | 
 |  |  |                 data[15] = getByteSum(data) | 
 |  |  | 
 |  |  |             try { | 
 |  |  |                 data[0] = projectCode.toByte() | 
 |  |  |  | 
 |  |  |                 // 设置余额 | 
 |  |  |                 val balanceBytes = HexUtil.hexToByteArray(HexUtil.get10To16LowHigh(balance)) | 
 |  |  |                 System.arraycopy(balanceBytes, 0, data, 1, 4) | 
 |  |  |                 // 设置余额 - 修复:确保数组长度正确 | 
 |  |  |                 val balanceHex = HexUtil.get10To16LowHigh(balance) | 
 |  |  |                 val balanceBytes = HexUtil.hexToByteArray(balanceHex) | 
 |  |  |                 val balancePadded = ByteArray(4) | 
 |  |  |                 System.arraycopy(balanceBytes, 0, balancePadded, 0, minOf(balanceBytes.size, 4)) | 
 |  |  |                 System.arraycopy(balancePadded, 0, data, 1, 4) | 
 |  |  |  | 
 |  |  |                 // 设置剩余水量 | 
 |  |  |                 val waterBytes = HexUtil.hexToByteArray(HexUtil.get10To16LowHigh(surplusWater)) | 
 |  |  |                 System.arraycopy(waterBytes, 0, data, 5, 4) | 
 |  |  |                 // 设置剩余水量 - 修复:确保数组长度正确 | 
 |  |  |                 val waterHex = HexUtil.get10To16LowHigh(surplusWater) | 
 |  |  |                 val waterBytes = HexUtil.hexToByteArray(waterHex) | 
 |  |  |                 val waterPadded = ByteArray(4) | 
 |  |  |                 System.arraycopy(waterBytes, 0, waterPadded, 0, minOf(waterBytes.size, 4)) | 
 |  |  |                 System.arraycopy(waterPadded, 0, data, 5, 4) | 
 |  |  |  | 
 |  |  |                 // 设置电价 | 
 |  |  |                 // 设置电价 - 修复:确保数组长度正确 | 
 |  |  |                 val priceBytes = HexUtil.hexToByteArray(HexUtil.floatToHexLowHigh(electricPrice)) | 
 |  |  |                 System.arraycopy(priceBytes, 0, data, 9, 2) | 
 |  |  |                 val pricePadded = ByteArray(2) | 
 |  |  |                 System.arraycopy(priceBytes, 0, pricePadded, 0, minOf(priceBytes.size, 2)) | 
 |  |  |                 System.arraycopy(pricePadded, 0, data, 9, 2) | 
 |  |  |  | 
 |  |  |                 // 设置充值时间 | 
 |  |  |                 rechargeDate?.let { | 
 |  |  | 
 |  |  |         fun toBytes(): ByteArray { | 
 |  |  |             val data = ByteArray(16) | 
 |  |  |             try { | 
 |  |  |                 // 备份余额和水量数据 | 
 |  |  |                 val balanceBytes = HexUtil.hexToByteArray(HexUtil.get10To16LowHigh(balance)) | 
 |  |  |                 System.arraycopy(balanceBytes, 0, data, 1, 4) | 
 |  |  |                 // 备份余额和水量数据 - 修复:确保数组长度正确 | 
 |  |  |                 val balanceHex = HexUtil.get10To16LowHigh(balance) | 
 |  |  |                 val balanceBytes = HexUtil.hexToByteArray(balanceHex) | 
 |  |  |                 val balancePadded = ByteArray(4) | 
 |  |  |                 System.arraycopy(balanceBytes, 0, balancePadded, 0, minOf(balanceBytes.size, 4)) | 
 |  |  |                 System.arraycopy(balancePadded, 0, data, 1, 4) | 
 |  |  |  | 
 |  |  |                 val waterBytes = HexUtil.hexToByteArray(HexUtil.get10To16LowHigh(surplusWater)) | 
 |  |  |                 System.arraycopy(waterBytes, 0, data, 5, 4) | 
 |  |  |                 val waterHex = HexUtil.get10To16LowHigh(surplusWater) | 
 |  |  |                 val waterBytes = HexUtil.hexToByteArray(waterHex) | 
 |  |  |                 val waterPadded = ByteArray(4) | 
 |  |  |                 System.arraycopy(waterBytes, 0, waterPadded, 0, minOf(waterBytes.size, 4)) | 
 |  |  |                 System.arraycopy(waterPadded, 0, data, 5, 4) | 
 |  |  |  | 
 |  |  |                 // 设置水价 | 
 |  |  |                 // 设置水价 - 修复:确保数组长度正确 | 
 |  |  |                 val priceBytes = HexUtil.hexToByteArray(HexUtil.floatToHexLowHigh(waterPrice)) | 
 |  |  |                 System.arraycopy(priceBytes, 0, data, 9, 2) | 
 |  |  |                 val pricePadded = ByteArray(2) | 
 |  |  |                 System.arraycopy(priceBytes, 0, pricePadded, 0, minOf(priceBytes.size, 2)) | 
 |  |  |                 System.arraycopy(pricePadded, 0, data, 9, 2) | 
 |  |  |  | 
 |  |  |                 // 设置充值时间 | 
 |  |  |                 rechargeDate?.let { | 
 
 |  |  | 
 |  |  |     val userName: String, // 姓名 | 
 |  |  |     val idCard: String, // 身份证号 | 
 |  |  |     val clientId: String, // 农户Id | 
 |  |  |     val cardFee: Double, // 工本费 | 
 |  |  |     val cardFee: Int, // 工本费 | 
 |  |  |     val remark: String, // 备注 | 
 |  |  |     val paymentMethod: Int, // 支付方式 | 
 |  |  |     val orderId: String? = null, // 订单id,初始为null,后续更新 | 
 
 |  |  | 
 |  |  | package com.dayu.general.bean.net | 
 |  |  |  | 
 |  |  | data class NewCardDataResult( | 
 |  |  |     var projectNo: String, | 
 |  |  |     var projectNo: Int, | 
 |  |  |     var cardNum: String, | 
 |  |  |     var balance: String, | 
 |  |  |     var waterPrice: String, | 
 
| New file | 
 |  |  | 
 |  |  | package com.dayu.general.tool | 
 |  |  |  | 
 |  |  | /** | 
 |  |  |  * 卡片操作类型 | 
 |  |  |  * 用于区分不同的卡片操作 | 
 |  |  |  */ | 
 |  |  | sealed class CardOperationType(val code: Int, val description: String) { | 
 |  |  |     object OpenCard : CardOperationType(1, "开卡") | 
 |  |  |     object Recharge : CardOperationType(2, "充值") | 
 |  |  |     object CancelCard : CardOperationType(3, "销卡") | 
 |  |  |     object ReplaceCard : CardOperationType(4, "补卡") | 
 |  |  |     object DeductCard : CardOperationType(5, "补扣") | 
 |  |  |     object CleanCard : CardOperationType(6, "清零卡") | 
 |  |  |     object CheckCard : CardOperationType(7, "检查卡") | 
 |  |  |  | 
 |  |  |     companion object { | 
 |  |  |         fun fromCode(code: Int): CardOperationType? { | 
 |  |  |             return when (code) { | 
 |  |  |                 1 -> OpenCard | 
 |  |  |                 2 -> Recharge | 
 |  |  |                 3 -> CancelCard | 
 |  |  |                 4 -> ReplaceCard | 
 |  |  |                 5 -> DeductCard | 
 |  |  |                 else -> null | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  | }  | 
 
 |  |  | 
 |  |  |                                 android:layout_height="wrap_content" | 
 |  |  |                                 android:background="@null" | 
 |  |  |                                 android:hint="请输入工本费(选填)" | 
 |  |  |                                 android:inputType="numberDecimal" | 
 |  |  |                                 android:inputType="number" | 
 |  |  |                                 android:textColor="#333333" | 
 |  |  |                                 android:textColorHint="#BBBBBB" | 
 |  |  |                                 android:textSize="@dimen/new_card_size" /> |