diff --git a/app/src/main/java/com/supwisdom/activities/consume/ConsumeActivity.kt b/app/src/main/java/com/supwisdom/activities/consume/ConsumeActivity.kt
index 5ae2b1a..5b4a3b7 100644
--- a/app/src/main/java/com/supwisdom/activities/consume/ConsumeActivity.kt
+++ b/app/src/main/java/com/supwisdom/activities/consume/ConsumeActivity.kt
@@ -1,765 +1,772 @@
-package com.supwisdom.activities.consume
-
-import android.annotation.SuppressLint
-import android.app.Activity
-import android.content.Intent
-import android.graphics.Color
-import android.os.Bundle
-import android.os.CountDownTimer
-import android.view.KeyEvent
-import android.view.View
-import android.widget.ImageView
-import android.widget.LinearLayout
-import android.widget.TextView
-import com.supwisdom.R
-import com.supwisdom.activities.BaseActivity
-import com.supwisdom.activities.SPApplication
-import com.supwisdom.activities.consume.bean.CardStatus
-import com.supwisdom.activities.consume.bean.CardUserInfoBean
-import com.supwisdom.activities.menu.MenuActivity
-import com.supwisdom.activities.transdtl.TransdtlActivity
-import com.supwisdom.auxscreen.AuxScreenController
-import com.supwisdom.entity.PayStatus
-import com.supwisdom.entity.PeriodFixPayRecord
-import com.supwisdom.entity.ReversalFlag
-import com.supwisdom.entity.TransdtlUnionRecord
-import com.supwisdom.utils.CommonUtil
-import com.supwisdom.utils.DateUtil
-import com.supwisdom.utils.PublicDef
-import com.supwisdom.utils.SoundUtil
-import com.supwisdom.view.DialogPurchase
-import java.util.*
-import java.util.concurrent.locks.ReentrantLock
-import kotlin.collections.ArrayList
-
-/**
- ** create by zzq on 2019/7/24
- ** @desc
- **/
-@Suppress("DEPRECATION")
-@SuppressLint("NewApi")
-class ConsumeActivity : BaseActivity(), IConsumeView {
-    private lateinit var amountTxt: TextView
-    private lateinit var presenter: ConsumePresenter
-    private lateinit var vLinkstat: TextView
-    private lateinit var vShopname: TextView
-    private lateinit var vCitizenName: TextView
-    private lateinit var vCitizenCardno: TextView
-    private lateinit var vCardstatus: TextView
-    private lateinit var vTime: TextView
-    private lateinit var vLinkLogo: ImageView
-    private lateinit var vLastResult: TextView
-    private lateinit var vLastPayamt: TextView
-    private lateinit var vLastCardno: TextView
-    private lateinit var vLastPayway: TextView
-    private lateinit var vLastPaytime: TextView
-    private lateinit var vLastPayFailreason: TextView
-    private lateinit var vLastPayFailll: LinearLayout
-    private lateinit var vLastPayamtll: LinearLayout
-    private val pos = SPApplication.getInstance().getPos()
-    private var beepManager: BeepManager? = null
-    private val scanLock = ReentrantLock()
-    @Volatile
-    private var cardPaying = false
-    @Volatile
-    private var payStatusEnable = false
-    @Volatile
-    private var isBackRunning = false
-    private var addAmount: Int = 0
-    @Volatile
-    private var amount: Int = 0
-    private var payMode: PayMode? = null
-    private val hotkeyPayMap = hashMapOf<Int, Int>()
-    private val hotkeyPayList = ArrayList<String>()
-    private var payWay: String? = null
-    private var counter: LastPayShowTimer? = null
-    private var lastPayInfo: CardUserInfoBean? = null
-    private var dialogPurchase: DialogPurchase? = null
-    private var periodFixPayList: List<PeriodFixPayRecord>? = null
-    private var periodFixPayEnable = false
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        setContentView(R.layout.activity_consume)
-
-        initView()
-        initData()
-    }
-
-    private fun initData() {
-        presenter = ConsumePresenter(this)
-        presenter.start()
-        beepManager = BeepManager(this)
-        dialogPurchase = DialogPurchase(this, object : DialogPurchase.ICallBack {
-            override fun callback(isManualCancel: Boolean, isPaying: Boolean) {
-                if (isPaying) {
-                    presenter.clickToInterrupt()
-                } else {
-                    when (payMode) {
-                        PayMode.FIXPAY -> checkAmtToPay(amount)
-                        PayMode.HOTKEY -> {
-                            AuxScreenController.getInstance().refreshContent(hotkeyPayList)
-                        }
-                        else -> {
-                            presenter.clickNoPay()
-                            amountTxt.text = ""
-                            AuxScreenController.getInstance()
-                                .refreshContent(Arrays.asList(" 欢迎光临!", " 请刷卡..."))
-                        }
-                    }
-                }
-            }
-
-            override fun callback(code: String) {
-                if (!scanLock.tryLock()) {
-                    return
-                }
-                try {
-                    //正在扣款
-                    if (someWayPaying()) {
-                        return
-                    }
-                    //已扣款
-                    if (!payStatusEnable) {
-                        return
-                    }
-                    beepManager!!.playBeepSoundAndVibrate()
-                    presenter.clickNoPay()
-                    dialogPurchase!!.codePaying = true
-                    dialogPurchase!!.codePayingNoCancelEnable = true
-                    payStatusEnable = false
-                    presenter.codeToPay(code, amount)
-                } finally {
-                    scanLock.unlock()
-                }
-            }
-        })
-        presenter.loadLastTransdtl()
-    }
-
-    private fun someWayPaying(): Boolean {
-        if (cardPaying || dialogPurchase!!.codePaying || isBackRunning) {
-            return true
-        }
-        return false
-    }
-
-    private fun initView() {
-        vShopname = this.findViewById<TextView>(R.id.tv_shopname)
-        vLinkLogo = this.findViewById<ImageView>(R.id.tv_linklogo)
-        vLinkstat = this.findViewById<TextView>(R.id.tv_linkstat)
-        amountTxt = this.findViewById<TextView>(R.id.tv_input_amt)
-        vCitizenName = this.findViewById<TextView>(R.id.tv_citizen_name)
-        vCitizenCardno = this.findViewById<TextView>(R.id.tv_citizen_cardno)
-        vCardstatus = this.findViewById<TextView>(R.id.tv_cardstatus)
-        vTime = this.findViewById<TextView>(R.id.tv_nowtime)
-        vLastResult = this.findViewById<TextView>(R.id.tv_last_pay_result)
-        vLastCardno = this.findViewById<TextView>(R.id.tv_last_cardno)
-        vLastPayamt = this.findViewById<TextView>(R.id.tv_last_payamt)
-        vLastPayway = this.findViewById<TextView>(R.id.tv_last_payway)
-        vLastPaytime = this.findViewById<TextView>(R.id.tv_last_paytime)
-        vLastPayFailreason = this.findViewById<TextView>(R.id.tv_last_failreason)
-        vLastPayFailll = this.findViewById<LinearLayout>(R.id.ll_consume_last_failreason)
-        vLastPayamtll = this.findViewById<LinearLayout>(R.id.ll_consume_last_payamt)
-    }
-
-    override fun onStop() {
-        super.onStop()
-        isBackRunning = true
-    }
-
-    override fun onDestroy() {
-        SoundUtil.releaseMusic()
-        presenter.stop()
-        beepManager!!.close()
-        super.onDestroy()
-    }
-
-    @SuppressLint("SetTextI18n")
-    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
-        if (event.action == KeyEvent.ACTION_DOWN) {
-            presenter.resetOperationTime()
-            when (payMode) {
-                PayMode.FIXPAY -> fixInputPay(event.keyCode)
-                PayMode.HOTKEY -> hotkeyInputPay(event.keyCode)
-                else -> normalInputPay(event.keyCode)
-            }
-        }
-        return super.dispatchKeyEvent(event)
-    }
-
-    private fun fixInputPay(keyCode: Int) {
-        when (keyCode) {
-            KeyEvent.KEYCODE_DPAD_LEFT -> {
-                //'F1'
-                isBackRunning = true
-                jumpActivity(MenuActivity::class.java)
-            }
-            KeyEvent.KEYCODE_DPAD_RIGHT -> {
-                //'F4'
-                jumpActivity(TransdtlActivity::class.java)
-            }
-        }
-    }
-
-    private fun hotkeyInputPay(keyCode: Int) {
-        when (keyCode) {
-            KeyEvent.KEYCODE_0,
-            KeyEvent.KEYCODE_1,
-            KeyEvent.KEYCODE_2,
-            KeyEvent.KEYCODE_3,
-            KeyEvent.KEYCODE_4,
-            KeyEvent.KEYCODE_5,
-            KeyEvent.KEYCODE_6,
-            KeyEvent.KEYCODE_7,
-            KeyEvent.KEYCODE_8,
-            KeyEvent.KEYCODE_9 -> {
-                val key = keyCode - KeyEvent.KEYCODE_0
-                if (hotkeyPayMap.containsKey(key)) {
-                    amount = hotkeyPayMap[key]!!
-                    checkAmtToPay(amount)
-                }
-            }
-            KeyEvent.KEYCODE_DEL -> {
-                //cancel
-                presenter.clickNoPay()
-                AuxScreenController.getInstance().refreshContent(hotkeyPayList)
-            }
-            KeyEvent.KEYCODE_DPAD_LEFT -> {
-                //'F1'
-                isBackRunning = true
-                jumpActivity(MenuActivity::class.java)
-            }
-            KeyEvent.KEYCODE_DPAD_RIGHT -> {
-                //'F4'
-                jumpActivity(TransdtlActivity::class.java)
-            }
-        }
-    }
-
-    private fun normalInputPay(keyCode: Int) {
-        when (keyCode) {
-            KeyEvent.KEYCODE_BACK -> {
-                amountTxt.text = "0"
-                presenter.clickNoPay()
-            }
-            KeyEvent.KEYCODE_0,
-            KeyEvent.KEYCODE_1,
-            KeyEvent.KEYCODE_2,
-            KeyEvent.KEYCODE_3,
-            KeyEvent.KEYCODE_4,
-            KeyEvent.KEYCODE_5,
-            KeyEvent.KEYCODE_6,
-            KeyEvent.KEYCODE_7,
-            KeyEvent.KEYCODE_8,
-            KeyEvent.KEYCODE_9 -> {
-                presenter.clickNoPay()
-                addValueToEdit(keyCode - KeyEvent.KEYCODE_0)
-            }
-            KeyEvent.KEYCODE_POUND, KeyEvent.KEYCODE_PERIOD -> {
-                presenter.clickNoPay()
-                val str = amountTxt.text.toString()
-                if (str.length < 8 && str.indexOf('.') < 0) {
-                    amountTxt.text = "$str."
-                    showScreenAmount()
-                }
-            }
-            KeyEvent.KEYCODE_NUMPAD_ADD -> {
-                //'+'
-                addAmount += getCurAmount()
-                amountTxt.text = ""
-                showScreenAmount()
-            }
-            KeyEvent.KEYCODE_DPAD_LEFT -> {
-                //'F1'
-                isBackRunning = true
-                jumpActivity(MenuActivity::class.java)
-            }
-//                KeyEvent.KEYCODE_DPAD_UP ->
-            //'F2'
-//                KeyEvent.KEYCODE_DPAD_DOWN ->
-            //'F3'
-            KeyEvent.KEYCODE_DPAD_RIGHT -> {
-                //'F4'
-                jumpActivity(TransdtlActivity::class.java)
-            }
-            KeyEvent.KEYCODE_DEL -> {
-                //cancel
-                presenter.clickNoPay()
-                delValueToEdit()
-            }
-            KeyEvent.KEYCODE_ENTER -> {
-                amount = getCurAmount() + addAmount
-                if (amount > 0) {
-                    checkAmtToPay(amount)
-                } else {
-                    AuxScreenController.getInstance()
-                        .refreshContent(Arrays.asList("请先输入金额:", "金额不能为0"))
-                }
-            }
-        }
-    }
-
-    override fun showUserInfo(info: CardUserInfoBean) {
-        CommonUtil.acquireWakeLock(this)
-        vCitizenName.text = info.username
-        vCitizenCardno.text = info.cardno
-        vCardstatus.text = info.cardstatus?.toString()
-        if (info.cardstatus != CardStatus.NORMAL) {
-            vCardstatus.setTextColor(Color.RED)
-        } else {
-            vCardstatus.setTextColor(resources.getColor(R.color.blue))
-        }
-    }
-
-    override fun screenSaver(flag: Boolean) {
-        if (flag) {
-            CommonUtil.setAppBrightness(this, PublicDef.SCREEN_SAVER_BRIGHTNESS)
-        } else {
-            CommonUtil.setAppBrightness(this, PublicDef.SCREEN_NORMAL_BRIGHTNESS)
-        }
-    }
-
-    private var lastshowtime: String? = null
-    override fun clearUserInfo(datetime: String) {
-        vCitizenName.text = null
-        vCitizenCardno.text = null
-        vCardstatus.text = null
-        val tmptime = datetime.substring(0, 16)
-        if (lastshowtime != tmptime) {
-            lastshowtime = tmptime
-            vTime.text = tmptime
-            AuxScreenController.getInstance().refreshBottom(tmptime)
-            if (periodFixPayEnable) {
-                parsePeriodFixPay()
-            }
-        }
-        if (dialogPurchase!!.isShowing &&
-            !dialogPurchase!!.isFixPay &&
-            payStatusEnable
-        ) {
-            beepManager!!.playBeepSoundAndVibrate()
-        }
-    }
-
-    override fun onResume() {
-        super.onResume()
-        isBackRunning = false
-        beepManager!!.updatePrefs()
-        dealIntent()
-        refresh()
-        refreshRecentDtl(lastPayInfo)
-    }
-
-    private fun dealIntent() {
-        amount = this.intent.getStringExtra("amount")?.toInt() ?: 0
-        payWay = this.intent.getStringExtra("payway")
-        val operation = this.intent.getStringExtra("operation")
-        if (operation == "reverse") {
-            presenter.clickToReverse(amount)
-            dialogPurchase!!.show("等待冲正", CommonUtil.showFormatAmount("金额", amount))
-        }
-        this.intent.putExtra("amount", "0")
-        this.intent.putExtra("payway", "")
-        this.intent.putExtra("operation", "")
-    }
-
-    override fun onNewIntent(intent: Intent) {
-        this.intent.putExtra("amount", intent.getStringExtra("amount"))
-        this.intent.putExtra("payway", intent.getStringExtra("payway"))
-        this.intent.putExtra("operation", intent.getStringExtra("operation"))
-    }
-
-    private fun refresh() {
-        addAmount = 0
-        amountTxt.text = "0"
-        var shopname = pos.getDynamicPara()!!.shopname
-        if (shopname == null || shopname.length < 9) {
-            vShopname.textSize = resources.getDimension(R.dimen.consume_shopname_text_size_normal)
-        } else {
-            vShopname.textSize = resources.getDimension(R.dimen.consume_shopname_text_size_middle)
-            if (shopname.length > 10) {
-                val len = shopname.length / 2
-                shopname = shopname.substring(0, len) + "\n" + shopname.substring(len)
-            }
-        }
-        vShopname.text = shopname
-
-        refreshLinkStatus(SPApplication.getInstance().isOnline())
-        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime().substring(0, 16))
-        AuxScreenController.getInstance().refreshContent(Arrays.asList(" 欢迎光临!", " 请刷卡..."))
-
-        periodFixPayEnable = false
-        dialogPurchase?.dismiss()
-        pos.getControlPara(PublicDef.CONTROL_FIXAMT)?.also { mode ->
-            when (mode.paraval) {
-                PayMode.HOTKEY.desc -> {
-                    presenter.setFixMode(false)
-                    payMode = PayMode.HOTKEY
-                    hotkeyPayMap.clear()
-                    hotkeyPayList.clear()
-                    pos.getHotkeyPay()?.forEach {
-                        hotkeyPayMap[it.key] = it.amount
-                        hotkeyPayList.add(
-                            String.format(
-                                "按键%d - %.02f元",
-                                it.key,
-                                it.amount / 100.0f
-                            )
-                        )
-                    }
-                    AuxScreenController.getInstance().refreshContent(hotkeyPayList)
-                }
-                PayMode.PERIODFIX.desc -> {
-                    periodFixPayEnable = true
-                    periodFixPayList = pos.getPeriodFixPay()
-                    parsePeriodFixPay()
-                }
-                PayMode.NORMAL.desc -> {
-                    doNormalPay()
-                }
-                else -> {
-                    try {
-                        doFixPay(Integer.parseInt(mode.paraval))
-                    } catch (ex: Exception) {
-                        ex.printStackTrace()
-                    }
-                }
-            }
-        }
-    }
-
-    private fun parsePeriodFixPay() {
-        val nowtime = DateUtil.getNowTimeNoFormat().substring(0, 4)
-        periodFixPayList?.forEach {
-            if (it.beginTime!! <= nowtime && nowtime < it.endTime!!) {
-                if (payMode != PayMode.FIXPAY || amount != it.amount) {
-                    doFixPay(it.amount)
-                }
-                return
-            }
-        }
-        if (payMode != PayMode.NORMAL) {
-            doNormalPay()
-        }
-    }
-
-    private fun doFixPay(fixamt: Int) {
-        presenter.setFixMode(true)
-        payMode = PayMode.FIXPAY
-        checkAmtToPay(fixamt)
-    }
-
-    private fun doNormalPay() {
-        amount = 0
-        presenter.setFixMode(false)
-        payMode = PayMode.NORMAL
-    }
-
-    override fun refreshLinkStatus(isOnline: Boolean) {
-        if (isOnline) {
-            vLinkLogo.setImageDrawable(getDrawable(R.drawable.wireless_on))
-            vLinkstat.text = "联机"
-            vLinkstat.setTextColor(resources.getColor(R.color.blue))
-            AuxScreenController.getInstance().refreshTitle("联机         F4查看上笔记录")
-        } else {
-            vLinkLogo.setImageDrawable(getDrawable(R.drawable.wireless_off))
-            vLinkstat.text = "脱机"
-            vLinkstat.setTextColor(Color.RED)
-            AuxScreenController.getInstance().refreshTitle("脱机         F4查看上笔记录")
-        }
-    }
-
-    override fun showConsumeSuc(info: CardUserInfoBean) {
-        dialogPurchase!!.showPaySuccess(info)
-        val auxList = ArrayList<String>()
-        auxList.add(info.retmsg!!)
-        auxList.add(CommonUtil.showFormatAmount("金额", info.payamt))
-        when {
-            info.amount > info.payamt -> {
-                auxList.add(CommonUtil.showFormatAmount("折扣", info.amount - info.payamt))
-            }
-            info.amount < info.payamt -> {
-                auxList.add(CommonUtil.showFormatAmount("搭伙", info.payamt - info.amount))
-            }
-        }
-        if (info.balance != null) {
-            auxList.add(CommonUtil.showFormatAmount("余额", info.balance!!))
-        }
-        AuxScreenController.getInstance().refreshContent(auxList)
-        SoundUtil.playMusic(applicationContext, R.raw.consume_suc)
-        refreshRecentDtl(info)
-    }
-
-    override fun showConsumeHint(hint: String) {
-        val amountStr = CommonUtil.showFormatAmount("金额", amount)
-        dialogPurchase!!.showProcess(hint, amountStr)
-        AuxScreenController.getInstance().refreshContent(Arrays.asList(hint, amountStr))
-    }
-
-    override fun showConsumeQuery(hint: String) {
-        dialogPurchase!!.showQueryProcess(hint, "请耐心等待")
-        AuxScreenController.getInstance().refreshContent(Arrays.asList(hint, "请耐心等待"))
-    }
-
-    override fun showConsumeInterrupt(info: CardUserInfoBean) {
-        showPayInterrupt(info.cardno)
-        dialogPurchase!!.showPayInterrupt()
-        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("交易取消", "以银行交易为准"))
-        SoundUtil.playMusic(applicationContext, R.raw.pay_cancel)
-    }
-
-    override fun showConsumeFail(info: CardUserInfoBean) {
-        dialogPurchase!!.showPayFail(info)
-        AuxScreenController.getInstance()
-            .refreshContent(Arrays.asList<String>("消费失败", "原因:", info.retmsg))
-        SoundUtil.playMusic(applicationContext, R.raw.consume_fail)
-        refreshRecentDtl(info)
-    }
-
-    override fun showReverseSuc(info: CardUserInfoBean) {
-        dialogPurchase!!.showReverseSuccess(info)
-        AuxScreenController.getInstance()
-            .refreshContent(
-                Arrays.asList<String>(
-                    info.retmsg,
-                    CommonUtil.showFormatAmount("金额", info.payamt)
-                )
-            )
-        SoundUtil.playMusic(applicationContext, R.raw.reversal_suc)
-        refreshRecentDtl(info)
-    }
-
-    override fun showReverseFail(info: CardUserInfoBean) {
-        dialogPurchase!!.showReverseFail(info)
-        AuxScreenController.getInstance()
-            .refreshContent(Arrays.asList<String>("冲正失败", "原因:", info.retmsg))
-        SoundUtil.playMusic(applicationContext, R.raw.reversal_fail)
-        refreshRecentDtl(info)
-    }
-
-    private var lastShowRecentTime: String? = null
-    private fun refreshRecentDtl(info: CardUserInfoBean?) {
-        if (info != null) {
-            val showtime: Long = 30 * 1000
-            lastPayInfo = info
-            if (lastShowRecentTime == null) {
-                if (info.transtime != null) {
-                    val paytime = DateUtil.timeFormatConvertToLong(info.transtime!!)
-                    val nowtime = DateUtil.timeFormatConvertToLong(DateUtil.getNowTimeNoFormat())
-                    if (nowtime - paytime > showtime) {
-                        return
-                    }
-                }
-            }
-            //已显示过不在显示
-            if (lastShowRecentTime == info.transtime) {
-                return
-            }
-            lastShowRecentTime = info.transtime
-
-            if (info.status == PayStatus.SUC) {
-                when {
-                    info.reversalFlag == ReversalFlag.AUTO -> vLastResult.text = "自动冲正"
-                    info.reversalFlag == ReversalFlag.MANUAL -> vLastResult.text = "手动撤销"
-                    else -> vLastResult.text = "消费成功"
-                }
-                vLastPayFailll.visibility = View.GONE
-                vLastPayamtll.visibility = View.VISIBLE
-                vLastPayamt.text = String.format("%.02f元", info.payamt / 100.0f)
-            } else {
-                if (info.reversalFlag == ReversalFlag.AUTO ||
-                    info.reversalFlag == ReversalFlag.MANUAL
-                ) {
-                    vLastResult.text = "冲正失败"
-                } else {
-                    vLastResult.text = "消费失败"
-                }
-                vLastPayFailll.visibility = View.VISIBLE
-                vLastPayamtll.visibility = View.GONE
-                vLastPayFailreason.text = info.retmsg
-            }
-            vLastCardno.text = info.cardno
-            vLastPayway.text = if (info.payway == "code") {
-                "二维码"
-            } else {
-                "市民卡"
-            }
-            val sb = StringBuilder()
-            sb.append(info.transtime?.substring(0, 2)).append(":")
-                .append(info.transtime?.substring(2, 4)).append(":")
-                .append(info.transtime?.substring(4))
-            vLastPaytime.text = sb.toString()
-            resetPayShowCounter(showtime)
-        }
-    }
-
-    private fun showPayInterrupt(cardno: String?) {
-        vLastResult.text = "交易取消"
-        vLastPayFailll.visibility = View.VISIBLE
-        vLastPayamtll.visibility = View.GONE
-        vLastPayFailreason.text = "以银行交易为准"
-        vLastCardno.text = cardno
-        vLastPayway.text = "card"
-        vLastPaytime.text = DateUtil.getNowTime()
-        resetPayShowCounter(30 * 1000)
-    }
-
-    private fun delValueToEdit() {
-        presenter.clickNoPay()
-        val str = amountTxt.text.toString()
-        val len = str.length
-        when {
-            len == 0 ||
-                    len == 1 -> {
-                refresh()
-            }
-            len > 1 -> {
-                amountTxt.text = str.substring(0, len - 1)
-                showScreenAmount()
-            }
-        }
-    }
-
-    private fun checkAmtToPay(inputAmt: Int) {
-        amount = inputAmt
-        amountTxt.text = String.format("%.02f", inputAmt / 100.0f)
-        payStatusEnable = true
-        presenter.clickToPay(inputAmt)
-        when (payMode) {
-            PayMode.FIXPAY -> {
-                AuxScreenController.getInstance()
-                    .refreshContent(
-                        Arrays.asList(
-                            "定额付款",
-                            CommonUtil.showFormatAmount("金额", inputAmt)
-                        )
-                    )
-                showDialogPay(true)
-            }
-            PayMode.HOTKEY -> {
-                AuxScreenController.getInstance()
-                    .refreshContent(
-                        Arrays.asList(
-                            "热键付款",
-                            CommonUtil.showFormatAmount("金额", inputAmt)
-                        )
-                    )
-                showDialogPay(false)
-            }
-            else -> {
-                AuxScreenController.getInstance()
-                    .refreshContent(
-                        Arrays.asList(
-                            "等待付款",
-                            CommonUtil.showFormatAmount("金额", inputAmt)
-                        )
-                    )
-                showDialogPay(false)
-            }
-        }
-    }
-
-    private fun showDialogPay(isFixPay: Boolean) {
-        dialogPurchase!!.codePaying = false
-        dialogPurchase!!.isFixPay = isFixPay
-        dialogPurchase!!.codePayingNoCancelEnable = false
-        dialogPurchase!!.show("请刷卡", CommonUtil.showFormatAmount("金额", amount))
-    }
-
-    private fun getCurAmount(): Int {
-        return try {
-            CommonUtil.YuanToFen(java.lang.Double.parseDouble(amountTxt.text.toString().trim { it <= ' ' }))
-        } catch (ex: Exception) {
-            ex.printStackTrace()
-            0
-        }
-    }
-
-    private fun addValueToEdit(value: Int) {
-        var str = amountTxt.text.toString()
-        if ("0" == str) {
-            str = ""
-        }
-        //如果已经有小数点，则小数点后面不能超过两位
-        if (str.indexOf(".") > 0) {
-            if (str.length - str.indexOf(".") <= 2) {
-                amountTxt.text = "$str$value"
-            }
-        } else {
-            //限制消费金额<10000
-            if (str.length < 4) {
-                amountTxt.text = "$str$value"
-            }
-        }
-        showScreenAmount()
-    }
-
-    private fun clearLastPayResult() {
-        vLastResult.text = null
-        vLastCardno.text = null
-        vLastPayamt.text = null
-        vLastPayway.text = null
-        vLastPaytime.text = null
-        vLastPayFailreason.text = null
-    }
-
-    private fun showScreenAmount() {
-        if (addAmount > 0) {
-            AuxScreenController.getInstance().refreshContent(
-                Arrays.asList(
-                    "输入金额: +" + String.format("%.02f", addAmount / 100.0f),
-                    amountTxt.text.toString()
-                )
-            )
-        } else {
-            AuxScreenController.getInstance()
-                .refreshContent(Arrays.asList("输入金额:", amountTxt.text.toString()))
-        }
-    }
-
-    override fun getActivity(): Activity {
-        return this
-    }
-
-    override fun isBackRunning(): Boolean {
-        return isBackRunning
-    }
-
-    override fun showRecentDtl(record: TransdtlUnionRecord?) {
-        if (record != null) {
-            val info = CardUserInfoBean(PublicDef.SUCCESS, "")
-            info.transdate = record.transdate
-            info.transtime = record.transtime
-            info.username = record.username
-            info.cardno = record.cardno
-            info.payamt = record.payamt
-            info.status = record.status
-            info.payway = record.payway
-            info.reversalFlag = record.reversalflag
-            refreshRecentDtl(info)
-        }
-    }
-
-    override fun cardPayingStatus(isPaying: Boolean) {
-        cardPaying = isPaying
-    }
-
-    private fun resetPayShowCounter(timems: Long) {
-        counter?.cancel()
-        counter = LastPayShowTimer(timems, 500)
-        counter?.start()
-    }
-
-    private inner class LastPayShowTimer(millisInFuture: Long, countDownInterval: Long) :
-        CountDownTimer(millisInFuture, countDownInterval) {
-
-        override fun onTick(millisUntilFinished: Long) {
-
-        }
-
-        override fun onFinish() {
-            clearLastPayResult()
-        }
-    }
+package com.supwisdom.activities.consume
+
+import android.annotation.SuppressLint
+import android.app.Activity
+import android.content.Intent
+import android.graphics.Color
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.view.KeyEvent
+import android.view.View
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.consume.bean.CardStatus
+import com.supwisdom.activities.consume.bean.CardUserInfoBean
+import com.supwisdom.activities.menu.MenuActivity
+import com.supwisdom.activities.transdtl.TransdtlActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.entity.PayStatus
+import com.supwisdom.entity.PeriodFixPayRecord
+import com.supwisdom.entity.ReversalFlag
+import com.supwisdom.entity.TransdtlUnionRecord
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.utils.PublicDef
+import com.supwisdom.utils.SoundUtil
+import com.supwisdom.view.DialogPurchase
+import java.util.*
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.collections.ArrayList
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+@Suppress("DEPRECATION")
+@SuppressLint("NewApi")
+class ConsumeActivity : BaseActivity(), IConsumeView {
+    private lateinit var amountTxt: TextView
+    private lateinit var presenter: ConsumePresenter
+    private lateinit var vLinkstat: TextView
+    private lateinit var vShopname: TextView
+    private lateinit var vCitizenName: TextView
+    private lateinit var vCitizenCardno: TextView
+    private lateinit var vCardstatus: TextView
+    private lateinit var vTime: TextView
+    private lateinit var vLinkLogo: ImageView
+    private lateinit var vLastResult: TextView
+    private lateinit var vLastPayamt: TextView
+    private lateinit var vLastCardno: TextView
+    private lateinit var vLastPayway: TextView
+    private lateinit var vLastPaytime: TextView
+    private lateinit var vLastPayFailreason: TextView
+    private lateinit var vLastPayFailll: LinearLayout
+    private lateinit var vLastPayamtll: LinearLayout
+    private val pos = SPApplication.getInstance().getPos()
+    private var beepManager: BeepManager? = null
+    private val scanLock = ReentrantLock()
+    @Volatile
+    private var cardPaying = false
+    @Volatile
+    private var payStatusEnable = false
+    @Volatile
+    private var isBackRunning = false
+    private var addAmount: Int = 0
+    @Volatile
+    private var amount: Int = 0
+    private var payMode: PayMode? = null
+    private val hotkeyPayMap = hashMapOf<Int, Int>()
+    private val hotkeyPayList = ArrayList<String>()
+    private var payWay: String? = null
+    private var counter: LastPayShowTimer? = null
+    private var lastPayInfo: CardUserInfoBean? = null
+    private var dialogPurchase: DialogPurchase? = null
+    private var periodFixPayList: List<PeriodFixPayRecord>? = null
+    private var periodFixPayEnable = false
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_consume)
+
+        initView()
+        initData()
+    }
+
+    private fun initData() {
+        presenter = ConsumePresenter(this)
+        presenter.start()
+        beepManager = BeepManager(this)
+        dialogPurchase = DialogPurchase(this, object : DialogPurchase.ICallBack {
+            override fun callback(isManualCancel: Boolean, isPaying: Boolean) {
+                if (isPaying) {
+                    presenter.clickToInterrupt()
+                } else {
+                    when (payMode) {
+                        PayMode.FIXPAY -> checkAmtToPay(amount)
+                        PayMode.HOTKEY -> {
+                            AuxScreenController.getInstance().refreshContent(hotkeyPayList)
+                        }
+                        else -> {
+                            presenter.clickNoPay()
+                            amountTxt.text = ""
+                            AuxScreenController.getInstance()
+                                .refreshContent(Arrays.asList(" 欢迎光临!", " 请刷卡..."))
+                        }
+                    }
+                }
+            }
+
+            override fun callback(code: String) {
+                if (!scanLock.tryLock()) {
+                    return
+                }
+                try {
+                    //正在扣款
+                    if (someWayPaying()) {
+                        return
+                    }
+                    //已扣款
+                    if (!payStatusEnable) {
+                        return
+                    }
+                    beepManager!!.playBeepSoundAndVibrate()
+                    presenter.clickNoPay()
+                    dialogPurchase!!.codePaying = true
+                    dialogPurchase!!.codePayingNoCancelEnable = true
+                    payStatusEnable = false
+                    presenter.codeToPay(code, amount)
+                } finally {
+                    scanLock.unlock()
+                }
+            }
+        })
+        presenter.loadLastTransdtl()
+    }
+
+    private fun someWayPaying(): Boolean {
+        if (cardPaying || dialogPurchase!!.codePaying || isBackRunning) {
+            return true
+        }
+        return false
+    }
+
+    private fun initView() {
+        vShopname = this.findViewById<TextView>(R.id.tv_shopname)
+        vLinkLogo = this.findViewById<ImageView>(R.id.tv_linklogo)
+        vLinkstat = this.findViewById<TextView>(R.id.tv_linkstat)
+        amountTxt = this.findViewById<TextView>(R.id.tv_input_amt)
+        vCitizenName = this.findViewById<TextView>(R.id.tv_citizen_name)
+        vCitizenCardno = this.findViewById<TextView>(R.id.tv_citizen_cardno)
+        vCardstatus = this.findViewById<TextView>(R.id.tv_cardstatus)
+        vTime = this.findViewById<TextView>(R.id.tv_nowtime)
+        vLastResult = this.findViewById<TextView>(R.id.tv_last_pay_result)
+        vLastCardno = this.findViewById<TextView>(R.id.tv_last_cardno)
+        vLastPayamt = this.findViewById<TextView>(R.id.tv_last_payamt)
+        vLastPayway = this.findViewById<TextView>(R.id.tv_last_payway)
+        vLastPaytime = this.findViewById<TextView>(R.id.tv_last_paytime)
+        vLastPayFailreason = this.findViewById<TextView>(R.id.tv_last_failreason)
+        vLastPayFailll = this.findViewById<LinearLayout>(R.id.ll_consume_last_failreason)
+        vLastPayamtll = this.findViewById<LinearLayout>(R.id.ll_consume_last_payamt)
+    }
+
+    override fun onStop() {
+        super.onStop()
+    }
+
+    override fun onPause() {
+        super.onPause()
+        isBackRunning = true
+    }
+
+    override fun onDestroy() {
+        SoundUtil.releaseMusic()
+        presenter.stop()
+        beepManager!!.close()
+        super.onDestroy()
+    }
+
+    @SuppressLint("SetTextI18n")
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            presenter.resetOperationTime()
+            when (payMode) {
+                PayMode.FIXPAY -> fixInputPay(event.keyCode)
+                PayMode.HOTKEY -> hotkeyInputPay(event.keyCode)
+                else -> normalInputPay(event.keyCode)
+            }
+        }
+        if (event.action == KeyEvent.ACTION_UP &&
+            event.keyCode == KeyEvent.KEYCODE_DPAD_LEFT
+        ) {
+            //'F1'
+            jumpActivity(MenuActivity::class.java)
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    private fun fixInputPay(keyCode: Int) {
+        when (keyCode) {
+            KeyEvent.KEYCODE_DPAD_LEFT -> {
+                //'F1'
+                jumpActivity(MenuActivity::class.java)
+            }
+            KeyEvent.KEYCODE_DPAD_RIGHT -> {
+                //'F4'
+                jumpActivity(TransdtlActivity::class.java)
+            }
+        }
+    }
+
+    private fun hotkeyInputPay(keyCode: Int) {
+        when (keyCode) {
+            KeyEvent.KEYCODE_0,
+            KeyEvent.KEYCODE_1,
+            KeyEvent.KEYCODE_2,
+            KeyEvent.KEYCODE_3,
+            KeyEvent.KEYCODE_4,
+            KeyEvent.KEYCODE_5,
+            KeyEvent.KEYCODE_6,
+            KeyEvent.KEYCODE_7,
+            KeyEvent.KEYCODE_8,
+            KeyEvent.KEYCODE_9 -> {
+                val key = keyCode - KeyEvent.KEYCODE_0
+                if (hotkeyPayMap.containsKey(key)) {
+                    amount = hotkeyPayMap[key]!!
+                    checkAmtToPay(amount)
+                }
+            }
+            KeyEvent.KEYCODE_DEL -> {
+                //cancel
+                presenter.clickNoPay()
+                AuxScreenController.getInstance().refreshContent(hotkeyPayList)
+            }
+            KeyEvent.KEYCODE_DPAD_LEFT -> {
+                //'F1'
+                jumpActivity(MenuActivity::class.java)
+            }
+            KeyEvent.KEYCODE_DPAD_RIGHT -> {
+                //'F4'
+                jumpActivity(TransdtlActivity::class.java)
+            }
+        }
+    }
+
+    private fun normalInputPay(keyCode: Int) {
+        when (keyCode) {
+            KeyEvent.KEYCODE_BACK -> {
+                amountTxt.text = "0"
+                presenter.clickNoPay()
+            }
+            KeyEvent.KEYCODE_0,
+            KeyEvent.KEYCODE_1,
+            KeyEvent.KEYCODE_2,
+            KeyEvent.KEYCODE_3,
+            KeyEvent.KEYCODE_4,
+            KeyEvent.KEYCODE_5,
+            KeyEvent.KEYCODE_6,
+            KeyEvent.KEYCODE_7,
+            KeyEvent.KEYCODE_8,
+            KeyEvent.KEYCODE_9 -> {
+                presenter.clickNoPay()
+                addValueToEdit(keyCode - KeyEvent.KEYCODE_0)
+            }
+            KeyEvent.KEYCODE_POUND, KeyEvent.KEYCODE_PERIOD -> {
+                presenter.clickNoPay()
+                val str = amountTxt.text.toString()
+                if (str.length < 8 && str.indexOf('.') < 0) {
+                    amountTxt.text = "$str."
+                    showScreenAmount()
+                }
+            }
+            KeyEvent.KEYCODE_NUMPAD_ADD -> {
+                //'+'
+                addAmount += getCurAmount()
+                amountTxt.text = ""
+                showScreenAmount()
+            }
+            KeyEvent.KEYCODE_DPAD_LEFT -> {
+                //'F1'
+                jumpActivity(MenuActivity::class.java)
+            }
+//                KeyEvent.KEYCODE_DPAD_UP ->
+            //'F2'
+//                KeyEvent.KEYCODE_DPAD_DOWN ->
+            //'F3'
+            KeyEvent.KEYCODE_DPAD_RIGHT -> {
+                //'F4'
+                jumpActivity(TransdtlActivity::class.java)
+            }
+            KeyEvent.KEYCODE_DEL -> {
+                //cancel
+                presenter.clickNoPay()
+                delValueToEdit()
+            }
+            KeyEvent.KEYCODE_ENTER -> {
+                amount = getCurAmount() + addAmount
+                if (amount > 0) {
+                    checkAmtToPay(amount)
+                } else {
+                    AuxScreenController.getInstance()
+                        .refreshContent(Arrays.asList("请先输入金额:", "金额不能为0"))
+                }
+            }
+        }
+    }
+
+    override fun showUserInfo(info: CardUserInfoBean) {
+        CommonUtil.acquireWakeLock(this)
+        vCitizenName.text = info.username
+        vCitizenCardno.text = info.cardno
+        vCardstatus.text = info.cardstatus?.toString()
+        if (info.cardstatus != CardStatus.NORMAL) {
+            vCardstatus.setTextColor(Color.RED)
+        } else {
+            vCardstatus.setTextColor(resources.getColor(R.color.blue))
+        }
+    }
+
+    override fun screenSaver(flag: Boolean) {
+        if (flag) {
+            CommonUtil.setAppBrightness(this, PublicDef.SCREEN_SAVER_BRIGHTNESS)
+        } else {
+            CommonUtil.setAppBrightness(this, PublicDef.SCREEN_NORMAL_BRIGHTNESS)
+        }
+    }
+
+    private var lastshowtime: String? = null
+    override fun clearUserInfo(datetime: String) {
+        vCitizenName.text = null
+        vCitizenCardno.text = null
+        vCardstatus.text = null
+        val tmptime = datetime.substring(0, 16)
+        if (lastshowtime != tmptime) {
+            lastshowtime = tmptime
+            vTime.text = tmptime
+            AuxScreenController.getInstance().refreshBottom(tmptime)
+            if (periodFixPayEnable) {
+                parsePeriodFixPay()
+            }
+        }
+        if (dialogPurchase!!.isShowing &&
+            !dialogPurchase!!.isFixPay &&
+            payStatusEnable
+        ) {
+            beepManager!!.playBeepSoundAndVibrate()
+        }
+    }
+
+    override fun onResume() {
+        super.onResume()
+        isBackRunning = false
+        beepManager!!.updatePrefs()
+        dealIntent()
+        refresh()
+        refreshRecentDtl(lastPayInfo)
+    }
+
+    private fun dealIntent() {
+        amount = this.intent.getStringExtra("amount")?.toInt() ?: 0
+        payWay = this.intent.getStringExtra("payway")
+        val operation = this.intent.getStringExtra("operation")
+        if (operation == "reverse") {
+            presenter.clickToReverse(amount)
+            dialogPurchase!!.show("等待冲正", CommonUtil.showFormatAmount("金额", amount))
+        }
+        this.intent.putExtra("amount", "0")
+        this.intent.putExtra("payway", "")
+        this.intent.putExtra("operation", "")
+    }
+
+    override fun onNewIntent(intent: Intent) {
+        this.intent.putExtra("amount", intent.getStringExtra("amount"))
+        this.intent.putExtra("payway", intent.getStringExtra("payway"))
+        this.intent.putExtra("operation", intent.getStringExtra("operation"))
+    }
+
+    private fun refresh() {
+        addAmount = 0
+        amountTxt.text = "0"
+        var shopname = pos.getDynamicPara()!!.shopname
+        if (shopname == null || shopname.length < 9) {
+            vShopname.textSize = resources.getDimension(R.dimen.consume_shopname_text_size_normal)
+        } else {
+            vShopname.textSize = resources.getDimension(R.dimen.consume_shopname_text_size_middle)
+            if (shopname.length > 10) {
+                val len = shopname.length / 2
+                shopname = shopname.substring(0, len) + "\n" + shopname.substring(len)
+            }
+        }
+        vShopname.text = shopname
+
+        refreshLinkStatus(SPApplication.getInstance().isOnline())
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime().substring(0, 16))
+        AuxScreenController.getInstance().refreshContent(Arrays.asList(" 欢迎光临!", " 请刷卡..."))
+
+        periodFixPayEnable = false
+        dialogPurchase?.dismiss()
+        pos.getControlPara(PublicDef.CONTROL_FIXAMT)?.also { mode ->
+            when (mode.paraval) {
+                PayMode.HOTKEY.desc -> {
+                    presenter.setFixMode(false)
+                    payMode = PayMode.HOTKEY
+                    hotkeyPayMap.clear()
+                    hotkeyPayList.clear()
+                    pos.getHotkeyPay()?.forEach {
+                        hotkeyPayMap[it.key] = it.amount
+                        hotkeyPayList.add(
+                            String.format(
+                                "按键%d - %.02f元",
+                                it.key,
+                                it.amount / 100.0f
+                            )
+                        )
+                    }
+                    AuxScreenController.getInstance().refreshContent(hotkeyPayList)
+                }
+                PayMode.PERIODFIX.desc -> {
+                    periodFixPayEnable = true
+                    periodFixPayList = pos.getPeriodFixPay()
+                    parsePeriodFixPay()
+                }
+                PayMode.NORMAL.desc -> {
+                    doNormalPay()
+                }
+                else -> {
+                    try {
+                        doFixPay(Integer.parseInt(mode.paraval))
+                    } catch (ex: Exception) {
+                        ex.printStackTrace()
+                    }
+                }
+            }
+        }
+    }
+
+    private fun parsePeriodFixPay() {
+        val nowtime = DateUtil.getNowTimeNoFormat().substring(0, 4)
+        periodFixPayList?.forEach {
+            if (it.beginTime!! <= nowtime && nowtime < it.endTime!!) {
+                if (payMode != PayMode.FIXPAY || amount != it.amount) {
+                    doFixPay(it.amount)
+                }
+                return
+            }
+        }
+        if (payMode != PayMode.NORMAL) {
+            doNormalPay()
+        }
+    }
+
+    private fun doFixPay(fixamt: Int) {
+        presenter.setFixMode(true)
+        payMode = PayMode.FIXPAY
+        checkAmtToPay(fixamt)
+    }
+
+    private fun doNormalPay() {
+        amount = 0
+        presenter.setFixMode(false)
+        payMode = PayMode.NORMAL
+    }
+
+    override fun refreshLinkStatus(isOnline: Boolean) {
+        if (isOnline) {
+            vLinkLogo.setImageDrawable(getDrawable(R.drawable.wireless_on))
+            vLinkstat.text = "联机"
+            vLinkstat.setTextColor(resources.getColor(R.color.blue))
+            AuxScreenController.getInstance().refreshTitle("联机         F4查看上笔记录")
+        } else {
+            vLinkLogo.setImageDrawable(getDrawable(R.drawable.wireless_off))
+            vLinkstat.text = "脱机"
+            vLinkstat.setTextColor(Color.RED)
+            AuxScreenController.getInstance().refreshTitle("脱机         F4查看上笔记录")
+        }
+    }
+
+    override fun showConsumeSuc(info: CardUserInfoBean) {
+        dialogPurchase!!.showPaySuccess(info)
+        val auxList = ArrayList<String>()
+        auxList.add(info.retmsg!!)
+        auxList.add(CommonUtil.showFormatAmount("金额", info.payamt))
+        when {
+            info.amount > info.payamt -> {
+                auxList.add(CommonUtil.showFormatAmount("折扣", info.amount - info.payamt))
+            }
+            info.amount < info.payamt -> {
+                auxList.add(CommonUtil.showFormatAmount("搭伙", info.payamt - info.amount))
+            }
+        }
+        if (info.balance != null) {
+            auxList.add(CommonUtil.showFormatAmount("余额", info.balance!!))
+        }
+        AuxScreenController.getInstance().refreshContent(auxList)
+        SoundUtil.playMusic(applicationContext, R.raw.consume_suc)
+        refreshRecentDtl(info)
+    }
+
+    override fun showConsumeHint(hint: String) {
+        val amountStr = CommonUtil.showFormatAmount("金额", amount)
+        dialogPurchase!!.showProcess(hint, amountStr)
+        AuxScreenController.getInstance().refreshContent(Arrays.asList(hint, amountStr))
+    }
+
+    override fun showConsumeQuery(hint: String) {
+        dialogPurchase!!.showQueryProcess(hint, "请耐心等待")
+        AuxScreenController.getInstance().refreshContent(Arrays.asList(hint, "请耐心等待"))
+    }
+
+    override fun showConsumeInterrupt(info: CardUserInfoBean) {
+        showPayInterrupt(info.cardno)
+        dialogPurchase!!.showPayInterrupt()
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("交易取消", "以银行交易为准"))
+        SoundUtil.playMusic(applicationContext, R.raw.pay_cancel)
+    }
+
+    override fun showConsumeFail(info: CardUserInfoBean) {
+        dialogPurchase!!.showPayFail(info)
+        AuxScreenController.getInstance()
+            .refreshContent(Arrays.asList<String>("消费失败", "原因:", info.retmsg))
+        SoundUtil.playMusic(applicationContext, R.raw.consume_fail)
+        refreshRecentDtl(info)
+    }
+
+    override fun showReverseSuc(info: CardUserInfoBean) {
+        dialogPurchase!!.showReverseSuccess(info)
+        AuxScreenController.getInstance()
+            .refreshContent(
+                Arrays.asList<String>(
+                    info.retmsg,
+                    CommonUtil.showFormatAmount("金额", info.payamt)
+                )
+            )
+        SoundUtil.playMusic(applicationContext, R.raw.reversal_suc)
+        refreshRecentDtl(info)
+    }
+
+    override fun showReverseFail(info: CardUserInfoBean) {
+        dialogPurchase!!.showReverseFail(info)
+        AuxScreenController.getInstance()
+            .refreshContent(Arrays.asList<String>("冲正失败", "原因:", info.retmsg))
+        SoundUtil.playMusic(applicationContext, R.raw.reversal_fail)
+        refreshRecentDtl(info)
+    }
+
+    private var lastShowRecentTime: String? = null
+    private fun refreshRecentDtl(info: CardUserInfoBean?) {
+        if (info != null) {
+            val showtime: Long = 30 * 1000
+            lastPayInfo = info
+            if (lastShowRecentTime == null) {
+                if (info.transtime != null) {
+                    val paytime = DateUtil.timeFormatConvertToLong(info.transtime!!)
+                    val nowtime = DateUtil.timeFormatConvertToLong(DateUtil.getNowTimeNoFormat())
+                    if (nowtime - paytime > showtime) {
+                        return
+                    }
+                }
+            }
+            //已显示过不在显示
+            if (lastShowRecentTime == info.transtime) {
+                return
+            }
+            lastShowRecentTime = info.transtime
+
+            if (info.status == PayStatus.SUC) {
+                when {
+                    info.reversalFlag == ReversalFlag.AUTO -> vLastResult.text = "自动冲正"
+                    info.reversalFlag == ReversalFlag.MANUAL -> vLastResult.text = "手动撤销"
+                    else -> vLastResult.text = "消费成功"
+                }
+                vLastPayFailll.visibility = View.GONE
+                vLastPayamtll.visibility = View.VISIBLE
+                vLastPayamt.text = String.format("%.02f元", info.payamt / 100.0f)
+            } else {
+                if (info.reversalFlag == ReversalFlag.AUTO ||
+                    info.reversalFlag == ReversalFlag.MANUAL
+                ) {
+                    vLastResult.text = "冲正失败"
+                } else {
+                    vLastResult.text = "消费失败"
+                }
+                vLastPayFailll.visibility = View.VISIBLE
+                vLastPayamtll.visibility = View.GONE
+                vLastPayFailreason.text = info.retmsg
+            }
+            vLastCardno.text = info.cardno
+            vLastPayway.text = if (info.payway == "code") {
+                "二维码"
+            } else {
+                "市民卡"
+            }
+            val sb = StringBuilder()
+            sb.append(info.transtime?.substring(0, 2)).append(":")
+                .append(info.transtime?.substring(2, 4)).append(":")
+                .append(info.transtime?.substring(4))
+            vLastPaytime.text = sb.toString()
+            resetPayShowCounter(showtime)
+        }
+    }
+
+    private fun showPayInterrupt(cardno: String?) {
+        vLastResult.text = "交易取消"
+        vLastPayFailll.visibility = View.VISIBLE
+        vLastPayamtll.visibility = View.GONE
+        vLastPayFailreason.text = "以银行交易为准"
+        vLastCardno.text = cardno
+        vLastPayway.text = "card"
+        vLastPaytime.text = DateUtil.getNowTime()
+        resetPayShowCounter(30 * 1000)
+    }
+
+    private fun delValueToEdit() {
+        presenter.clickNoPay()
+        val str = amountTxt.text.toString()
+        val len = str.length
+        when {
+            len == 0 ||
+                    len == 1 -> {
+                refresh()
+            }
+            len > 1 -> {
+                amountTxt.text = str.substring(0, len - 1)
+                showScreenAmount()
+            }
+        }
+    }
+
+    private fun checkAmtToPay(inputAmt: Int) {
+        amount = inputAmt
+        amountTxt.text = String.format("%.02f", inputAmt / 100.0f)
+        payStatusEnable = true
+        presenter.clickToPay(inputAmt)
+        when (payMode) {
+            PayMode.FIXPAY -> {
+                AuxScreenController.getInstance()
+                    .refreshContent(
+                        Arrays.asList(
+                            "定额付款",
+                            CommonUtil.showFormatAmount("金额", inputAmt)
+                        )
+                    )
+                showDialogPay(true)
+            }
+            PayMode.HOTKEY -> {
+                AuxScreenController.getInstance()
+                    .refreshContent(
+                        Arrays.asList(
+                            "热键付款",
+                            CommonUtil.showFormatAmount("金额", inputAmt)
+                        )
+                    )
+                showDialogPay(false)
+            }
+            else -> {
+                AuxScreenController.getInstance()
+                    .refreshContent(
+                        Arrays.asList(
+                            "等待付款",
+                            CommonUtil.showFormatAmount("金额", inputAmt)
+                        )
+                    )
+                showDialogPay(false)
+            }
+        }
+    }
+
+    private fun showDialogPay(isFixPay: Boolean) {
+        dialogPurchase!!.codePaying = false
+        dialogPurchase!!.isFixPay = isFixPay
+        dialogPurchase!!.codePayingNoCancelEnable = false
+        dialogPurchase!!.show("请刷卡", CommonUtil.showFormatAmount("金额", amount))
+    }
+
+    private fun getCurAmount(): Int {
+        return try {
+            CommonUtil.YuanToFen(java.lang.Double.parseDouble(amountTxt.text.toString().trim { it <= ' ' }))
+        } catch (ex: Exception) {
+            ex.printStackTrace()
+            0
+        }
+    }
+
+    private fun addValueToEdit(value: Int) {
+        var str = amountTxt.text.toString()
+        if ("0" == str) {
+            str = ""
+        }
+        //如果已经有小数点，则小数点后面不能超过两位
+        if (str.indexOf(".") > 0) {
+            if (str.length - str.indexOf(".") <= 2) {
+                amountTxt.text = "$str$value"
+            }
+        } else {
+            //限制消费金额<10000
+            if (str.length < 4) {
+                amountTxt.text = "$str$value"
+            }
+        }
+        showScreenAmount()
+    }
+
+    private fun clearLastPayResult() {
+        vLastResult.text = null
+        vLastCardno.text = null
+        vLastPayamt.text = null
+        vLastPayway.text = null
+        vLastPaytime.text = null
+        vLastPayFailreason.text = null
+    }
+
+    private fun showScreenAmount() {
+        if (addAmount > 0) {
+            AuxScreenController.getInstance().refreshContent(
+                Arrays.asList(
+                    "输入金额: +" + String.format("%.02f", addAmount / 100.0f),
+                    amountTxt.text.toString()
+                )
+            )
+        } else {
+            AuxScreenController.getInstance()
+                .refreshContent(Arrays.asList("输入金额:", amountTxt.text.toString()))
+        }
+    }
+
+    override fun getActivity(): Activity {
+        return this
+    }
+
+    override fun isBackRunning(): Boolean {
+        return isBackRunning
+    }
+
+    override fun showRecentDtl(record: TransdtlUnionRecord?) {
+        if (record != null) {
+            val info = CardUserInfoBean(PublicDef.SUCCESS, "")
+            info.transdate = record.transdate
+            info.transtime = record.transtime
+            info.username = record.username
+            info.cardno = record.cardno
+            info.payamt = record.payamt
+            info.status = record.status
+            info.payway = record.payway
+            info.reversalFlag = record.reversalflag
+            refreshRecentDtl(info)
+        }
+    }
+
+    override fun cardPayingStatus(isPaying: Boolean) {
+        cardPaying = isPaying
+    }
+
+    private fun resetPayShowCounter(timems: Long) {
+        counter?.cancel()
+        counter = LastPayShowTimer(timems, 500)
+        counter?.start()
+    }
+
+    private inner class LastPayShowTimer(millisInFuture: Long, countDownInterval: Long) :
+        CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+
+        }
+
+        override fun onFinish() {
+            clearLastPayResult()
+        }
+    }
 }
\ No newline at end of file
