- 新增 getMemberDiscount 接口用于查询会员折扣 - 在人脸识别支付中集成会员折扣计算逻辑 - 将支付金额计算从 vipPrice 切换到 specPrice 并应用会员折扣 - 在初始化活动中添加设备配置获取功能 - 使用 ConstraintLayout 重构主餐品列表布局 - 添加 Timber 日志框架替换原有 Log 工具 - 重构 MainScreenPresentation 中的食物价格计算逻辑 - 移除重复的设备配置获取代码,统一在 InitActivity 中处理
375 lines
13 KiB
Kotlin
375 lines
13 KiB
Kotlin
package com.sw.dualscreen.activity
|
|
|
|
import androidx.activity.OnBackPressedCallback
|
|
import androidx.activity.viewModels
|
|
import androidx.fragment.app.Fragment
|
|
import com.sw.dualscreen.GlobalKey
|
|
import com.sw.dualscreen.R
|
|
import com.sw.dualscreen.activity.fragment.pay.CashPayFragment
|
|
import com.sw.dualscreen.activity.fragment.pay.FacePayFragment
|
|
import com.sw.dualscreen.activity.fragment.pay.NumberPayFragment
|
|
import com.sw.dualscreen.activity.fragment.pay.PayResultFragment
|
|
import com.sw.dualscreen.activity.fragment.pay.ScanQrCodePayFragment
|
|
import com.sw.dualscreen.databinding.ActivityPayBinding
|
|
import com.sw.dualscreen.ext.gone
|
|
import com.sw.dualscreen.model.response.FoodInfo
|
|
import com.sw.dualscreen.model.response.MemberInfo
|
|
import com.sw.dualscreen.model.response.PaySuccessEvent
|
|
import com.sw.dualscreen.presentation.pay.PayPresentation
|
|
import com.sw.dualscreen.utils.Debouncer
|
|
import com.sw.dualscreen.utils.SPUtil
|
|
import com.sw.dualscreen.utils.SoundPoolUtil
|
|
import com.sw.dualscreen.viewmodel.BaseViewModel
|
|
import com.sw.dualscreen.viewmodel.UserViewModel
|
|
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
|
import org.greenrobot.eventbus.EventBus
|
|
import timber.log.Timber
|
|
|
|
class PayActivity : BaseActivity<ActivityPayBinding>() {
|
|
|
|
companion object {
|
|
|
|
const val FOOD_INFO = "foodInfo"
|
|
const val TOTAL_AMOUNT = "totalAmount"
|
|
const val FOOD_ORDER_ID = "foodOrderId"
|
|
const val FOOD_EAT_NUM = "foodEatNum"
|
|
|
|
// const val MEMBER_INFO = "memberInfo"
|
|
const val TAG_PAY_QR_CODE = "tagPayQrCode"
|
|
const val TAG_PAY_CASH = "tagPayCash"
|
|
const val TAG_PAY_NUMBER = "tagPayNumber"
|
|
const val TAG_PAY_FACE = "tagPayFace"
|
|
const val TAG_PAY_RESULT = "tagPayResult"
|
|
const val PAY_SUCCESS = "pay_success"
|
|
}
|
|
|
|
val userViewModel by viewModels<UserViewModel>()
|
|
val recognizeViewModel by viewModels<RecognizeViewModel>()
|
|
|
|
override fun getViewModel(): BaseViewModel {
|
|
return userViewModel
|
|
}
|
|
|
|
override fun inflateViewBinding(): ActivityPayBinding {
|
|
return ActivityPayBinding.inflate(layoutInflater)
|
|
}
|
|
|
|
var foodInfo: FoodInfo? = null
|
|
|
|
// var totalAmount:Double = 0.0
|
|
private var qrCodePayFragment: ScanQrCodePayFragment? = null
|
|
private var cashPayFragment: CashPayFragment? = null
|
|
private var numberPayFragment: NumberPayFragment? = null
|
|
var facePayFragment: FacePayFragment? = null
|
|
private var payResultFragment: PayResultFragment? = null
|
|
|
|
var foodOrderId: String = ""
|
|
var eatNum: Int = 1
|
|
var isMember: Boolean = false
|
|
|
|
val presentation by lazy {
|
|
PayPresentation(
|
|
activity = this@PayActivity,
|
|
userViewModel = userViewModel,
|
|
recognizeViewModel = recognizeViewModel,
|
|
display = displays[1]
|
|
)
|
|
}
|
|
|
|
fun playSoundOnPaySuccess() {
|
|
SoundPoolUtil.getInstance().play(PAY_SUCCESS, 0)
|
|
}
|
|
|
|
@Suppress("DEPRECATION")
|
|
override fun initialize() {
|
|
super.initialize()
|
|
presentation.show()
|
|
registerKeyEvent()
|
|
addBackEventListener()
|
|
val soundMap = hashMapOf<String, Int>()
|
|
soundMap[PAY_SUCCESS] = R.raw.pay_success
|
|
SoundPoolUtil.getInstance().loadR(this, soundMap)
|
|
|
|
foodInfo = intent.getParcelableExtra(FOOD_INFO)
|
|
foodOrderId = intent.getStringExtra(FOOD_ORDER_ID) ?: ""
|
|
eatNum = intent.getIntExtra(FOOD_EAT_NUM, 1)
|
|
// totalAmount = intent.getDoubleExtra(TOTAL_AMOUNT,0.0)
|
|
// memberInfo = intent.getParcelableExtra(MEMBER_INFO)
|
|
binding.tvFoodName.text = foodInfo?.foodName
|
|
binding.include.ivPageBack.setOnClickListener { finish() }
|
|
binding.include.tvPageTitle.text = "下单结算"
|
|
binding.btnPayQrCode.setOnClickListener {
|
|
isMember = false
|
|
if (binding.btnPayQrCode.isChecked) {
|
|
return@setOnClickListener
|
|
}
|
|
showScanQrCodePay()
|
|
}
|
|
binding.btnPayCash.setOnClickListener {
|
|
isMember = false
|
|
if (binding.btnPayCash.isChecked) {
|
|
return@setOnClickListener
|
|
}
|
|
cashPayFragment = CashPayFragment()
|
|
showFragment(cashPayFragment!!, TAG_PAY_CASH)
|
|
switchButton(false, true, false, false)
|
|
}
|
|
binding.btnPayNumber.setOnClickListener {
|
|
if (binding.btnPayNumber.isChecked) {
|
|
return@setOnClickListener
|
|
}
|
|
numberPayFragment = NumberPayFragment()
|
|
showFragment(numberPayFragment!!, TAG_PAY_NUMBER)
|
|
switchButton(false, false, true, false)
|
|
}
|
|
binding.btnPayFace.setOnClickListener {
|
|
if (binding.btnPayFace.isChecked) {
|
|
return@setOnClickListener
|
|
}
|
|
showFacePay()
|
|
}
|
|
showScanQrCodePay()
|
|
}
|
|
|
|
private fun showScanQrCodePay() {
|
|
qrCodePayFragment = ScanQrCodePayFragment()
|
|
showFragment(qrCodePayFragment!!, TAG_PAY_QR_CODE)
|
|
switchButton(true, false, false, false)
|
|
}
|
|
|
|
private fun switchButton(vararg arr: Boolean) {
|
|
binding.btnPayQrCode.isChecked = arr[0]
|
|
binding.btnPayCash.isChecked = arr[1]
|
|
binding.btnPayNumber.isChecked = arr[2]
|
|
binding.btnPayFace.isChecked = arr[3]
|
|
}
|
|
|
|
fun showFacePay() {
|
|
facePayFragment = FacePayFragment()
|
|
showFragment(facePayFragment!!, TAG_PAY_FACE)
|
|
switchButton(false, false, false, true)
|
|
}
|
|
|
|
private fun showFragment(fragment: Fragment, tag: String) {
|
|
runCatching {
|
|
supportFragmentManager.beginTransaction().apply {
|
|
replace(R.id.fragmentContainerView, fragment)
|
|
commitNowAllowingStateLoss()
|
|
}
|
|
}.onFailure {
|
|
it.printStackTrace()
|
|
}
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
presentation.dismiss()
|
|
super.onDestroy()
|
|
}
|
|
|
|
var memberDiscount = 1.0
|
|
|
|
var memberInfo: MemberInfo? = null
|
|
fun showPayInfo(type: Int = 1, isVip: Boolean = false, memberInfo: MemberInfo? = null) {
|
|
this.memberInfo = memberInfo
|
|
payResultFragment = PayResultFragment.instance(type, memberInfo)
|
|
showFragment(payResultFragment!!, TAG_PAY_RESULT)
|
|
// if (displays.size > 1) {
|
|
// scanQrCodePayPresentation = ScanQrCodePayPresentation(
|
|
// activity = this,
|
|
// display = displays[1],
|
|
// type = type
|
|
// ) {
|
|
// scanQrCodePaypresentation.dismiss()
|
|
// }.also {
|
|
// it.foodName = foodInfo?.foodName
|
|
// //确认使用vipPrice 还是 specPrice
|
|
// val onePrice = if (isVip) foodInfo?.vipPrice else foodInfo?.specPrice
|
|
// it.totalPrice = (onePrice ?: 0.0) * eatNum
|
|
// }
|
|
// scanQrCodePaypresentation.show()
|
|
// }
|
|
presentation.let {
|
|
it.pageType = PayPresentation.QR_CODE_PAY
|
|
it.type = type
|
|
it.foodName = foodInfo?.foodName
|
|
//确认使用vipPrice 还是 specPrice
|
|
//val onePrice = if (isVip) foodInfo?.vipPrice else foodInfo?.specPrice
|
|
if (isVip) {
|
|
userViewModel.getMemberDiscount(memberInfo?.faceUserId?:"") { discount ->
|
|
memberDiscount = if (discount == null) 1.0 else discount / 10
|
|
var onePrice = foodInfo?.specPrice ?: 0.0
|
|
onePrice = if (isVip) onePrice * memberDiscount else onePrice
|
|
it.totalPrice = onePrice * eatNum
|
|
presentation.initView()
|
|
}
|
|
} else {
|
|
it.totalPrice = (foodInfo?.specPrice ?: 0.0) * eatNum
|
|
presentation.initView()
|
|
}
|
|
}
|
|
}
|
|
|
|
fun updateQrCodeImage(qrCodeUrl: String?) {
|
|
// scanQrCodePaypresentation.loadQrCodeImage(qrCodeUrl)
|
|
presentation.loadQrCodeImage(qrCodeUrl)
|
|
}
|
|
|
|
private var debouncer = Debouncer(5000)
|
|
|
|
fun showPaySuccess(isVip: Boolean) {
|
|
debouncer.debounce {
|
|
playSoundOnPaySuccess()
|
|
EventBus.getDefault().post(PaySuccessEvent())
|
|
showPayInfo(type = 2, isVip = isVip, memberInfo = memberInfo)
|
|
hidePayTab()
|
|
}
|
|
}
|
|
|
|
fun getQrCodeImg(
|
|
orderId: String,
|
|
userId: String? = null,
|
|
totalFee: String? = null,
|
|
block: (String?) -> Unit
|
|
) {
|
|
userViewModel.getQrCodeImg(
|
|
orderId = orderId,
|
|
userId = userId,
|
|
totalFee = totalFee
|
|
) { qrCodeImg ->
|
|
runOnUiThread {
|
|
if (qrCodeImg.isNullOrBlank()) {
|
|
//ToastUtils.showToast("获取二维码失败")
|
|
return@runOnUiThread
|
|
}
|
|
block(qrCodeImg)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun cashPay(param: HashMap<String, String>, block: (Boolean) -> Unit) {
|
|
userViewModel.cashPay(param) {
|
|
runOnUiThread {
|
|
block(it)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun memberPay(param: HashMap<String, String?>, block: () -> Unit) {
|
|
userViewModel.memberPay(param) {
|
|
runOnUiThread {
|
|
if (it.not()) {
|
|
//ToastUtils.showToast("支付失败,请稍后重试")
|
|
return@runOnUiThread
|
|
}
|
|
block()
|
|
}
|
|
}
|
|
}
|
|
|
|
suspend fun queryOrderState(block: (Boolean) -> Unit) {
|
|
userViewModel.queryOrderState(orderId = foodOrderId) { payResult ->
|
|
runOnUiThread {
|
|
if (payResult) {
|
|
block(true)
|
|
} else {
|
|
block(false)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun hidePayTab() {
|
|
binding.llPayTab.gone()
|
|
}
|
|
|
|
fun getMemberInfoByPhone(phone: String, key: String, block: (MemberInfo?) -> Unit) {
|
|
userViewModel.getMemberInfoByPhone(phone, key) { memberInfo ->
|
|
runOnUiThread {
|
|
block(memberInfo)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun getMemberInfoById(userId: String, block: (MemberInfo?) -> Unit) {
|
|
userViewModel.getMemberInfoById(memberId = userId) { memberInfo ->
|
|
runOnUiThread {
|
|
block(memberInfo)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun bindOrder(userId: String, block: (Boolean) -> Unit) {
|
|
//0-即放即取,1-余量计量
|
|
val pickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0)
|
|
val mode = if (pickupMode == 1) 1 else 2
|
|
userViewModel.bindOrder(userId, foodOrderId, mode = mode) { bindResult ->
|
|
runOnUiThread {
|
|
block(bindResult)
|
|
}
|
|
}
|
|
}
|
|
|
|
fun qrCodePay(scanInfo: String) {
|
|
showWaitingDialog("支付中……")
|
|
userViewModel.qrCodePay(scanInfo, foodOrderId, memberInfo?.id) { payState, backData ->
|
|
Timber.d("qrCodePay支付返回数据:state=$payState,backData=$backData")
|
|
hideWaitingDialog()
|
|
if (payState) {
|
|
showPaySuccess(isMember)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// fun bindOrder(userId: String, block: () -> Unit) {
|
|
// val pickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0)
|
|
// val mode = if (pickupMode == 1) 1 else 2
|
|
// userViewModel.bindOrder(userId, foodOrderId, mode = mode) { bindResult ->
|
|
// runOnUiThread {
|
|
// if (bindResult.not()) {
|
|
// hideWaitingDialog()
|
|
// //ToastUtils.showToast("订单绑定失败")
|
|
// return@runOnUiThread
|
|
// }
|
|
// binding.root.postDelayed({
|
|
// hideWaitingDialog()
|
|
// showPayInfo(type = 1, isVip = true, memberInfo = memberInfo)
|
|
// hidePayTab()
|
|
// block()
|
|
// }, 1000)
|
|
// }
|
|
// }
|
|
// }
|
|
// fun getMemberInfoByPhone(phone: String, key: String, block: (MemberInfo) -> Unit) {
|
|
// userViewModel.getMemberInfoByPhone(phone, key) { memberInfo ->
|
|
// runOnUiThread {
|
|
// if (memberInfo == null) {
|
|
// hideWaitingDialog()
|
|
// //ToastUtils.showToast("查询会员信息失败,请稍后重试")
|
|
// return@runOnUiThread
|
|
// }
|
|
// block(memberInfo)
|
|
// }
|
|
// }
|
|
// }
|
|
// fun getMemberInfo(userId: String, block: (MemberInfo) -> Unit) {
|
|
// userViewModel.getMemberInfoById(memberId = userId) { memberInfo ->
|
|
// runOnUiThread {
|
|
// if (memberInfo == null) {
|
|
// hideWaitingDialog()
|
|
// //ToastUtils.showToast("查询会员信息失败,请稍后重试")
|
|
// return@runOnUiThread
|
|
// }
|
|
// block(memberInfo)
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
fun addBackEventListener() {
|
|
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
|
override fun handleOnBackPressed() {
|
|
|
|
}
|
|
})
|
|
}
|
|
} |