From dd2562d8dc2b01bcdfca3152f82f09efbbd09259 Mon Sep 17 00:00:00 2001 From: zuoxiao <lf_zuo@163.com> Date: 星期三, 25 六月 2025 19:49:48 +0800 Subject: [PATCH] fix(generallibrary): 优化卡片处理和支付方式获取逻辑- 修复地区卡处理逻辑,增加对"00"类型卡的特殊处理 - 优化用户卡数据解析和显示逻辑,提高容错性 - 改进支付方式获取方法,增加错误处理和日志记录 -调整充值接口调用参数,确保正确传递当前余额等信息- 修复 AreaCard 中 areaNumber 类型,改为字符串处理 --- generallibrary/src/main/java/com/dayu/general/activity/RechargeDetailActivity.kt | 371 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 339 insertions(+), 32 deletions(-) diff --git a/generallibrary/src/main/java/com/dayu/general/activity/RechargeDetailActivity.kt b/generallibrary/src/main/java/com/dayu/general/activity/RechargeDetailActivity.kt index 3d1a949..7658e5b 100644 --- a/generallibrary/src/main/java/com/dayu/general/activity/RechargeDetailActivity.kt +++ b/generallibrary/src/main/java/com/dayu/general/activity/RechargeDetailActivity.kt @@ -3,41 +3,60 @@ import android.content.Context import android.content.Intent import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher import android.util.TypedValue import android.view.View +import android.widget.EditText import android.widget.RadioButton import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.dayu.baselibrary.net.subscribers.SubscriberListener +import com.dayu.baselibrary.utils.MornyUtil import com.dayu.baselibrary.utils.ToastUtil import com.dayu.baselibrary.view.TitleBar +import com.dayu.general.BaseApplication import com.dayu.general.R import com.dayu.general.bean.net.CardInfoResult import com.dayu.general.bean.net.PaymentMethod import com.dayu.general.bean.net.PaymentMethodResponse +import com.dayu.general.bean.net.RechargeRequest +import com.dayu.general.bean.net.RechargeResult +import com.dayu.general.bean.card.UserCard +import com.dayu.general.bean.net.PaymentMethodListResponse import com.dayu.general.databinding.ActivityRechargeDetailBinding 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 class RechargeDetailActivity : AppCompatActivity() { private lateinit var binding: ActivityRechargeDetailBinding private var cardInfo: CardInfoResult? = null private var cardAddress: String? = null + private var userCard: UserCard? = null // 鏀粯鏂瑰紡鐩稿叧灞炴�� private var paymentMethod: String = "鐜伴噾" - private var paymentId: Long = 0 + private var paymentId: String = "" private var paymentMethodList: List<PaymentMethod> = listOf() companion object { private const val EXTRA_CARD_INFO = "extra_card_info" private const val EXTRA_CARD_ADDRESS = "extra_card_address" + private const val EXTRA_USER_CARD = "extra_user_card" - fun start(context: Context, cardInfo: CardInfoResult?, cardAddress: String?) { + fun start( + context: Context, + cardInfo: CardInfoResult?, + cardAddress: String?, + userCard: UserCard? + ) { val intent = Intent(context, RechargeDetailActivity::class.java) intent.putExtra(EXTRA_CARD_INFO, cardInfo) intent.putExtra(EXTRA_CARD_ADDRESS, cardAddress) + intent.putExtra(EXTRA_USER_CARD, userCard) context.startActivity(intent) } } @@ -53,11 +72,14 @@ // 鑾峰彇浼犻�掔殑鏁版嵁 cardInfo = intent.getSerializableExtra(EXTRA_CARD_INFO) as? CardInfoResult cardAddress = intent.getStringExtra(EXTRA_CARD_ADDRESS) + userCard = intent.getSerializableExtra(EXTRA_USER_CARD) as? UserCard initView() displayCardInfo() // 鑾峰彇鏀粯鏂瑰紡 getPaymentMethods() + // 纭繚姘翠环鍙敤锛堝鏋滀负绌轰細鑷姩瑙﹀彂MainActivity鑾峰彇锛� + BaseApplication.requestWaterPrice() } private fun initView() { @@ -68,29 +90,120 @@ // 璁剧疆鎸夐挳鐐瑰嚮浜嬩欢 binding.rechargeRegistBtn.setOnClickListener { - // 澶勭悊鍐欏崱閫昏緫 - handleWriteCard() + // 澶勭悊鍏呭�奸�昏緫 + handleRecharge() } + + // 璁剧疆閲戦杈撳叆闄愬埗 + setupAmountInputLimit(binding.rechargeMorny) + setupAmountInputLimit(binding.rechargeWater) } /** - * 鑾峰彇鏀粯鏂瑰紡鍒楄〃 + * 璁剧疆閲戦杈撳叆闄愬埗锛屾渶澶氫繚鐣欎袱浣嶅皬鏁� + */ + private fun setupAmountInputLimit(editText: EditText) { + editText.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} + + override fun afterTextChanged(s: Editable?) { + val text = s.toString() + if (text.isEmpty()) return + + // 妫�鏌ユ槸鍚﹀寘鍚皬鏁扮偣 + if (text.contains(".")) { + val parts = text.split(".") + if (parts.size == 2) { + val decimalPart = parts[1] + // 濡傛灉灏忔暟浣嶈秴杩�2浣嶏紝鎴彇鍓嶄袱浣� + if (decimalPart.length > 2) { + val newText = "${parts[0]}.${decimalPart.substring(0, 2)}" + editText.removeTextChangedListener(this) + editText.setText(newText) + editText.setSelection(newText.length) + editText.addTextChangedListener(this) + } + } + } + + // 闃叉杈撳叆澶氫釜灏忔暟鐐� + val dotCount = text.count { it == '.' } + if (dotCount > 1) { + val newText = text.substring(0, text.lastIndexOf('.')) + editText.removeTextChangedListener(this) + editText.setText(newText) + editText.setSelection(newText.length) + editText.addTextChangedListener(this) + } + + // 闃叉浠ュ皬鏁扮偣寮�澶� + if (text.startsWith(".")) { + editText.removeTextChangedListener(this) + editText.setText("0$text") + editText.setSelection(editText.text.length) + editText.addTextChangedListener(this) + } + } + }) + } + + /** + * 鑾峰彇鏀粯鏂瑰紡鍒楄〃 - 浣跨敤Object绫诲瀷瀹夊叏澶勭悊JSON鏁扮粍 */ private fun getPaymentMethods() { ApiManager.getInstance().requestGetLoading( this, - "sell/paymentmethod/get", - PaymentMethodResponse::class.java, + "terminal/paymentmethod/get", + Any::class.java, null, - object : SubscriberListener<BaseResponse<PaymentMethodResponse>>() { - override fun onNext(response: BaseResponse<PaymentMethodResponse>) { + object : SubscriberListener<BaseResponse<Any>>() { + override fun onNext(response: BaseResponse<Any>) { if (response.success) { - // 鑾峰彇鏀粯鏂瑰紡鍒楄〃 - val paymentMethods = response.content?.obj ?: listOf() - if (paymentMethods.isNotEmpty()) { - paymentMethodList = paymentMethods - // 鏇存柊鏀粯鏂瑰紡鏄剧ず - updatePaymentMethodRadioGroup() + try { + // 瀹夊叏鍦板鐞嗚繑鍥炵殑content锛屾湇鍔″櫒杩斿洖鐨勬槸ArrayList<LinkedHashMap> + val paymentMethods = mutableListOf<PaymentMethod>() + val content = response.content + + if (content is List<*>) { + content.forEach { item -> + if (item is Map<*, *>) { + val id = item["id"]?.toString() ?: "" + val name = item["name"]?.toString() ?: "" + if (id.isNotEmpty() && name.isNotEmpty()) { + paymentMethods.add(PaymentMethod(id, name)) + } + } + } + } + + if (paymentMethods.isNotEmpty()) { + paymentMethodList = paymentMethods + // 鏇存柊鏀粯鏂瑰紡鏄剧ず + updatePaymentMethodRadioGroup() + + // 璋冭瘯鏃ュ織 + android.util.Log.d("RechargeDetail", "鎴愬姛鑾峰彇${paymentMethods.size}涓敮浠樻柟寮�:") + paymentMethods.forEach { method -> + android.util.Log.d("RechargeDetail", "- ID: ${method.id}, Name: ${method.name}") + } + } else { + Toast.makeText( + this@RechargeDetailActivity, + "鑾峰彇鏀粯鏂瑰紡澶辫触锛氳繑鍥炴暟鎹负绌�", + Toast.LENGTH_SHORT + ).show() + } + } catch (e: Exception) { + android.util.Log.e("RechargeDetail", "瑙f瀽鏀粯鏂瑰紡鏁版嵁澶辫触", e) + android.util.Log.e("RechargeDetail", "鍘熷鏁版嵁绫诲瀷: ${response.content?.javaClass?.name}") + android.util.Log.e("RechargeDetail", "鍘熷鏁版嵁鍐呭: $response.content") + Toast.makeText( + this@RechargeDetailActivity, + "瑙f瀽鏀粯鏂瑰紡鏁版嵁澶辫触: ${e.message}", + Toast.LENGTH_SHORT + ).show() } } else { Toast.makeText( @@ -103,6 +216,7 @@ override fun onError(e: Throwable?) { super.onError(e) + android.util.Log.e("RechargeDetail", "缃戠粶璇锋眰澶辫触", e) Toast.makeText( this@RechargeDetailActivity, "鑾峰彇鏀粯鏂瑰紡澶辫触: ${e?.message ?: "缃戠粶寮傚父"}", @@ -180,10 +294,19 @@ binding.redInitCode.text = cardAddress ?: "" binding.userName.text = info.userName ?: "" binding.redCardNum.text = info.cardNum ?: "" - binding.redRemainderBlance.text = "${info.balance ?: 0} 鍏�" + + // 浣跨敤鐢ㄦ埛鍗′腑鐨勪綑棰濇樉绀� + val balance = userCard?.let { + // 灏嗗垎杞崲涓哄厓锛屼繚鐣欎袱浣嶅皬鏁� + String.format("%.2f", it.balance / 100.0) + } ?: run { + // 濡傛灉鐢ㄦ埛鍗′负绌猴紝鍒欎娇鐢ㄦ湇鍔″櫒杩斿洖鐨勪綑棰� + String.format("%.2f", info.balance ?: 0.0) + } + binding.redRemainderBlance.text = "$balance 鍏�" // 璁剧疆鍗$姸鎬佸拰瀵瑰簲棰滆壊 - val cardStatus = when (info.status) { + val cardStatus = when (info.state) { 1 -> "姝e父" 2 -> "鎸傚け" 3 -> "閿佸畾" @@ -193,7 +316,7 @@ binding.redStatu.text = cardStatus // 鏍规嵁鍗$姸鎬佽缃笉鍚岄鑹� - val statusColor = when (info.status) { + val statusColor = when (info.state) { 1 -> android.graphics.Color.parseColor("#4CAF50") // 缁胯壊-姝e父 2 -> android.graphics.Color.parseColor("#FF9800") // 姗欒壊-鎸傚け 3 -> android.graphics.Color.parseColor("#F44336") // 绾㈣壊-閿佸畾 @@ -203,7 +326,10 @@ } } - private fun handleWriteCard() { + /** + * 澶勭悊鍏呭�奸�昏緫 + */ + private fun handleRecharge() { // 楠岃瘉鍏呭�奸噾棰� val rechargeAmountStr = binding.rechargeMorny.text.toString().trim() if (rechargeAmountStr.isEmpty()) { @@ -235,20 +361,201 @@ 0.0 } - // 鏄剧ず纭淇℃伅 - val totalAmount = rechargeAmount + bonusAmount - val confirmMessage = """ - 纭鍏呭�间俊鎭細 - 鍗″彿锛�${cardAddress} - 鍏呭�奸噾棰濓細${rechargeAmount}鍏� - 璧犻�侀噾棰濓細${bonusAmount}鍏� - 鎬婚噾棰濓細${totalAmount}鍏� - 鏀粯鏂瑰紡锛�${paymentMethod} - """.trimIndent() + // 鑾峰彇褰撳墠浣欓锛堣浆鎹负鍏冿級 + val currentBalance = userCard?.let { + // 灏嗗垎杞崲涓哄厓 + it.balance / 100.0 + } ?: run { + // 濡傛灉鐢ㄦ埛鍗′负绌猴紝鍒欎娇鐢ㄦ湇鍔″櫒杩斿洖鐨勪綑棰� + cardInfo?.balance ?: 0.0 + } - ToastUtil.show(confirmMessage) + // 璁$畻鍏呭�煎悗鐨勬�讳綑棰� + val totalAmountAfterRecharge = currentBalance + rechargeAmount + bonusAmount - // TODO: 璋冪敤鍐欏崱API - // 杩欓噷鍙互娣诲姞瀹為檯鐨勫啓鍗¢�昏緫 + // 妫�鏌ユ槸鍚﹁秴杩囨渶澶т綑棰濋檺鍒�9999.99鍏� + if (totalAmountAfterRecharge > 9999.99) { + val maxRechargeAmount = 9999.99 - currentBalance + ToastUtil.show("鍏呭�煎け璐ワ細鍏呭�煎悗浣欓涓嶈兘瓒呰繃9999.99鍏僜n褰撳墠浣欓锛�${String.format("%.2f", currentBalance)}鍏僜n鏈�澶氬彲鍏呭�硷細${String.format("%.2f", maxRechargeAmount)}鍏�") + return + } + + // 璋冪敤鍏呭�兼帴鍙o紝浼犻�掑綋鍓嶄綑棰� + callRechargeApi(currentBalance, rechargeAmount, bonusAmount) + } + + /** + * 璋冪敤鍏呭�兼帴鍙� + */ + private fun callRechargeApi(currentBalance: Double, rechargeAmount: Double, bonusAmount: Double) { + val cardNum = cardInfo?.cardNum ?: cardAddress ?: "" + if (cardNum.isEmpty()) { + ToastUtil.show("鍗″彿淇℃伅缂哄け") + return + } + + // 楠岃瘉鏀粯鏂瑰紡鏄惁宸查�夋嫨锛屽鏋滀负绌哄垯閲嶆柊鑾峰彇鏀粯鏂瑰紡 + if (paymentId.isEmpty()) { + ToastUtil.show("鏀粯鏂瑰紡鏈姞杞斤紝姝e湪閲嶆柊鑾峰彇...") + // 閲嶆柊鑾峰彇鏀粯鏂瑰紡锛屾垚鍔熷悗鑷姩閲嶈瘯鍏呭�� + getPaymentMethodsAndRetryRecharge(currentBalance, rechargeAmount, bonusAmount) + return + } + + // 鑾峰彇姘翠环锛堝鏋滀负绌轰細鑷姩瑙﹀彂MainActivity鑾峰彇锛� + val currentWaterPrice = BaseApplication.requestWaterPrice() + + // 鎵撳嵃璋冭瘯淇℃伅 + android.util.Log.d("RechargeDetail", "鍏呭�煎弬鏁� - paymentMethod: $paymentMethod, paymentId: $paymentId") + android.util.Log.d("RechargeDetail", "瀛楁鍚箟 - money(褰撳墠浣欓): ${String.format("%.2f", currentBalance)}鍏�, amount(鍏呭�奸噾棰�): ${String.format("%.2f", rechargeAmount)}鍏�, gift(璧犻�侀噾棰�): ${String.format("%.2f", bonusAmount)}鍏�") + + // 鏋勫缓鍏呭�艰姹傚弬鏁� - 淇瀛楁鍚箟 + val rechargeRequest = RechargeRequest( + rechargeType = 2, + cardNum = cardNum, + money = String.format("%.2f", currentBalance), // money涓哄綋鍓嶅崱浣欓 + amount = String.format("%.2f", rechargeAmount), // amount涓哄厖鍊奸噾棰� + gift = String.format("%.2f", bonusAmount), // gift涓鸿禒閫侀噾棰� + paymentId = paymentId, + price = String.format("%.2f", currentWaterPrice), // 浣跨敤缁熶竴鑾峰彇鐨勬按浠� + remarks = "鍏呭��", + operator = BaseApplication.userId // 榛樿鎿嶄綔鍛業D锛屽彲浠ユ牴鎹疄闄呮儏鍐佃皟鏁� + ) + + // 杞崲涓篗ap鏍煎紡 + val params = mapOf( + "rechargeType" to rechargeRequest.rechargeType, + "cardNum" to rechargeRequest.cardNum, + "money" to rechargeRequest.money, + "amount" to rechargeRequest.amount, + "gift" to rechargeRequest.gift, + "paymentId" to rechargeRequest.paymentId, + "price" to rechargeRequest.price, + "remarks" to rechargeRequest.remarks, + "operator" to rechargeRequest.operator + ) + + ApiManager.getInstance().requestPostLoading( + this, + "terminal/card/termRecharge", + RechargeResult::class.java, + params, + object : SubscriberListener<BaseResponse<RechargeResult>>() { + override fun onNext(response: BaseResponse<RechargeResult>) { + if (response.success && response.code == "0001") { + // 鍏呭�兼垚鍔燂紝璺宠浆鍒板啓鍗$晫闈� + response.content?.let { rechargeResult -> + startWriteCardActivity(rechargeResult, rechargeAmount, bonusAmount) + } ?: run { + ToastUtil.show("鍏呭�兼垚鍔熶絾杩斿洖鏁版嵁涓虹┖") + } + } else { + ToastUtil.show("鍏呭�煎け璐�: ${response.msg ?: "鏈煡閿欒"}") + } + } + + override fun onError(e: Throwable?) { + super.onError(e) + ToastUtil.show("鍏呭�煎け璐�: ${e?.message ?: "缃戠粶寮傚父"}") + } + } + ) + } + + /** + * 閲嶆柊鑾峰彇鏀粯鏂瑰紡骞堕噸璇曞厖鍊� + */ + private fun getPaymentMethodsAndRetryRecharge(currentBalance: Double, rechargeAmount: Double, bonusAmount: Double) { + ApiManager.getInstance().requestGetLoading( + this, + "terminal/paymentmethod/get", + Any::class.java, + null, + object : SubscriberListener<BaseResponse<Any>>() { + override fun onNext(response: BaseResponse<Any>) { + if (response.success) { + try { + // 瀹夊叏鍦板鐞嗚繑鍥炵殑content锛屾湇鍔″櫒杩斿洖鐨勬槸ArrayList<LinkedHashMap> + val paymentMethods = mutableListOf<PaymentMethod>() + val content = response.content + + if (content is List<*>) { + content.forEach { item -> + if (item is Map<*, *>) { + val id = item["id"]?.toString() ?: "" + val name = item["name"]?.toString() ?: "" + if (id.isNotEmpty() && name.isNotEmpty()) { + paymentMethods.add(PaymentMethod(id, name)) + } + } + } + } + + if (paymentMethods.isNotEmpty()) { + paymentMethodList = paymentMethods + // 鏇存柊鏀粯鏂瑰紡鏄剧ず + updatePaymentMethodRadioGroup() + // 鏀粯鏂瑰紡鍔犺浇鎴愬姛鍚庯紝鑷姩閲嶈瘯鍏呭�� + ToastUtil.show("鏀粯鏂瑰紡鍔犺浇鎴愬姛锛屾鍦ㄩ噸璇曞厖鍊�...") + callRechargeApi(currentBalance, rechargeAmount, bonusAmount) + } else { + ToastUtil.show("鑾峰彇鏀粯鏂瑰紡澶辫触锛氳繑鍥炴暟鎹负绌�") + } + } catch (e: Exception) { + android.util.Log.e("RechargeDetail", "瑙f瀽鏀粯鏂瑰紡鏁版嵁澶辫触", e) + android.util.Log.e("RechargeDetail", "鍘熷鏁版嵁绫诲瀷: ${response.content?.javaClass?.name}") + android.util.Log.e("RechargeDetail", "鍘熷鏁版嵁鍐呭: ${response.content}") + ToastUtil.show("瑙f瀽鏀粯鏂瑰紡鏁版嵁澶辫触: ${e.message}") + } + } else { + ToastUtil.show("鑾峰彇鏀粯鏂瑰紡澶辫触: ${response.msg}") + } + } + + override fun onError(e: Throwable?) { + super.onError(e) + ToastUtil.show("鑾峰彇鏀粯鏂瑰紡澶辫触: ${e?.message ?: "缃戠粶寮傚父"}") + } + } + ) + } + + /** + * 鍚姩鍐欏崱鐣岄潰 + */ + private fun startWriteCardActivity( + rechargeResult: RechargeResult, + rechargeAmount: Double, + bonusAmount: Double + ) { + try { + // 鍒涘缓UserCard瀵硅薄鐢ㄤ簬鍐欏崱 + val userCard = UserCard().apply { + // 璁剧疆鐢ㄦ埛鍗′俊鎭� + cardInfo?.let { info -> + balance = MornyUtil.changeY2F(rechargeResult.balance) + } + + // 璁剧疆鍏朵粬蹇呰淇℃伅 + projectCode = rechargeResult.projectNo + waterPrice = MornyUtil.changeY2F(rechargeResult.waterPrice.toString()) + rechargeDate = java.util.Calendar.getInstance() + } + + // 鍚姩鍐欏崱Activity + val intent = Intent(this, NfcWreatActivity::class.java).apply { + putExtra("cardType", USER_CARD_TYPE_1) // 鐢ㄦ埛鍗$被鍨� + putExtra("cardAddr", cardAddress) + putExtra("operationTypeCode", CardOperationType.Recharge.code) + putExtra("orderNumber", rechargeResult.orderNo) + putExtra("userCard", userCard) + putExtra("rechargeAmount", rechargeAmount) // 浼犻�掑厖鍊奸噾棰� + putExtra("bonusAmount", bonusAmount) // 浼犻�掕禒閫侀噾棰� + } + startActivity(intent) + finish() + } catch (e: Exception) { + ToastUtil.show("鍚姩鍐欏崱鐣岄潰澶辫触: ${e.message}") + } } } \ No newline at end of file -- Gitblit v1.8.0