From 5edfd12deb166302708857515a833d1471a0f208 Mon Sep 17 00:00:00 2001 From: zuoxiao <lf_zuo@163.com> Date: 星期三, 25 六月 2025 16:15:23 +0800 Subject: [PATCH] feat(database): 增加管理卡相关功能并优化数据库结构- 新增 ManagerCardBean 数据类用于管理卡信息 - 在 AppDataBase 中添加 ManagerCardDao 接口 - 实现管理卡的数据库迁移策略 - 优化支付方式 ID 类型,从 Long改为 String - 重构更新写卡和上报状态的逻辑,支持管理卡和用户卡 --- generallibrary/src/main/java/com/dayu/general/activity/MainActivity.kt | 346 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 342 insertions(+), 4 deletions(-) diff --git a/generallibrary/src/main/java/com/dayu/general/activity/MainActivity.kt b/generallibrary/src/main/java/com/dayu/general/activity/MainActivity.kt index d30a700..9c52341 100644 --- a/generallibrary/src/main/java/com/dayu/general/activity/MainActivity.kt +++ b/generallibrary/src/main/java/com/dayu/general/activity/MainActivity.kt @@ -1,28 +1,366 @@ package com.dayu.general.activity +import android.content.Intent import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.KeyEvent +import android.view.LayoutInflater +import android.widget.Toast +import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope +import com.dayu.baselibrary.net.subscribers.SubscriberListener +import com.dayu.baselibrary.utils.ToastUtil +import com.dayu.general.BaseApplication +import com.dayu.general.R +import com.dayu.general.adapter.TabAdapter +import com.dayu.general.bean.net.UserInfoResult +import com.dayu.general.bean.net.WaterPriceResult +import com.dayu.general.dao.BaseDaoSingleton +import com.dayu.general.databinding.ActivityMainBinding +import com.dayu.general.net.ApiManager +import com.dayu.general.net.BaseResponse +import com.dayu.general.tool.CardOperationType +import com.tencent.bugly.crashreport.CrashReport +import kotlinx.coroutines.launch -class MainActivity : BaseActivity(){ +class MainActivity : BaseNfcActivity() { - + var binding: ActivityMainBinding? = null private val fragments: ArrayList<Fragment> = ArrayList() + var mExitTime: Long = 0 + private val handler = Handler(Looper.getMainLooper()) + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setupFragments(); + binding = ActivityMainBinding.inflate(LayoutInflater.from(this)) + setContentView(binding?.root) + + // 娉ㄥ唽MainActivity瀹炰緥鍒癇aseApplication + BaseApplication.setMainActivity(this) + + setupFragments() + initView() + initTab() + getUserInfo() + + // 寤舵椂20绉掑悗鑾峰彇姘翠环 + handler.postDelayed({ + getWaterPriceFromActivity() + }, 20000) // 20绉掑欢鏃� + } + + override fun onDestroy() { + super.onDestroy() + // 娓呯悊Handler鍥炶皟锛岄槻姝㈠唴瀛樻硠婕� + handler.removeCallbacksAndMessages(null) + // 娓呯悊BaseApplication涓殑MainActivity寮曠敤 + BaseApplication.setMainActivity(null) + } + + override fun onNfcBack(intent: Intent) { + intent.let { nfcIntent -> + // 鑾峰彇褰撳墠鏄剧ず鐨凢ragment + val currentFragment = fragments[binding?.viewPager?.currentItem ?: 0] + + // 濡傛灉褰撳墠鏄剧ず鐨勬槸鍏呭�糉ragment锛屽垯灏哊FC淇℃伅浼犻�掔粰瀹冨鐞� + if (currentFragment is RechargeFragment) { + currentFragment.handleNfcIntent(nfcIntent) + } + } + } + + /** + * 鑾峰彇姘翠环淇℃伅 - 鍏紑鏂规硶渚涘叾浠栧湴鏂硅皟鐢� + */ + fun getWaterPriceFromActivity() { + // 濡傛灉姘翠环宸插瓨鍦ㄤ笖澶т簬0锛屽垯涓嶉噸澶嶈幏鍙� + if (BaseApplication.waterPrice > 0.0) { + return + } + + ApiManager.getInstance().requestGetHideLoading( + this, + "terminal/client/getWaterPrice", + WaterPriceResult::class.java, + null, + object : SubscriberListener<BaseResponse<WaterPriceResult>>() { + override fun onNext(response: BaseResponse<WaterPriceResult>) { + if (response.success && response.code == "0001") { + // 鑾峰彇姘翠环鎴愬姛锛屼繚瀛樺埌BaseApplication + response.content?.let { waterPriceResult -> + BaseApplication.waterPrice = waterPriceResult.price + } + } + } + + override fun onError(e: Throwable?) { + super.onError(e) + // 缃戠粶寮傚父鏃朵笉鏄剧ず閿欒淇℃伅锛岄伩鍏嶅奖鍝嶇敤鎴蜂綋楠� + } + } + ) + } + + private fun getUserInfo() { + // 浣跨敤姝g‘鐨勭被鍨嬪弬鏁� + ApiManager.getInstance().requestGetLoading( + this, + "base/user/getUserInfos/" + BaseApplication.userId, + UserInfoResult::class.java, + null, + object : SubscriberListener<BaseResponse<UserInfoResult>>() { + override fun onNext(t: BaseResponse<UserInfoResult>) { + if (t.success) { + BaseApplication.userName = t.content?.userName ?: "" + BaseApplication.userPhone = t.content?.phone ?: "" + BaseApplication.blockName = t.content?.blockName ?: "" + } else { + // 澶勭悊鎼滅储澶辫触鐨勬儏鍐� + ToastUtil.show(t.msg) + } + } + + override fun onError(e: Throwable?) { + super.onError(e) + ToastUtil.show("鎼滅储澶辫触: ${e?.message ?: "鏈煡閿欒"}") + } + } + ) } + private fun initView() { + binding!!.BSCardLL.setOnClickListener { changeBottomState(Tab.BSC) } + binding!!.myLL.setOnClickListener { changeBottomState(Tab.MY) } + binding!!.rechargeLL.setOnClickListener { changeBottomState(Tab.RECHARGE) } + } private fun setupFragments() { fragments.add(BSCardFragment()) fragments.add(RechargeFragment()) - fragments.add(BSCardFragment()) + fragments.add(MyFragment()) } + private fun initTab() { + binding?.viewPager?.adapter = TabAdapter(this, fragments) + binding?.viewPager?.currentItem = (1) + binding?.viewPager?.offscreenPageLimit = 3 + binding?.viewPager?.isUserInputEnabled = false + } + private enum class Tab { + BSC, RECHARGE, MY + } + /** + * 淇敼搴曢儴鐘舵�� + */ + private fun changeBottomState(tab: Tab) { + resetTabState() + when (tab) { + Tab.BSC -> updateTabUI(0, R.drawable.bottom_card_white, R.color.white) + Tab.RECHARGE -> updateTabUI(1, R.drawable.bottom_recharge_white, R.color.white) + Tab.MY -> updateTabUI(2, R.drawable.bottom_my_white, R.color.white) + } + } + /** + * 閲嶇疆鎵�鏈� Tab 鐨勯粯璁ょ姸鎬� + */ + private fun resetTabState() { + binding!!.BSCardImg.setImageDrawable( + ContextCompat.getDrawable( + this, + R.drawable.bottom_card_black + ) + ) + binding!!.BSCardText.setTextColor(ContextCompat.getColor(this, R.color.black)) + binding!!.rechargeImg.setImageDrawable( + ContextCompat.getDrawable( + this, + R.drawable.bottom_recharge_black + ) + ) + binding!!.rechargeText.setTextColor(ContextCompat.getColor(this, R.color.black)) + + binding!!.myImg.setImageDrawable( + ContextCompat.getDrawable( + this, + R.drawable.bottom_my_black + ) + ) + binding!!.myText.setTextColor(ContextCompat.getColor(this, R.color.black)) + } + + /** + * 鏇存柊鏌愪釜 Tab 鐨� UI 鐘舵�� + */ + private fun updateTabUI(position: Int, iconResId: Int, textColorResId: Int) { + if (position == 1) { + binding!!.viewPager.setCurrentItem(position, true) + } else { + binding!!.viewPager.setCurrentItem(position, false) + } + when (position) { + 0 -> { + binding!!.BSCardImg.setImageDrawable(ContextCompat.getDrawable(this, iconResId)) + binding!!.BSCardText.setTextColor(ContextCompat.getColor(this, textColorResId)) + } + + 1 -> { + binding!!.rechargeImg.setImageDrawable(ContextCompat.getDrawable(this, iconResId)) + binding!!.rechargeText.setTextColor(ContextCompat.getColor(this, textColorResId)) + } + + 2 -> { + binding!!.myImg.setImageDrawable(ContextCompat.getDrawable(this, iconResId)) + binding!!.myText.setTextColor(ContextCompat.getColor(this, textColorResId)) + } + } + } + + //鐐瑰嚮涓ゆ閫�鍑虹▼搴� 鏈夋椂闂撮棿闅� 闂撮殧鍐呯偣鍑诲垯閫�鍑虹▼搴� 鍚﹀垯 鍒欐彁绀� + override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if ((System.currentTimeMillis() - mExitTime) > 2000) { + Toast.makeText(this@MainActivity, "鍐嶆寜涓�娆¢��鍑虹▼搴�", Toast.LENGTH_SHORT) + .show() + mExitTime = System.currentTimeMillis() + } else { + this@MainActivity.finish() + } + return true + } + return super.onKeyDown(keyCode, event) + } + + /** + * 鍚戞湇鍔″櫒涓婃姤鍐欏崱鎿嶄綔缁撴灉 + * 鍐欏崱鎴愬姛鍚庤皟鐢ㄦ鏂规硶閫氱煡鏈嶅姟鍣ㄦ搷浣滃畬鎴愶紝鎴愬姛鍚庢洿鏂版湰鍦版暟鎹簱isReported涓簍rue + * + * @param cardAddr 鍗″湴鍧�/鍗″彿 + * @param operationTypeCode 鎿嶄綔绫诲瀷浠g爜 + * @param orderNumber 璁㈠崟鍙� + * @param regionNumber 鍖哄煙鍙� + * @param projectNumber 椤圭洰鍙� + */ + fun postCardData( + cardAddr: String, + operationTypeCode: Int, + orderNumber: String = "", + regionNumber: String = "", + projectNumber: String = "" + ) { + val map = mutableMapOf<String, Any>() + + // 娣诲姞鍗″湴鍧�鍙傛暟 + if (cardAddr.isNotEmpty()) { + map["cardAddr"] = cardAddr + } + + // 娣诲姞鎿嶄綔绫诲瀷鍙傛暟 + // 鍒ゆ柇鏄惁涓虹鐞嗗崱鍒朵綔鎿嶄綔绫诲瀷锛�100-108锛夛紝濡傛灉鏄垯浼犻�扢ANAGEMENT_CARD_WRITE鐨勫�硷紙7锛� + val operateTypeToSend = if (operationTypeCode in 100..108) { + CardOperationType.MANAGEMENT_CARD_WRITE.code + } else { + operationTypeCode + } + map["operateType"] = operateTypeToSend + + // 娣诲姞璁㈠崟鍙峰弬鏁帮紙濡傛灉瀛樺湪锛� + if (orderNumber.isNotEmpty()) { + map["orderNumber"] = orderNumber + } + + // 娣诲姞鍖哄煙鍙峰拰椤圭洰鍙峰弬鏁� + if (regionNumber.isNotEmpty()) { + map["regionNumber"] = regionNumber + } + if (projectNumber.isNotEmpty()) { + map["projectNumber"] = projectNumber + } + + // 璋冪敤鏈嶅姟鍣ㄦ帴鍙d笂鎶ユ搷浣滅粨鏋� + ApiManager.getInstance().requestPostHideLoading( + this, + "terminal/card/termCallBack", // 缁堢鍐欏崱鍥炶皟鎺ュ彛 + String::class.java, + map, + object : SubscriberListener<BaseResponse<String>>() { + override fun onNext(t: BaseResponse<String>) { + if (t.success) { + // 涓婃姤鎴愬姛锛屾洿鏂版湰鍦版暟鎹簱isReported涓簍rue + updateCardReportedStatus(cardAddr, orderNumber, operationTypeCode) + } else { + // 涓婃姤澶辫触锛岃褰曢敊璇絾涓嶅奖鍝嶇敤鎴锋搷浣� + CrashReport.postCatchedException(Exception("涓婃姤鍐欏崱缁撴灉澶辫触: ${t.msg}")) + } + } + + override fun onError(e: Throwable?) { + super.onError(e) + // 缃戠粶閿欒锛岃褰曢敊璇絾涓嶅奖鍝嶇敤鎴锋搷浣� + CrashReport.postCatchedException(e ?: Exception("涓婃姤鍐欏崱缁撴灉缃戠粶閿欒")) + } + } + ) + } + + /** + * 鏇存柊鏈湴鏁版嵁搴撲腑鐨勪笂鎶ョ姸鎬� + * 鏍规嵁鎿嶄綔绫诲瀷鍒ゆ柇鏄洿鏂癕anagerCardBean杩樻槸CardRegistrationBean鐨刬sReported鐘舵�佷负true + * + * @param cardNumber 鍗″彿 + * @param orderNumber 璁㈠崟鍙� + * @param operationTypeCode 鎿嶄綔绫诲瀷浠g爜 + */ + private fun updateCardReportedStatus(cardNumber: String, orderNumber: String = "", operationTypeCode: Int = -1) { + lifecycleScope.launch { + try { + val baseDaoSingleton = BaseDaoSingleton.getInstance(this@MainActivity) + + // 鏍规嵁鎿嶄綔绫诲瀷鍒ゆ柇鏄鐞嗗崱杩樻槸鐢ㄦ埛鍗℃搷浣� + val isManagerCardOperation = operationTypeCode in 100..108 + + if (isManagerCardOperation) { + // 绠$悊鍗″埗浣滄搷浣滅被鍨嬶紝鏌ヨ鍜屾洿鏂癕anagerCardBean + val managerCardDao = baseDaoSingleton.managerCardDao() + val managerCard = if (orderNumber.isNotEmpty()) { + managerCardDao.getByOrderId(orderNumber) + } else { + managerCardDao.getByCardAddress(cardNumber) + } + + if (managerCard != null) { + val updatedManagerCard = managerCard.copy(isReported = true) + managerCardDao.update(updatedManagerCard) + } + } else { + // 鐢ㄦ埛鍗℃搷浣滅被鍨嬶紝鏌ヨ鍜屾洿鏂癈ardRegistrationBean + val cardRegistrationDao = baseDaoSingleton.cardRegistrationDao() + val cardRegistration = if (orderNumber.isNotEmpty()) { + cardRegistrationDao.getByOrderId(orderNumber) + } else { + // 濡傛灉娌℃湁璁㈠崟鍙凤紝鍒欓�氳繃鍗″彿鏌ユ壘 + cardRegistrationDao.getByCardNumber(cardNumber) + } + + if (cardRegistration != null) { + // 鍒涘缓鏇存柊鍚庣殑CardRegistrationBean瀵硅薄锛屽皢isReported璁剧疆涓簍rue + val updatedCardRegistration = cardRegistration.copy(isReported = true) + // 鏇存柊鏁版嵁搴撹褰� + cardRegistrationDao.update(updatedCardRegistration) + } + } + } catch (e: Exception) { + // 璁板綍寮傚父淇℃伅锛屼絾涓嶅奖鍝嶇敤鎴锋搷浣� + CrashReport.postCatchedException(e) + e.printStackTrace() + } + } + } } \ No newline at end of file -- Gitblit v1.8.0