消费
diff --git a/app/build.gradle b/app/build.gradle
index 3881173..63e7988 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -67,6 +67,7 @@
     compile 'com.android.support:multidex:1.0.3'
     compile 'org.jetbrains.kotlin:kotlin-reflect:1.3.41'
     compile 'org.springframework.android:spring-android-core:1.0.1.RELEASE'
-    compile files('libs/apache-httpcomponents-httpcore.jar')
+    compile 'org.apache.httpcomponents:httpcore:4.4.10'
+//    compile files('libs/apache-httpcomponents-httpcore.jar')
     compile files('libs/zxinglibsl.jar')
 }
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6830380..78ca339 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -71,10 +71,6 @@
             <intent-filter>
                 <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/>
             </intent-filter>
-
-            <meta-data
-                    android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"
-                    android:resource="@xml/device_filter"/>
         </activity>
 
         <service android:name=".activities.ServiceDemo">
@@ -83,11 +79,30 @@
             </intent-filter>
         </service>
 
-        <!--<activity-->
-        <!--android:name=".activities.consume.WaitActivity"-->
-        <!--android:label="@string/title_activity_consume"-->
-        <!--android:launchMode="singleInstance"/>-->
-
+        <activity
+                android:name=".activities.consume.ConsumeActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleInstance"/>
+        <activity
+                android:name=".activities.init.InitActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.cardlib.CardlibActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.load.LoadActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.unregister.UnregisterActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.upgrade.UpgradeAcvitity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
     </application>
 
 </manifest>
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/SPApplication.kt b/app/src/main/java/com/supwisdom/activities/SPApplication.kt
index 16adb48..61e704d 100644
--- a/app/src/main/java/com/supwisdom/activities/SPApplication.kt
+++ b/app/src/main/java/com/supwisdom/activities/SPApplication.kt
@@ -15,6 +15,8 @@
  **/
 class SPApplication : MultiDexApplication() {
     private var mPos: Pos? = null
+    @Volatile
+    private var epayLinking: Boolean = false //链路状态 true 联机
 
     companion object {
         @Volatile
@@ -36,6 +38,14 @@
         return mPos!!
     }
 
+    fun setEpayLinking(isOnline: Boolean) {
+        epayLinking = isOnline
+    }
+
+    fun isOnline(): Boolean {
+        return epayLinking
+    }
+
     override fun onCreate() {
         super.onCreate()
         mInstance = this
diff --git a/app/src/main/java/com/supwisdom/activities/cardlib/CardlibActivity.kt b/app/src/main/java/com/supwisdom/activities/cardlib/CardlibActivity.kt
new file mode 100644
index 0000000..a85fbc5
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/cardlib/CardlibActivity.kt
@@ -0,0 +1,11 @@
+package com.supwisdom.activities.cardlib
+
+import com.supwisdom.activities.BaseActivity
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardlibActivity : BaseActivity() {
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/ConsumePresenter.kt b/app/src/main/java/com/supwisdom/activities/consume/ConsumePresenter.kt
new file mode 100644
index 0000000..d42ccfc
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/ConsumePresenter.kt
@@ -0,0 +1,8 @@
+package com.supwisdom.activities.consume
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class ConsumePresenter constructor(iConsumeView: IConsumeView){
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/bean/CardBean.kt b/app/src/main/java/com/supwisdom/activities/consume/bean/CardBean.kt
new file mode 100644
index 0000000..162ff9b
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/bean/CardBean.kt
@@ -0,0 +1,16 @@
+package com.supwisdom.activities.consume.bean
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardBean {
+    var cardphyid: String? = null
+    var cardNo: String? = null
+    var idCard: String? = null
+    var expireDate: String? = null
+    var datetime: String? = null
+    var amount: Int = 0
+    var username: String? = null
+    var userid: Int = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/bean/CardPayConfirmRetBean.kt b/app/src/main/java/com/supwisdom/activities/consume/bean/CardPayConfirmRetBean.kt
new file mode 100644
index 0000000..d469a56
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/bean/CardPayConfirmRetBean.kt
@@ -0,0 +1,16 @@
+package com.supwisdom.activities.consume.bean
+
+import com.supwisdom.bean.BaseResp
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardPayConfirmRetBean : BaseResp() {
+    var amount: Int = 0
+    var extraamt: Int = 0
+    var balance: Int = 0
+    var require_query: Boolean = false
+//    var username: String? = null
+//    var userid: Int = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/bean/CardPayInitRetBean.kt b/app/src/main/java/com/supwisdom/activities/consume/bean/CardPayInitRetBean.kt
new file mode 100644
index 0000000..074e62c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/bean/CardPayInitRetBean.kt
@@ -0,0 +1,16 @@
+package com.supwisdom.activities.consume.bean
+
+import com.supwisdom.bean.BaseResp
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardPayInitRetBean : BaseResp() {
+    var billno: String? = null
+    var username: String? = null
+    var userid: Int = 0
+    var anonymous: Boolean = false
+    var sourcetype: String? = null
+    var needpwdconfirm: Boolean = false
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/bean/CardUserInfoBean.kt b/app/src/main/java/com/supwisdom/activities/consume/bean/CardUserInfoBean.kt
new file mode 100644
index 0000000..1fd28f2
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/bean/CardUserInfoBean.kt
@@ -0,0 +1,12 @@
+package com.supwisdom.activities.consume.bean
+
+import com.supwisdom.bean.BaseResp
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardUserInfoBean constructor(retcode: Int, retmsg: String) : BaseResp(retcode, retmsg) {
+    var username: String? = null
+    var showtime: Int = 3
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/mode/CardPayService.kt b/app/src/main/java/com/supwisdom/activities/consume/mode/CardPayService.kt
new file mode 100644
index 0000000..c11c4d8
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/mode/CardPayService.kt
@@ -0,0 +1,284 @@
+package com.supwisdom.activities.consume.mode
+
+import android.os.Handler
+import android.os.Message
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.consume.IConsumeView
+import com.supwisdom.activities.consume.bean.CardBean
+import com.supwisdom.activities.consume.bean.CardPayConfirmRetBean
+import com.supwisdom.activities.consume.bean.CardPayInitRetBean
+import com.supwisdom.activities.consume.bean.CardUserInfoBean
+import com.supwisdom.entity.TransdtlOfflineRecord
+import com.supwisdom.entity.TransdtlOnlineRecord
+import com.supwisdom.epaycard.Cardlib
+import com.supwisdom.exception.CardNotFoundError
+import com.supwisdom.exception.CardPayCancelFailError
+import com.supwisdom.exception.CardPayFailError
+import com.supwisdom.okhttp.TransResp
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.utils.GsonUtil
+import com.supwisdom.utils.PublicDef
+import org.apache.http.HttpStatus
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardPayService constructor(iConsumeView: IConsumeView, handler: Handler) {
+    private val iConsumeView = iConsumeView
+    private val handler = handler
+    private val pos = SPApplication.getInstance().getPos()
+    private val runnable = CardPayRunnable()
+    private val consumeApi = ConsumeApi()
+    @Volatile
+    private var isExist = false
+    @Volatile
+    private var clickStat = ClickStat.INIT
+    @Volatile
+    private var amount: Int = 0
+    private var thread: Thread? = null
+    private lateinit var cardBean: CardBean
+
+    fun start() {
+        isExist = false
+        if (thread == null) {
+            thread = Thread(runnable)
+            thread!!.start()
+        }
+    }
+
+    fun stop() {
+        isExist = true
+        thread?.interrupt()
+        thread = null
+    }
+
+    private inner class CardPayRunnable : Runnable {
+        private lateinit var onlRecord: TransdtlOnlineRecord
+        private lateinit var offRecord: TransdtlOfflineRecord
+        override fun run() {
+            while (!isExist) {
+                CommonUtil.doSleep(100)
+                try {
+                    readCard()
+                    when (clickStat) {
+                        ClickStat.PAY -> {
+                            try {
+                                doConsume()
+                            } catch (ex: CardPayFailError) {
+                                sendMsg(PublicDef.MSG_CARD_PAY_FAIL, getErrorInfo(ex.message))
+                                clickStat = ClickStat.INIT
+                            }
+                        }
+                        ClickStat.REVERSE -> {
+                            try {
+                                doReverse()
+                            } catch (ex: CardPayCancelFailError) {
+                                sendMsg(PublicDef.MSG_CARD_PAYCANCEL_FAIL, getErrorInfo(ex.message))
+                                clickStat = ClickStat.INIT
+                            }
+                        }
+                        ClickStat.INIT -> {
+
+                        }
+                    }
+                } catch (ex: CardNotFoundError) {
+                    ex.printStackTrace()
+                    continue
+                }
+
+            }
+        }
+
+        private fun readCard() {
+            val cardphyid = Cardlib.instance.requestCard()
+            val cardinfo = Cardlib.instance.readCard()
+            cardBean = CardBean()
+            cardBean.cardphyid = cardphyid
+            cardBean.cardNo = cardinfo.cardNo
+            cardBean.idCard = cardinfo.idCard
+            cardBean.expireDate = cardinfo.expireDate
+            cardBean.amount = amount
+            cardBean.datetime = DateUtil.getNowDateTimeFormat()
+        }
+
+        private fun doConsume() {
+            sendMsg(PublicDef.MSG_CARD_PAYING, "正在扣款...")
+            if (SPApplication.getInstance().isOnline()) {
+                if (!doOnlineConsume()) {
+                    /**
+                     * 由于不写卡,联机消费失败直接转离线
+                     */
+                    doOfflineConsume()
+                }
+            } else {
+                doOfflineConsume()
+            }
+        }
+
+        private fun doReverse() {
+            throw CardPayCancelFailError("暂不支持")
+        }
+
+        private fun doOnlineConsume(): Boolean {
+            initTransdtlOnline()
+            var resp = consumeApi.payInit(onlRecord)
+            var result = parseInitResult(resp)
+            if (!result) {
+                return result
+            }
+            resp = consumeApi.payConfirm(onlRecord)
+            result = parseConfirmResult(resp)
+            updateTransdtlOnline(result)
+            return result
+        }
+
+        private fun parseInitResult(resp: TransResp?): Boolean {
+            if (resp == null || resp.retcode != HttpStatus.SC_OK) {
+                SPApplication.getInstance().setEpayLinking(false)
+                return false
+            }
+            val retBean = GsonUtil.GsonToBean(resp.retjson!!, CardPayInitRetBean::class.java)
+            if (retBean.retcode != PublicDef.SUCCESS) {
+                throw CardPayFailError(retBean.retmsg!!)
+            }
+            onlRecord.billno = retBean.billno
+            onlRecord.username = retBean.username
+            onlRecord.userid = retBean.userid
+            return true
+        }
+
+        private fun parseConfirmResult(resp: TransResp?): Boolean {
+            if (resp == null || resp.retcode != HttpStatus.SC_OK) {
+                SPApplication.getInstance().setEpayLinking(false)
+                return false
+            }
+            val retBean = GsonUtil.GsonToBean(resp.retjson!!, CardPayConfirmRetBean::class.java)
+            if (retBean.retcode != PublicDef.SUCCESS) {
+                throw CardPayFailError(retBean.retmsg!!)
+            }
+            if (retBean.require_query) {
+                //TODO
+                throw CardPayFailError("查询未实现")
+            }
+            onlRecord.payamt = retBean.amount
+            onlRecord.extraamt = retBean.extraamt
+            return true
+        }
+
+        private fun initTransdtlOnline() {
+            onlRecord = TransdtlOnlineRecord()
+            var seqno = pos.getTransdtlOnlineMaxSeqno()
+            if (seqno == 0) {
+                seqno = pos.getControlPara(PublicDef.CONTROL_TRANSDTLONL_SEQNO)?.paraval?.toInt() ?: 0
+            }
+            onlRecord.devphyid = pos.getConfigPara()!!.devphyid
+            onlRecord.transdate = cardBean.datetime!!.substring(0, 8)
+            onlRecord.transtime = cardBean.datetime!!.substring(8)
+            onlRecord.devseqno = seqno
+            onlRecord.cardno = cardBean.cardNo
+            onlRecord.cardphyid = cardBean.cardphyid
+            onlRecord.payamt = cardBean.amount
+            onlRecord.extraamt = 0
+            onlRecord.transtype = "card"
+            onlRecord.status = "init"
+            onlRecord.upflag = 1
+            if (!pos.saveTransdtlOnline(onlRecord)) {
+                throw CardPayFailError("保存流水失败")
+            }
+        }
+
+        private fun updateTransdtlOnline(issuccess: Boolean) {
+            if (issuccess) {
+                onlRecord.status = "suc"
+            } else {
+                onlRecord.status = "fail"
+            }
+            onlRecord.upflag = 0
+            if (!pos.updateTransdtlOnline(onlRecord)) {
+                throw CardPayFailError("更新流水失败")
+            }
+        }
+
+        private fun doOfflineConsume() {
+            initTransdtlOffline()
+            checkCardValid()
+            updateTransdtlOffline(true)
+        }
+
+        private fun checkCardValid() {
+            val sysRecord = pos.getSysPara()
+            if (!sysRecord!!.offlineEnable) {
+                throw CardPayFailError("禁止离线交易")
+            }
+            val offdate = DateUtil.getDayDateNoFormatBefore(sysRecord.maxOfflineDays)
+            val validdate = pos.getDynamicPara()!!.lastauthtime?.substring(0, 8) ?: "00000000"
+            if (offdate > validdate) {
+                throw CardPayFailError("设备已脱机${sysRecord.maxOfflineDays}天")
+            }
+
+            val whiteRecord =
+                pos.getWhiteList(offRecord.cardphyid!!, offRecord.cardno!!) ?: throw CardPayFailError("卡无权限")
+            if (whiteRecord.flag == 1) {
+                throw CardPayFailError("卡已锁定")
+            }
+            if (whiteRecord.balance < offRecord.payamt) {
+                throw CardPayFailError("请到联机设备使用")
+            }
+        }
+
+        private fun initTransdtlOffline() {
+            offRecord = TransdtlOfflineRecord()
+            var seqno = pos.getTransdtlOfflineMaxSeqno()
+            if (seqno == 0) {
+                seqno = pos.getControlPara(PublicDef.CONTROL_TRANSDTLOFF_SEQNO)?.paraval?.toInt() ?: 0
+            }
+            offRecord.devphyid = pos.getConfigPara()!!.devphyid
+            offRecord.transdate = cardBean.datetime!!.substring(0, 8)
+            offRecord.transtime = cardBean.datetime!!.substring(8)
+            offRecord.devseqno = seqno
+            offRecord.cardno = cardBean.cardNo
+            offRecord.cardphyid = cardBean.cardphyid
+            offRecord.payamt = cardBean.amount
+            offRecord.extraamt = 0
+            offRecord.managefeetype = "none"
+            offRecord.status = "init"
+            offRecord.upflag = 1
+            if (!pos.saveTransdtlOffline(offRecord)) {
+                throw CardPayFailError("保存流水失败")
+            }
+        }
+
+        private fun updateTransdtlOffline(issuccess: Boolean) {
+            if (issuccess) {
+                offRecord.status = "suc"
+            } else {
+                offRecord.status = "fail"
+            }
+            offRecord.upflag = 0
+            if (!pos.updateTransdtlOffline(offRecord)) {
+                throw CardPayFailError("更新流水失败")
+            }
+        }
+
+        private fun getErrorInfo(errmsg: String?): CardUserInfoBean {
+            val info = CardUserInfoBean(PublicDef.ERROR, errmsg ?: "null")
+            info.showtime = pos.getSysPara()!!.consumeFailShowtime
+            return info
+        }
+
+        private fun sendMsg(code: Int, obj: Any) {
+            val msg = Message()
+            msg.what = code
+            msg.obj = obj
+            handler.sendMessage(msg)
+        }
+    }
+}
+
+enum class ClickStat {
+    INIT,
+    PAY,
+    REVERSE
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/service/ConsumeApi.kt b/app/src/main/java/com/supwisdom/activities/consume/mode/ConsumeApi.kt
similarity index 97%
rename from app/src/main/java/com/supwisdom/service/ConsumeApi.kt
rename to app/src/main/java/com/supwisdom/activities/consume/mode/ConsumeApi.kt
index 5b460fa..54627af 100644
--- a/app/src/main/java/com/supwisdom/service/ConsumeApi.kt
+++ b/app/src/main/java/com/supwisdom/activities/consume/mode/ConsumeApi.kt
@@ -1,4 +1,4 @@
-package com.supwisdom.service
+package com.supwisdom.activities.consume.mode
 
 import com.supwisdom.activities.YktSession
 import com.supwisdom.entity.TransdtlOnlineRecord
diff --git a/app/src/main/java/com/supwisdom/activities/load/LoadPresenter.kt b/app/src/main/java/com/supwisdom/activities/load/LoadPresenter.kt
index 701e029..d72769f 100644
--- a/app/src/main/java/com/supwisdom/activities/load/LoadPresenter.kt
+++ b/app/src/main/java/com/supwisdom/activities/load/LoadPresenter.kt
@@ -4,7 +4,14 @@
 import android.os.Looper
 import android.os.Message
 import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.YktSession
+import com.supwisdom.entity.ControlParaRecord
+import com.supwisdom.service.AuthEpay
+import com.supwisdom.service.EpayApiImpl
 import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.PublicDef
+import com.supwisdom.utils.ThreadPool
+import java.lang.Exception
 
 /**
  ** create by zzq on 2019/7/24
@@ -25,6 +32,7 @@
     private val LOAD_DONE = 3
 
     private var hasInit: Boolean = false
+    @Volatile
     private var loading: Boolean = false
 
     fun isLoading(): Boolean {
@@ -32,7 +40,90 @@
     }
 
     fun start() {
+        loading = true
+        var cfgRecord = pos.getConfigPara()
+        hasInit = cfgRecord?.initOK ?: false
 
+        YktSession.getInstance().setWebAPISession(
+            cfgRecord!!.epayIP!!,
+            cfgRecord.epayPort,
+            cfgRecord.epayUri!!,
+            cfgRecord.devphyid!!,
+            CommonUtil.getCommunicateTime()
+        )
+
+        ThreadPool.getShortPool().execute(Runnable {
+            sendMessage(LOAD_PROGRESS, "正在系统签到...")
+            val apiInterface = EpayApiImpl()
+            val bean = AuthEpay().login()
+            if (bean.retcode != PublicDef.SUCCESS) {
+                sendMessage(LOAD_DONE, bean.retmsg!!)
+                loading = false
+                if (!hasInit) {
+                    sendMessage(JUMP_TO_UNREGISTER, "签到错误:${bean.retcode},${bean.retmsg}")
+                    return@Runnable
+                }
+            } else {
+                cfgRecord = pos.getConfigPara()
+                cfgRecord!!.deviceid = bean.deviceid
+                cfgRecord!!.merchaccno = bean.merchaccno
+                cfgRecord!!.shopname = bean.shopname
+                pos.replaceConfigPara(cfgRecord!!)
+
+                // 保存流水号
+                if (!hasInit) {
+                    saveControlPara(PublicDef.CONTROL_TRANSDTLONL_SEQNO, bean.onlineseqno.toString())
+                    saveControlPara(PublicDef.CONTROL_TRANSDTLOFF_SEQNO, bean.offlineseqno.toString())
+                }
+
+                SPApplication.getInstance().setEpayLinking(true)
+                sendMessage(LOAD_DONE, "系统签到成功")
+            }
+
+            // 设置通讯参数
+//            YktSession.getInstance().setSessionKey(pos.getDynamicPara().getSessionKey())
+            try {
+                sendMessage(LOAD_PROGRESS, "加载系统参数...")
+                apiInterface.downloadSyspara(bean.paraverno, bean.paragroupid)
+                sendMessage(LOAD_DONE, "加载系统参数成功")
+            } catch (ex: Exception) {
+                sendMessage(LOAD_DONE, "加载系统参数失败:${ex.message}")
+                if (!hasInit) {
+                    loading = false
+                    return@Runnable
+                }
+            }
+
+            try {
+                sendMessage(LOAD_PROGRESS, "加载白名单...")
+                apiInterface.downloadWhitelist(bean.cardverno!!)
+                sendMessage(LOAD_DONE, "加载白名单成功")
+            } catch (ex: Exception) {
+                sendMessage(LOAD_DONE, "加载白名单失败:${ex.message}")
+                if (!hasInit) {
+                    loading = false
+                    return@Runnable
+                }
+            }
+
+            cfgRecord = pos.getConfigPara()
+            cfgRecord!!.initOK = true
+            pos.replaceConfigPara(cfgRecord!!)
+
+            val ctlRecord = pos.getControlPara(PublicDef.CONTROL_HAS_REGISTER) ?: ControlParaRecord()
+            ctlRecord.paraname = PublicDef.CONTROL_HAS_REGISTER
+            ctlRecord.paraval = "1"
+            pos.replaceControlPara(ctlRecord)
+
+            sendMessage(LOAD_SUCCESS, "加载成功")
+        })
+    }
+
+    private fun saveControlPara(paraname: String, paraval: String): Boolean {
+        val para = ControlParaRecord()
+        para.paraname = paraname
+        para.paraval = paraval
+        return pos.replaceControlPara(para)
     }
 
     private fun createHandler() {
diff --git a/app/src/main/java/com/supwisdom/activities/splash/SplashActivity.kt b/app/src/main/java/com/supwisdom/activities/splash/SplashActivity.kt
new file mode 100644
index 0000000..6e53f15
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/splash/SplashActivity.kt
@@ -0,0 +1,84 @@
+package com.supwisdom.activities.splash
+
+import android.Manifest
+import android.content.pm.PackageManager
+import android.os.Build
+import android.os.Bundle
+import android.view.View
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.cardlib.CardlibActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class SplashActivity : BaseActivity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_splash)
+        initView()
+    }
+
+    override fun onResume() {
+        super.onResume()
+        refresh()
+        if (hasSdcardPermession()) {
+            processStart()
+        }
+    }
+
+    private fun processStart() {
+        CommonUtil.writeLinnuuxParams()
+        jumpActivity(CardlibActivity::class.java)
+    }
+
+    private fun refresh() {
+        AuxScreenController.getInstance().refreshTitle("新开普智能设备")
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDate())
+        AuxScreenController.getInstance().refreshContent(listOf<String>("欢迎使用智能设备"))
+    }
+
+    private fun initView() {
+        val tv = findViewById<View>(R.id.versionNumber) as TextView
+        tv.text = CommonUtil.getVersionName(applicationContext)
+        AuxScreenController.getInstance().open()
+    }
+
+    private val REQUEST_RETCODE = 99
+
+    private fun hasSdcardPermession(): Boolean {
+        /**
+         * 动态获取权限,Android 6.0 新特性,一些保护权限,除了要在AndroidManifest中声明权限,还要使用如下代码动态获取
+         */
+        if (Build.VERSION.SDK_INT >= 23) {
+            val permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)
+            //验证是否许可权限
+            for (str in permissions) {
+                if (this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {
+                    //申请权限
+                    this.requestPermissions(permissions, REQUEST_RETCODE)
+                    return false
+                }
+            }
+        }
+        return true
+    }
+
+    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+        if (requestCode == REQUEST_RETCODE) {
+            for (i in grantResults.indices) {
+                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
+                    return
+                }
+            }
+            // 请求权限的结果  true代表用户同意了
+            processStart()
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/AuthRetBean.kt b/app/src/main/java/com/supwisdom/bean/AuthRetBean.kt
new file mode 100644
index 0000000..b488ac6
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/AuthRetBean.kt
@@ -0,0 +1,16 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class AuthRetBean constructor(retcode: Int, retmsg: String) : BaseResp(retcode, retmsg) {
+    var deviceid: Int = 0
+    var merchaccno: Int = 0
+    var shopname: String? = null
+    var onlineseqno: Int = 0
+    var offlineseqno: Int = 0
+    var paraverno: Int = 0
+    var paragroupid: Int = 0
+    var cardverno: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/BeanPropEnum.kt b/app/src/main/java/com/supwisdom/db/BeanPropEnum.kt
index d4c1de4..fe6dfc9 100644
--- a/app/src/main/java/com/supwisdom/db/BeanPropEnum.kt
+++ b/app/src/main/java/com/supwisdom/db/BeanPropEnum.kt
@@ -9,7 +9,7 @@
         id,
         returnFlag,
         heatBeat,
-        offlineFlag,
+        offlineEnable,
         maxOfflineDays,
         mngpasswd,
         fixpayGap,
@@ -81,4 +81,11 @@
         status,
         upflag
     }
+
+    enum class WhiteList {
+        cardphyid,
+        cardno,
+        flag,
+        balance
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/DBParaHelper.kt b/app/src/main/java/com/supwisdom/db/DBParaHelper.kt
index ff24314..ebcb7d8 100644
--- a/app/src/main/java/com/supwisdom/db/DBParaHelper.kt
+++ b/app/src/main/java/com/supwisdom/db/DBParaHelper.kt
@@ -18,6 +18,7 @@
         val TABLE_NAME_SYSPARA = "tb_syspara"
         val TABLE_NAME_DYNAMICPARA = "tb_dynamicpara"
         val TABLE_NAME_CONTROLPARA = "tb_controlpara"
+        val TABLE_NAME_WHITELIST = "tb_whitelist"
 
         private var instance: DBParaHelper? = null
         fun getInstance(context: Context): DBParaHelper {
@@ -36,6 +37,15 @@
     /**
      * SQL for create table
      */
+    private val CREATE_TABLE_NAME_WHITELIST = ("create table IF NOT EXISTS "
+            + TABLE_NAME_WHITELIST + " ( "
+            + BeanPropEnum.WhiteList.cardphyid + " varchar(32),"
+            + BeanPropEnum.WhiteList.cardno + " varchar(32),"
+            + BeanPropEnum.WhiteList.flag + " integer,"
+            + BeanPropEnum.WhiteList.balance + " integer,"
+            + "primary key ("
+            + BeanPropEnum.WhiteList.cardphyid + ","
+            + BeanPropEnum.WhiteList.cardno + ") )")
 
     private val CREATE_TABLE_NAME_CONTROLPARA = ("create table IF NOT EXISTS "
             + TABLE_NAME_CONTROLPARA + " ( "
@@ -55,7 +65,7 @@
             + BeanPropEnum.Syspara.id + " long primary key, "
             + BeanPropEnum.Syspara.returnFlag + " integer, "
             + BeanPropEnum.Syspara.heatBeat + " integer, "
-            + BeanPropEnum.Syspara.offlineFlag + " integer, "
+            + BeanPropEnum.Syspara.offlineEnable + " integer, "
             + BeanPropEnum.Syspara.maxOfflineDays + " integer, "
             + BeanPropEnum.Syspara.mngpasswd + " char(6), "
             + BeanPropEnum.Syspara.fixpayGap + " integer, "
@@ -73,6 +83,7 @@
         db.execSQL(CREATE_TABLE_NAME_SYSPARA)
         db.execSQL(CREATE_TABLE_NAME_DYNAMICPARA)
         db.execSQL(CREATE_TABLE_NAME_CONTROLPARA)
+        db.execSQL(CREATE_TABLE_NAME_WHITELIST)
     }
 
     override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
diff --git a/app/src/main/java/com/supwisdom/db/Pos.kt b/app/src/main/java/com/supwisdom/db/Pos.kt
index 79caa4b..205e656 100644
--- a/app/src/main/java/com/supwisdom/db/Pos.kt
+++ b/app/src/main/java/com/supwisdom/db/Pos.kt
@@ -17,8 +17,11 @@
     private val sysParaDao = SysParaDao(context)
     private var sysRecord: SysParaRecord? = null
     private val controlParaDao = ControlParaDao(context)
+    private val whiteListDao = WhiteListDao(context)
     private val transdtlOnlineDao = TransdtlOnlineDao(sdContext)
     private val transdtlOfflineDao = TransdtlOfflineDao(sdContext)
+    private var onlMaxSeqno = 0
+    private var offMaxSeqno = 0
 
     init {
     }
@@ -119,6 +122,36 @@
         return sysRecord
     }
 
+    fun saveWhiteList(list: List<WhiteListRecord>): Boolean {
+        try {
+            whiteListDao.getLock().lock()
+            return whiteListDao.replace(list)
+        } finally {
+            whiteListDao.getLock().unlock()
+        }
+    }
+
+    fun getWhiteList(cardphyid: String, cardno: String): WhiteListRecord? {
+        try {
+            whiteListDao.getLock().lock()
+            return whiteListDao.get(cardphyid, cardno)
+        } finally {
+            whiteListDao.getLock().unlock()
+        }
+    }
+
+    fun getTransdtlOnlineMaxSeqno(): Int {
+        if (onlMaxSeqno == 0) {
+            try {
+                transdtlOnlineDao.getLock().lock()
+                onlMaxSeqno = transdtlOnlineDao.getMaxSeqno()
+            } finally {
+                transdtlOnlineDao.getLock().unlock()
+            }
+        }
+        return onlMaxSeqno
+    }
+
     fun getTransdtlOnlineUnconfirm(): List<TransdtlOnlineRecord> {
         try {
             transdtlOnlineDao.getLock().lock()
@@ -155,6 +188,18 @@
         }
     }
 
+    fun getTransdtlOfflineMaxSeqno(): Int {
+        if (offMaxSeqno == 0) {
+            try {
+                transdtlOfflineDao.getLock().lock()
+                offMaxSeqno = transdtlOfflineDao.getMaxSeqno()
+            } finally {
+                transdtlOfflineDao.getLock().unlock()
+            }
+        }
+        return offMaxSeqno
+    }
+
     fun getTransdtlOfflineUnconfirm(): List<TransdtlOfflineRecord> {
         try {
             transdtlOfflineDao.getLock().lock()
diff --git a/app/src/main/java/com/supwisdom/db/SysParaDao.kt b/app/src/main/java/com/supwisdom/db/SysParaDao.kt
index 8d3b045..e6676df 100644
--- a/app/src/main/java/com/supwisdom/db/SysParaDao.kt
+++ b/app/src/main/java/com/supwisdom/db/SysParaDao.kt
@@ -39,10 +39,11 @@
         val values = getContentValues(record)
         try {
             db.beginTransaction()
-            if (db.update(TABLE, values, BeanPropEnum.Syspara.id.toString() + "=?", arrayOf(INDEX)) > 0) {
-                db.setTransactionSuccessful()
-                return true
+            if (db.update(TABLE, values, BeanPropEnum.Syspara.id.toString() + "=?", arrayOf(INDEX)) < 0) {
+                return false
             }
+            db.setTransactionSuccessful()
+            return true
         } finally {
             db.endTransaction()
         }
@@ -84,7 +85,8 @@
         val record = SysParaRecord()
         record.returnFlag = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.returnFlag.toString()))
         record.heatBeat = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.heatBeat.toString()))
-        record.offlineFlag = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.offlineFlag.toString()))
+        val enable = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.offlineEnable.toString()))
+        record.offlineEnable = enable == 1
         record.maxOfflineDays = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.maxOfflineDays.toString()))
         record.mngPasswd = cursor.getString(cursor.getColumnIndex(BeanPropEnum.Syspara.mngpasswd.toString()))
         record.fixpayGap = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.fixpayGap.toString()))
@@ -100,7 +102,11 @@
         values.put(BeanPropEnum.Syspara.id.toString(), INDEX)
         values.put(BeanPropEnum.Syspara.returnFlag.toString(), record.returnFlag)
         values.put(BeanPropEnum.Syspara.heatBeat.toString(), record.heatBeat)
-        values.put(BeanPropEnum.Syspara.offlineFlag.toString(), record.offlineFlag)
+        if (record.offlineEnable) {
+            values.put(BeanPropEnum.Syspara.offlineEnable.toString(), 1)
+        } else {
+            values.put(BeanPropEnum.Syspara.offlineEnable.toString(), 0)
+        }
         values.put(BeanPropEnum.Syspara.maxOfflineDays.toString(), record.maxOfflineDays)
         values.put(BeanPropEnum.Syspara.mngpasswd.toString(), record.mngPasswd)
         values.put(BeanPropEnum.Syspara.fixpayGap.toString(), record.fixpayGap)
diff --git a/app/src/main/java/com/supwisdom/db/TransdtlOfflineDao.kt b/app/src/main/java/com/supwisdom/db/TransdtlOfflineDao.kt
index f3b3f6c..c2f158b 100644
--- a/app/src/main/java/com/supwisdom/db/TransdtlOfflineDao.kt
+++ b/app/src/main/java/com/supwisdom/db/TransdtlOfflineDao.kt
@@ -70,6 +70,21 @@
         }
     }
 
+    fun getMaxSeqno(): Int {
+        val db = dbHelper.readableDatabase
+        val sql = ("select max(${BeanPropEnum.TransdtlOffline.devseqno}) as seqno from $TABLE")
+        var cursor: Cursor? = null
+        try {
+            cursor = db.rawQuery(sql, null, null)
+            if (cursor != null && cursor.moveToNext()) {
+                return cursor.getInt(cursor.getColumnIndex("seqno"))
+            }
+        } finally {
+            cursor?.close()
+        }
+        return 0
+    }
+
     fun clear(): Boolean {
         val db = dbHelper.writableDatabase
         try {
diff --git a/app/src/main/java/com/supwisdom/db/TransdtlOnlineDao.kt b/app/src/main/java/com/supwisdom/db/TransdtlOnlineDao.kt
index e4e7b55..c6a4f6d 100644
--- a/app/src/main/java/com/supwisdom/db/TransdtlOnlineDao.kt
+++ b/app/src/main/java/com/supwisdom/db/TransdtlOnlineDao.kt
@@ -70,6 +70,21 @@
         }
     }
 
+    fun getMaxSeqno(): Int {
+        val db = dbHelper.readableDatabase
+        val sql = ("select max(${BeanPropEnum.TransdtlOnline.devseqno}) as seqno from $TABLE")
+        var cursor: Cursor? = null
+        try {
+            cursor = db.rawQuery(sql, null, null)
+            if (cursor != null && cursor.moveToNext()) {
+                return cursor.getInt(cursor.getColumnIndex("seqno"))
+            }
+        } finally {
+            cursor?.close()
+        }
+        return 0
+    }
+
     fun clear(): Boolean {
         val db = dbHelper.writableDatabase
         try {
diff --git a/app/src/main/java/com/supwisdom/db/WhiteListDao.kt b/app/src/main/java/com/supwisdom/db/WhiteListDao.kt
new file mode 100644
index 0000000..a5dfcdd
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/WhiteListDao.kt
@@ -0,0 +1,84 @@
+package com.supwisdom.db
+
+import android.content.ContentValues
+import android.content.Context
+import android.database.Cursor
+import com.supwisdom.entity.WhiteListRecord
+import java.util.concurrent.locks.Lock
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class WhiteListDao constructor(context: Context) {
+    private val dbHelper = DBParaHelper.getInstance(context)
+    private val TABLE = DBParaHelper.TABLE_NAME_WHITELIST
+
+    fun getLock(): Lock {
+        return dbHelper.getLock()
+    }
+
+    fun replace(list: List<WhiteListRecord>): Boolean {
+        val db = dbHelper.readableDatabase
+        try {
+            db.beginTransaction()
+            list.forEach {
+                val values = getContentValues(it)
+                if (db.replace(TABLE, null, values) < 0) {
+                    return false
+                }
+            }
+            db.setTransactionSuccessful()
+            return true
+        } finally {
+            db.endTransaction()
+        }
+    }
+
+    fun get(cardphyid: String, cardno: String): WhiteListRecord? {
+        val db = dbHelper.readableDatabase
+        var cursor: Cursor? = null
+        val selection = BeanPropEnum.WhiteList.cardphyid.toString() + "=? and " + BeanPropEnum.WhiteList.cardno + "=?"
+        try {
+            cursor = db.query(TABLE, null, selection, arrayOf(cardphyid, cardno), null, null, null)
+            if (cursor != null && cursor.moveToNext()) {
+                return getRecord(cursor)
+            }
+        } finally {
+            cursor?.close()
+        }
+        return null
+    }
+
+    fun clear(): Boolean {
+        val db = dbHelper.writableDatabase
+        try {
+            db.beginTransaction()
+            if (db.delete(TABLE, null, null) < 0) {
+                return false
+            }
+            db.setTransactionSuccessful()
+            return true
+        } finally {
+            db.endTransaction()
+        }
+    }
+
+    private fun getRecord(cursor: Cursor): WhiteListRecord {
+        val record = WhiteListRecord()
+        record.cardphyid = cursor.getString(cursor.getColumnIndex(BeanPropEnum.WhiteList.cardphyid.toString()))
+        record.cardno = cursor.getString(cursor.getColumnIndex(BeanPropEnum.WhiteList.cardno.toString()))
+        record.flag = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.WhiteList.flag.toString()))
+        record.balance = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.WhiteList.balance.toString()))
+        return record
+    }
+
+    private fun getContentValues(record: WhiteListRecord): ContentValues {
+        val values = ContentValues()
+        values.put(BeanPropEnum.WhiteList.cardphyid.toString(), record.cardphyid)
+        values.put(BeanPropEnum.WhiteList.cardno.toString(), record.cardno)
+        values.put(BeanPropEnum.WhiteList.flag.toString(), record.flag)
+        values.put(BeanPropEnum.WhiteList.balance.toString(), record.balance)
+        return values
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/entity/ConfigParaRecord.kt b/app/src/main/java/com/supwisdom/entity/ConfigParaRecord.kt
index 2a7c948..3c344a7 100644
--- a/app/src/main/java/com/supwisdom/entity/ConfigParaRecord.kt
+++ b/app/src/main/java/com/supwisdom/entity/ConfigParaRecord.kt
@@ -2,7 +2,7 @@
 
 /**
  ** create by zzq on 2019/7/24
- ** @desc
+ ** @desc 本地配置参数
  **/
 class ConfigParaRecord {
     var mode: Int = 0//
diff --git a/app/src/main/java/com/supwisdom/entity/ControlParaRecord.kt b/app/src/main/java/com/supwisdom/entity/ControlParaRecord.kt
index 9028aa7..441d056 100644
--- a/app/src/main/java/com/supwisdom/entity/ControlParaRecord.kt
+++ b/app/src/main/java/com/supwisdom/entity/ControlParaRecord.kt
@@ -2,7 +2,7 @@
 
 /**
  ** create by zzq on 2019/7/24
- ** @desc
+ ** @desc 本地控制参数
  **/
 class ControlParaRecord {
     var paraname: String? = null
diff --git a/app/src/main/java/com/supwisdom/entity/DynamicParaRecord.kt b/app/src/main/java/com/supwisdom/entity/DynamicParaRecord.kt
index bb2a939..d396060 100644
--- a/app/src/main/java/com/supwisdom/entity/DynamicParaRecord.kt
+++ b/app/src/main/java/com/supwisdom/entity/DynamicParaRecord.kt
@@ -2,7 +2,7 @@
 
 /**
  ** create by zzq on 2019/7/24
- ** @desc
+ ** @desc 后台动态参数
  **/
 class DynamicParaRecord {
     var paraverno: Int = 0//参数版本
@@ -10,4 +10,5 @@
     var cardverno: String? = null // 黑名单版本号 12byte
     var jwt: String? = null
     var token: String? = null
+    var lastauthtime: String? = null //最后一次认证时间 yyyyMMddhhmmss
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/entity/SysParaRecord.kt b/app/src/main/java/com/supwisdom/entity/SysParaRecord.kt
index 288567e..adb38d9 100644
--- a/app/src/main/java/com/supwisdom/entity/SysParaRecord.kt
+++ b/app/src/main/java/com/supwisdom/entity/SysParaRecord.kt
@@ -2,12 +2,12 @@
 
 /**
  ** create by zzq on 2019/7/24
- ** @desc
+ ** @desc 后台系统参数
  **/
 class SysParaRecord {
     var returnFlag: Int = 0// 消费撤销开关  0bit -0x1表示冲正使能
     var heatBeat: Int = 0// 心跳间隔
-    var offlineFlag: Int = 0 // 脱机消费时限开关  0-关闭, 1-开启
+    var offlineEnable: Boolean = false // 脱机消费时限开关  false-关闭, true-开启
     var maxOfflineDays: Int = 0// 最大脱机天数
     var mngPasswd: String? = null// 维护密码
     var consumeShowtime: Int = 0// 消费成功显示时间
diff --git a/app/src/main/java/com/supwisdom/entity/TransdtlOnlineRecord.kt b/app/src/main/java/com/supwisdom/entity/TransdtlOnlineRecord.kt
index ba06561..1037fb9 100644
--- a/app/src/main/java/com/supwisdom/entity/TransdtlOnlineRecord.kt
+++ b/app/src/main/java/com/supwisdom/entity/TransdtlOnlineRecord.kt
@@ -16,6 +16,8 @@
     var payamt: Int = 0
     var extraamt: Int = 0
     var managefeetype: String? = null // none,discount,mealer
+    var username: String? = null
+    var userid: Int = 0
     var billno: String? = null
     var reversalflag: String? = null //消费null 自动冲正auto 手动撤销 manual
     var reversalbillno: String? = null //被冲正交易参考号
diff --git a/app/src/main/java/com/supwisdom/entity/WhiteListRecord.kt b/app/src/main/java/com/supwisdom/entity/WhiteListRecord.kt
new file mode 100644
index 0000000..bbda15c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/entity/WhiteListRecord.kt
@@ -0,0 +1,12 @@
+package com.supwisdom.entity
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc 白名单
+ **/
+class WhiteListRecord {
+    var cardphyid: String? = null
+    var cardno: String? = null
+    var flag: Int = 0 // 0--白卡 1--黑卡
+    var balance: Int = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/epaycard/ApduResponse.kt b/app/src/main/java/com/supwisdom/epaycard/ApduResponse.kt
new file mode 100644
index 0000000..ec0b7c7
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/epaycard/ApduResponse.kt
@@ -0,0 +1,40 @@
+package com.supwisdom.epaycard
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class ApduResponse constructor(val buffer: ByteArray) {
+    val sW1: Int
+        get() {
+            return buffer[buffer.size - 2].toInt() and 0xFF
+        }
+
+    val sW2: Int
+        get() {
+            return buffer[buffer.size - 1].toInt() and 0xFF
+        }
+
+    val sw: Int
+        get() {
+            return (sW1 shl 8) or sW2
+        }
+
+    val data: ByteArray
+        get() {
+            return buffer.copyOfRange(0, buffer.size - 2)
+        }
+
+    val bytes: ByteArray
+        get() {
+            return buffer
+        }
+
+    fun isOK(): Boolean {
+        return sW1 == 0x90 && sW2 == 0x00
+    }
+
+    fun swToString(): String {
+        return "%02X%02X".format(sW1, sW2)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/epaycard/CardBaseInfoBean.kt b/app/src/main/java/com/supwisdom/epaycard/CardBaseInfoBean.kt
new file mode 100644
index 0000000..855b57c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/epaycard/CardBaseInfoBean.kt
@@ -0,0 +1,22 @@
+package com.supwisdom.epaycard
+
+import com.supwisdom.utils.decodeBCD
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardBaseInfoBean constructor(val data: ByteArray) {
+    val cardNo: String
+        get() {
+            return data.copyOfRange(31, 42).decodeBCD()
+        }
+    val idCard: String
+        get() {
+            return data.copyOfRange(43, 60).decodeBCD()
+        }
+    val expireDate: String
+        get() {
+            return data.copyOfRange(61, 64).decodeBCD()
+        }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/epaycard/Cardlib.kt b/app/src/main/java/com/supwisdom/epaycard/Cardlib.kt
new file mode 100644
index 0000000..4ee2bc0
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/epaycard/Cardlib.kt
@@ -0,0 +1,12 @@
+package com.supwisdom.epaycard
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class Cardlib {
+    companion object {
+        @JvmStatic
+        val instance: EpayCardlib = EpayCardlib()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/epaycard/DaliReader.kt b/app/src/main/java/com/supwisdom/epaycard/DaliReader.kt
new file mode 100644
index 0000000..4992921
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/epaycard/DaliReader.kt
@@ -0,0 +1,154 @@
+package com.supwisdom.epaycard
+
+import android.os.Build
+import com.newcapec.jni.ApduResp
+import com.newcapec.jni.ApduSend
+import com.newcapec.jni.Picc
+import com.supwisdom.exception.CardNotFoundError
+import com.supwisdom.exception.CardlibInitError
+import com.supwisdom.exception.CardlibValueError
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.LogUtil
+import com.supwisdom.utils.encodeHex
+import com.supwisdom.utils.unsignedToInt
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class DaliReader {
+    private val TAG = "DaliReader"
+    private var cardTag = Picc.DetectInfo()
+    private var picc: Picc? = null
+
+    fun close() {
+        picc?.close()
+        picc = null
+    }
+
+    @Throws(CardlibInitError::class)
+    fun init() {
+        // CAP08S-V1.1.0.20181107 test-keys
+        //****设备固件版本>1.0.8c 使用新读卡驱动
+        /** 固件版本<=1.08 使用v108so ***/
+        /** 固件版本<=1.10 使用v110so ***/
+        /** 固件版本>=1.15 使用v115so ***/
+        /** 固件版本>=1.16 使用v116so ***/
+        val temp = Build.DISPLAY
+        val version = if (temp.contains("CAP08S-V1")) {
+            when {
+                temp < "CAP08S-V1.0.9" -> 108
+                temp < "CAP08S-V1.1.1" -> 110
+                else -> 115
+            }
+        } else {
+            /**
+             * v1.1.6
+             */
+            CommonUtil.getSerialNumber()?.replace("v", "")
+                ?.replace("V", "")
+                ?.replace(".", "")
+                ?.toInt() ?: 116
+        }
+        picc = Picc(version)
+        val ret = picc!!.open()
+        if (ret != 0) {
+            LogUtil.d(TAG, "A711Reader init error,ret=$ret")
+            throw CardlibInitError("加载卡库错误=$ret")
+        }
+    }
+
+    @Throws(CardNotFoundError::class)
+    fun requestCard(): String {
+        picc!!.remove('R'.toByte(), 0)
+        val ret = picc!!.detect('X'.toByte(), cardTag)
+        if (ret != 0) {
+            throw CardNotFoundError("寻卡错误=$ret")
+        }
+        val uidLen = cardTag.SerialInfo_Array[0].unsignedToInt()
+        val cardSN = cardTag.SerialInfo_Array.copyOfRange(1, 1 + uidLen)
+        return cardSN.encodeHex()
+    }
+
+    @Throws(CardlibValueError::class)
+    fun cpuApdu(cmd: ByteArray): ApduResponse {
+        val send = ApduSend()
+        val resp = ApduResp()
+        when {
+            cmd.size == 4 -> System.arraycopy(cmd, 0, send.Command, 0, 4)
+            cmd.size == 5 -> {
+                System.arraycopy(cmd, 0, send.Command, 0, 4)
+                send.Le = cmd[4].unsignedToInt().toShort()
+                if (0xB2 == cmd[1].unsignedToInt() &&
+                    0x84 == cmd[3].unsignedToInt()
+                ) {
+                    //file 0x10
+                    send.Le = 24
+                } else if (0xB2 == cmd[1].unsignedToInt() &&
+                    0x4C == cmd[3].unsignedToInt()
+                ) {
+                    //file 0x09
+                    send.Le = 37
+                }
+            }
+            else -> {
+                System.arraycopy(cmd, 0, send.Command, 0, 4)
+                send.Lc = cmd[4].unsignedToInt().toShort()
+                System.arraycopy(cmd, 5, send.DataIn, 0, send.Lc.toInt())
+                if (cmd.size > 5 + send.Lc) {
+                    send.Le = cmd[5 + send.Lc].unsignedToInt().toShort()
+                }
+            }
+        }
+        var ret = picc!!.sendIsoCommand(0.toByte(), send, resp)
+        if (ret == 0) {
+            if (resp.SWA.unsignedToInt() == 0x61 &&
+                resp.SWB.unsignedToInt() > 0
+            ) {
+                var recv = ByteArray(resp.LenOut.toInt())
+                System.arraycopy(resp.DataOut, 0, recv, 0, resp.LenOut.toInt())
+                while (true) {
+                    val innercmd = ByteArray(5)
+                    innercmd[0] = 0x0
+                    innercmd[1] = 0xC0.toByte()
+                    innercmd[2] = 0x0
+                    innercmd[3] = 0x0
+                    innercmd[4] = resp.SWB
+                    System.arraycopy(innercmd, 0, send.Command, 0, 4)
+                    send.Le = innercmd[4].unsignedToInt().toShort()
+                    send.Lc = 0
+                    ret = picc!!.sendIsoCommand(0.toByte(), send, resp)
+                    if (ret == 0) {
+                        if (resp.SWA.unsignedToInt() == 0x61 &&
+                            resp.SWB.unsignedToInt() > 0
+                        ) {
+                            val tmp = ByteArray(resp.LenOut.toInt() + recv.size)
+                            System.arraycopy(recv, 0, tmp, 0, recv.size)
+                            System.arraycopy(resp.DataOut, 0, tmp, recv.size, resp.LenOut.toInt())
+                            recv = tmp
+                            continue
+                        } else {
+                            val tmp = ByteArray(resp.LenOut.toInt() + recv.size + 2)
+                            System.arraycopy(recv, 0, tmp, 0, recv.size)
+                            System.arraycopy(resp.DataOut, 0, tmp, recv.size, resp.LenOut.toInt())
+                            tmp[tmp.size - 2] = resp.SWA
+                            tmp[tmp.size - 1] = resp.SWB
+                            recv = tmp
+                            return ApduResponse(recv)
+                        }
+                    } else {
+                        throw CardlibValueError("交互失败,错误码=$ret")
+                    }
+                }
+            } else {
+                val recv = ByteArray(resp.LenOut + 2)
+                System.arraycopy(resp.DataOut, 0, recv, 0, resp.LenOut.toInt())
+                recv[resp.LenOut.toInt()] = resp.SWA
+                recv[resp.LenOut + 1] = resp.SWB
+                return ApduResponse(recv)
+            }
+        }
+        LogUtil.d(TAG, "A711Reader cpuApdu error,ret=$ret")
+        throw CardlibValueError("交互失败,错误码=$ret")
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/epaycard/EpayCardlib.kt b/app/src/main/java/com/supwisdom/epaycard/EpayCardlib.kt
new file mode 100644
index 0000000..6c68cb9
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/epaycard/EpayCardlib.kt
@@ -0,0 +1,45 @@
+package com.supwisdom.epaycard
+
+import com.supwisdom.exception.CardNotFoundError
+import com.supwisdom.exception.CardlibInitError
+import com.supwisdom.exception.CardlibValueError
+import com.supwisdom.utils.decodeHex
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class EpayCardlib {
+    private var reader = DaliReader()
+
+    @Throws(CardlibInitError::class)
+    fun init() {
+        reader.init()
+    }
+
+    @Throws(CardNotFoundError::class)
+    fun requestCard(): String {
+        return reader.requestCard()
+    }
+
+    @Throws(CardlibValueError::class)
+    fun readCard(): CardBaseInfoBean {
+        selectADF()
+        return readBaseInfo()
+    }
+
+    private fun selectADF() {
+        val res = reader.cpuApdu("00A40000023F00".decodeHex())
+        if (!res.isOK()) {
+            throw CardlibValueError("选应用错误:${res.swToString()}")
+        }
+    }
+
+    private fun readBaseInfo(): CardBaseInfoBean {
+        val res = reader.cpuApdu("00B09500".decodeHex())
+        if (!res.isOK()) {
+            throw CardlibValueError("读基本信息错误:${res.swToString()}")
+        }
+        return CardBaseInfoBean(res.data)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/exception/CardNotFoundError.kt b/app/src/main/java/com/supwisdom/exception/CardNotFoundError.kt
new file mode 100644
index 0000000..43d882c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/CardNotFoundError.kt
@@ -0,0 +1,19 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardNotFoundError : Exception {
+    constructor(message: String, ex: Exception) {
+        Exception(message + ex.message)
+    }
+
+    constructor(message: String) {
+        Exception(message)
+    }
+
+    constructor(ex: Exception) {
+        Exception(ex.message)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/exception/CardPayCancelFailError.kt b/app/src/main/java/com/supwisdom/exception/CardPayCancelFailError.kt
new file mode 100644
index 0000000..4ab662e
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/CardPayCancelFailError.kt
@@ -0,0 +1,19 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardPayCancelFailError : Exception {
+    constructor(message: String, ex: Exception) {
+        Exception(message + ex.message)
+    }
+
+    constructor(message: String) {
+        Exception(message)
+    }
+
+    constructor(ex: Exception) {
+        Exception(ex.message)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/exception/CardPayFailError.kt b/app/src/main/java/com/supwisdom/exception/CardPayFailError.kt
new file mode 100644
index 0000000..558562b
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/CardPayFailError.kt
@@ -0,0 +1,19 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardPayFailError : Exception {
+    constructor(message: String, ex: Exception) {
+        Exception(message + ex.message)
+    }
+
+    constructor(message: String) {
+        Exception(message)
+    }
+
+    constructor(ex: Exception) {
+        Exception(ex.message)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/exception/CardlibInitError.kt b/app/src/main/java/com/supwisdom/exception/CardlibInitError.kt
new file mode 100644
index 0000000..7404615
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/CardlibInitError.kt
@@ -0,0 +1,19 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardlibInitError : Exception {
+    constructor(message: String, ex: Exception) {
+        Exception(message + ex.message)
+    }
+
+    constructor(message: String) {
+        Exception(message)
+    }
+
+    constructor(ex: Exception) {
+        Exception(ex.message)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/exception/CardlibValueError.kt b/app/src/main/java/com/supwisdom/exception/CardlibValueError.kt
new file mode 100644
index 0000000..b069e0b
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/CardlibValueError.kt
@@ -0,0 +1,19 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardlibValueError : Exception {
+    constructor(message: String, ex: Exception) {
+        Exception(message + ex.message)
+    }
+
+    constructor(message: String) {
+        Exception(message)
+    }
+
+    constructor(ex: Exception) {
+        Exception(ex.message)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/exception/HeartBeatError.kt b/app/src/main/java/com/supwisdom/exception/HeartBeatError.kt
new file mode 100644
index 0000000..b1b4852
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/HeartBeatError.kt
@@ -0,0 +1,19 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class HeartBeatError : Exception {
+    constructor(message: String, ex: Exception) {
+        Exception(message + ex.message)
+    }
+
+    constructor(message: String) {
+        Exception(message)
+    }
+
+    constructor(ex: Exception) {
+        Exception(ex.message)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/exception/SysParaError.kt b/app/src/main/java/com/supwisdom/exception/SysParaError.kt
new file mode 100644
index 0000000..3d3c073
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/SysParaError.kt
@@ -0,0 +1,19 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class SysParaError : Exception {
+    constructor(message: String, ex: Exception) {
+        Exception(message + ex.message)
+    }
+
+    constructor(message: String) {
+        Exception(message)
+    }
+
+    constructor(ex: Exception) {
+        Exception(ex.message)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/exception/TransdtlUploadError.kt b/app/src/main/java/com/supwisdom/exception/TransdtlUploadError.kt
new file mode 100644
index 0000000..4064c79
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/TransdtlUploadError.kt
@@ -0,0 +1,19 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class TransdtlUploadError : Exception {
+    constructor(message: String, ex: Exception) {
+        Exception(message + ex.message)
+    }
+
+    constructor(message: String) {
+        Exception(message)
+    }
+
+    constructor(ex: Exception) {
+        Exception(ex.message)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/exception/WhiteListError.kt b/app/src/main/java/com/supwisdom/exception/WhiteListError.kt
new file mode 100644
index 0000000..5204298
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/WhiteListError.kt
@@ -0,0 +1,19 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class WhiteListError : Exception {
+    constructor(message: String, ex: Exception) {
+        Exception(message + ex.message)
+    }
+
+    constructor(message: String) {
+        Exception(message)
+    }
+
+    constructor(ex: Exception) {
+        Exception(ex.message)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/service/AuthEpay.kt b/app/src/main/java/com/supwisdom/service/AuthEpay.kt
index 185c534..a2a3799 100644
--- a/app/src/main/java/com/supwisdom/service/AuthEpay.kt
+++ b/app/src/main/java/com/supwisdom/service/AuthEpay.kt
@@ -1,11 +1,14 @@
 package com.supwisdom.service
 
+import com.supwisdom.bean.AuthRetBean
+import com.supwisdom.utils.PublicDef
+
 /**
  ** create by zzq on 2019/7/23
  ** @desc
  **/
 class AuthEpay {
-    fun login() {
-
+    fun login(): AuthRetBean {
+        return AuthRetBean(PublicDef.ERROR, "未实行")
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/service/EpayApiImpl.kt b/app/src/main/java/com/supwisdom/service/EpayApiImpl.kt
index 6a4d21f..17cb4a6 100644
--- a/app/src/main/java/com/supwisdom/service/EpayApiImpl.kt
+++ b/app/src/main/java/com/supwisdom/service/EpayApiImpl.kt
@@ -4,6 +4,10 @@
 import com.supwisdom.activities.YktSession
 import com.supwisdom.entity.TransdtlOfflineRecord
 import com.supwisdom.entity.TransdtlOnlineRecord
+import com.supwisdom.exception.HeartBeatError
+import com.supwisdom.exception.SysParaError
+import com.supwisdom.exception.TransdtlUploadError
+import com.supwisdom.exception.WhiteListError
 import com.supwisdom.okhttp.WebParams
 import com.supwisdom.utils.DateUtil
 
@@ -13,6 +17,8 @@
  **/
 class EpayApiImpl : APIInterface {
     private val pos = SPApplication.getInstance().getPos()
+
+    @Throws(HeartBeatError::class)
     override fun heartBeat() {
         val dyRecord = pos.getDynamicPara()
         val params = WebParams()
@@ -29,6 +35,7 @@
         TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
     }
 
+    @Throws(SysParaError::class)
     override fun downloadSyspara(paraverno: Int, paragroupid: Int) {
         val dyRecord = pos.getDynamicPara()
         val params = WebParams()
@@ -40,6 +47,7 @@
         val resp = YktSession.getInstance().sendYktRequestPost("/api/pos/systempara", "", params)
     }
 
+    @Throws(WhiteListError::class)
     override fun downloadWhitelist(maxCardverno: String) {
         val params = WebParams()
         params.setParameter("devphyid", pos.getConfigPara()!!.devphyid)
@@ -49,6 +57,7 @@
         val resp = YktSession.getInstance().sendYktRequestPost("/api/pos/whitelist", "", params)
     }
 
+    @Throws(TransdtlUploadError::class)
     override fun uploadTransdtl(record: TransdtlOnlineRecord) {
         val params = WebParams()
         params.setParameter("devphyid", record.devphyid)
@@ -58,6 +67,7 @@
         val resp = YktSession.getInstance().sendYktRequestPost("/api/pos/paycancel", "", params)
     }
 
+    @Throws(TransdtlUploadError::class)
     override fun uploadTransdtl(record: TransdtlOfflineRecord) {
         val params = WebParams()
         params.setParameter("devphyid", record.devphyid)
diff --git a/app/src/main/java/com/supwisdom/service/WebsocketProcess.kt b/app/src/main/java/com/supwisdom/service/WebsocketProcess.kt
index 63a23ba..5ae8a0c 100644
--- a/app/src/main/java/com/supwisdom/service/WebsocketProcess.kt
+++ b/app/src/main/java/com/supwisdom/service/WebsocketProcess.kt
@@ -31,7 +31,7 @@
     @Volatile
     private var connectDoing: Boolean = false
     private var webSocket: Future<WebSocket>? = null
-    private var reLinkCnt: Long = 0
+    private var reLinkCnt: Int = 0
     private var clientID = ""
     @Volatile
     private var hasRecv: Boolean = false
@@ -51,7 +51,7 @@
                 }
             }
         }
-        clientID = SPApplication.getInstance().getPos().getConfigPara().getDevphyid()
+        clientID = SPApplication.getInstance().getPos().getConfigPara()!!.devphyid!!
     }
 
     fun setHandler(handler: Handler) {
@@ -127,7 +127,7 @@
 //                val loginStr = getLoginString()
 //                webSocket.send(loginStr)
                 webSocket.stringCallback = WebSocket.StringCallback { s ->
-//                    if (!CommonUtil.isEmpty(s)) {
+                    //                    if (!CommonUtil.isEmpty(s)) {
 //                        try {
 //                            val retBean = GsonUtil.GsonToBean(s, WebsocketRetBean::class.java)
 //                            if (retBean.getRetcode() === PublicDef.SUCCESS) {
diff --git a/app/src/main/java/com/supwisdom/utils/CommonUtil.kt b/app/src/main/java/com/supwisdom/utils/CommonUtil.kt
index 91af8f7..5891662 100644
--- a/app/src/main/java/com/supwisdom/utils/CommonUtil.kt
+++ b/app/src/main/java/com/supwisdom/utils/CommonUtil.kt
@@ -50,6 +50,18 @@
         return commTime
     }
 
+    fun getSerialNumber(): String? {
+        try {
+            val c = Class.forName("android.os.SystemProperties")
+            val get = c.getMethod("get", String::class.java)
+            return get.invoke(c, "ro.product.firmware") as String
+        } catch (ex: Exception) {
+            ex.printStackTrace()
+        }
+
+        return null
+    }
+
     fun YuanToFen(yuan: Double): Int {
         return Math.round(yuan * 100).toInt()
     }
diff --git a/app/src/main/java/com/supwisdom/utils/PublicDef.kt b/app/src/main/java/com/supwisdom/utils/PublicDef.kt
index 14fc606..7f1204d 100644
--- a/app/src/main/java/com/supwisdom/utils/PublicDef.kt
+++ b/app/src/main/java/com/supwisdom/utils/PublicDef.kt
@@ -21,6 +21,12 @@
 
     /**************************************************************/
     /*************************handler 状态码***********************/
+    const val MSG_CARD_PAYING = 10
+    const val MSG_CARD_PAY_FAIL = 11
+    const val MSG_CARD_PAY_SUC = 12
+    const val MSG_CARD_PAY_QUERY = 13
+    const val MSG_CARD_PAYCANCEL_FAIL = 14
+    const val MSG_CARD_PAYCANCEL_SUC = 15
     /*************************不能重复*****************************/
     /**
      * 卡消费标志(1 byte)
@@ -57,4 +63,14 @@
     const val DIALOG_TYPE_ORDINARY_CONSUME = 7
     const val DIALOG_TYPE_DEPOSIT = 8
     const val DIALOG_TYPE_NSD_CONFIG = 9
+
+    /**
+     * 本地全局控制参数
+     */
+    const val CONTROL_TRANSDTLONL_SEQNO = "onlseqno"
+    const val CONTROL_TRANSDTLOFF_SEQNO = "offseqno"
+    const val CONTROL_FIXAMT = "fixamt"
+    const val CONTROL_HAS_REGISTER = "hasregister"
+    const val CONTROL_GATEMODE_FLAG = "gatemodeflag"
+    const val CONTROL_REVENUE_WAY = "revenueway"
 }
\ No newline at end of file
diff --git a/app/src/main/res/drawable-hdpi/app_logo.png b/app/src/main/res/drawable-hdpi/app_logo.png
new file mode 100644
index 0000000..b4073ad
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/app_logo.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/consume_middle_background.png b/app/src/main/res/drawable-hdpi/consume_middle_background.png
new file mode 100644
index 0000000..9af8c90
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/consume_middle_background.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/iconerrork.png b/app/src/main/res/drawable-hdpi/iconerrork.png
new file mode 100644
index 0000000..57493fe
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/iconerrork.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/iconfont_del.png b/app/src/main/res/drawable-hdpi/iconfont_del.png
new file mode 100644
index 0000000..6c89d1c
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/iconfont_del.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/loading.png b/app/src/main/res/drawable-hdpi/loading.png
new file mode 100644
index 0000000..c9acbab
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/loading.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/loading_white.png b/app/src/main/res/drawable-hdpi/loading_white.png
new file mode 100644
index 0000000..abfb07f
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/loading_white.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/minus.png b/app/src/main/res/drawable-hdpi/minus.png
new file mode 100644
index 0000000..e672aaf
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/minus.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/minus_click.png b/app/src/main/res/drawable-hdpi/minus_click.png
new file mode 100644
index 0000000..580c410
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/minus_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/pay_fail.png b/app/src/main/res/drawable-hdpi/pay_fail.png
new file mode 100644
index 0000000..9b0ac71
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/pay_fail.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/pay_success.png b/app/src/main/res/drawable-hdpi/pay_success.png
new file mode 100644
index 0000000..62ed4e2
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/pay_success.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/scrollbar.xml b/app/src/main/res/drawable-hdpi/scrollbar.xml
new file mode 100644
index 0000000..8289699
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/scrollbar.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:startColor="#505050"
+        android:endColor="#C0C0C0"
+        android:angle="0" />
+    <corners android:radius="0dp" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable-hdpi/scrollbar_bg.xml b/app/src/main/res/drawable-hdpi/scrollbar_bg.xml
new file mode 100644
index 0000000..2a31b9e
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/scrollbar_bg.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <gradient
+        android:startColor="#ffff792a"
+        android:endColor="#ffff792a"
+        android:angle="0" />
+    <corners android:radius="4dp" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable-hdpi/user_logo.png b/app/src/main/res/drawable-hdpi/user_logo.png
new file mode 100644
index 0000000..138412d
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/user_logo.png
Binary files differ
diff --git a/app/src/main/res/drawable-hdpi/user_logo_default.png b/app/src/main/res/drawable-hdpi/user_logo_default.png
new file mode 100644
index 0000000..2ae652f
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/user_logo_default.png
Binary files differ
diff --git a/app/src/main/res/layout/activity_splash.xml b/app/src/main/res/layout/activity_splash.xml
new file mode 100644
index 0000000..c89c3e3
--- /dev/null
+++ b/app/src/main/res/layout/activity_splash.xml
@@ -0,0 +1,48 @@
+<!--
+android:gravity是对元素本身说的,元素本身的文本显示在什么地方靠着换个属性设置,不过不设置默认是在左侧的。
+android:layout_gravity是相对与它的父元素说的,说明元素显示在父元素的什么位置
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/LinearLayout01"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:background="@color/light_blue2"
+    android:orientation="vertical">
+    <!--
+    android:scaleType是控制图片如何resized/moved来匹对ImageView的size
+    CENTER_INSIDE / centerInside  将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽
+    -->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="20dp"
+        android:background="@drawable/corner_bg_white"
+        android:gravity="center|center"
+        android:orientation="vertical">
+
+        <ImageView
+            android:id="@+id/wordpress_logo"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:scaleType="centerInside"
+            android:src="@drawable/app_logo"></ImageView>
+        <!--
+        android:typeface 字体风格
+        -->
+        <TextView
+            android:id="@+id/versionNumber"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dip"
+            android:gravity="bottom"
+            android:shadowColor="#FFFFFF"
+            android:shadowDx="0"
+            android:shadowDy="2"
+            android:shadowRadius="1"
+            android:text="0.0.0"
+            android:textColor="@color/pos_theme_color"
+            android:textSize="@dimen/main_caption_size"
+            android:typeface="serif" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 44fc515..c26513d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -58,10 +58,10 @@
     <string name="title_activity_qrcamera">扫码</string>
     <string name="title_activity_splash">树维pos</string>
     <string name="waiting_msg">正在识别,请稍后…</string>
-    <string name="username">姓    名</string>
+    <string name="username">姓 名</string>
     <string name="userStuEmpNo">学工号</string>
     <string name="userExpireDate">有效期</string>
-    <string name="userBalance">余    额</string>
+    <string name="userBalance">余 额</string>
     <string name="consumeAmount">消费额(元)</string>
     <string name="title_activity_consume_cancel">消费撤销</string>
     <string name="title_activity_update_blacklist">更新黑名单</string>