generallibrary/src/main/AndroidManifest.xml
@@ -90,7 +90,7 @@ <!-- 写卡成功页面 --> <activity android:name=".activity.CardWriteSuccessActivity" /> <!-- 挂失页面 --> <activity android:name=".activity.LossCardActivity" /> <activity android:name=".activity.CardLossActivity" /> <!-- 读卡页面 --> <activity android:name=".activity.CardReadActivity" @@ -136,9 +136,18 @@ </intent-filter> </activity> <activity android:name=".activity.UnlossCardActivity" android:name=".activity.CardUnlossActivity" android:exported="false" android:launchMode="singleTop"/> <activity android:name=".activity.CardReplaceActivity" android:exported="false" android:launchMode="singleTop"> <intent-filter> <action android:name="android.nfc.action.ACTION_NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> </activity> <meta-data android:name="BUGLY_APP_VERSION" generallibrary/src/main/java/com/dayu/general/activity/BSCardFragment.kt
@@ -79,7 +79,7 @@ // 挂失卡按钮点击事件 binding.homeLossLL.setOnClickListener { // 跳转到挂失卡页面 val intent = Intent(context, LossCardActivity::class.java) val intent = Intent(context, CardLossActivity::class.java) startActivity(intent) } @@ -108,7 +108,7 @@ } binding.homeReplacement.setOnClickListener { context?.let { val intent = Intent(context, UnlossCardActivity::class.java) val intent = Intent(context, CardUnlossActivity::class.java) startActivity(intent) } } generallibrary/src/main/java/com/dayu/general/activity/CardLossActivity.kt
File was renamed from generallibrary/src/main/java/com/dayu/general/activity/LossCardActivity.kt @@ -22,7 +22,7 @@ * Author: zuo * Date: 2025/6/11 */ class LossCardActivity : BaseActivity() { class CardLossActivity : BaseActivity() { var binding: ActivityCardListBinding? = null private var cardAdapter: CardListAdapter? = null @@ -82,7 +82,7 @@ private fun setupRecyclerView() { cardAdapter = CardListAdapter(this) binding?.recyclerView?.apply { layoutManager = LinearLayoutManager(this@LossCardActivity) layoutManager = LinearLayoutManager(this@CardLossActivity) adapter = cardAdapter } @@ -96,13 +96,11 @@ card.cardNum.toString(), card.money.toString() ) refundDialog.setOnConfirmListener { refundAmount, remark -> // TODO: 处理退款逻辑 lossPost(card.idCard.toString()) refundDialog.setOnConfirmListener { _username, cardNumber, balance, refundAmount, remark -> // 调用挂失接口 lossPost(cardNumber, balance, refundAmount, remark) } } } private fun setupRefreshLayout() { @@ -247,38 +245,56 @@ ) } private fun lossPost(cardNumber: String) { /** * 执行挂失操作 * @param cardNumber 卡号 * @param balance 余额 * @param refundAmount 退款金额 * @param remark 备注 */ private fun lossPost(cardNumber: String, balance: String, refundAmount: String, remark: String) { val map = mutableMapOf<String, Any>() map["cardNum"] = cardNumber // 处理余额格式,去除千位分隔符逗号和"元"字符 val balanceValue = balance.replace("元", "").replace(",", "").toFloatOrNull() ?: 0f map["money"] = balanceValue map["refund"] = refundAmount.toFloatOrNull() ?: 0f map["remarks"] = remark.ifEmpty { "挂失" } map["operator"] = BaseApplication.userId ApiManager.getInstance().requestGetLoading( ApiManager.getInstance().requestPostLoading( this, "/sell/card/loss", SearchCardResult::class.java, "terminal/card/termReportLoss", ReportLossResult::class.java, map, object : SubscriberListener<BaseResponse<SearchCardResult>>() { override fun onNext(t: BaseResponse<SearchCardResult>) { if (t.success) { object : SubscriberListener<BaseResponse<ReportLossResult>>() { override fun onNext(t: BaseResponse<ReportLossResult>) { if (t.success && t.code == "0001") { ToastUtil.show("挂失成功") // 刷新列表数据 searchCards(currentFarmerId, currentFarmerName, currentCardNumber, true) } else { // 处理搜索失败的情况 ToastUtil.show(t.msg) ToastUtil.show(t.msg ?: "挂失失败") } } override fun onError(e: Throwable?) { super.onError(e) // 完成刷新或加载动作 ToastUtil.show("搜索失败: ${e?.message ?: "未知错误"}") ToastUtil.show("挂失失败: ${e?.message ?: "网络错误"}") } } ) } /** * 挂失接口返回结果 */ data class ReportLossResult( val content: Boolean? = null ) /** * 完成刷新或加载操作 generallibrary/src/main/java/com/dayu/general/activity/CardReplaceActivity.kt
New file @@ -0,0 +1,516 @@ package com.dayu.general.activity 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.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 import com.dayu.general.tool.CardCommon import com.dayu.general.tool.CardOperationType import com.dayu.general.tool.NfcReadHelper /** * @author: zuo * @desc: 补卡Activity * @since: 2025/6/17 */ class CardReplaceActivity : BaseNfcActivity() { private lateinit var binding: ActivityCardReplaceBinding private var cardNumber: String? = null private var cardInfo: CardInfoResult? = null private var userCard: UserCard? = null // 支付方式相关属性 private var paymentMethod: String = "现金" private var paymentId: Long = 0 private var paymentMethodList: List<PaymentMethod> = listOf() companion object { /** * 启动补卡Activity */ fun start(context: Context) { val intent = Intent(context, CardReplaceActivity::class.java) context.startActivity(intent) } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityCardReplaceBinding.inflate(layoutInflater) setContentView(binding.root) initView() // 获取支付方式 getPaymentMethods() } private fun initView() { // 设置TitleBar的返回按钮点击事件 binding.titleBar.setOnItemclickListner(TitleBar.ClickType_LEFT_IMAGE) { finish() } // 设置补卡按钮点击事件 binding.btnReplace.setOnClickListener { performCardReplace() } } /** * 获取支付方式列表 */ 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 } } } } /** * 重置到读卡状态 */ private fun resetToReadingState() { binding.scrollReadCard.visibility = android.view.View.VISIBLE binding.cardInfoContainer.visibility = android.view.View.GONE binding.bottomButtonContainer.visibility = android.view.View.GONE cardNumber = null cardInfo = null binding.etCardCost.setText("") binding.etReturnAmount.setText("0") } /** * 显示确认对话框 */ private fun showConfirmDialog(message: String, onConfirm: () -> Unit) { val confirmDialog = TipDialog(this, message) { onConfirm() } confirmDialog.show() } override fun onNfcBack(intent: Intent?) { intent?.let { // 处理正常的读卡操作 handleNfcIntent(it) } ?: run { showConfirmDialog("NFC数据异常,请重新刷卡") { } } } /** * 处理NFC刷卡信息 */ private fun handleNfcIntent(intent: Intent) { try { // 检查intent中是否包含NFC Tag if (intent.getParcelableExtra<android.nfc.Tag>(android.nfc.NfcAdapter.EXTRA_TAG) == null) { showConfirmDialog("未检测到NFC卡片,请确保卡片已正确放置") { } return } val nfcAdapter = NfcReadHelper.getInstance(intent, this) val cardTypeAndCardNumber = nfcAdapter.getCardTypeAndCardNumber() if (cardTypeAndCardNumber.isNullOrBlank() || !cardTypeAndCardNumber.contains(",")) { showConfirmDialog("卡片信息读取失败,请重新刷卡") { } return } val parts = cardTypeAndCardNumber.split(",") if (parts.size < 2) { showConfirmDialog("卡片信息格式异常,请重新刷卡") { } return } val cardNumber = parts[0] val cardType = parts[1] this.cardNumber = cardNumber if (cardNumber.isBlank()) { showConfirmDialog("卡号为空,无法进行操作,请重新刷卡") { } return } // 根据卡片类型进行不同处理 when (cardType) { CardCommon.USER_CARD_TYPE_1, CardCommon.USER_CARD_TYPE_2, CardCommon.USER_CARD_TYPE_3 -> { // 用户卡:解析卡内数据并调用接口 showConfirmDialog("该卡片类型不支持补卡操作") { resetToReadingState() } } else -> { // 管理类卡不支持补卡 handleUserCard(cardNumber, cardType, nfcAdapter) } } } catch (e: Exception) { showConfirmDialog("读卡异常:${e.message}") { } e.printStackTrace() } } /** * 处理用户卡 */ 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 // 显示当前卡地址 binding.tvCurrentCardAddress.text = 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) + "元" } } /** * 处理卡信息获取错误 */ private fun handleCardInfoError(code: String?, msg: String?) { val errorMessage: String = when (code) { "1001" -> { "该卡片未在系统中注册,无法进行补卡操作。" } else -> { when { msg.isNullOrBlank() -> "获取卡信息失败,请重新刷卡重试。" msg.contains("数据不存在") -> "该卡片未在系统中注册,无法进行补卡操作。" msg.contains("网络") -> "网络连接异常,请检查网络连接后重新刷卡。" msg.contains("超时") -> "网络请求超时,请重新刷卡重试。" else -> "获取卡信息失败:$msg\n\n请重新刷卡重试。" } } } // 显示错误信息的对话框 showConfirmDialog(errorMessage) { resetToReadingState() } } /** * 执行补卡操作 */ private fun performCardReplace() { // 验证输入 val cardCostStr = binding.etCardCost.text.toString().trim() val returnAmountStr = binding.etReturnAmount.text.toString().trim() // 工本费验证(必填) if (cardCostStr.isEmpty()) { ToastUtil.show("请输入工本费") return } val cardCost = try { val cost = cardCostStr.toDouble() if (cost < 0) { ToastUtil.show("工本费不能为负数") return } cost } catch (e: NumberFormatException) { ToastUtil.show("请输入有效的工本费") return } // 返回金额验证(必填) if (returnAmountStr.isEmpty()) { ToastUtil.show("请输入返回金额") return } val returnAmount = try { val amount = returnAmountStr.toDouble() if (amount < 0) { ToastUtil.show("返回金额不能为负数") return } amount } catch (e: NumberFormatException) { ToastUtil.show("请输入有效的返回金额") return } callReplaceCardApi(cardCost, returnAmount) } /** * 调用补卡API接口 */ private fun callReplaceCardApi(cardCost: Double, returnAmount: Double) { if (cardNumber.isNullOrBlank()) { ToastUtil.show("卡号信息异常,请重新刷卡") return } val map = mutableMapOf<String, Any>() map["cardAddr"] = cardNumber!! map["cardNum"] = cardInfo?.cardNum.toString() map["cardCost"] = cardCost map["returnAmount"] = returnAmount // 使用返回金额 map["paymentId"] = paymentId // 使用选中的支付方式ID map["paymentMethod"] = paymentMethod // 添加支付方式名称 map["remarks"] = "补卡操作" // 固定备注 map["operator"] = BaseApplication.userId ApiManager.getInstance().requestPostLoading( this, "terminal/card/termReissue", CardReplaceResult::class.java, map, object : SubscriberListener<BaseResponse<CardReplaceResult>>() { override fun onNext(t: BaseResponse<CardReplaceResult>) { if (t.success && t.content != null) { // 补卡成功,跳转到写卡界面 startWriteCardActivity(t.content!!, cardCost, returnAmount, userCard!!) } else { // 补卡失败 val errorMsg = if (t.msg.isNullOrBlank()) "补卡失败,请重试" else t.msg showConfirmDialog("补卡失败:$errorMsg") { } } } override fun onError(e: Throwable?) { super.onError(e) showConfirmDialog("补卡请求失败: ${e?.message ?: "网络异常,请检查网络连接"}") { } } } ) } /** * 跳转到写卡界面进行卡内容更新 */ private fun startWriteCardActivity( replaceResult: CardReplaceResult, cardCost: Double, returnAmount: Double, userCard: UserCard ) { // 创建更新后的用户卡数据 val updatedUserCard = UserCard().apply { // 复制原有属性 cardType = userCard.cardType areaNumber = userCard.areaNumber userCode = userCard.userCode userCodeNumber = userCard.userCodeNumber phoneNumber = userCard.phoneNumber projectCode = userCard.projectCode surplusWater = userCard.surplusWater waterPrice = userCard.waterPrice electricPrice = userCard.electricPrice rechargeDate = userCard.rechargeDate // 使用返回的新余额 balance = MornyUtil.changeY2F(replaceResult.balance.toString()) } val intent = Intent(this, NfcWreatActivity::class.java).apply { putExtra("cardAddr", cardNumber) putExtra("operationTypeCode", CardOperationType.ReplaceCard.code) // 使用补卡类型进行写卡 putExtra("orderNumber", replaceResult.orderNo) putExtra("cardCost", cardCost) putExtra("returnAmount", returnAmount) // 传递返回金额 putExtra("paymentMethod", paymentMethod) // 传递支付方式 putExtra("paymentId", paymentId) // 传递支付方式ID putExtra("userCard", updatedUserCard as java.io.Serializable) } startActivity(intent) finish() } } generallibrary/src/main/java/com/dayu/general/activity/CardUnlossActivity.kt
File was renamed from generallibrary/src/main/java/com/dayu/general/activity/UnlossCardActivity.kt @@ -22,7 +22,7 @@ * Author: zuo * Date: 2025/6/11 */ class UnlossCardActivity : BaseActivity() { class CardUnlossActivity : BaseActivity() { var binding: ActivityCardListBinding? = null private var cardAdapter: UnlossCardListAdapter? = null @@ -88,7 +88,7 @@ private fun setupRecyclerView() { cardAdapter = UnlossCardListAdapter(this) binding?.recyclerView?.apply { layoutManager = LinearLayoutManager(this@UnlossCardActivity) layoutManager = LinearLayoutManager(this@CardUnlossActivity) adapter = cardAdapter } @@ -99,7 +99,8 @@ // 设置补卡按钮点击事件 cardAdapter?.setOnReplaceClickListener { card -> showReplaceConfirmDialog(card) CardReplaceActivity.start(this) } } @@ -263,26 +264,7 @@ confirmDialog.show() } /** * 显示补卡确认对话框 */ private fun showReplaceConfirmDialog(card: SearchCardResult.CardInfo) { val confirmMessage = "确认要补办新卡吗?\n\n" + "卡号:${card.cardNum ?: "无"}\n" + "持卡人:${card.clientName ?: "未知"}\n" + "余额:${card.money ?: "0.00"}元\n\n" + "补卡后将生成新的卡片,原卡作废!" val confirmDialog = ConfirmDialog( this, "补卡确认", confirmMessage ) { // 用户点击确认后执行补卡操作 replaceCard(card) } confirmDialog.show() } /** * 解除挂失 @@ -315,41 +297,6 @@ override fun onError(e: Throwable?) { super.onError(e) ToastUtil.show("解除挂失失败: ${e?.message ?: "未知错误"}") } } ) } /** * 补卡 */ private fun replaceCard(card: SearchCardResult.CardInfo) { val map = mutableMapOf<String, Any>() map["cardNum"] = card.cardNum.toString() map["operator"] = BaseApplication.userId ApiManager.getInstance().requestGetLoading( this, "/sell/card/replace", SearchCardResult::class.java, map, object : SubscriberListener<BaseResponse<SearchCardResult>>() { override fun onNext(t: BaseResponse<SearchCardResult>) { if (t.success) { ToastUtil.show("补卡成功") // 刷新列表 currentPage = 1 hasMoreData = true binding?.refreshLayout?.resetNoMoreData() searchCards(currentFarmerId, currentFarmerName, currentCardNumber, true) } else { ToastUtil.show(t.msg) } } override fun onError(e: Throwable?) { super.onError(e) ToastUtil.show("补卡失败: ${e?.message ?: "未知错误"}") } } ) generallibrary/src/main/java/com/dayu/general/activity/CardWriteSuccessActivity.kt
@@ -85,6 +85,22 @@ binding.successMessage.text = message } CardOperationType.ReplaceCard -> { // 设置标题 binding.titleBar.setCenterText("补卡成功") // 设置成功信息 binding.successTitle.text = "补卡成功" // 设置详细信息 val message = if (cardNumber.isNullOrBlank()) { "补卡操作已成功完成\n新卡已写入数据,可正常使用" } else { "补卡操作已成功完成\n卡号:$cardNumber\n新卡已写入数据,可正常使用" } binding.successMessage.text = message } CardOperationType.Recharge -> { binding.titleBar.setCenterText("写卡成功") binding.successTitle.text = "写卡成功" generallibrary/src/main/java/com/dayu/general/activity/NfcWreatActivity.kt
@@ -44,6 +44,10 @@ // 补扣相关信息 private var deductAmount = 0.0 // 补卡相关信息 private var cardCost = 0.0 private var reissueAmount = 0.0 //订单编号 var orderNumber = "" private lateinit var userCard: UserCard @@ -80,6 +84,10 @@ // 获取补扣相关信息 deductAmount = intent?.getDoubleExtra("deductAmount", 0.0) ?: 0.0 // 获取补卡相关信息 cardCost = intent?.getDoubleExtra("cardCost", 0.0) ?: 0.0 reissueAmount = intent?.getDoubleExtra("reissueAmount", 0.0) ?: 0.0 if (intent?.hasExtra("cardFee") == true) { cardFee = intent?.getIntExtra("cardFee", 0) ?: 0 @@ -185,8 +193,20 @@ binding?.cardData?.text = textData.toString() } CardOperationType.ReplaceCard -> { var textData = StringBuilder() textData.append("补卡\n") textData.append("卡内余额:" + MornyUtil.changeF2Y(userCard.balance) + "元\n") if (cardCost > 0) { textData.append("工本费:" + String.format("%.2f", cardCost) + "元\n") } if (reissueAmount > 0) { textData.append("补卡金额:" + String.format("%.2f", reissueAmount) + "元") } binding?.cardData?.text = textData.toString() } CardOperationType.CheckCard -> TODO() CardOperationType.ReplaceCard -> TODO() null -> TODO() } } @@ -297,8 +317,22 @@ }) } CardOperationType.ReplaceCard -> { nfcWreatHelper.writeUserDataAsync(userCard, object : NFCCallBack { override fun isSusses(flag: Boolean, msg: String?) { // 确保Toast在主线程中调用 runOnUiThread { if (flag) { postCardData(cardAddr) } else { ToastUtil.show("补卡写卡失败: ${msg ?: "未知错误"}") } } } }) } CardOperationType.CheckCard -> TODO() CardOperationType.ReplaceCard -> TODO() null -> TODO() } } else { generallibrary/src/main/java/com/dayu/general/activity/SearchCardListActivity.kt
@@ -90,9 +90,9 @@ card.cardNum.toString(), card.money.toString() ) refundDialog.setOnConfirmListener { refundAmount, remark -> // TODO: 处理退款逻辑 lossPost(card.idCard.toString()) refundDialog.setOnConfirmListener { _username, cardNumber, balance, refundAmount, remark -> // 调用挂失接口 lossPost(cardNumber, balance, refundAmount, remark) } } @@ -217,38 +217,56 @@ ) } private fun lossPost(cardNumber: String) { /** * 执行挂失操作 * @param cardNumber 卡号 * @param balance 余额 * @param refundAmount 退款金额 * @param remark 备注 */ private fun lossPost(cardNumber: String, balance: String, refundAmount: String, remark: String) { val map = mutableMapOf<String, Any>() map["cardNum"] = cardNumber // 处理余额格式,去除千位分隔符逗号和"元"字符 val balanceValue = balance.replace("元", "").replace(",", "").toFloatOrNull() ?: 0f map["money"] = balanceValue map["refund"] = refundAmount.toFloatOrNull() ?: 0f map["remarks"] = remark.ifEmpty { "挂失" } map["operator"] = BaseApplication.userId ApiManager.getInstance().requestGetLoading( ApiManager.getInstance().requestPostLoading( this, "/sell/card/loss", SearchCardResult::class.java, "sell/card/loss", ReportLossResult::class.java, map, object : SubscriberListener<BaseResponse<SearchCardResult>>() { override fun onNext(t: BaseResponse<SearchCardResult>) { if (t.success) { object : SubscriberListener<BaseResponse<ReportLossResult>>() { override fun onNext(t: BaseResponse<ReportLossResult>) { if (t.success && t.code == "0001") { ToastUtil.show("挂失成功") // 刷新列表数据 searchCards(currentFarmerId, currentFarmerName, currentCardNumber, true) } else { // 处理搜索失败的情况 ToastUtil.show(t.msg) ToastUtil.show(t.msg ?: "挂失失败") } } override fun onError(e: Throwable?) { super.onError(e) // 完成刷新或加载动作 ToastUtil.show("搜索失败: ${e?.message ?: "未知错误"}") ToastUtil.show("挂失失败: ${e?.message ?: "网络错误"}") } } ) } /** * 挂失接口返回结果 */ data class ReportLossResult( val content: Boolean? = null ) /** * 完成刷新或加载操作 generallibrary/src/main/java/com/dayu/general/view/CardRefundDialog.kt
@@ -5,21 +5,15 @@ import android.os.Bundle import android.view.Gravity import android.view.WindowManager 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.databinding.DialogCardRefundBinding import com.dayu.general.net.ApiManager import com.dayu.general.net.BaseResponse /** *卡片挂失对话框 */ class CardRefundDialog(context: Context) : Dialog(context) { private var binding: DialogCardRefundBinding? = null private var onConfirmListener: ((String, String) -> Unit)? = null private var onSuccessListener: (() -> Unit)? = null private var onConfirmListener: ((String, String, String, String, String) -> Unit)? = null private var username: String? = null private var cardNumber: String? = null private var balance: String? = null @@ -47,8 +41,15 @@ val refundAmount = binding?.etRefundAmount?.text.toString() val remark = binding?.etRemark?.text.toString() // 调用挂失接口 callReportLossApi(refundAmount, remark) // 通过回调将数据传递给Activity处理 username?.let { username -> cardNumber?.let { cardNumber -> balance?.let { balance -> onConfirmListener?.invoke(username, cardNumber, balance, refundAmount, remark) dismiss() } } } } // 如果有预设的用户信息,设置它们 @@ -80,58 +81,11 @@ } } fun setOnConfirmListener(listener: (String, String) -> Unit) { /** * 设置确认监听器 * @param listener 回调函数,参数为:用户名、卡号、余额、退款金额、备注 */ fun setOnConfirmListener(listener: (String, String, String, String, String) -> Unit) { onConfirmListener = listener } fun setOnSuccessListener(listener: () -> Unit) { onSuccessListener = listener } /** * 调用挂失接口 */ private fun callReportLossApi(refundAmount: String, remark: String) { val params = mutableMapOf<String, Any>() params["cardNum"] = cardNumber ?: "" // 处理余额格式,去除千位分隔符逗号和"元"字符 val balanceValue = balance?.replace("元", "")?.replace(",", "")?.toFloatOrNull() ?: 0f params["money"] = balanceValue params["refund"] = refundAmount.toFloatOrNull() ?: 0f params["remarks"] = remark.ifEmpty { "挂失" } params["operator"] = BaseApplication.userId ApiManager.getInstance().requestPostLoading( context, "terminal/card/termReportLoss", ReportLossResult::class.java, params, object : SubscriberListener<BaseResponse<ReportLossResult>>() { override fun onNext(response: BaseResponse<ReportLossResult>) { if (response.success && response.code == "0001") { ToastUtil.show("挂失成功") onConfirmListener?.invoke(refundAmount, remark) onSuccessListener?.invoke() dismiss() } else { ToastUtil.show(response.msg ?: "挂失失败") } } override fun onError(e: Throwable?) { super.onError(e) ToastUtil.show("挂失失败: ${e?.message ?: "网络错误"}") } } ) } /** * 挂失接口返回结果 */ data class ReportLossResult( val content: Boolean? = null ) } generallibrary/src/main/res/layout/activity_card_replace.xml
@@ -1,49 +1,424 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:orientation="vertical"> android:background="@color/base_green_bg"> <com.dayu.baselibrary.view.TitleBar android:id="@+id/titleBar" android:layout_width="match_parent" android:layout_height="@dimen/dimen_title_height" app:centerText="补卡" /> android:background="@color/title_bar_bg" android:elevation="4dp" app:centerText="补卡" app:leftImage="@mipmap/icon_back" /> <FrameLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"> <com.scwang.smart.refresh.layout.SmartRefreshLayout android:id="@+id/refreshLayout" <!-- 读卡提示区域 - 全屏显示 --> <ScrollView android:id="@+id/scroll_read_card" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/titleBar"> android:layout_below="@+id/titleBar" android:fillViewport="true" android:visibility="visible"> <com.scwang.smart.refresh.header.ClassicsHeader android:layout_width="match_parent" android:layout_height="wrap_content" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/base_list_bg" android:overScrollMode="never" android:padding="10dp" /> android:orientation="vertical" android:padding="16dp"> <com.scwang.smart.refresh.footer.ClassicsFooter <LinearLayout android:id="@+id/card_read_LL" android:layout_width="match_parent" android:layout_height="wrap_content" /> </com.scwang.smart.refresh.layout.SmartRefreshLayout> android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="16dp" app:cardCornerRadius="8dp" app:cardElevation="2dp"> </FrameLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <TextView android:id="@+id/tv_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="100dp" android:gravity="center" android:text="补卡操作" android:layout_marginTop="20dp" android:textColor="@color/base_blue_bg" android:textSize="@dimen/big_text_size" android:textStyle="bold" /> <TextView android:id="@+id/tv_subtitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/tv_title" android:layout_marginBottom="20dp" android:gravity="center" android:text="请将需要补办的卡片贴在设备上进行读取" android:textColor="#333333" android:textSize="@dimen/text_size" android:textStyle="bold" /> <ImageView android:id="@+id/iv_nfc" android:layout_width="120dp" android:layout_height="120dp" android:layout_below="@+id/tv_subtitle" android:layout_centerHorizontal="true" android:layout_marginBottom="20dp" android:scaleType="fitCenter" android:src="@mipmap/nfc_write" /> <TextView android:id="@+id/tv_tip" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/iv_nfc" android:gravity="center" android:text="请保持手持机和卡片不要移动" android:textColor="#666666" android:textSize="@dimen/new_card_size" /> </RelativeLayout> </androidx.cardview.widget.CardView> </LinearLayout> </LinearLayout> </ScrollView> <!-- 卡片信息显示区域 - 带固定底部按钮 --> <LinearLayout android:id="@+id/card_info_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/bottom_button_container" android:layout_below="@+id/titleBar" android:orientation="vertical" android:visibility="gone"> <ScrollView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:fillViewport="true" android:padding="12dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <!-- 当前卡地址显示区域 --> <androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="12dp" app:cardCornerRadius="8dp" app:cardElevation="2dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="12dp" android:text="当前卡地址" android:textColor="@color/base_blue_bg" android:textSize="18sp" android:textStyle="bold" /> <TextView android:id="@+id/tv_current_card_address" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#F5F5F5" android:padding="12dp" android:text="--" android:textColor="#333333" android:textSize="16sp" android:textIsSelectable="true" /> </LinearLayout> </androidx.cardview.widget.CardView> <!-- 旧卡信息区域 --> <androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" app:cardCornerRadius="8dp" app:cardElevation="2dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="12dp" android:text="旧卡信息" android:textColor="@color/base_blue_bg" android:textSize="18sp" android:textStyle="bold" /> <!-- 持卡人 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="1dp" android:background="#F8F9FA" android:gravity="center_vertical" android:orientation="horizontal" android:padding="12dp"> <TextView android:layout_width="100dp" android:layout_height="wrap_content" android:text="持卡人:" android:textColor="#333333" android:textSize="16sp" android:textStyle="bold" /> <TextView android:id="@+id/tv_user_name" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="--" android:textColor="#666666" android:textSize="16sp" /> </LinearLayout> <!-- 卡片状态 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="1dp" android:background="#FFFFFF" android:gravity="center_vertical" android:orientation="horizontal" android:padding="12dp"> <TextView android:layout_width="100dp" android:layout_height="wrap_content" android:text="卡片状态:" android:textColor="#333333" android:textSize="16sp" android:textStyle="bold" /> <TextView android:id="@+id/tv_card_status" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="正常" android:textColor="#4CAF50" android:textSize="16sp" /> </LinearLayout> <!-- 卡内余额 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="1dp" android:background="#F8F9FA" android:gravity="center_vertical" android:orientation="horizontal" android:padding="12dp"> <TextView android:layout_width="100dp" android:layout_height="wrap_content" android:text="卡内余额:" android:textColor="#333333" android:textSize="16sp" android:textStyle="bold" /> <TextView android:id="@+id/tv_card_balance" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="0.00元" android:textColor="#FF6B35" android:textSize="16sp" android:textStyle="bold" /> </LinearLayout> <!-- 手机号 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#FFFFFF" android:gravity="center_vertical" android:orientation="horizontal" android:padding="12dp"> <TextView android:layout_width="100dp" android:layout_height="wrap_content" android:text="手机号:" android:textColor="#333333" android:textSize="16sp" android:textStyle="bold" /> <TextView android:id="@+id/tv_phone" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="--" android:textColor="#666666" android:textSize="16sp" /> </LinearLayout> </LinearLayout> </androidx.cardview.widget.CardView> </LinearLayout> </ScrollView> </LinearLayout> <!-- 底部操作区域 --> <LinearLayout android:id="@+id/bottom_button_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="#FFFFFF" android:elevation="4dp" android:orientation="vertical" android:padding="16dp" android:visibility="gone"> <!-- 支付方式选择区域 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginBottom="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:text="支付方式" android:textColor="#333333" android:textSize="16sp" android:textStyle="bold" /> <RadioGroup android:id="@+id/payment_method_group" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <!-- 支付方式RadioButton将动态添加 --> </RadioGroup> </LinearLayout> <!-- 工本费和返回金额输入区域 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_marginBottom="16dp"> <!-- 工本费输入 --> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_marginEnd="8dp" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="6dp" android:text="工本费(元)" android:textColor="#333333" android:textSize="14sp" android:textStyle="bold" /> <EditText android:id="@+id/et_card_cost" android:layout_width="match_parent" android:layout_height="48dp" android:background="@drawable/edit_text_bg" android:hint="工本费" android:inputType="numberDecimal" android:padding="12dp" android:text="" android:textColor="#333333" android:textColorHint="#999999" android:textSize="16sp" /> </LinearLayout> <!-- 返回金额输入 --> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_marginStart="8dp" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="6dp" android:text="返回金额(元)" android:textColor="#333333" android:textSize="14sp" android:textStyle="bold" /> <EditText android:id="@+id/et_return_amount" android:layout_width="match_parent" android:layout_height="48dp" android:background="@drawable/edit_text_bg" android:hint="返回金额" android:inputType="numberDecimal" android:padding="12dp" android:text="0" android:textColor="#333333" android:textColorHint="#999999" android:textSize="16sp" /> </LinearLayout> </LinearLayout> <!-- 补卡按钮 --> <Button android:id="@+id/btn_replace" android:layout_width="match_parent" android:layout_height="48dp" android:background="@drawable/button_blue_bg" android:text="确认补卡" android:textColor="#FFFFFF" android:textSize="@dimen/big_text_size" android:textStyle="bold" /> </LinearLayout> </RelativeLayout>