支付页面统一副屏逻辑
This commit is contained in:
@@ -14,11 +14,10 @@ import com.sw.dualscreen.ext.gone
|
|||||||
import com.sw.dualscreen.model.response.FoodInfo
|
import com.sw.dualscreen.model.response.FoodInfo
|
||||||
import com.sw.dualscreen.model.response.MemberInfo
|
import com.sw.dualscreen.model.response.MemberInfo
|
||||||
import com.sw.dualscreen.model.response.PaySuccessEvent
|
import com.sw.dualscreen.model.response.PaySuccessEvent
|
||||||
import com.sw.dualscreen.presentation.pay.ScanQrCodePayPresentation
|
import com.sw.dualscreen.presentation.pay.PayPresentation
|
||||||
import com.sw.dualscreen.utils.SPUtil
|
import com.sw.dualscreen.utils.SPUtil
|
||||||
import com.sw.dualscreen.viewmodel.BaseViewModel
|
import com.sw.dualscreen.viewmodel.BaseViewModel
|
||||||
import com.sw.dualscreen.viewmodel.UserViewModel
|
import com.sw.dualscreen.viewmodel.UserViewModel
|
||||||
import com.sw.plate.utils.ToastUtils
|
|
||||||
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
|
||||||
@@ -62,9 +61,19 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
|
|||||||
var foodOrderId: String = ""
|
var foodOrderId: String = ""
|
||||||
var eatNum: Int = 1
|
var eatNum: Int = 1
|
||||||
|
|
||||||
|
val presentation by lazy {
|
||||||
|
PayPresentation(
|
||||||
|
activity = this@PayActivity,
|
||||||
|
userViewModel = userViewModel,
|
||||||
|
recognizeViewModel = recognizeViewModel,
|
||||||
|
display = displays[1]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
override fun initialize() {
|
override fun initialize() {
|
||||||
super.initialize()
|
super.initialize()
|
||||||
|
presentation.show()
|
||||||
foodInfo = intent.getParcelableExtra(FOOD_INFO)
|
foodInfo = intent.getParcelableExtra(FOOD_INFO)
|
||||||
foodOrderId = intent.getStringExtra(FOOD_ORDER_ID) ?: ""
|
foodOrderId = intent.getStringExtra(FOOD_ORDER_ID) ?: ""
|
||||||
eatNum = intent.getIntExtra(FOOD_EAT_NUM, 1)
|
eatNum = intent.getIntExtra(FOOD_EAT_NUM, 1)
|
||||||
@@ -101,7 +110,6 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
|
|||||||
}
|
}
|
||||||
showFacePay()
|
showFacePay()
|
||||||
}
|
}
|
||||||
|
|
||||||
showScanQrCodePay()
|
showScanQrCodePay()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,39 +144,43 @@ class PayActivity : BaseActivity<ActivityPayBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
qrCodePayFragment?.presentation?.dismiss()
|
presentation?.dismiss()
|
||||||
cashPayFragment?.presentation?.dismiss()
|
|
||||||
numberPayFragment?.presentation?.dismiss()
|
|
||||||
facePayFragment?.presentation?.dismiss()
|
|
||||||
scanQrCodePayPresentation?.dismiss()
|
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var scanQrCodePayPresentation: ScanQrCodePayPresentation? = null
|
|
||||||
var memberInfo: MemberInfo? = null
|
var memberInfo: MemberInfo? = null
|
||||||
fun showPayInfo(type: Int = 1, isVip: Boolean = false, memberInfo: MemberInfo? = null) {
|
fun showPayInfo(type: Int = 1, isVip: Boolean = false, memberInfo: MemberInfo? = null) {
|
||||||
this.memberInfo = memberInfo
|
this.memberInfo = memberInfo
|
||||||
payResultFragment = PayResultFragment.instance(type, memberInfo)
|
payResultFragment = PayResultFragment.instance(type, memberInfo)
|
||||||
showFragment(payResultFragment!!, TAG_PAY_RESULT)
|
showFragment(payResultFragment!!, TAG_PAY_RESULT)
|
||||||
if (displays.size > 1) {
|
// if (displays.size > 1) {
|
||||||
scanQrCodePayPresentation = ScanQrCodePayPresentation(
|
// scanQrCodePayPresentation = ScanQrCodePayPresentation(
|
||||||
activity = this,
|
// activity = this,
|
||||||
display = displays[1],
|
// display = displays[1],
|
||||||
type = type
|
// type = type
|
||||||
) {
|
// ) {
|
||||||
scanQrCodePayPresentation?.dismiss()
|
// scanQrCodePayPresentation?.dismiss()
|
||||||
}.also {
|
// }.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.type = type
|
||||||
it.foodName = foodInfo?.foodName
|
it.foodName = foodInfo?.foodName
|
||||||
//确认使用vipPrice 还是 specPrice
|
//确认使用vipPrice 还是 specPrice
|
||||||
val onePrice = if (isVip) foodInfo?.vipPrice else foodInfo?.specPrice
|
val onePrice = if (isVip) foodInfo?.vipPrice else foodInfo?.specPrice
|
||||||
it.totalPrice = (onePrice ?: 0.0) * eatNum
|
it.totalPrice = (onePrice ?: 0.0) * eatNum
|
||||||
}
|
presentation.initView()
|
||||||
scanQrCodePayPresentation?.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateQrCodeImage(qrCodeUrl: String?) {
|
fun updateQrCodeImage(qrCodeUrl: String?) {
|
||||||
scanQrCodePayPresentation?.loadQrCodeImage(qrCodeUrl)
|
// scanQrCodePayPresentation?.loadQrCodeImage(qrCodeUrl)
|
||||||
|
presentation?.loadQrCodeImage(qrCodeUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showPaySuccess(isVip: Boolean) {
|
fun showPaySuccess(isVip: Boolean) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.sw.dualscreen.activity.PayActivity
|
|||||||
import com.sw.dualscreen.activity.fragment.BaseFragment
|
import com.sw.dualscreen.activity.fragment.BaseFragment
|
||||||
import com.sw.dualscreen.databinding.FragmentCashPayBinding
|
import com.sw.dualscreen.databinding.FragmentCashPayBinding
|
||||||
import com.sw.dualscreen.ext.format2String
|
import com.sw.dualscreen.ext.format2String
|
||||||
import com.sw.dualscreen.presentation.pay.CashPayPresentation
|
import com.sw.dualscreen.presentation.pay.PayPresentation
|
||||||
import com.sw.plate.utils.ToastUtils
|
import com.sw.plate.utils.ToastUtils
|
||||||
|
|
||||||
class CashPayFragment : BaseFragment<FragmentCashPayBinding>() {
|
class CashPayFragment : BaseFragment<FragmentCashPayBinding>() {
|
||||||
@@ -17,8 +17,6 @@ class CashPayFragment : BaseFragment<FragmentCashPayBinding>() {
|
|||||||
private var foodName: String? = null
|
private var foodName: String? = null
|
||||||
private var payAmount: Double? = null
|
private var payAmount: Double? = null
|
||||||
|
|
||||||
var presentation: CashPayPresentation? = null
|
|
||||||
|
|
||||||
override fun inflateViewBinding(): FragmentCashPayBinding {
|
override fun inflateViewBinding(): FragmentCashPayBinding {
|
||||||
return FragmentCashPayBinding.inflate(layoutInflater)
|
return FragmentCashPayBinding.inflate(layoutInflater)
|
||||||
}
|
}
|
||||||
@@ -32,7 +30,8 @@ class CashPayFragment : BaseFragment<FragmentCashPayBinding>() {
|
|||||||
binding.tvRealAmount.text = getAmountText(payAmount.format2String(2))
|
binding.tvRealAmount.text = getAmountText(payAmount.format2String(2))
|
||||||
|
|
||||||
binding.btnConfirmPayFinish.setOnClickListener {
|
binding.btnConfirmPayFinish.setOnClickListener {
|
||||||
payActivity.cashPay(hashMapOf(
|
payActivity.cashPay(
|
||||||
|
hashMapOf(
|
||||||
//标价金额(单位为元)
|
//标价金额(单位为元)
|
||||||
"totalFee" to payAmount.format2String(2),
|
"totalFee" to payAmount.format2String(2),
|
||||||
//订单类型(0付款1会员充值)
|
//订单类型(0付款1会员充值)
|
||||||
@@ -41,7 +40,8 @@ class CashPayFragment : BaseFragment<FragmentCashPayBinding>() {
|
|||||||
"orderNo" to payActivity.foodOrderId,
|
"orderNo" to payActivity.foodOrderId,
|
||||||
//支付来源:0线下收款 、3:线上纯会员支付 101:支付宝主动、102:支付宝被动、201:微信主动、202:微信被动
|
//支付来源:0线下收款 、3:线上纯会员支付 101:支付宝主动、102:支付宝被动、201:微信主动、202:微信被动
|
||||||
"paySource" to "0"
|
"paySource" to "0"
|
||||||
)) { paySuccess ->
|
)
|
||||||
|
) { paySuccess ->
|
||||||
if (paySuccess.not()) {
|
if (paySuccess.not()) {
|
||||||
ToastUtils.showToast("接口调用失败")
|
ToastUtils.showToast("接口调用失败")
|
||||||
return@cashPay
|
return@cashPay
|
||||||
@@ -51,39 +51,47 @@ class CashPayFragment : BaseFragment<FragmentCashPayBinding>() {
|
|||||||
}
|
}
|
||||||
showSubScreen()
|
showSubScreen()
|
||||||
}
|
}
|
||||||
override fun onHiddenChanged(hidden: Boolean) {
|
|
||||||
super.onHiddenChanged(hidden)
|
|
||||||
if (hidden) {
|
|
||||||
dismissSubScreen()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
//showSubScreen()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
// override fun onHiddenChanged(hidden: Boolean) {
|
||||||
dismissSubScreen()
|
// super.onHiddenChanged(hidden)
|
||||||
super.onDestroy()
|
// if (hidden) {
|
||||||
}
|
// dismissSubScreen()
|
||||||
|
// return
|
||||||
private fun dismissSubScreen() {
|
// }
|
||||||
presentation?.let {
|
// //showSubScreen()
|
||||||
if (it.isShowing) {
|
// }
|
||||||
it.dismiss()
|
//
|
||||||
}
|
// override fun onDestroy() {
|
||||||
}
|
// dismissSubScreen()
|
||||||
}
|
// super.onDestroy()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private fun dismissSubScreen() {
|
||||||
|
// }
|
||||||
|
|
||||||
private fun showSubScreen() {
|
private fun showSubScreen() {
|
||||||
// 查找副屏(通常索引为1)
|
// // 查找副屏(通常索引为1)
|
||||||
if (displays.size > 1) {
|
// if (displays.size > 1) {
|
||||||
dismissSubScreen()
|
// dismissSubScreen()
|
||||||
presentation = CashPayPresentation(activity = payActivity, display = displays[1]) {
|
// presentation = PayPresentation(
|
||||||
presentation?.dismiss()
|
// activity = payActivity,
|
||||||
}.also {
|
// pageType = PayPresentation.CASH_PAY,
|
||||||
|
// userViewModel = payActivity.userViewModel,
|
||||||
|
// recognizeViewModel = payActivity.recognizeViewModel,
|
||||||
|
// display = displays[1]
|
||||||
|
// ) {
|
||||||
|
// presentation?.dismiss()
|
||||||
|
// }.also {
|
||||||
|
// it.foodName = foodName
|
||||||
|
// it.payAmount = payAmount.format2String(2)
|
||||||
|
// }
|
||||||
|
// presentation?.show()
|
||||||
|
// }
|
||||||
|
payActivity.presentation.let {
|
||||||
|
it.pageType = PayPresentation.CASH_PAY
|
||||||
it.foodName = foodName
|
it.foodName = foodName
|
||||||
it.payAmount = payAmount.format2String(2)
|
it.payAmount = payAmount.format2String(2)
|
||||||
}
|
it.initView()
|
||||||
presentation?.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,13 @@ import com.sw.dualscreen.activity.PayActivity
|
|||||||
import com.sw.dualscreen.activity.fragment.BaseFragment
|
import com.sw.dualscreen.activity.fragment.BaseFragment
|
||||||
import com.sw.dualscreen.databinding.FragmentFacePayBinding
|
import com.sw.dualscreen.databinding.FragmentFacePayBinding
|
||||||
import com.sw.dualscreen.ext.format2String
|
import com.sw.dualscreen.ext.format2String
|
||||||
import com.sw.dualscreen.presentation.pay.FacePayPresentation
|
import com.sw.dualscreen.presentation.pay.PayPresentation
|
||||||
|
|
||||||
class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
|
class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
|
||||||
|
|
||||||
private lateinit var payActivity: PayActivity
|
private lateinit var payActivity: PayActivity
|
||||||
private var foodName: String? = null
|
private var foodName: String? = null
|
||||||
private var payAmount: Double? = null
|
private var payAmount: Double? = null
|
||||||
var presentation: FacePayPresentation? = null
|
|
||||||
override fun inflateViewBinding(): FragmentFacePayBinding {
|
override fun inflateViewBinding(): FragmentFacePayBinding {
|
||||||
return FragmentFacePayBinding.inflate(layoutInflater)
|
return FragmentFacePayBinding.inflate(layoutInflater)
|
||||||
}
|
}
|
||||||
@@ -32,24 +31,26 @@ class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
|
|||||||
override fun onHiddenChanged(hidden: Boolean) {
|
override fun onHiddenChanged(hidden: Boolean) {
|
||||||
super.onHiddenChanged(hidden)
|
super.onHiddenChanged(hidden)
|
||||||
if (hidden) {
|
if (hidden) {
|
||||||
dismissSubScreen()
|
// dismissSubScreen()
|
||||||
|
payActivity.presentation.pauseCamera()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
payActivity.presentation.resumeCamera()
|
||||||
//showSubScreen()
|
//showSubScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
// override fun onDestroy() {
|
||||||
dismissSubScreen()
|
// dismissSubScreen()
|
||||||
super.onDestroy()
|
// super.onDestroy()
|
||||||
}
|
// }
|
||||||
|
|
||||||
private fun dismissSubScreen() {
|
// private fun dismissSubScreen() {
|
||||||
presentation?.let {
|
// presentation?.let {
|
||||||
if (it.isShowing) {
|
// if (it.isShowing) {
|
||||||
it.dismiss()
|
// it.dismiss()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
fun loadBitmap(frame: Bitmap) {
|
fun loadBitmap(frame: Bitmap) {
|
||||||
binding.ivFaceImage.setImageBitmap(frame)
|
binding.ivFaceImage.setImageBitmap(frame)
|
||||||
@@ -57,21 +58,28 @@ class FacePayFragment : BaseFragment<FragmentFacePayBinding>() {
|
|||||||
|
|
||||||
private fun showSubScreen() {
|
private fun showSubScreen() {
|
||||||
// 查找副屏(通常索引为1)
|
// 查找副屏(通常索引为1)
|
||||||
if (displays.size > 1) {
|
// if (displays.size > 1) {
|
||||||
dismissSubScreen()
|
// dismissSubScreen()
|
||||||
presentation = FacePayPresentation(
|
// presentation = PayPresentation(
|
||||||
activity = payActivity,
|
// activity = payActivity,
|
||||||
display = displays[1],
|
// pageType = PayPresentation.FACE_PAY,
|
||||||
userViewModel = payActivity.userViewModel,
|
// userViewModel = payActivity.userViewModel,
|
||||||
recognizeViewModel = payActivity.recognizeViewModel,
|
// recognizeViewModel = payActivity.recognizeViewModel,
|
||||||
// parentTextureView = binding.parentTextureView,
|
// display = displays[1]
|
||||||
) {
|
// ) {
|
||||||
presentation?.dismiss()
|
// presentation?.dismiss()
|
||||||
}.also {
|
// }.also {
|
||||||
|
// it.foodName = foodName
|
||||||
|
// it.payAmount = payAmount.format2String(2)
|
||||||
|
// }
|
||||||
|
// presentation?.show()
|
||||||
|
// }
|
||||||
|
payActivity.presentation.let {
|
||||||
|
it.pageType = PayPresentation.FACE_PAY
|
||||||
it.foodName = foodName
|
it.foodName = foodName
|
||||||
it.payAmount = payAmount.format2String(2)
|
it.payAmount = payAmount.format2String(2)
|
||||||
|
it.initView()
|
||||||
}
|
}
|
||||||
presentation?.show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ import com.sw.dualscreen.activity.fragment.BaseFragment
|
|||||||
import com.sw.dualscreen.databinding.FragmentNumberPayBinding
|
import com.sw.dualscreen.databinding.FragmentNumberPayBinding
|
||||||
import com.sw.dualscreen.ext.format2String
|
import com.sw.dualscreen.ext.format2String
|
||||||
import com.sw.dualscreen.ext.hideKeyboard
|
import com.sw.dualscreen.ext.hideKeyboard
|
||||||
import com.sw.dualscreen.presentation.pay.CashPayPresentation
|
import com.sw.dualscreen.presentation.pay.PayPresentation
|
||||||
import com.sw.plate.utils.ToastUtils
|
import com.sw.plate.utils.ToastUtils
|
||||||
|
|
||||||
class NumberPayFragment : BaseFragment<FragmentNumberPayBinding>() {
|
class NumberPayFragment : BaseFragment<FragmentNumberPayBinding>() {
|
||||||
@@ -13,7 +13,6 @@ class NumberPayFragment : BaseFragment<FragmentNumberPayBinding>() {
|
|||||||
private lateinit var payActivity: PayActivity
|
private lateinit var payActivity: PayActivity
|
||||||
private var foodName: String? = null
|
private var foodName: String? = null
|
||||||
private var payAmount: Double? = null
|
private var payAmount: Double? = null
|
||||||
var presentation: CashPayPresentation? = null
|
|
||||||
override fun inflateViewBinding(): FragmentNumberPayBinding {
|
override fun inflateViewBinding(): FragmentNumberPayBinding {
|
||||||
return FragmentNumberPayBinding.inflate(layoutInflater)
|
return FragmentNumberPayBinding.inflate(layoutInflater)
|
||||||
}
|
}
|
||||||
@@ -79,39 +78,49 @@ class NumberPayFragment : BaseFragment<FragmentNumberPayBinding>() {
|
|||||||
showSubScreen()
|
showSubScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onHiddenChanged(hidden: Boolean) {
|
// override fun onHiddenChanged(hidden: Boolean) {
|
||||||
super.onHiddenChanged(hidden)
|
// super.onHiddenChanged(hidden)
|
||||||
if (hidden) {
|
// if (hidden) {
|
||||||
dismissSubScreen()
|
// dismissSubScreen()
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
//showSubScreen()
|
// //showSubScreen()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// override fun onDestroy() {
|
||||||
|
// dismissSubScreen()
|
||||||
|
// super.onDestroy()
|
||||||
|
// }
|
||||||
|
|
||||||
override fun onDestroy() {
|
// private fun dismissSubScreen() {
|
||||||
dismissSubScreen()
|
// presentation?.let {
|
||||||
super.onDestroy()
|
// if (it.isShowing) {
|
||||||
}
|
// it.dismiss()
|
||||||
|
// }
|
||||||
private fun dismissSubScreen() {
|
// }
|
||||||
presentation?.let {
|
// }
|
||||||
if (it.isShowing) {
|
|
||||||
it.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showSubScreen() {
|
private fun showSubScreen() {
|
||||||
// 查找副屏(通常索引为1)
|
// 查找副屏(通常索引为1)
|
||||||
if (displays.size > 1) {
|
// if (displays.size > 1) {
|
||||||
dismissSubScreen()
|
// dismissSubScreen()
|
||||||
presentation = CashPayPresentation(activity = payActivity, display = displays[1]) {
|
// presentation = PayPresentation(
|
||||||
presentation?.dismiss()
|
// activity = payActivity,
|
||||||
}.also {
|
// pageType = PayPresentation.CASH_PAY,
|
||||||
|
// userViewModel = payActivity.userViewModel,
|
||||||
|
// recognizeViewModel = payActivity.recognizeViewModel,
|
||||||
|
// display = displays[1]
|
||||||
|
// ).also {
|
||||||
|
// it.foodName = foodName
|
||||||
|
// it.payAmount = payAmount.format2String(2)
|
||||||
|
// }
|
||||||
|
// presentation?.show()
|
||||||
|
// }
|
||||||
|
payActivity.presentation.let {
|
||||||
|
it.pageType = PayPresentation.CASH_PAY
|
||||||
it.foodName = foodName
|
it.foodName = foodName
|
||||||
it.payAmount = payAmount.format2String(2)
|
it.payAmount = payAmount.format2String(2)
|
||||||
}
|
it.initView()
|
||||||
presentation?.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-21
@@ -8,11 +8,11 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import com.sw.dualscreen.activity.PayActivity
|
import com.sw.dualscreen.activity.PayActivity
|
||||||
import com.sw.dualscreen.activity.fragment.BaseFragment
|
import com.sw.dualscreen.activity.fragment.BaseFragment
|
||||||
import com.sw.dualscreen.ext.load
|
import com.sw.dualscreen.ext.load
|
||||||
import com.sw.dualscreen.presentation.pay.ScanQrCodePayPresentation
|
|
||||||
import com.sw.dualscreen.utils.countDownByFlow
|
import com.sw.dualscreen.utils.countDownByFlow
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import com.sw.dualscreen.databinding.FragmentScanQrcodePayBinding
|
import com.sw.dualscreen.databinding.FragmentScanQrcodePayBinding
|
||||||
import com.sw.dualscreen.ext.format2String
|
import com.sw.dualscreen.ext.format2String
|
||||||
|
import com.sw.dualscreen.presentation.pay.PayPresentation
|
||||||
import com.sw.dualscreen.utils.IntervalExecutor
|
import com.sw.dualscreen.utils.IntervalExecutor
|
||||||
|
|
||||||
class ScanQrCodePayFragment : BaseFragment<FragmentScanQrcodePayBinding>() {
|
class ScanQrCodePayFragment : BaseFragment<FragmentScanQrcodePayBinding>() {
|
||||||
@@ -25,7 +25,6 @@ class ScanQrCodePayFragment : BaseFragment<FragmentScanQrcodePayBinding>() {
|
|||||||
private var foodName: String? = null
|
private var foodName: String? = null
|
||||||
private var payAmount: Double? = null
|
private var payAmount: Double? = null
|
||||||
private var payQrCodePic: String? = null
|
private var payQrCodePic: String? = null
|
||||||
var presentation: ScanQrCodePayPresentation? = null
|
|
||||||
private var countDownJob: Job? = null
|
private var countDownJob: Job? = null
|
||||||
|
|
||||||
override fun inflateViewBinding(): FragmentScanQrcodePayBinding {
|
override fun inflateViewBinding(): FragmentScanQrcodePayBinding {
|
||||||
@@ -60,41 +59,48 @@ class ScanQrCodePayFragment : BaseFragment<FragmentScanQrcodePayBinding>() {
|
|||||||
|
|
||||||
override fun onHiddenChanged(hidden: Boolean) {
|
override fun onHiddenChanged(hidden: Boolean) {
|
||||||
super.onHiddenChanged(hidden)
|
super.onHiddenChanged(hidden)
|
||||||
if (hidden) {
|
// if (hidden) {
|
||||||
dismissSubScreen()
|
//// dismissSubScreen()
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
//showSubScreen()
|
//showSubScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
dismissSubScreen()
|
// dismissSubScreen()
|
||||||
countDownJob?.cancel() // 自动取消订阅,防止内存泄漏
|
countDownJob?.cancel() // 自动取消订阅,防止内存泄漏
|
||||||
payTaskJob?.cancel()
|
payTaskJob?.cancel()
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun dismissSubScreen() {
|
private fun dismissSubScreen() {
|
||||||
presentation?.let {
|
// presentation?.let {
|
||||||
if (it.isShowing) {
|
// if (it.isShowing) {
|
||||||
it.dismiss()
|
// it.dismiss()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showSubScreen() {
|
private fun showSubScreen() {
|
||||||
// 查找副屏(通常索引为1)
|
// // 查找副屏(通常索引为1)
|
||||||
if (displays.size > 1) {
|
// if (displays.size > 1) {
|
||||||
dismissSubScreen()
|
// dismissSubScreen()
|
||||||
presentation =
|
// presentation =
|
||||||
ScanQrCodePayPresentation(activity = payActivity, type = 0, display = displays[1]) {
|
// ScanQrCodePayPresentation(activity = payActivity, type = 0, display = displays[1]) {
|
||||||
presentation?.dismiss()
|
// presentation?.dismiss()
|
||||||
}.also {
|
// }.also {
|
||||||
|
// it.foodName = foodName
|
||||||
|
// it.totalPrice = payAmount ?: 0.0
|
||||||
|
// it.payQrCodePic = payQrCodePic
|
||||||
|
// }
|
||||||
|
// presentation?.show()
|
||||||
|
// }
|
||||||
|
payActivity.presentation.let {
|
||||||
|
it.pageType = PayPresentation.QR_CODE_PAY
|
||||||
it.foodName = foodName
|
it.foodName = foodName
|
||||||
it.totalPrice = payAmount ?: 0.0
|
it.totalPrice = payAmount ?: 0.0
|
||||||
it.payQrCodePic = payQrCodePic
|
it.payQrCodePic = payQrCodePic
|
||||||
}
|
it.initView()
|
||||||
presentation?.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ data class MemberInfo(
|
|||||||
//赠送余额
|
//赠送余额
|
||||||
val rewardBalance: Double?,
|
val rewardBalance: Double?,
|
||||||
//积分余额
|
//积分余额
|
||||||
val integralBalance: Int?
|
val integralBalance: Int?,
|
||||||
|
val member: Boolean
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
||||||
data class TextBean(
|
data class TextBean(
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
package com.sw.dualscreen.presentation.pay
|
//package com.sw.dualscreen.presentation.pay
|
||||||
|
//
|
||||||
import android.R
|
//import android.R
|
||||||
import android.app.Presentation
|
//import android.app.Presentation
|
||||||
import android.os.Bundle
|
//import android.os.Bundle
|
||||||
import android.text.Spanned
|
//import android.text.Spanned
|
||||||
import android.text.SpannedString
|
//import android.text.SpannedString
|
||||||
import android.text.style.AbsoluteSizeSpan
|
//import android.text.style.AbsoluteSizeSpan
|
||||||
import android.view.Display
|
//import android.view.Display
|
||||||
import androidx.core.text.buildSpannedString
|
//import androidx.core.text.buildSpannedString
|
||||||
import com.sw.dualscreen.activity.PayActivity
|
//import com.sw.dualscreen.activity.PayActivity
|
||||||
import com.sw.dualscreen.databinding.PresentationCashPayBinding
|
//import com.sw.dualscreen.databinding.PresentationCashPayBinding
|
||||||
import com.sw.dualscreen.ext.load
|
//import com.sw.dualscreen.ext.load
|
||||||
|
//
|
||||||
class CashPayPresentation(
|
//class CashPayPresentation(
|
||||||
val activity: PayActivity,
|
// val activity: PayActivity,
|
||||||
display: Display,
|
// display: Display,
|
||||||
private val onDismissListener: () -> Unit = {}
|
// private val onDismissListener: () -> Unit = {}
|
||||||
) : Presentation(activity, display) {
|
//) : Presentation(activity, display) {
|
||||||
|
//
|
||||||
private lateinit var binding: PresentationCashPayBinding
|
// private lateinit var binding: PresentationCashPayBinding
|
||||||
|
//
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
// override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
// super.onCreate(savedInstanceState)
|
||||||
binding = PresentationCashPayBinding.inflate(layoutInflater)
|
// binding = PresentationCashPayBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
// setContentView(binding.root)
|
||||||
window?.setBackgroundDrawableResource(R.color.transparent)
|
// window?.setBackgroundDrawableResource(R.color.transparent)
|
||||||
initView()
|
// initView()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
var foodName: String? = null
|
// var foodName: String? = null
|
||||||
var payAmount: String? = null
|
// var payAmount: String? = null
|
||||||
private fun initView() {
|
// private fun initView() {
|
||||||
binding.tvFoodName.text = foodName
|
// binding.tvFoodName.text = foodName
|
||||||
binding.tvRealAmount.text = getAmountText(payAmount ?: "")
|
// binding.tvRealAmount.text = getAmountText(payAmount ?: "")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private fun getAmountText(amount: String): SpannedString {
|
// private fun getAmountText(amount: String): SpannedString {
|
||||||
return buildSpannedString {
|
// return buildSpannedString {
|
||||||
append("¥", AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
// append("¥", AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
// append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override fun onDisplayRemoved() {
|
// override fun onDisplayRemoved() {
|
||||||
super.onDisplayRemoved()
|
// super.onDisplayRemoved()
|
||||||
onDismissListener()
|
// onDismissListener()
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,804 @@
|
|||||||
|
package com.sw.dualscreen.presentation.pay
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.app.Presentation
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.graphics.Point
|
||||||
|
import android.hardware.Camera
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.Spanned
|
||||||
|
import android.text.SpannedString
|
||||||
|
import android.text.TextUtils
|
||||||
|
import android.text.style.AbsoluteSizeSpan
|
||||||
|
import android.view.Display
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.ViewTreeObserver
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.text.buildSpannedString
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.arcsoft.face.ErrorInfo
|
||||||
|
import com.sw.dualscreen.GlobalKey
|
||||||
|
import com.sw.dualscreen.R
|
||||||
|
import com.sw.dualscreen.activity.PayActivity
|
||||||
|
import com.sw.dualscreen.databinding.PresentationFacePayBinding
|
||||||
|
import com.sw.dualscreen.databinding.PresentationPayBinding
|
||||||
|
import com.sw.dualscreen.ext.dp
|
||||||
|
import com.sw.dualscreen.ext.format2String
|
||||||
|
import com.sw.dualscreen.ext.gone
|
||||||
|
import com.sw.dualscreen.ext.invisible
|
||||||
|
import com.sw.dualscreen.ext.load
|
||||||
|
import com.sw.dualscreen.ext.visible
|
||||||
|
import com.sw.dualscreen.model.response.MemberInfo
|
||||||
|
import com.sw.dualscreen.model.response.TextBean
|
||||||
|
import com.sw.dualscreen.utils.SPUtil
|
||||||
|
import com.sw.dualscreen.utils.SpannedUtils
|
||||||
|
import com.sw.dualscreen.view.CustomDialog
|
||||||
|
import com.sw.dualscreen.viewmodel.UserViewModel
|
||||||
|
import com.sw.plate.utils.ToastUtils
|
||||||
|
import com.sw.plate.utils.arcface.ConfigUtil
|
||||||
|
import com.sw.plate.utils.arcface.ErrorCodeUtil
|
||||||
|
import com.sw.plate.utils.arcface.FaceRectTransformer
|
||||||
|
import com.sw.plate.utils.arcface.FaceRectView
|
||||||
|
import com.sw.plate.utils.arcface.FaceRectView.DrawInfo
|
||||||
|
import com.sw.plate.utils.arcface.PreviewConfig
|
||||||
|
import com.sw.plate.utils.arcface.camera.CameraListener
|
||||||
|
import com.sw.plate.utils.arcface.camera.DualCameraHelper
|
||||||
|
import com.sw.plate.utils.arcface.face.constants.LivenessType
|
||||||
|
import com.sw.plate.utils.arcface.face.model.CompareResult
|
||||||
|
import com.sw.plate.utils.arcface.face.model.FacePreviewInfo
|
||||||
|
import com.sw.plate.utils.arcface.face.model.RecognizeConfiguration
|
||||||
|
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
class PayPresentation(
|
||||||
|
val activity: PayActivity,
|
||||||
|
display: Display,
|
||||||
|
val userViewModel: UserViewModel,
|
||||||
|
val recognizeViewModel: RecognizeViewModel,
|
||||||
|
private val onDismissListener: () -> Unit = {}
|
||||||
|
) : Presentation(activity, display), ViewTreeObserver.OnGlobalLayoutListener {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "PayPresentation"
|
||||||
|
const val CASH_PAY = 100
|
||||||
|
const val FACE_PAY = 200
|
||||||
|
const val QR_CODE_PAY = 300
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var binding: PresentationPayBinding
|
||||||
|
|
||||||
|
// 虹软人脸配置 ⬇
|
||||||
|
private var isRecognition = false
|
||||||
|
private var rgbCameraHelper: DualCameraHelper? = null
|
||||||
|
private var rgbFaceRectTransformer: FaceRectTransformer? = null
|
||||||
|
private val livenessType = LivenessType.IR
|
||||||
|
private var openRectInfoDraw = false
|
||||||
|
|
||||||
|
private var irCameraHelper: DualCameraHelper? = null
|
||||||
|
private var irFaceRectTransformer: FaceRectTransformer? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = PresentationPayBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
window?.setBackgroundDrawableResource(android.R.color.white)
|
||||||
|
|
||||||
|
setupArcCamera()
|
||||||
|
registerDataChange()
|
||||||
|
initView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun show() {
|
||||||
|
super.show()
|
||||||
|
pauseCamera()
|
||||||
|
}
|
||||||
|
|
||||||
|
var pageType: Int = 0
|
||||||
|
var type: Int = 0
|
||||||
|
|
||||||
|
// fun updatePage(pageType:Int, type:Int = -1) {
|
||||||
|
// this.pageType == pageType
|
||||||
|
// this.type = type
|
||||||
|
// if (pageType == PayPresentation.CASH_PAY) {
|
||||||
|
//
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// if (pageType == PayPresentation.FACE_PAY) {
|
||||||
|
//
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// if (pageType == PayPresentation.QR_CODE_PAY) {
|
||||||
|
//
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
var foodName: String? = null
|
||||||
|
var payAmount: String? = null
|
||||||
|
fun initView() {
|
||||||
|
when (pageType) {
|
||||||
|
FACE_PAY -> {
|
||||||
|
//人脸识别
|
||||||
|
binding.flCashPay.gone()
|
||||||
|
binding.flQrCodePay.gone()
|
||||||
|
binding.flFacePay.visible()
|
||||||
|
|
||||||
|
binding.tvFoodName.text = foodName
|
||||||
|
binding.tvRealAmount.text = SpannedUtils.getAmountText(
|
||||||
|
listOf(
|
||||||
|
TextBean(text = "¥", textSize = 32),
|
||||||
|
TextBean(text = payAmount ?: "", textSize = 48),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
//pauseCamera()
|
||||||
|
resumeCamera()
|
||||||
|
// binding.root.postDelayed({
|
||||||
|
// resumeCamera()
|
||||||
|
// }, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
QR_CODE_PAY -> {
|
||||||
|
//二维码
|
||||||
|
binding.flCashPay.gone()
|
||||||
|
binding.flQrCodePay.visible()
|
||||||
|
binding.flFacePay.gone()
|
||||||
|
initQrCodeView()
|
||||||
|
}
|
||||||
|
|
||||||
|
CASH_PAY -> {
|
||||||
|
binding.flCashPay.visible()
|
||||||
|
binding.flQrCodePay.gone()
|
||||||
|
binding.flFacePay.gone()
|
||||||
|
binding.tvFoodName2.text = foodName
|
||||||
|
binding.tvRealAmount2.text = getAmountText(payAmount ?: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAmountText(amount: String): SpannedString {
|
||||||
|
return buildSpannedString {
|
||||||
|
append("¥", AbsoluteSizeSpan(32, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
append(amount, AbsoluteSizeSpan(48, true), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onGlobalLayout() {
|
||||||
|
Timber.tag(TAG).d("onGlobalLayout")
|
||||||
|
binding.dualCameraTexturePreviewRgb.getViewTreeObserver().removeOnGlobalLayoutListener(this)
|
||||||
|
//parentTextureView.getViewTreeObserver().removeOnGlobalLayoutListener(this)
|
||||||
|
openCamera()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openCamera() {
|
||||||
|
Timber.tag(TAG).d("openCamera")
|
||||||
|
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) !=
|
||||||
|
PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
ToastUtils.showToast("无摄像头权限")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val cameraCount = Camera.getNumberOfCameras()
|
||||||
|
if (cameraCount < 3) {
|
||||||
|
ToastUtils.showToast("摄像头数量异常")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
recognizeViewModel.init(
|
||||||
|
PreviewConfig(
|
||||||
|
2, 1, 90, 90
|
||||||
|
)
|
||||||
|
)
|
||||||
|
initRgbCamera()
|
||||||
|
if (DualCameraHelper.hasDualCamera() && livenessType === LivenessType.IR) {
|
||||||
|
initIrCamera()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.tag(TAG).e(e, "打开摄像头失败")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用虹软人脸失败
|
||||||
|
*/
|
||||||
|
private fun setupArcCamera() {
|
||||||
|
initArcViewModel()
|
||||||
|
initArcView()
|
||||||
|
openRectInfoDraw = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerDataChange() {
|
||||||
|
activity.lifecycleScope.launch {
|
||||||
|
userViewModel.loadFaceResult.collect { needUpdate ->
|
||||||
|
if (needUpdate) {
|
||||||
|
recognizeViewModel.refreshFaceList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
rgbCameraHelper?.release()
|
||||||
|
rgbCameraHelper = null
|
||||||
|
irCameraHelper?.release()
|
||||||
|
irCameraHelper = null
|
||||||
|
recognizeViewModel.destroy()
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resumeCamera() {
|
||||||
|
Timber.tag(TAG).d("resumeCamera isRecognition = $isRecognition")
|
||||||
|
isRecognition = true
|
||||||
|
if (rgbCameraHelper?.isStopped == true) {
|
||||||
|
rgbCameraHelper?.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pauseCamera() {
|
||||||
|
Timber.tag(TAG).d("pauseCamera isRecognition = $isRecognition")
|
||||||
|
isRecognition = false
|
||||||
|
|
||||||
|
recognizeViewModel.onPreviewFrame(ByteArray(1382400), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initArcViewModel() {
|
||||||
|
recognizeViewModel.setLiveType(livenessType)
|
||||||
|
recognizeViewModel.ftInitCode.observe(activity, Observer { ftInitCode: Int? ->
|
||||||
|
if (ftInitCode != ErrorInfo.MOK) {
|
||||||
|
val error: String? = context.getString(
|
||||||
|
R.string.specific_engine_init_failed, "ftEngine",
|
||||||
|
ftInitCode, ErrorCodeUtil.arcFaceErrorCodeToFieldName(ftInitCode!!)
|
||||||
|
)
|
||||||
|
Timber.tag(TAG).e("ftInitCode observe = $error")
|
||||||
|
ToastUtils.showToast(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
recognizeViewModel.frInitCode.observe(activity, Observer { frInitCode: Int? ->
|
||||||
|
if (frInitCode != ErrorInfo.MOK) {
|
||||||
|
val error: String? = context.getString(
|
||||||
|
R.string.specific_engine_init_failed, "frEngine",
|
||||||
|
frInitCode, ErrorCodeUtil.arcFaceErrorCodeToFieldName(frInitCode!!)
|
||||||
|
)
|
||||||
|
Timber.tag(TAG).e("frInitCode observe = $error")
|
||||||
|
ToastUtils.showToast(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
recognizeViewModel.flInitCode.observe(activity, Observer { flInitCode: Int? ->
|
||||||
|
if (flInitCode != ErrorInfo.MOK) {
|
||||||
|
val error: String? = context.getString(
|
||||||
|
R.string.specific_engine_init_failed, "flEngine",
|
||||||
|
flInitCode, ErrorCodeUtil.arcFaceErrorCodeToFieldName(flInitCode!!)
|
||||||
|
)
|
||||||
|
Timber.tag(TAG).e("flInitCode observe = $error")
|
||||||
|
ToastUtils.showToast(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
recognizeViewModel.recognizeConfiguration
|
||||||
|
.observe(activity, Observer { recognizeConfiguration: RecognizeConfiguration? ->
|
||||||
|
Timber.tag(TAG)
|
||||||
|
.i("recognizeConfiguration: observe = ${recognizeConfiguration.toString()}")
|
||||||
|
})
|
||||||
|
recognizeViewModel.recognizeNotice.observe(activity, Observer { notice: String? ->
|
||||||
|
Timber.tag(TAG).i("recognizeNotice observe notice = $notice")
|
||||||
|
})
|
||||||
|
|
||||||
|
recognizeViewModel.recognizeUserId.observe(
|
||||||
|
activity,
|
||||||
|
Observer { compareResult: CompareResult ->
|
||||||
|
Timber.tag(TAG)
|
||||||
|
.i("recognizeUserId observe compareResult = ${compareResult.trackId}, userId = ${compareResult.faceEntity.userName}")
|
||||||
|
// recognitionTime = System.currentTimeMillis()
|
||||||
|
// recognitionWeight = lastWeight
|
||||||
|
lastFaceTrackId = compareResult.trackId
|
||||||
|
val faceEntity = compareResult.faceEntity
|
||||||
|
val userId = faceEntity.userName
|
||||||
|
if (userId == null) return@Observer
|
||||||
|
// TODO: 测试支付用户id
|
||||||
|
// userId = "1987710988425662466"
|
||||||
|
faceRecSuccess(userId)
|
||||||
|
})
|
||||||
|
|
||||||
|
recognizeViewModel.drawRectInfoText.observe(activity, Observer { info ->
|
||||||
|
Timber.tag(TAG).i("drawRectInfoText observe info = $info")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initArcView() {
|
||||||
|
//在布局结束后才做初始化操作
|
||||||
|
binding.dualCameraTexturePreviewRgb.getViewTreeObserver().addOnGlobalLayoutListener(this)
|
||||||
|
//parentTextureView.getViewTreeObserver().addOnGlobalLayoutListener(this)
|
||||||
|
recognizeViewModel.getCompareResultList().getValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调整View的宽高,使预览显示正常且采集框固定为
|
||||||
|
*
|
||||||
|
* @param rgbPreview RGB预览View
|
||||||
|
* @param previewView 显示预览数据的view
|
||||||
|
* @param faceRectView 画框的view
|
||||||
|
* @param previewSize 预览大小
|
||||||
|
* @param displayOrientation 相机旋转角度
|
||||||
|
* @param scale 缩放比例
|
||||||
|
* @return 调整后的LayoutParams
|
||||||
|
*/
|
||||||
|
private fun adjustPreviewViewSize(
|
||||||
|
rgbPreview: View,
|
||||||
|
previewView: View,
|
||||||
|
faceRectView: FaceRectView,
|
||||||
|
previewSize: Camera.Size,
|
||||||
|
displayOrientation: Int,
|
||||||
|
scale: Float
|
||||||
|
): ViewGroup.LayoutParams {
|
||||||
|
val w = (600.dp * 1.5).toInt()
|
||||||
|
val h = 1068.dp
|
||||||
|
val layoutParams = FrameLayout.LayoutParams(w, h)
|
||||||
|
|
||||||
|
previewView.setLayoutParams(layoutParams)
|
||||||
|
faceRectView.setLayoutParams(layoutParams)
|
||||||
|
return layoutParams
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initRgbCamera() {
|
||||||
|
val cameraListener: CameraListener = object : CameraListener {
|
||||||
|
override fun onCameraOpened(
|
||||||
|
camera: Camera,
|
||||||
|
cameraId: Int,
|
||||||
|
displayOrientation: Int,
|
||||||
|
isMirror: Boolean
|
||||||
|
) {
|
||||||
|
Timber.tag(TAG)
|
||||||
|
.d("initRgbCamera Rgb onCameraOpened: cameraId = $cameraId, displayOrientation = $displayOrientation")
|
||||||
|
activity.runOnUiThread({
|
||||||
|
val previewSizeRgb = camera.getParameters().getPreviewSize()
|
||||||
|
val layoutParams = adjustPreviewViewSize(
|
||||||
|
binding.dualCameraTexturePreviewRgb,
|
||||||
|
binding.dualCameraTexturePreviewRgb, binding.dualCameraFaceRectView,
|
||||||
|
previewSizeRgb, displayOrientation, 0.6F
|
||||||
|
)
|
||||||
|
|
||||||
|
Timber.tag(TAG)
|
||||||
|
.d("initRgbCamera previewSizeRgb = ${previewSizeRgb.width}-${previewSizeRgb.height}")
|
||||||
|
Timber.tag(TAG)
|
||||||
|
.d("initRgbCamera layoutParams = ${layoutParams.width}-${layoutParams.height}")
|
||||||
|
Timber.tag(TAG).d(
|
||||||
|
"initRgbCamera isMirror = ${isMirror}, isDrawRgbRectHorizontalMirror = ${
|
||||||
|
ConfigUtil.isDrawRgbRectHorizontalMirror(
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}, isDrawRgbRectVerticalMirror = ${
|
||||||
|
ConfigUtil.isDrawRgbRectVerticalMirror(
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
// 调整识别窗口位置
|
||||||
|
rgbFaceRectTransformer = FaceRectTransformer(
|
||||||
|
previewSizeRgb.width,
|
||||||
|
previewSizeRgb.height,
|
||||||
|
// layoutParams.width,
|
||||||
|
// layoutParams.height,
|
||||||
|
layoutParams.width,
|
||||||
|
layoutParams.height,
|
||||||
|
90,
|
||||||
|
cameraId,
|
||||||
|
isMirror,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
recognizeViewModel.onRgbCameraOpened(camera)
|
||||||
|
recognizeViewModel.setRgbFaceRectTransformer(rgbFaceRectTransformer)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.Q)
|
||||||
|
override fun onPreview(nv21: ByteArray?, camera: Camera?) {
|
||||||
|
if (!isRecognition) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
binding.dualCameraFaceRectView.clearFaceInfo()
|
||||||
|
val facePreviewInfoList: MutableList<FacePreviewInfo?>? =
|
||||||
|
recognizeViewModel.onPreviewFrame(nv21, true)
|
||||||
|
if (facePreviewInfoList != null && rgbFaceRectTransformer != null) {
|
||||||
|
drawPreviewInfo(facePreviewInfoList)
|
||||||
|
}
|
||||||
|
recognizeViewModel.clearLeftFace(facePreviewInfoList)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCameraClosed() {
|
||||||
|
Timber.tag(TAG).i("initRgbCamera onCameraClosed: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCameraError(e: java.lang.Exception) {
|
||||||
|
Timber.tag(TAG).i("initRgbCamera onCameraError: %s", e.message)
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCameraConfigurationChanged(cameraID: Int, displayOrientation: Int) {
|
||||||
|
Timber.tag(TAG)
|
||||||
|
.i("initRgbCamera onCameraConfigurationChanged: threadName = ${Thread.currentThread().name}")
|
||||||
|
if (rgbFaceRectTransformer != null) {
|
||||||
|
rgbFaceRectTransformer!!.cameraDisplayOrientation = displayOrientation
|
||||||
|
}
|
||||||
|
Timber.tag(TAG)
|
||||||
|
.i("initRgbCamera onCameraConfigurationChanged: $cameraID $displayOrientation")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val measuredWidth = binding.dualCameraTexturePreviewRgb.measuredWidth
|
||||||
|
val measuredHeight = binding.dualCameraTexturePreviewRgb.measuredHeight
|
||||||
|
Timber.tag(TAG)
|
||||||
|
.i("initRgbCamera measuredWidth=$measuredWidth,measuredHeight=$measuredHeight")
|
||||||
|
|
||||||
|
val previewConfig: PreviewConfig = recognizeViewModel.previewConfig
|
||||||
|
rgbCameraHelper = DualCameraHelper.Builder()
|
||||||
|
.previewViewSize(Point(measuredWidth, measuredHeight))
|
||||||
|
.rotation(activity.windowManager.defaultDisplay.rotation)
|
||||||
|
.additionalRotation(previewConfig.rgbAdditionalDisplayOrientation) // 角度
|
||||||
|
.previewSize(recognizeViewModel.loadPreviewSize())
|
||||||
|
.specificCameraId(previewConfig.rgbCameraId)
|
||||||
|
.isMirror(true)
|
||||||
|
.previewOn(binding.dualCameraTexturePreviewRgb)
|
||||||
|
.cameraListener(cameraListener)
|
||||||
|
.build()
|
||||||
|
rgbCameraHelper!!.setSurfaceFrameCallback { frame ->
|
||||||
|
activity.facePayFragment?.loadBitmap(frame)
|
||||||
|
}
|
||||||
|
rgbCameraHelper!!.init()
|
||||||
|
// rgbCameraHelper!!.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化红外相机,若活体检测类型是可见光活体检测或不启用活体,则不需要启用
|
||||||
|
*/
|
||||||
|
private fun initIrCamera() {
|
||||||
|
Timber.tag(TAG).d("initIrCamera: livenessType = $livenessType")
|
||||||
|
if (livenessType === LivenessType.RGB) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val irCameraListener: CameraListener = object : CameraListener {
|
||||||
|
override fun onCameraOpened(
|
||||||
|
camera: Camera,
|
||||||
|
cameraId: Int,
|
||||||
|
displayOrientation: Int,
|
||||||
|
isMirror: Boolean
|
||||||
|
) {
|
||||||
|
Timber.tag(TAG)
|
||||||
|
.d("initIrCamera IR onCameraOpened: cameraId = $cameraId, displayOrientation = $displayOrientation")
|
||||||
|
val previewSizeIr = camera.getParameters().getPreviewSize()
|
||||||
|
val layoutParams = adjustPreviewViewSize(
|
||||||
|
binding.dualCameraTexturePreviewRgb,
|
||||||
|
binding.dualCameraTexturePreviewIr, binding.dualCameraFaceRectViewIr,
|
||||||
|
previewSizeIr, displayOrientation, 0.25f
|
||||||
|
)
|
||||||
|
|
||||||
|
irFaceRectTransformer = FaceRectTransformer(
|
||||||
|
previewSizeIr.width, previewSizeIr.height,
|
||||||
|
// layoutParams.width, layoutParams.height,
|
||||||
|
layoutParams.width, layoutParams.height,
|
||||||
|
displayOrientation, cameraId, isMirror,
|
||||||
|
ConfigUtil.isDrawIrRectHorizontalMirror(context),
|
||||||
|
ConfigUtil.isDrawIrRectVerticalMirror(context)
|
||||||
|
)
|
||||||
|
|
||||||
|
recognizeViewModel.onIrCameraOpened(camera)
|
||||||
|
recognizeViewModel.setIrFaceRectTransformer(irFaceRectTransformer)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onPreview(nv21: ByteArray?, camera: Camera?) {
|
||||||
|
recognizeViewModel.refreshIrPreviewData(nv21)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCameraClosed() {
|
||||||
|
Timber.tag(TAG).i("initIrCamera onCameraClosed: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCameraError(e: java.lang.Exception) {
|
||||||
|
Timber.tag(TAG).i("initIrCamera onCameraError: ${e.message}")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCameraConfigurationChanged(
|
||||||
|
cameraID: Int,
|
||||||
|
displayOrientation: Int
|
||||||
|
) {
|
||||||
|
if (irFaceRectTransformer != null) {
|
||||||
|
irFaceRectTransformer!!.cameraDisplayOrientation = displayOrientation
|
||||||
|
}
|
||||||
|
Timber.tag(TAG)
|
||||||
|
.i("initIrCamera onCameraConfigurationChanged: cameraID = $cameraID, displayOrientation = $displayOrientation")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val previewConfig = recognizeViewModel.previewConfig
|
||||||
|
irCameraHelper = DualCameraHelper.Builder()
|
||||||
|
.previewViewSize(
|
||||||
|
Point(
|
||||||
|
binding.dualCameraTexturePreviewIr.measuredWidth,
|
||||||
|
binding.dualCameraTexturePreviewIr.measuredHeight
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.rotation(activity.windowManager.defaultDisplay.rotation)
|
||||||
|
.specificCameraId(previewConfig.irCameraId)
|
||||||
|
.previewOn(binding.dualCameraTexturePreviewIr)
|
||||||
|
.cameraListener(irCameraListener)
|
||||||
|
.isMirror(true)
|
||||||
|
.previewSize(recognizeViewModel.loadPreviewSize()) //相机预览大小设置,RGB与IR需使用相同大小
|
||||||
|
.additionalRotation(previewConfig.irAdditionalDisplayOrientation) //额外旋转角度
|
||||||
|
.build()
|
||||||
|
irCameraHelper!!.init()
|
||||||
|
try {
|
||||||
|
irCameraHelper!!.start()
|
||||||
|
} catch (e: RuntimeException) {
|
||||||
|
ToastUtils.showToast(e.message + context.getString(R.string.camera_error_notice))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制RGB、IR画面的实时人脸信息
|
||||||
|
*
|
||||||
|
* @param facePreviewInfoList RGB画面的实时人脸信息
|
||||||
|
*/
|
||||||
|
private fun drawPreviewInfo(facePreviewInfoList: MutableList<FacePreviewInfo?>) {
|
||||||
|
// Timber.tag(TAG).d("drawPreviewInfo facePreviewInfoList = ${facePreviewInfoList.size}, rgbFaceRectTransformer = ${rgbFaceRectTransformer != null}")
|
||||||
|
if (rgbFaceRectTransformer != null) {
|
||||||
|
val rgbDrawInfoList: MutableList<DrawInfo?>? = recognizeViewModel.getDrawInfo(
|
||||||
|
facePreviewInfoList,
|
||||||
|
LivenessType.RGB,
|
||||||
|
openRectInfoDraw
|
||||||
|
)
|
||||||
|
// 识别成功
|
||||||
|
binding.dualCameraFaceRectView.drawRealtimeFaceInfo(rgbDrawInfoList)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (facePreviewInfoList.isEmpty() || (lastFaceTrackId != facePreviewInfoList[0]!!.trackId)) {
|
||||||
|
if (lastFaceTrackId != -1) {
|
||||||
|
// mealPickupMode = SPUtil.getInstance().get(GlobalKey.KEY_PICKUP_MODE, 0) ?: 0
|
||||||
|
// Timber.tag(TAG).i("$lastFaceTrackId 用户离开")
|
||||||
|
// lastFaceTrackId = -1
|
||||||
|
// postUserData()
|
||||||
|
// if (mealPickupMode == 0) {
|
||||||
|
// step1FoodRecognizing()
|
||||||
|
// } else {
|
||||||
|
// step2FaceRecognizing(currentFood!!)
|
||||||
|
// }
|
||||||
|
|
||||||
|
resumeCamera()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var lastFaceTrackId: Int = -1 // 上一次的人脸信息
|
||||||
|
|
||||||
|
override fun onDisplayRemoved() {
|
||||||
|
super.onDisplayRemoved()
|
||||||
|
onDismissListener()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun faceRecSuccess(userId: String) {
|
||||||
|
activity.runOnUiThread {
|
||||||
|
activity.showWaitingDialog("加载中,请稍后……")
|
||||||
|
}
|
||||||
|
activity.getMemberInfoById(userId) { memberInfo ->
|
||||||
|
if (memberInfo == null) {
|
||||||
|
activity.hideWaitingDialog()
|
||||||
|
//ToastUtils.showToast("查询会员信息失败,请稍后重试")
|
||||||
|
return@getMemberInfoById
|
||||||
|
}
|
||||||
|
activity.bindOrder(memberInfo.faceUserId ?: "") { bindResult ->
|
||||||
|
if (bindResult.not()) {
|
||||||
|
activity.hideWaitingDialog()
|
||||||
|
//ToastUtils.showToast("订单绑定失败")
|
||||||
|
return@bindOrder
|
||||||
|
}
|
||||||
|
binding.root.postDelayed({
|
||||||
|
activity.hideWaitingDialog()
|
||||||
|
// TODO: 测试 memberInfo.member是否返回正常数据---------------
|
||||||
|
activity.showPayInfo(type = 1, isVip = memberInfo.member, memberInfo = memberInfo)
|
||||||
|
activity.hidePayTab()
|
||||||
|
binding.root.postDelayed({
|
||||||
|
dismiss()
|
||||||
|
}, 500)
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// private 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, activity.foodOrderId, mode = mode) { bindResult ->
|
||||||
|
// activity.runOnUiThread {
|
||||||
|
// if (bindResult.not()) {
|
||||||
|
// activity.hideWaitingDialog()
|
||||||
|
// //ToastUtils.showToast("订单绑定失败")
|
||||||
|
// return@runOnUiThread
|
||||||
|
// }
|
||||||
|
// block()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// private fun getMemberInfo(userId: String, block:(MemberInfo)-> Unit) {
|
||||||
|
// userViewModel.getMemberInfoById(memberId = userId) { memberInfo ->
|
||||||
|
// activity.runOnUiThread {
|
||||||
|
// if (memberInfo == null) {
|
||||||
|
// activity.hideWaitingDialog()
|
||||||
|
// //ToastUtils.showToast("查询会员信息失败,请稍后重试")
|
||||||
|
// return@runOnUiThread
|
||||||
|
// }
|
||||||
|
// block(memberInfo)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
var payQrCodePic: Any? = null
|
||||||
|
|
||||||
|
//总价格
|
||||||
|
var totalPrice = 0.0
|
||||||
|
|
||||||
|
//余额
|
||||||
|
private var balance = 0.0
|
||||||
|
|
||||||
|
//实际支付金额
|
||||||
|
private var realPayPrice = 0.0
|
||||||
|
|
||||||
|
//扣除余额
|
||||||
|
private var expensesBalance = 0.0
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
private fun initQrCodeView() {
|
||||||
|
|
||||||
|
when (type) {
|
||||||
|
0 -> {
|
||||||
|
binding.layoutVip.gone()
|
||||||
|
binding.layoutPaySuccess.gone()
|
||||||
|
binding.layoutScanQrCode.visible()
|
||||||
|
|
||||||
|
binding.tvPayTip.text = "请扫码支付或出示付款码"
|
||||||
|
binding.tvFoodName3.text = foodName
|
||||||
|
binding.tvRealAmount3.text = SpannedUtils.getAmountText(
|
||||||
|
listOf(
|
||||||
|
TextBean(text = "¥", textSize = 32),
|
||||||
|
TextBean(text = totalPrice.format2String(2), textSize = 48),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
binding.ivPayQrCode.load(payQrCodePic)
|
||||||
|
}
|
||||||
|
|
||||||
|
1 -> {
|
||||||
|
val memberInfo = activity.memberInfo
|
||||||
|
binding.layoutVip.run {
|
||||||
|
if (memberInfo != null) visible() else gone()
|
||||||
|
}
|
||||||
|
binding.layoutPaySuccess.gone()
|
||||||
|
binding.layoutScanQrCode.visible()
|
||||||
|
|
||||||
|
balance = (memberInfo?.topUpBalance ?: 0.0) + (memberInfo?.rewardBalance ?: 0.0)
|
||||||
|
realPayPrice = if (balance >= totalPrice) 0.0 else totalPrice - balance
|
||||||
|
expensesBalance = if (balance >= totalPrice) totalPrice else balance
|
||||||
|
|
||||||
|
memberInfo?.let { loadUserInfo(it) }
|
||||||
|
binding.tvUserBalance.text = SpannedUtils.getAmountText(
|
||||||
|
listOf(
|
||||||
|
TextBean(text = "¥", textSize = 20),
|
||||||
|
TextBean(text = balance.format2String(2), textSize = 32),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.tvFoodName3.text = foodName
|
||||||
|
binding.tvRealAmount3.text = SpannedUtils.getAmountText(
|
||||||
|
listOf(
|
||||||
|
TextBean(text = "¥", textSize = 32),
|
||||||
|
TextBean(text = totalPrice.format2String(2), textSize = 48),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
binding.ivPayQrCode.run {
|
||||||
|
// load(payQrCodePic)
|
||||||
|
if (balance >= totalPrice) invisible() else visible()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.tvPayTip.text = SpannedUtils.getAmountText(getAmountList())
|
||||||
|
}
|
||||||
|
|
||||||
|
2 -> {
|
||||||
|
val memberInfo = activity.memberInfo
|
||||||
|
binding.layoutVip.run {
|
||||||
|
if (memberInfo != null) visible() else gone()
|
||||||
|
}
|
||||||
|
binding.layoutPaySuccess.visible()
|
||||||
|
binding.layoutScanQrCode.gone()
|
||||||
|
|
||||||
|
balance = if (memberInfo != null) (memberInfo.topUpBalance
|
||||||
|
?: 0.0) + (memberInfo.rewardBalance ?: 0.0) else 0.0
|
||||||
|
realPayPrice = if (balance >= totalPrice) 0.0 else totalPrice - balance
|
||||||
|
expensesBalance = if (balance >= totalPrice) totalPrice else balance
|
||||||
|
|
||||||
|
memberInfo?.let { loadUserInfo(it) }
|
||||||
|
val remainBalance = if (balance >= totalPrice) balance - totalPrice else 0.0
|
||||||
|
binding.tvUserBalance.text = SpannedUtils.getAmountText(
|
||||||
|
listOf(
|
||||||
|
TextBean(text = "¥", textSize = 24),
|
||||||
|
TextBean(text = remainBalance.format2String(2), textSize = 36),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val showBalance = expensesBalance.format2String(2)
|
||||||
|
val showTotal = totalPrice.format2String(2)
|
||||||
|
binding.tvPayInfo.text = "余额扣除 $showBalance 元,在线支付 $showTotal 元"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadQrCodeImage(qrCodeUrl: String?) {
|
||||||
|
binding.ivPayQrCode.load(qrCodeUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadUserInfo(item: MemberInfo) {
|
||||||
|
binding.ivHeadPic.load(
|
||||||
|
if (item.faceUrl.isNullOrBlank()) R.drawable.ic_avatar_default
|
||||||
|
else item.faceUrl
|
||||||
|
)
|
||||||
|
binding.tvUserName.text = item.name
|
||||||
|
|
||||||
|
val phone = item.phone ?: ""
|
||||||
|
binding.tvUserPhone.text =
|
||||||
|
if (phone.length == 11) phone.replace(phone.substring(3, 7), "****")
|
||||||
|
else phone
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAmountList(): List<TextBean> {
|
||||||
|
val list: MutableList<TextBean> = mutableListOf()
|
||||||
|
|
||||||
|
list.add(TextBean(text = "余额扣除 ", textSize = 30, textColor = "#FF5E7585"))
|
||||||
|
list.add(
|
||||||
|
TextBean(
|
||||||
|
text = "-${expensesBalance.format2String(2)}",
|
||||||
|
textSize = 30,
|
||||||
|
textColor = "#FF0A1428",
|
||||||
|
isBold = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (balance >= totalPrice) {
|
||||||
|
//余额大于等于总价格,使用余额支付
|
||||||
|
list.add(TextBean(text = " 元,扣除后可用余额 ", textSize = 30, textColor = "#FF5E7585"))
|
||||||
|
val remainingBalance = balance - totalPrice
|
||||||
|
list.add(
|
||||||
|
TextBean(
|
||||||
|
text = remainingBalance.format2String(2),
|
||||||
|
textSize = 30,
|
||||||
|
textColor = "#FF0A1428",
|
||||||
|
isBold = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
//余额小于总价格,使用余额+扫码支付
|
||||||
|
//实际支付金额
|
||||||
|
list.add(TextBean(text = " 元,还需支付 ", textSize = 30, textColor = "#FF5E7585"))
|
||||||
|
list.add(
|
||||||
|
TextBean(
|
||||||
|
text = realPayPrice.format2String(2),
|
||||||
|
textSize = 30,
|
||||||
|
textColor = "#FF0A1428",
|
||||||
|
isBold = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
list.add(TextBean(text = " 元", textSize = 30, textColor = "#FF5E7585"))
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+202
-202
@@ -1,202 +1,202 @@
|
|||||||
package com.sw.dualscreen.presentation.pay
|
//package com.sw.dualscreen.presentation.pay
|
||||||
|
//
|
||||||
import android.annotation.SuppressLint
|
//import android.annotation.SuppressLint
|
||||||
import android.app.Presentation
|
//import android.app.Presentation
|
||||||
import android.os.Bundle
|
//import android.os.Bundle
|
||||||
import android.view.Display
|
//import android.view.Display
|
||||||
import com.sw.dualscreen.R
|
//import com.sw.dualscreen.R
|
||||||
import com.sw.dualscreen.activity.PayActivity
|
//import com.sw.dualscreen.activity.PayActivity
|
||||||
import com.sw.dualscreen.databinding.PresentationScanQrcodePayBinding
|
//import com.sw.dualscreen.databinding.PresentationScanQrcodePayBinding
|
||||||
import com.sw.dualscreen.ext.format2String
|
//import com.sw.dualscreen.ext.format2String
|
||||||
import com.sw.dualscreen.ext.gone
|
//import com.sw.dualscreen.ext.gone
|
||||||
import com.sw.dualscreen.ext.invisible
|
//import com.sw.dualscreen.ext.invisible
|
||||||
import com.sw.dualscreen.ext.load
|
//import com.sw.dualscreen.ext.load
|
||||||
import com.sw.dualscreen.ext.visible
|
//import com.sw.dualscreen.ext.visible
|
||||||
import com.sw.dualscreen.model.response.MemberInfo
|
//import com.sw.dualscreen.model.response.MemberInfo
|
||||||
import com.sw.dualscreen.model.response.TextBean
|
//import com.sw.dualscreen.model.response.TextBean
|
||||||
import com.sw.dualscreen.utils.SpannedUtils
|
//import com.sw.dualscreen.utils.SpannedUtils
|
||||||
|
//
|
||||||
class ScanQrCodePayPresentation(
|
//class ScanQrCodePayPresentation(
|
||||||
val activity: PayActivity,
|
// val activity: PayActivity,
|
||||||
display: Display,
|
// display: Display,
|
||||||
val type: Int,
|
// val type: Int,
|
||||||
private val onDismissListener: () -> Unit = {}
|
// private val onDismissListener: () -> Unit = {}
|
||||||
) : Presentation(activity, display) {
|
//) : Presentation(activity, display) {
|
||||||
|
//
|
||||||
//type = 0,扫码支付默认显示二维码
|
// //type = 0,扫码支付默认显示二维码
|
||||||
//type = 1,会员结算显示二维码,是会员则显示名字、头像、手机号、可用余额
|
// //type = 1,会员结算显示二维码,是会员则显示名字、头像、手机号、可用余额
|
||||||
//type = 2,支付成功,是会员则显示名字、头像、手机号、可用余额
|
// //type = 2,支付成功,是会员则显示名字、头像、手机号、可用余额
|
||||||
|
//
|
||||||
private lateinit var binding: PresentationScanQrcodePayBinding
|
// private lateinit var binding: PresentationScanQrcodePayBinding
|
||||||
|
//
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
// override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
// super.onCreate(savedInstanceState)
|
||||||
binding = PresentationScanQrcodePayBinding.inflate(layoutInflater)
|
// binding = PresentationScanQrcodePayBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
// setContentView(binding.root)
|
||||||
window?.setBackgroundDrawableResource(android.R.color.transparent)
|
// window?.setBackgroundDrawableResource(android.R.color.transparent)
|
||||||
initView()
|
// initView()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
var foodName: String? = null
|
// var foodName: String? = null
|
||||||
var payQrCodePic: Any? = null
|
// var payQrCodePic: Any? = null
|
||||||
|
//
|
||||||
//总价格
|
// //总价格
|
||||||
var totalPrice = 0.0
|
// var totalPrice = 0.0
|
||||||
|
//
|
||||||
//余额
|
// //余额
|
||||||
private var balance = 0.0
|
// private var balance = 0.0
|
||||||
|
//
|
||||||
//实际支付金额
|
// //实际支付金额
|
||||||
private var realPayPrice = 0.0
|
// private var realPayPrice = 0.0
|
||||||
|
//
|
||||||
//扣除余额
|
// //扣除余额
|
||||||
private var expensesBalance = 0.0
|
// private var expensesBalance = 0.0
|
||||||
|
//
|
||||||
@SuppressLint("SetTextI18n")
|
// @SuppressLint("SetTextI18n")
|
||||||
private fun initView() {
|
// private fun initView() {
|
||||||
when (type) {
|
// when (type) {
|
||||||
0 -> {
|
// 0 -> {
|
||||||
binding.layoutVip.gone()
|
// binding.layoutVip.gone()
|
||||||
binding.layoutPaySuccess.gone()
|
// binding.layoutPaySuccess.gone()
|
||||||
binding.layoutScanQrCode.visible()
|
// binding.layoutScanQrCode.visible()
|
||||||
|
//
|
||||||
binding.tvPayTip.text = "请扫码支付或出示付款码"
|
// binding.tvPayTip.text = "请扫码支付或出示付款码"
|
||||||
binding.tvFoodName.text = foodName
|
// binding.tvFoodName.text = foodName
|
||||||
binding.tvRealAmount.text = SpannedUtils.getAmountText(
|
// binding.tvRealAmount.text = SpannedUtils.getAmountText(
|
||||||
listOf(
|
// listOf(
|
||||||
TextBean(text = "¥", textSize = 32),
|
// TextBean(text = "¥", textSize = 32),
|
||||||
TextBean(text = totalPrice.format2String(2), textSize = 48),
|
// TextBean(text = totalPrice.format2String(2), textSize = 48),
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
binding.ivPayQrCode.load(payQrCodePic)
|
// binding.ivPayQrCode.load(payQrCodePic)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
1 -> {
|
// 1 -> {
|
||||||
val memberInfo = activity.memberInfo
|
// val memberInfo = activity.memberInfo
|
||||||
binding.layoutVip.run {
|
// binding.layoutVip.run {
|
||||||
if (memberInfo != null) visible() else gone()
|
// if (memberInfo != null) visible() else gone()
|
||||||
}
|
// }
|
||||||
binding.layoutPaySuccess.gone()
|
// binding.layoutPaySuccess.gone()
|
||||||
binding.layoutScanQrCode.visible()
|
// binding.layoutScanQrCode.visible()
|
||||||
|
//
|
||||||
balance = (memberInfo?.topUpBalance ?: 0.0) + (memberInfo?.rewardBalance ?: 0.0)
|
// balance = (memberInfo?.topUpBalance ?: 0.0) + (memberInfo?.rewardBalance ?: 0.0)
|
||||||
realPayPrice = if (balance >= totalPrice) 0.0 else totalPrice - balance
|
// realPayPrice = if (balance >= totalPrice) 0.0 else totalPrice - balance
|
||||||
expensesBalance = if (balance >= totalPrice) totalPrice else balance
|
// expensesBalance = if (balance >= totalPrice) totalPrice else balance
|
||||||
|
//
|
||||||
memberInfo?.let { loadUserInfo(it) }
|
// memberInfo?.let { loadUserInfo(it) }
|
||||||
binding.tvUserBalance.text = SpannedUtils.getAmountText(
|
// binding.tvUserBalance.text = SpannedUtils.getAmountText(
|
||||||
listOf(
|
// listOf(
|
||||||
TextBean(text = "¥", textSize = 20),
|
// TextBean(text = "¥", textSize = 20),
|
||||||
TextBean(text = balance.format2String(2), textSize = 32),
|
// TextBean(text = balance.format2String(2), textSize = 32),
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
binding.tvFoodName.text = foodName
|
// binding.tvFoodName.text = foodName
|
||||||
binding.tvRealAmount.text = SpannedUtils.getAmountText(
|
// binding.tvRealAmount.text = SpannedUtils.getAmountText(
|
||||||
listOf(
|
// listOf(
|
||||||
TextBean(text = "¥", textSize = 32),
|
// TextBean(text = "¥", textSize = 32),
|
||||||
TextBean(text = totalPrice.format2String(2), textSize = 48),
|
// TextBean(text = totalPrice.format2String(2), textSize = 48),
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
binding.ivPayQrCode.run {
|
// binding.ivPayQrCode.run {
|
||||||
// load(payQrCodePic)
|
//// load(payQrCodePic)
|
||||||
if (balance >= totalPrice) invisible() else visible()
|
// if (balance >= totalPrice) invisible() else visible()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
binding.tvPayTip.text = SpannedUtils.getAmountText(getAmountList())
|
// binding.tvPayTip.text = SpannedUtils.getAmountText(getAmountList())
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
2 -> {
|
// 2 -> {
|
||||||
val memberInfo = activity.memberInfo
|
// val memberInfo = activity.memberInfo
|
||||||
binding.layoutVip.run {
|
// binding.layoutVip.run {
|
||||||
if (memberInfo != null) visible() else gone()
|
// if (memberInfo != null) visible() else gone()
|
||||||
}
|
// }
|
||||||
binding.layoutPaySuccess.visible()
|
// binding.layoutPaySuccess.visible()
|
||||||
binding.layoutScanQrCode.gone()
|
// binding.layoutScanQrCode.gone()
|
||||||
|
//
|
||||||
balance = if (memberInfo != null) (memberInfo.topUpBalance
|
// balance = if (memberInfo != null) (memberInfo.topUpBalance
|
||||||
?: 0.0) + (memberInfo.rewardBalance ?: 0.0) else 0.0
|
// ?: 0.0) + (memberInfo.rewardBalance ?: 0.0) else 0.0
|
||||||
realPayPrice = if (balance >= totalPrice) 0.0 else totalPrice - balance
|
// realPayPrice = if (balance >= totalPrice) 0.0 else totalPrice - balance
|
||||||
expensesBalance = if (balance >= totalPrice) totalPrice else balance
|
// expensesBalance = if (balance >= totalPrice) totalPrice else balance
|
||||||
|
//
|
||||||
memberInfo?.let { loadUserInfo(it) }
|
// memberInfo?.let { loadUserInfo(it) }
|
||||||
val remainBalance = if (balance >= totalPrice) balance - totalPrice else 0.0
|
// val remainBalance = if (balance >= totalPrice) balance - totalPrice else 0.0
|
||||||
binding.tvUserBalance.text = SpannedUtils.getAmountText(
|
// binding.tvUserBalance.text = SpannedUtils.getAmountText(
|
||||||
listOf(
|
// listOf(
|
||||||
TextBean(text = "¥", textSize = 24),
|
// TextBean(text = "¥", textSize = 24),
|
||||||
TextBean(text = remainBalance.format2String(2), textSize = 36),
|
// TextBean(text = remainBalance.format2String(2), textSize = 36),
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
val showBalance = expensesBalance.format2String(2)
|
// val showBalance = expensesBalance.format2String(2)
|
||||||
val showTotal = totalPrice.format2String(2)
|
// val showTotal = totalPrice.format2String(2)
|
||||||
binding.tvPayInfo.text = "余额扣除 $showBalance 元,在线支付 $showTotal 元"
|
// binding.tvPayInfo.text = "余额扣除 $showBalance 元,在线支付 $showTotal 元"
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
fun loadQrCodeImage(qrCodeUrl: String?) {
|
// fun loadQrCodeImage(qrCodeUrl: String?) {
|
||||||
binding.ivPayQrCode.load(qrCodeUrl)
|
// binding.ivPayQrCode.load(qrCodeUrl)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private fun loadUserInfo(item: MemberInfo) {
|
// private fun loadUserInfo(item: MemberInfo) {
|
||||||
binding.ivHeadPic.load(
|
// binding.ivHeadPic.load(
|
||||||
if(item.faceUrl.isNullOrBlank()) R.drawable.ic_avatar_default
|
// if(item.faceUrl.isNullOrBlank()) R.drawable.ic_avatar_default
|
||||||
else item.faceUrl
|
// else item.faceUrl
|
||||||
)
|
// )
|
||||||
binding.tvUserName.text = item.name
|
// binding.tvUserName.text = item.name
|
||||||
|
//
|
||||||
val phone = item.phone ?: ""
|
// val phone = item.phone ?: ""
|
||||||
binding.tvUserPhone.text =
|
// binding.tvUserPhone.text =
|
||||||
if (phone.length == 11) phone.replace(phone.substring(3, 7), "****")
|
// if (phone.length == 11) phone.replace(phone.substring(3, 7), "****")
|
||||||
else phone
|
// else phone
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private fun getAmountList(): List<TextBean> {
|
// private fun getAmountList(): List<TextBean> {
|
||||||
val list: MutableList<TextBean> = mutableListOf()
|
// val list: MutableList<TextBean> = mutableListOf()
|
||||||
|
//
|
||||||
list.add(TextBean(text = "余额扣除 ", textSize = 30, textColor = "#FF5E7585"))
|
// list.add(TextBean(text = "余额扣除 ", textSize = 30, textColor = "#FF5E7585"))
|
||||||
list.add(
|
// list.add(
|
||||||
TextBean(
|
// TextBean(
|
||||||
text = "-${expensesBalance.format2String(2)}",
|
// text = "-${expensesBalance.format2String(2)}",
|
||||||
textSize = 30,
|
// textSize = 30,
|
||||||
textColor = "#FF0A1428",
|
// textColor = "#FF0A1428",
|
||||||
isBold = true
|
// isBold = true
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
if (balance >= totalPrice) {
|
// if (balance >= totalPrice) {
|
||||||
//余额大于等于总价格,使用余额支付
|
// //余额大于等于总价格,使用余额支付
|
||||||
list.add(TextBean(text = " 元,扣除后可用余额 ", textSize = 30, textColor = "#FF5E7585"))
|
// list.add(TextBean(text = " 元,扣除后可用余额 ", textSize = 30, textColor = "#FF5E7585"))
|
||||||
val remainingBalance = balance - totalPrice
|
// val remainingBalance = balance - totalPrice
|
||||||
list.add(
|
// list.add(
|
||||||
TextBean(
|
// TextBean(
|
||||||
text = remainingBalance.format2String(2),
|
// text = remainingBalance.format2String(2),
|
||||||
textSize = 30,
|
// textSize = 30,
|
||||||
textColor = "#FF0A1428",
|
// textColor = "#FF0A1428",
|
||||||
isBold = true
|
// isBold = true
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
} else {
|
// } else {
|
||||||
//余额小于总价格,使用余额+扫码支付
|
// //余额小于总价格,使用余额+扫码支付
|
||||||
//实际支付金额
|
// //实际支付金额
|
||||||
list.add(TextBean(text = " 元,还需支付 ", textSize = 30, textColor = "#FF5E7585"))
|
// list.add(TextBean(text = " 元,还需支付 ", textSize = 30, textColor = "#FF5E7585"))
|
||||||
list.add(
|
// list.add(
|
||||||
TextBean(
|
// TextBean(
|
||||||
text = realPayPrice.format2String(2),
|
// text = realPayPrice.format2String(2),
|
||||||
textSize = 30,
|
// textSize = 30,
|
||||||
textColor = "#FF0A1428",
|
// textColor = "#FF0A1428",
|
||||||
isBold = true
|
// isBold = true
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
list.add(TextBean(text = " 元", textSize = 30, textColor = "#FF5E7585"))
|
// list.add(TextBean(text = " 元", textSize = 30, textColor = "#FF5E7585"))
|
||||||
|
//
|
||||||
return list
|
// return list
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override fun onDisplayRemoved() {
|
// override fun onDisplayRemoved() {
|
||||||
super.onDisplayRemoved()
|
// super.onDisplayRemoved()
|
||||||
onDismissListener()
|
// onDismissListener()
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
@@ -0,0 +1,418 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFE7EFF8">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/flFacePay"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFE7EFF8"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="28dp"
|
||||||
|
android:layout_marginTop="28dp"
|
||||||
|
android:background="@drawable/setting_border"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingVertical="56dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvFoodName"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#FF0A1428"
|
||||||
|
android:textSize="40sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="岐山臊子面" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="55dp"
|
||||||
|
android:text="应付金额"
|
||||||
|
android:textColor="#FF5E7585"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvRealAmount"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="28dp"
|
||||||
|
android:textColor="#FFFF3232"
|
||||||
|
android:textSize="32sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="¥36.80" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="28dp"
|
||||||
|
android:background="@drawable/setting_border"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="79dp"
|
||||||
|
android:text="会员验证"
|
||||||
|
android:textColor="#ff0a1428"
|
||||||
|
android:textSize="27sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<!-- android:layout_width="300dp"-->
|
||||||
|
<!-- android:layout_height="510dp"-->
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="510dp">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/flFace"
|
||||||
|
android:layout_width="400dp"
|
||||||
|
android:layout_height="680dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="-85dp">
|
||||||
|
|
||||||
|
<TextureView
|
||||||
|
android:id="@+id/dual_camera_texture_preview_rgb"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
<com.sw.plate.utils.arcface.FaceRectView
|
||||||
|
android:id="@+id/dual_camera_face_rect_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/flRecognizeIr"
|
||||||
|
android:layout_width="1.33dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<TextureView
|
||||||
|
android:id="@+id/dual_camera_texture_preview_ir"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<com.sw.plate.utils.arcface.FaceRectView
|
||||||
|
android:id="@+id/dual_camera_face_rect_view_ir"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/llCircleArea"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="#FFF4FAFF" />
|
||||||
|
|
||||||
|
<com.sw.dualscreen.view.HollowOvalInRectView
|
||||||
|
android:layout_width="400dp"
|
||||||
|
android:layout_height="510dp"
|
||||||
|
android:layout_gravity="center_horizontal" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="#FFF4FAFF" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="请正视屏幕进行面部识别..."
|
||||||
|
android:textColor="#ff5e7585"
|
||||||
|
android:textSize="22sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_gravity="bottom|center_horizontal"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
</FrameLayout>
|
||||||
|
<!-- <View-->
|
||||||
|
<!-- android:layout_width="match_parent"-->
|
||||||
|
<!-- android:layout_height="85dp"-->
|
||||||
|
<!-- android:layout_gravity="bottom"-->
|
||||||
|
<!-- android:background="#FFF4FAFF"/>-->
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/flCashPay"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFE7EFF8"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:layout_margin="28dp"
|
||||||
|
android:background="@drawable/setting_border"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvFoodName2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#FF0A1428"
|
||||||
|
android:layout_marginTop="210dp"
|
||||||
|
android:textSize="40sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="岐山臊子面" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="55dp"
|
||||||
|
android:text="应付金额"
|
||||||
|
android:textColor="#FF5E7585"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvRealAmount2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="28dp"
|
||||||
|
android:textColor="#FFFF3232"
|
||||||
|
android:textSize="32sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="¥36.80" />
|
||||||
|
|
||||||
|
<!-- <TextView-->
|
||||||
|
<!-- android:id="@+id/tvPayTip"-->
|
||||||
|
<!-- android:layout_width="wrap_content"-->
|
||||||
|
<!-- android:layout_height="wrap_content"-->
|
||||||
|
<!-- android:layout_marginTop="55dp"-->
|
||||||
|
<!-- android:text="请扫码支付或出示付款码"-->
|
||||||
|
<!-- android:textColor="#FF5E7585"-->
|
||||||
|
<!-- android:textSize="24sp"-->
|
||||||
|
<!-- android:textStyle="bold"-->
|
||||||
|
<!-- tools:ignore="HardcodedText" />-->
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/flQrCodePay"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#FFE7EFF8"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutScanQrCode"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:layout_margin="28dp"
|
||||||
|
android:background="@drawable/setting_border"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvFoodName3"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="327dp"
|
||||||
|
android:textColor="#FF0A1428"
|
||||||
|
android:textSize="40sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="岐山臊子面" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="55dp"
|
||||||
|
android:text="应付金额"
|
||||||
|
android:textColor="#FF5E7585"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvRealAmount3"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="28dp"
|
||||||
|
android:textColor="#FFFF3232"
|
||||||
|
android:textSize="48sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="¥36.80" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivPayQrCode"
|
||||||
|
android:layout_width="333dp"
|
||||||
|
android:layout_height="333dp"
|
||||||
|
android:layout_marginTop="56dp"
|
||||||
|
tools:ignore="ContentDescription"
|
||||||
|
tools:src="@drawable/ic_qrcode" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvPayTip"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="55dp"
|
||||||
|
android:text="请扫码支付或出示付款码"
|
||||||
|
android:textColor="#FF5E7585"
|
||||||
|
android:textSize="24sp"
|
||||||
|
tools:ignore="HardcodedText" />
|
||||||
|
<!-- android:textStyle="bold"-->
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutPaySuccess"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:layout_margin="28dp"
|
||||||
|
android:background="@drawable/setting_border"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:layout_marginTop="471dp"
|
||||||
|
android:src="@drawable/ic_pay_success" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="28dp"
|
||||||
|
android:text="支付成功"
|
||||||
|
android:textColor="#ff00c864"
|
||||||
|
android:textSize="48sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvPayInfo"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="55dp"
|
||||||
|
android:textColor="#FF5E7585"
|
||||||
|
android:textSize="24sp"
|
||||||
|
tools:text="余额扣除 16.80 元,在线支付 20.00 元" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/layoutVip"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardBackgroundColor="@color/white"
|
||||||
|
android:layout_marginTop="56dp"
|
||||||
|
android:layout_marginHorizontal="56dp"
|
||||||
|
app:cardCornerRadius="5dp"
|
||||||
|
app:cardElevation="0dp"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingHorizontal="28dp">
|
||||||
|
|
||||||
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
|
android:id="@+id/ivHeadPic"
|
||||||
|
android:layout_width="84dp"
|
||||||
|
android:layout_height="84dp"
|
||||||
|
android:src="@drawable/ic_avatar_default"
|
||||||
|
android:layout_marginTop="28dp"
|
||||||
|
app:shapeAppearance="@style/CircleStyle"
|
||||||
|
app:strokeColor="@android:color/transparent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvUserName"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="27dp"
|
||||||
|
android:textColor="#ff0a1428"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/tvUserPhone"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/ivHeadPic"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/ivHeadPic"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
|
tools:text="DAMIHU" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvUserPhone"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
android:textColor="#ff889ac2"
|
||||||
|
android:textSize="20sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/ivHeadPic"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/tvUserName"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tvUserName"
|
||||||
|
tools:text="138****8000" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginTop="28dp"
|
||||||
|
android:background="#FFDBE5FB"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/ivHeadPic" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvBalanceName"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="79dp"
|
||||||
|
android:text="可用余额"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:textColor="#ff889ac2"
|
||||||
|
android:textSize="24sp"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/ivHeadPic"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/divider" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvUserBalance"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#FF0A1428"
|
||||||
|
android:textSize="20sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/tvBalanceName"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/tvBalanceName"
|
||||||
|
tools:text="¥16.80" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
Reference in New Issue
Block a user