Merge branch 'feature/init' into develop
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..e9986f9
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,76 @@
+plugins {
+    id 'com.gladed.androidgitversion' version '0.4.9'
+}
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+android {
+    compileSdkVersion 28
+    defaultConfig {
+        applicationId "com.supwisdom.posa711"
+        minSdkVersion 22
+        targetSdkVersion 28
+        versionCode 1
+        versionName "1.0"
+        ndk {
+            abiFilters "arm64-v8a"
+        }
+        multiDexEnabled true
+    }
+    signingConfigs {
+        release {
+            storeFile file("$rootDir/keys-app.jks")
+            storePassword "123456"
+            keyAlias "sup"
+            keyPassword "123456"
+        }
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+    compileOptions {
+        sourceCompatibility 1.8
+        targetCompatibility 1.8
+    }
+    packagingOptions {
+        exclude 'META-INF/DEPENDENCIES'
+        exclude 'META-INF/LICENSE'
+        exclude 'META-INF/LICENSE.txt'
+        exclude 'META-INF/license.txt'
+        exclude 'META-INF/NOTICE'
+        exclude 'META-INF/NOTICE.txt'
+        exclude 'META-INF/notice.txt'
+        exclude 'META-INF/ASL2.0'
+    }
+}
+
+dependencies {
+//    implementation fileTree(dir: 'libs', include: ['*.jar'])
+    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+    implementation 'com.android.support:appcompat-v7:28.0.0'
+    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+    testImplementation 'junit:junit:4.12'
+    androidTestImplementation 'com.android.support.test:runner:1.0.2'
+    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+
+//    compile 'com.alibaba:fastjson:1.1.70.android'
+    compile 'com.google.code.gson:gson:2.8.5'
+    compile 'com.nineoldandroids:parent:2.4.0'
+    compile 'com.squareup.okhttp3:okhttp:3.10.0'
+    compile 'net.java.dev.jna:jna:4.5.0@aar'
+    compile 'com.koushikdutta.async:androidasync:2.2.1'
+    compile group: 'com.android.support', name: 'recyclerview-v7', version: '28.0.0'
+    compile 'org.apache.commons:commons-lang3:3.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 'org.apache.httpcomponents:httpcore:4.4.10'
+    compile("com.beust:klaxon:0.30") {
+        exclude group: 'org.jetbrains'
+    }
+    compile files('libs/zxinglibsl.jar')
+}
diff --git a/app/libs/zxinglibsl.jar b/app/libs/zxinglibsl.jar
new file mode 100644
index 0000000..c645c93
--- /dev/null
+++ b/app/libs/zxinglibsl.jar
Binary files differ
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/com/supwisdom/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/supwisdom/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..2aff141
--- /dev/null
+++ b/app/src/androidTest/java/com/supwisdom/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.supwisdom
+
+import android.support.test.InstrumentationRegistry
+import android.support.test.runner.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+    @Test
+    fun useAppContext() {
+        // Context of the app under test.
+        val appContext = InstrumentationRegistry.getTargetContext()
+        assertEquals("com.supwisdom", appContext.packageName)
+    }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ed48cb0
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:serviceandroid="http://schemas.android.com/tools"
+          package="com.supwisdom"
+          android:sharedUserId="android.uid.system">
+
+    <uses-permission android:name="android.permission.VIBRATE"/>
+    <uses-permission
+            android:name="android.permission.WRITE_SETTINGS"
+            serviceandroid:ignore="ProtectedPermissions"/>
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
+    <uses-permission
+            android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
+            serviceandroid:ignore="ProtectedPermissions"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.CAMERA"/>
+    <uses-permission android:name="android.permission.NFC"/>
+    <uses-permission android:name="android.permission.READ_PROFILE"/>
+    <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT"/>
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
+    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
+    <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
+    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
+    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
+    <uses-permission android:name="android.permission.USE_CREDENTIALS"/>
+    <uses-permission android:name="android.permission.FLASHLIGHT"/>
+    <uses-permission android:name="android.permission.WEITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.WAKE_LOCK"/>
+
+    <!--写时钟权限-->
+    <uses-permission
+            android:name="android.permission.WRITE_SETTINGS"
+            serviceandroid:ignore="ProtectedPermissions"/>
+    <uses-permission
+            android:name="android.permission.WRITE_SECURE_SETTINGS"
+            serviceandroid:ignore="ProtectedPermissions"/>
+
+    <uses-feature android:name="android.hardware.camera"/>
+    <uses-feature android:name="android.hardware.camera.autofocus"/>
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
+    <uses-permission
+            android:name="android.permission.READ_LOGS"
+            serviceandroid:ignore="ProtectedPermissions"/>
+
+    <application
+            android:name=".activities.SPApplication"
+            android:allowBackup="true"
+            android:icon="@drawable/app_logo"
+            android:label="@string/app_name"
+            android:persistent="false"
+            android:supportsRtl="true"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+        <activity
+                android:name=".activities.splash.SplashActivity"
+                android:launchMode="singleTask"
+                android:screenOrientation="portrait">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+
+                <!--<category android:name="android.intent.category.HOME" />-->
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/>
+            </intent-filter>
+        </activity>
+
+        <service android:name=".activities.ServiceDemo">
+            <intent-filter>
+                <category android:name="android.intent.category.default"/>
+            </intent-filter>
+        </service>
+
+        <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:windowSoftInputMode="stateHidden"
+                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.UpgradeActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.control.ControlActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.manage.ManageActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.menu.MenuActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.transdtl.TransdtlActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.communicate.CommunicateActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.checkShoppwd.CheckShoppwdActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.checkMngpwd.CheckMngpwdActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.consumeMode.ConsumeModeActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.passwd.PasswdActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.revenue.RevenueActivity"
+                android:label="@string/title_activity_consume"
+                android:launchMode="singleTask"/>
+        <activity
+                android:name=".activities.syspara.SysparaActivity"
+                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/newcapec/jni/ApduResp.java b/app/src/main/java/com/newcapec/jni/ApduResp.java
new file mode 100644
index 0000000..940be4b
--- /dev/null
+++ b/app/src/main/java/com/newcapec/jni/ApduResp.java
@@ -0,0 +1,9 @@
+package com.newcapec.jni;
+
+public class ApduResp {
+
+    public short LenOut;        //????IC??????????????
+    public byte[] DataOut = new byte[512];     //??IC??????????????
+    public byte SWA;          //IC??????1
+    public byte SWB;            //IC??????2
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/newcapec/jni/ApduSend.java b/app/src/main/java/com/newcapec/jni/ApduSend.java
new file mode 100644
index 0000000..d5dbe30
--- /dev/null
+++ b/app/src/main/java/com/newcapec/jni/ApduSend.java
@@ -0,0 +1,9 @@
+package com.newcapec.jni;
+
+
+public class ApduSend {
+    public byte[] Command = new byte[4];     //CLA, INS, P1, P2
+    public short Lc;           //?????IC???????????
+    public byte[] DataIn = new byte[512];      //?????IC????????
+    public short Le;           //????????????????
+}
diff --git a/app/src/main/java/com/newcapec/jni/AuxScreen.java b/app/src/main/java/com/newcapec/jni/AuxScreen.java
new file mode 100644
index 0000000..6e7a1cb
--- /dev/null
+++ b/app/src/main/java/com/newcapec/jni/AuxScreen.java
@@ -0,0 +1,197 @@
+package com.newcapec.jni;
+
+public class AuxScreen {
+
+    /**
+     * font code  type
+     */
+    public static final int FONT_CODE_UCS2 = 0;
+    public static final int FONT_CODE_GB2312 = 1;
+    public static final int FONT_CODE_UTF8 = 2;
+
+
+    static {
+        try {
+            System.loadLibrary("auxScreen");
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @return
+     */
+    public int open() {
+        return Native_ScrOpen();
+    }
+
+    /**
+     *
+     */
+    public void close() {
+        Native_ScrClose();
+    }
+
+    /**
+     * 清全屏
+     *
+     * @return
+     */
+    public int cls() {
+        return Native_ScrCls();
+    }
+
+    /**
+     * 清屏
+     *
+     * @param startline 起始行
+     * @param endline   结束行
+     * @return
+     */
+    public int clrLine(int startline, int endline) {
+        return Native_ScrClrLine(startline, endline);
+    }
+
+    /**
+     * 设置前景颜色
+     *
+     * @param fgcolor
+     * @return
+     */
+    public int setFgcolor(int fgcolor) {
+        return Native_ScrSetFgcolor(fgcolor);
+    }
+
+    /**
+     * 设置背景颜色
+     *
+     * @param bgcolor
+     * @return
+     */
+    public int setBgcolor(int bgcolor) {
+        return Native_ScrSetBgcolor(bgcolor);
+    }
+
+    /**
+     * 选择字体
+     *
+     * @param fonttype
+     * @return
+     */
+    public int selectFont(int fonttype) {
+        return Native_ScrSelectFont(fonttype);
+    }
+
+    /**
+     * 设置字体大小
+     *
+     * @param fontsize
+     * @return
+     */
+    public int setFontSize(int fontsize) {
+        return Native_ScrSetFontSize(fontsize);
+    }
+
+    /**
+     * 设置字、行间距
+     *
+     * @param CharSpace
+     * @param LineSpace
+     */
+    public void setSpace(int CharSpace, int LineSpace) {
+        Native_ScrSpaceSet(CharSpace, LineSpace);
+    }
+
+    /**
+     * 设置像素点颜色
+     *
+     * @param x
+     * @param y
+     * @param color
+     */
+    public void drawDot(int x, int y, int color) {
+        Native_ScrDrawDot(x, y, color);
+    }
+
+    /**
+     * 矩形框
+     *
+     * @param left
+     * @param top
+     * @param right
+     * @param bottom
+     * @param color
+     */
+    public void drawRect(int left, int top, int right, int bottom, int color) {
+        Native_ScrDrawRect(left, top, right, bottom, color);
+    }
+
+    /**
+     * 从某个点画字
+     *
+     * @param x
+     * @param y
+     * @param txt
+     * @return
+     */
+    public int textOut(int x, int y, String txt) {
+        return Native_ScrTextOut(x, y, txt);
+    }
+
+    /**
+     * 获取屏幕的宽高
+     *
+     * @param width
+     * @param height
+     * @return
+     */
+    public int getSize(int width[], int height[]) {
+        return Native_ScrGetSize(width, height);
+    }
+
+    public int drawBmp(int width, int height, byte bmp[]) {
+        return Native_ScrDrawBmp(width, height, bmp);
+    }
+
+    public void ScrDrawLogo() {
+        Native_ScrDrawLogo();
+    }
+
+    public void ScrClrRect(int left, int top, int width, int height) {
+        Native_ScrClrRect(left, top, width, height);
+    }
+
+
+    private native final int Native_ScrOpen();
+
+    private native final void Native_ScrClose();
+
+    private native final int Native_ScrCls();
+
+    private native final int Native_ScrClrLine(int startline, int endline);
+
+    private native final int Native_ScrSetFgcolor(int fgcolor);
+
+    private native final int Native_ScrSetBgcolor(int bgcolor);
+
+    private native final int Native_ScrSelectFont(int fonttype);
+
+    private native final int Native_ScrSetFontSize(int fontsize);
+
+    private native final void Native_ScrSpaceSet(int CharSpace, int LineSpace);
+
+    private native final void Native_ScrDrawDot(int x, int y, int color);
+
+    private native final void Native_ScrDrawRect(int left, int top, int right, int bottom, int color);
+
+    private native final int Native_ScrTextOut(int x, int y, String txt);
+
+    private native final int Native_ScrGetSize(int width[], int height[]);
+
+    private native final int Native_ScrDrawBmp(int width, int height, byte bmp[]);
+
+    private native final void Native_ScrDrawLogo();
+
+    private native final void Native_ScrClrRect(int left, int top, int width, int height);
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/newcapec/jni/Icc.java b/app/src/main/java/com/newcapec/jni/Icc.java
new file mode 100644
index 0000000..3a4f197
--- /dev/null
+++ b/app/src/main/java/com/newcapec/jni/Icc.java
@@ -0,0 +1,57 @@
+package com.newcapec.jni;
+
+/**
+ * 接触卡
+ *
+ * @author mayixi
+ */
+public class Icc {
+    static {
+
+    }
+
+    /**
+     * @param version
+     */
+    public Icc(int version) {
+        if (version < 110) {
+            System.loadLibrary("iccV108");
+        } else if (version < 115) {
+            System.loadLibrary("iccV110");
+        } else if (version < 116) {
+            System.loadLibrary("iccV115");
+        } else {
+            System.loadLibrary("iccV116");
+        }
+    }
+
+    public int init(byte slot, byte attr[]) {
+        return Native_Icc_Init(slot, attr);
+    }
+
+    public int close(byte slot) {
+        return Native_Icc_Close(slot);
+    }
+
+    public int autoResp(byte slot, byte autoresp) {
+        return Native_Icc_AutoResp(slot, autoresp);
+    }
+
+    public int sendIsoCommand(byte slot, ApduSend send, ApduResp recv) {
+        return Native_Icc_IsoCommand(slot, send, recv);
+    }
+
+    public int detect(byte slot) {
+        return Native_Icc_Detect(slot);
+    }
+
+    private native final int Native_Icc_Init(byte slot, byte atr[]);
+
+    private native final int Native_Icc_Close(byte slot);
+
+    private native final int Native_Icc_AutoResp(byte slot, byte autoresp);
+
+    private native final int Native_Icc_IsoCommand(byte slot, ApduSend send, ApduResp recv);
+
+    private native final int Native_Icc_Detect(byte slot);
+};
diff --git a/app/src/main/java/com/newcapec/jni/Picc.java b/app/src/main/java/com/newcapec/jni/Picc.java
new file mode 100644
index 0000000..fadb179
--- /dev/null
+++ b/app/src/main/java/com/newcapec/jni/Picc.java
@@ -0,0 +1,195 @@
+/*******************************************************************
+ * PiccInterface.java
+ * PiccInterface 、PICC_PARA、DetectInfo、ErrocCode
+ * A302 射频卡操作接口类
+ * 2014-11-05
+ * v0.1
+ *******************************************************************/
+package com.newcapec.jni;
+
+public class Picc {
+    static {
+
+    }
+
+    public static class PICC_PARA {
+
+        public byte drv_ver[];       // 驱动程序的版本信息,如:”1.01A”;只能读取,写入无效
+        public byte drv_date[];      // 驱动程序的日期信息,如:”2006.08.25”; 只能读取
+        public byte a_conduct_w;     // A卡输出电导写入允许:1--允许,其它—不允许
+        public byte a_conduct_val;   // A卡输出电导控制变量,有效范围0~63,超出时视为63
+        public byte m_conduct_w;       // M1卡输出电导写入允许
+        public byte m_conduct_val;   // M1卡输出电导控制变量,有效范围0~63,超出时视为63
+        public byte b_modulate_w;    //B卡调制指数写入允许:
+        public byte b_modulate_val;  // B卡调制指数控制变量,有效范围0~63,超出时视为63
+        public byte card_buffer_w;   //卡片接收缓冲区大小写入允许:
+
+        public short card_buffer_val;      //卡片接收缓冲区大小参数(单位:字节),有效值1~256.大于256时,将以256写入;设为0时,将不会写入
+        public byte wait_retry_limit_w;     // S(WTX)响应发送次数写入允许(暂不适用)
+        public short wait_retry_limit_val; //S(WTX)响应最大重试次数(暂不适用)
+        public byte card_type_check_w;      //卡片类型检查写入允许 */
+        public byte card_type_check_val;    // 0-检查卡片类型,其他-不检查卡片类型(默认为检查卡片类型)
+        public byte card_RxThreshold_w;     //B卡片接收灵敏度写入允许:1--允许,其它值--不允许。该值不可读
+        public byte card_RxThreshold_val;      //B卡片接收灵敏度
+
+        public byte f_modulate_w;          //felica调制指数写入允许
+        public byte f_modulate_val;
+        public byte a_modulate_w;
+        public byte a_modulate_val;
+        public byte a_card_RxThreshold_w;
+        public byte a_card_RxThreshold_val;    //felica调制指数
+
+        /*A卡调制指数控制变量,有效范围0~63,超出时视为63*/
+        /*A卡接收灵敏度检查写入允许:1--允许,其它值--不允许*/
+        /*A卡接收灵敏度*/
+        public byte a_card_antenna_gain_w;
+        public byte a_card_antenna_gain_val;    //A卡的天线增益
+        public byte b_card_antenna_gain_w;
+        public byte b_card_antenna_gain_val;    //B卡的天线增益
+        public byte f_card_antenna_gain_w;
+        public byte f_card_antenna_gain_val;    //Felica的天线增益
+        public byte f_card_RxThreshold_w;
+        public byte f_card_RxThreshold_val;    //Felica的接收灵敏度
+        public byte f_conduct_w;
+        public byte f_conduct_val;
+        public byte user_control_w;
+        public byte user_control_val;         //paypass认证需求,指定按键值,按下时强制退出交易*/	/*Felica的电导率*/
+        public byte reserved[];                //保留字节,用于将来扩展;写入时应全清零
+
+        public PICC_PARA() {
+            drv_ver = new byte[5];
+            drv_date = new byte[12];
+            reserved = new byte[72];
+        }
+    }
+
+    public static class DetectInfo {
+        public String CardType;
+        public String SerialInfo;
+        public String Cid;
+        public String Other;
+        public byte Cid_Array[];
+        public byte SerialInfo_Array[];
+
+        public DetectInfo() {
+            CardType = new String();
+            SerialInfo = new String();
+            Other = new String();
+            Cid = new String();
+
+            Cid_Array = new byte[10];
+            SerialInfo_Array = new byte[20];
+        }
+    }
+
+//    public class ErrocCode {
+//        public final static int PICC_STATUS_SUCCESS = 0x00;            //成功
+//        public final static int PICC_STATUS_ARGUMENTS_ERROR = 0x01;           //参数错误
+//        public final static int PICC_STATUS_NOT_OPEN = 0x02;           //射频模块未开启
+//        public final static int PICC_STATUS_NO_CARD = 0x03;           //未搜寻到卡片(感应区内无指定类型的卡片)
+//        public final static int PICC_STATUS_MANY_CARD = 0x04;           //感应区内卡片过多(出现通讯冲突)
+//        public final static int PICC_STATUS_ERROR_PROTOCOL = 0x06;          //协议错误(卡片应答中出现违反协议规定的数据)
+//        public final static int PICC_STATUS_CARD_NO_ACTIVE = 0x13;          //卡片未激活
+//        public final static int PICC_STATUS_CARDS_CONFLICT = 0x14;          //多卡冲突?
+//        public final static int PICC_STATUS_TIMEOUT = 0x15;          //超时无响应
+//        //public final static int   PICC_STATUS_DATA_LONG      =       0x16 ;          //协议错误
+//        public final static int PICC_STATUS_COMMUNICAT_ERROR = 0x17;         //通信传输错误
+//        public final static int PICC_STATUS_M1_CARD_Authentication_ERROR = 0x18;    //M1卡认证失败
+//        public final static int PICC_STATUS_SECTION_NO_Authentication = 0x19;   //扇区未认证
+//        public final static int PICC_STATUS_DATA_FORMAT_ERROR = 0x1A;   //数值块数据格式有误
+//        public final static int PICC_STATUS_CARD_IN_INDUCTION_ZONE = 0x1B;     //卡片仍在感应区内
+//        public final static int PICC_STATUS_CARD_STATE_ERROR = 0x1C;        //卡片状态错误(如A/B卡调用M1卡接口, 或M1卡调用PiccIsoCommand接口)
+//        public final static int PICC_STATUS_CARD_ABORT = 0xFF;        //接口芯片不存在或异常
+//    }
+
+    /**
+     * @param version
+     */
+    public Picc(int version) {
+        if (version < 110) {
+            System.loadLibrary("piccV108");
+        } else if (version < 116) {
+            System.loadLibrary("piccV115");
+        } else {
+            System.loadLibrary("piccV116");
+        }
+    }
+
+    public int open() {
+        return Native_Picc_Open();
+    }
+
+    public int setup(byte mode, PICC_PARA para) {
+        return Native_Picc_Setup(mode, para);
+    }
+
+    public int sendIsoCommand(byte cid, ApduSend Send, ApduResp Resp) {
+        return Native_Picc_IsoCommand(cid, Send, Resp);
+    }
+
+    public int remove(byte mode, byte cid) {
+        return Native_Picc_Remove(mode, cid);
+    }
+
+    public int close() {
+        return Native_Picc_Close();
+    }
+
+    public int m1Authority(byte Type, byte BlkNo, byte Pwd[], byte SerialNo[]) {
+        return Native_Picc_M1Authority(Type, BlkNo, Pwd, SerialNo);
+    }
+
+    public int readM1Block(byte BlkNo, byte BlkValue[], int BlkLen) {
+        return Native_Picc_M1ReadBlock(BlkNo, BlkValue, BlkLen);
+    }
+
+    public int writeM1Block(byte BlkNo, byte BlkValue[], int BlkLen) {
+        return Native_Picc_M1WriteBlock(BlkNo, BlkValue, BlkLen);
+    }
+
+    public int operateM1(byte Type, byte BlkNo, byte Value[], byte UpdateBlkNo) {
+        return Native_Picc_M1Operate(Type, BlkNo, Value, UpdateBlkNo);
+    }
+
+    public int light(byte ucLedIndex, byte ucOnOff) {
+        return Native_Picc_Light(ucLedIndex, ucOnOff);
+    }
+
+    public int initFelica(byte ucRate, byte ucPol) {
+        return Native_Picc_InitFelica(ucRate, ucPol);
+    }
+
+    public int exchangeCmd(int uiSendLen, String paucInData, int puiRecLen[], String paucOutData) {
+        return Native_Picc_CmdExchange(uiSendLen, paucInData, puiRecLen, paucOutData);
+    }
+
+    public int detect(byte Mode, DetectInfo info) {
+        return Native_Picc_Detect(Mode, info);
+    }
+
+    private native final int Native_Picc_Open();
+
+    private native final int Native_Picc_Setup(byte mode, PICC_PARA para);
+
+    private native final int Native_Picc_IsoCommand(byte cid, ApduSend ApduSend, ApduResp ApduRecv);
+
+    private native final int Native_Picc_Remove(byte mode, byte cid);
+
+    private native final int Native_Picc_Close();
+
+    private native final int Native_Picc_M1Authority(byte Type, byte BlkNo, byte Pwd[], byte SerialNo[]);
+
+    private native final int Native_Picc_M1ReadBlock(byte BlkNo, byte BlkValue[], int BlkLen);
+
+    private native final int Native_Picc_M1WriteBlock(byte BlkNo, byte BlkValue[], int BlkLen);
+
+    private native final int Native_Picc_M1Operate(byte Type, byte BlkNo, byte Value[], byte UpdateBlkNo);
+
+    private native final int Native_Picc_Light(byte ucLedIndex, byte ucOnOff);
+
+    private native final int Native_Picc_InitFelica(byte ucRate, byte ucPol);
+
+    private native final int Native_Picc_CmdExchange(int uiSendLen, String paucInData, int puiRecLen[], String paucOutData);
+
+    private native final int Native_Picc_Detect(byte Mode, DetectInfo info);
+};
diff --git a/app/src/main/java/com/newcapec/serial/SerialPort.java b/app/src/main/java/com/newcapec/serial/SerialPort.java
new file mode 100644
index 0000000..f8099fb
--- /dev/null
+++ b/app/src/main/java/com/newcapec/serial/SerialPort.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2009 Cedric Priscal
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+package com.newcapec.serial;
+
+import java.io.IOException;
+
+public class SerialPort {
+
+	private static final String TAG = "SerialPort";
+	static {
+		System.loadLibrary("serial_port");
+	}
+	
+	/**
+	 * @name    open
+	 * @desc    ??????1
+	 * @param : ??
+	 * @return  0-???, ????-???
+	 * @throws IOException  ??
+	 */
+	public int open(int port, int baudrate, int flags)	
+	{
+		return Native_Serial_Open(port, baudrate, flags);
+	}
+	
+	/**
+	 * @name    sendMsg
+	 * @desc    ????????
+	 * @param : ??
+	 * @return  0-???, ????-???
+	 * @throws IOException  ??
+	 */
+	public int sendMsg(byte[] msg)	
+	{
+		return Native_Serial_SendMsg(msg);
+	}
+	
+	/**
+	 * @name    recvMsg
+	 * @desc    ????????
+	 * @param : ??
+	 * @return  0-???, ????-???
+	 * @throws IOException  ??
+	 */
+	public byte[] recvMsg()	
+	{
+		return Native_Serial_RecvMsg();
+	}	
+	
+	/**
+	 * @name    close
+	 * @desc    ??????
+	 * @param : ??
+	 * @return  0-???, ????-???
+	 * @throws IOException  ??
+	 */
+	public int close()	
+	{
+		return Native_Serial_Close();
+	}	
+	
+		
+	private native final int	Native_Serial_Open(int port, int baudrate, int flags);
+	private native final int	Native_Serial_SendMsg(byte[] msg);
+	private native final byte[]	Native_Serial_RecvMsg();
+	private native final int	Native_Serial_Close();
+	
+}
diff --git a/app/src/main/java/com/supwisdom/activities/BaseActivity.kt b/app/src/main/java/com/supwisdom/activities/BaseActivity.kt
new file mode 100644
index 0000000..6183f9a
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/BaseActivity.kt
@@ -0,0 +1,31 @@
+package com.supwisdom.activities
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import com.supwisdom.utils.AppExitUtil
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+open class BaseActivity : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        //getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+        AppExitUtil.add(this)
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        AppExitUtil.remove(this)
+    }
+
+    override fun onResume() {
+        super.onResume()
+    }
+
+    fun <T> jumpActivity(cls: Class<T>) {
+        startActivity(Intent(applicationContext, cls))
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/CrashHandler.kt b/app/src/main/java/com/supwisdom/activities/CrashHandler.kt
new file mode 100644
index 0000000..48caaf3
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/CrashHandler.kt
@@ -0,0 +1,133 @@
+package com.supwisdom.activities
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.Build
+import android.os.Looper
+import com.supwisdom.utils.*
+import com.supwisdom.view.ToastUtil
+import java.io.PrintWriter
+import java.io.StringWriter
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+class CrashHandler : Thread.UncaughtExceptionHandler {
+    private var context: Context? = null
+    private var mDefaultHandler: Thread.UncaughtExceptionHandler? = null
+    private val info = HashMap<String, String>()
+
+    companion object {
+        @SuppressLint("StaticFieldLeak")
+        private var INSTANCE: CrashHandler? = null
+
+        fun getInstance(): CrashHandler {
+            if (INSTANCE == null) {
+                synchronized(CrashHandler::class) {
+                    if (INSTANCE == null) {
+                        INSTANCE = CrashHandler()
+                    }
+                }
+            }
+            return INSTANCE!!
+        }
+    }
+
+    fun init(context: Context) {
+        this.context = context
+        // 获取系统默认的 UncaughtException 处理器
+        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler()
+        // 设置该 CrashHandler 为程序的默认处理器
+        Thread.setDefaultUncaughtExceptionHandler(this)
+    }
+
+    override fun uncaughtException(thread: Thread, ex: Throwable) {
+        if (!handleException(ex) && mDefaultHandler != null) {
+            // 如果自定义的没有处理则让系统默认的异常处理器来处理
+            mDefaultHandler!!.uncaughtException(thread, ex)
+        } else {
+            AppExitUtil.exit()
+        }
+    }
+
+    /**
+     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
+     *
+     * @param ex 异常信息
+     * @return true 如果处理了该异常信息;否则返回false.
+     */
+    private fun handleException(ex: Throwable?): Boolean {
+        ThreadPool.getShortPool().execute(Runnable {
+            CommonUtil.doSleep(500)
+            Looper.prepare()
+            ToastUtil.show(context!!, "很抱歉,程序运行异常")
+            Looper.loop()
+        })
+        if (ex == null) {
+            return false
+        }
+        // 收集设备参数信息
+        collectDeviceInfo()
+        // 保存日志文件
+        saveCrashInfo2File(ex)
+        return true
+    }
+
+    /**
+     * 收集设备参数信息
+     */
+
+    private fun collectDeviceInfo() {
+        try {
+            val pm = context!!.packageManager// 获得包管理器
+            val pi = pm.getPackageInfo(
+                context!!.packageName,
+                PackageManager.GET_ACTIVITIES
+            )// 得到该应用的信息,即主Activity
+            if (pi != null) {
+                info["versionName"] = pi.versionName ?: "null"
+                info["versionCode"] = pi.versionCode.toString()
+            }
+        } catch (e: PackageManager.NameNotFoundException) {
+            e.printStackTrace()
+        }
+
+        val fields = Build::class.java.declaredFields// 反射机制
+        for (field in fields) {
+            try {
+                field.isAccessible = true
+                info[field.name] = field.get("").toString()
+            } catch (e: IllegalArgumentException) {
+                e.printStackTrace()
+            } catch (e: IllegalAccessException) {
+                e.printStackTrace()
+            }
+        }
+    }
+
+    private fun saveCrashInfo2File(ex: Throwable): Boolean {
+        val sb = StringBuffer()
+        sb.append("\r\n crash time :").append(DateUtil.getNowTime()).append("\r\n")
+        for ((key, value) in info) {
+            sb.append("$key=$value\r\n")
+        }
+        val writer = StringWriter()
+        val pw = PrintWriter(writer)
+        ex.printStackTrace(pw)
+        var cause: Throwable? = ex.cause
+        // 循环着把所有的异常信息写入writer中
+        while (cause != null) {
+            cause.printStackTrace(pw)
+            cause = cause.cause
+        }
+        pw.close()// 记得关闭
+        val result = writer.toString()
+        sb.append(result)
+        // 保存文件
+        FileUtil.writeCrashFile(sb.toString())
+        return true
+    }
+}
\ 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
new file mode 100644
index 0000000..61e704d
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/SPApplication.kt
@@ -0,0 +1,70 @@
+package com.supwisdom.activities
+
+import android.content.Context
+import android.content.Intent
+import android.support.multidex.MultiDex
+import android.support.multidex.MultiDexApplication
+import com.supwisdom.db.Pos
+import com.supwisdom.service.BackgroundTaskService
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.PublicDef
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+class SPApplication : MultiDexApplication() {
+    private var mPos: Pos? = null
+    @Volatile
+    private var epayLinking: Boolean = false //链路状态 true 联机
+
+    companion object {
+        @Volatile
+        private var mInstance: SPApplication? = null
+
+        fun getInstance(): SPApplication {
+            return mInstance!!
+        }
+    }
+
+    fun getPos(): Pos {
+        if (mPos == null) {
+            synchronized(SPApplication::class.java) {
+                if (mPos == null) {
+                    mPos = Pos(applicationContext)
+                }
+            }
+        }
+        return mPos!!
+    }
+
+    fun setEpayLinking(isOnline: Boolean) {
+        epayLinking = isOnline
+    }
+
+    fun isOnline(): Boolean {
+        return epayLinking
+    }
+
+    override fun onCreate() {
+        super.onCreate()
+        mInstance = this
+        startService()
+        CrashHandler.getInstance().init(applicationContext)
+    }
+
+    override fun attachBaseContext(base: Context) {
+        super.attachBaseContext(base)
+        MultiDex.install(this)
+    }
+
+    private fun startService() {
+        if (!CommonUtil.isServiceWork(this, PublicDef.BG_SERVICE_NAME)) {
+            startService(Intent(this, BackgroundTaskService::class.java))
+        }
+    }
+
+    fun stopService() {
+        stopService(Intent(this, BackgroundTaskService::class.java))
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/ServiceDemo.kt b/app/src/main/java/com/supwisdom/activities/ServiceDemo.kt
new file mode 100644
index 0000000..c0bc6b1
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/ServiceDemo.kt
@@ -0,0 +1,15 @@
+package com.supwisdom.activities
+
+import android.app.Service
+import android.content.Intent
+import android.os.IBinder
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+class ServiceDemo : Service() {
+    override fun onBind(intent: Intent): IBinder? {
+        return null
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/YktSession.kt b/app/src/main/java/com/supwisdom/activities/YktSession.kt
new file mode 100644
index 0000000..0d01687
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/YktSession.kt
@@ -0,0 +1,81 @@
+package com.supwisdom.activities
+
+import com.supwisdom.okhttp.NetworkHandler
+import com.supwisdom.okhttp.TransResp
+import com.supwisdom.okhttp.WebAPISession
+import com.supwisdom.okhttp.WebParams
+import com.supwisdom.utils.DateUtil
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class YktSession private constructor() {
+    companion object {
+        private var yktSession: YktSession? = null
+        private var mSession: WebAPISession? = null
+        /**
+         * Create YktSession instance
+         *
+         * @return YktSession object
+         */
+        @Synchronized
+        fun getInstance(): YktSession {
+            if (null == yktSession) {
+                synchronized(YktSession::class.java) {
+                    if (null == yktSession) {
+                        yktSession = YktSession()
+                        mSession = WebAPISession()
+                    }
+                }
+            }
+            return yktSession!!
+        }
+    }
+
+    fun setSessionKey(sessionKey: String) {
+        mSession!!.setSessionKey(sessionKey)
+    }
+
+
+    // 设置通信参数
+    fun setWebAPISession(epayIP: String, epayPort: Int, uri: String, termid: String, commTime: Int) {
+        val sb = StringBuilder()
+        if (epayIP.startsWith("http")) {
+            sb.append(epayIP)
+        } else {
+            sb.append("http://").append(epayIP)
+        }
+        sb.append(":").append(epayPort).append("/").append(uri)
+
+        mSession!!.setEpayurl(sb.toString())
+        NetworkHandler.getInstance().setCommTime(commTime)
+    }
+
+    // post
+    fun sendYktRequestPost(uri: String, signdata: String, params: WebParams): TransResp? {
+        val timestamp = DateUtil.getNowDateTimeNoFormat()
+        val temp = signdata.replace("null".toRegex(), "")
+        val mysign = calcSignForCardPay(temp, timestamp)
+        params.setParameter("sign", mysign)
+            .setParameter("timestamp", timestamp)
+        val url = mSession!!.getEpayurl() + uri
+        return NetworkHandler.getInstance().post(url, params)
+    }
+
+    fun sendYktRequestLongPost(uri: String, signdata: String, params: WebParams): TransResp? {
+        val timestamp = DateUtil.getNowDateTimeNoFormat()
+        val temp = signdata.replace("null".toRegex(), "")
+        val mysign = calcSignForCardPay(temp, timestamp)
+        params.setParameter("sign", mysign)
+            .setParameter("timestamp", timestamp)
+        val url = mSession!!.getEpayurl() + uri
+        return NetworkHandler.getInstance().longPost(url, params)
+    }
+
+    private fun calcSignForCardPay(extdata: String, nTimestamp: String): String {
+        val signData = extdata + nTimestamp + mSession!!.getSessionKey()
+//        val mySign = Encrypt.HMACSHA1(signData, mSession.getAppSecret())
+        return ""//mySign.toLowerCase()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenController.kt b/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenController.kt
new file mode 100644
index 0000000..2e81b1c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenController.kt
@@ -0,0 +1,263 @@
+package com.supwisdom.auxscreen
+
+import android.graphics.Color
+import com.newcapec.jni.AuxScreen
+import com.supwisdom.utils.CommonUtil
+import java.util.concurrent.locks.ReentrantLock
+
+/**
+ * @author gqy
+ * @version 1.0.1
+ * @date 2018/7/11
+ * @desc 小屏控制器
+ */
+class AuxScreenController private constructor() {
+    private var auxScreen = AuxScreen()
+    private val xStart = 15
+    private val xSecStart = 240
+    private val sTitle = "refreshTitle"
+    private val sContent = "refreshContent"
+    private val sBottom = "refreshBottom"
+    private val lock = ReentrantLock()
+    private val refreshMap = hashMapOf<String, Any>()
+    private val auxRunnable = AuxRunnable()
+    private var isExit = false
+    private var taskThread: Thread? = null
+
+    companion object {
+        @Volatile
+        private var auxController: AuxScreenController? = null
+
+        fun getInstance(): AuxScreenController {
+            if (null == auxController) {
+                synchronized(AuxScreenController::class.java) {
+                    if (null == auxController) {
+                        auxController = AuxScreenController()
+                    }
+                }
+            }
+            return auxController!!
+        }
+    }
+
+    /**
+     * 刷新标题栏
+     * @param title 标题
+     */
+    fun refreshTitle(title: String) {
+        lock.lock()
+        refreshMap[sTitle] = title
+        lock.unlock()
+    }
+
+    private fun localRefreshTitle(title: String) {
+        auxScreen.setBgcolor(Color.parseColor("#FFFFFF"))
+        auxScreen.clrLine(0, 50)
+        auxScreen.setBgcolor(Color.parseColor("#FFFFFF"))
+        auxScreen.setFontSize(20)
+        auxScreen.setFgcolor(Color.parseColor("#000000"))
+        auxScreen.textOut(xStart, 15, title)
+    }
+
+    /**
+     * 内容显示
+     * @param list 显示内容 size<=5
+     */
+    fun refreshContent(list: List<String>) {
+        lock.lock()
+        refreshMap[sContent] = list
+        lock.unlock()
+    }
+
+    private fun localRefreshContent(list: List<String>) {
+        auxScreen.setBgcolor(Color.parseColor("#F2F2F2"))
+        clearCenterContent()
+
+        val size = list.size
+        auxScreen.setFgcolor(Color.parseColor("#000000"))
+        when (size) {
+            0 -> {
+
+            }
+            1 -> {
+                auxScreen.setFontSize(40)
+                auxScreen.textOut(xStart, 140, getNotEmptyString(list[0]))
+            }
+            2 -> {
+                auxScreen.setFontSize(35)
+                for (index in 0 until size) {
+                    auxScreen.textOut(xStart, 120 + 60 * index, getNotEmptyString(list[index]))
+                }
+            }
+            3 -> {
+                auxScreen.setFontSize(30)
+                for (index in 0 until size) {
+                    auxScreen.textOut(xStart, 100 + 50 * index, getNotEmptyString(list[index]))
+                }
+            }
+            4 -> {
+                auxScreen.setFontSize(25)
+                for (index in 0 until size) {
+                    auxScreen.textOut(xStart, 80 + 45 * index, getNotEmptyString(list[index]))
+                }
+            }
+            5 -> {
+                auxScreen.setFontSize(20)
+                for (index in 0 until size) {
+                    auxScreen.textOut(xStart, 70 + 40 * index, getNotEmptyString(list[index]))
+                }
+            }
+            6 -> {
+                auxScreen.setFontSize(15)
+                for (index in 0 until size) {
+                    auxScreen.textOut(xStart, 60 + 35 * index, getNotEmptyString(list[index]))
+                }
+            }
+            7, 8 -> {
+                auxScreen.setFontSize(25)
+                for (index in 0 until (size + 1) / 2) {
+                    auxScreen.textOut(xStart, 80 + 45 * index, getNotEmptyString(list[2 * index]))
+                    if (2 * index + 1 < size) {
+                        auxScreen.textOut(xSecStart, 80 + 45 * index, getNotEmptyString(list[2 * index + 1]))
+                    }
+                }
+            }
+            9, 10 -> {
+                auxScreen.setFontSize(20)
+                for (index in 0 until (size + 1) / 2) {
+                    auxScreen.textOut(xStart, 70 + 40 * index, getNotEmptyString(list[2 * index]))
+                    if (2 * index + 1 < size) {
+                        auxScreen.textOut(xSecStart, 70 + 40 * index, getNotEmptyString(list[2 * index + 1]))
+                    }
+                }
+            }
+            else -> {
+                auxScreen.setFontSize(15)
+                for (index in 0 until (size + 1) / 2) {
+                    auxScreen.textOut(xStart, 60 + 35 * index, getNotEmptyString(list[2 * index]))
+                    if (2 * index + 1 < size) {
+                        auxScreen.textOut(xSecStart, 60 + 35 * index, getNotEmptyString(list[2 * index + 1]))
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 处理输入的空字符串
+     */
+    private fun getNotEmptyString(input: String?): String {
+        if (input == null || input.isEmpty()) {
+            return " "
+        }
+        return input
+    }
+
+    /**
+     * 刷新底部状态
+     * @param bottom 提示
+     */
+    fun refreshBottom(bottom: String) {
+        lock.lock()
+        refreshMap[sBottom] = bottom
+        lock.unlock()
+    }
+
+    private fun localRefreshBootom(bottom: String) {
+        auxScreen.setBgcolor(Color.parseColor("#FFFFFF"))
+        auxScreen.clrLine(269, 319)
+
+        auxScreen.setFontSize(20)
+        auxScreen.setFgcolor(Color.parseColor("#000000"))
+        auxScreen.textOut(15, 284, bottom)
+    }
+
+    /**
+     * 清空中间的内容
+     * @注意:此处必须一行一行的清除,底层bug
+     */
+    private fun clearCenterContent() {
+        auxScreen.clrLine(50, 100)
+        auxScreen.clrLine(100, 150)
+        auxScreen.clrLine(150, 200)
+        auxScreen.clrLine(200, 250)
+        auxScreen.clrLine(250, 269)
+        auxScreen.setFontSize(50)
+    }
+
+    /**
+     * 打开小屏
+     */
+    fun open() {
+        auxScreen.open()
+        if (taskThread == null) {
+            isExit = false
+            taskThread = Thread(auxRunnable)
+            taskThread!!.start()
+        }
+    }
+
+    /**
+     * 关闭小屏
+     */
+    fun close() {
+        auxScreen.close()
+        isExit = true
+        taskThread?.interrupt()
+        taskThread = null
+    }
+
+    /**
+     * 初始化小屏
+     */
+    private fun init() {
+        auxScreen.setBgcolor(Color.parseColor("#F2F2F2"))
+        auxScreen.cls()
+        auxScreen.setSpace(5, 5)
+        auxScreen.selectFont(AuxScreen.FONT_CODE_UTF8)
+    }
+
+    inner class AuxRunnable : Runnable {
+        override fun run() {
+            init()
+            while (!isExit) {
+                try {
+                    try {
+                        lock.lock()
+                        val title = refreshMap[sTitle]
+                        if (title != null) {
+                            localRefreshTitle(title as String)
+                            refreshMap.remove(sTitle)
+                        }
+                    } finally {
+                        lock.unlock()
+                    }
+                    try {
+                        lock.lock()
+                        val content = refreshMap[sContent]
+                        if (content != null) {
+                            localRefreshContent(content as List<String>)
+                            refreshMap.remove(sContent)
+                        }
+                    } finally {
+                        lock.unlock()
+                    }
+                    try {
+                        lock.lock()
+                        val bottom = refreshMap[sBottom]
+                        if (bottom != null) {
+                            localRefreshBootom(bottom as String)
+                            refreshMap.remove(sBottom)
+                        }
+                    } finally {
+                        lock.unlock()
+                    }
+                } catch (ex: Exception) {
+                    ex.printStackTrace()
+                }
+                CommonUtil.doSleep(25)
+            }
+        }
+    }
+}
+
diff --git a/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenViewSchedule.kt b/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenViewSchedule.kt
new file mode 100644
index 0000000..896e3a6
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/auxscreen/AuxScreenViewSchedule.kt
@@ -0,0 +1,51 @@
+package com.supwisdom.activities.auxscreen
+
+import android.os.Handler
+import android.os.HandlerThread
+import android.os.Message
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class AuxScreenViewSchedule private constructor() {
+    private val mExector: Runnable? = null
+    private var mAuxWorkHandler: Handler
+    private var mHandlerThread: HandlerThread
+
+    companion object {
+        private var _instance: AuxScreenViewSchedule? = null
+        fun getInstancs(): AuxScreenViewSchedule {
+            if (_instance == null)
+                _instance =
+                    AuxScreenViewSchedule()
+            return _instance!!
+        }
+    }
+
+    init {
+        mHandlerThread = HandlerThread("AuxScreenViewThread")
+
+        mHandlerThread.start()
+
+        mAuxWorkHandler = object : Handler(mHandlerThread.looper) {
+            override// 消息处理的操作
+            fun handleMessage(msg: Message) {
+                super.handleMessage(msg)
+            }
+        }
+    }
+
+    fun Post(r: Runnable, attr: Int) {
+        //定时任务
+        //mAuxWorkHandler.getLooper().getQueue()
+        mAuxWorkHandler.removeCallbacks(r)
+        mAuxWorkHandler.post(r)
+    }
+
+    fun PostDelayed(r: Runnable, millis: Int) {
+        //定时任务
+        //mAuxWorkHandler.getLooper().getQueue()
+        mAuxWorkHandler.postDelayed(r, millis.toLong())
+    }
+}
\ No newline at end of file
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..f64c8cb
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/cardlib/CardlibActivity.kt
@@ -0,0 +1,121 @@
+package com.supwisdom.activities.cardlib
+
+import android.os.Bundle
+import android.view.KeyEvent
+import android.view.View
+import android.view.Window
+import android.widget.ProgressBar
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.init.InitActivity
+import com.supwisdom.activities.load.LoadActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.AppExitUtil
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.view.BigProgressDialog
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+@Suppress("DEPRECATION")
+class CardlibActivity : BaseActivity(), ICardlibView {
+    private val pos = SPApplication.getInstance().getPos()
+    private var vResult: TextView? = null
+    private var vProgressBar: ProgressBar? = null
+    private var presenter: CardlibPresenter? = null
+    @Volatile
+    private var isLoading = false
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        //在窗口标题上显示带进度的横向进度条
+        requestWindowFeature(Window.FEATURE_PROGRESS)
+        //显示不带进度的进度条
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS)
+
+        setContentView(R.layout.activity_cardlib)
+        initView()
+        initData()
+    }
+
+    private fun initData() {
+        presenter = CardlibPresenter(this)
+    }
+
+    private fun initView() {
+        vProgressBar = this.findViewById(R.id.cardlib_bar) as ProgressBar
+        vResult = this.findViewById(R.id.cardlib_result) as TextView
+    }
+
+    override fun showProgress(progress: Int) {
+        vProgressBar!!.progress = progress
+    }
+
+    override fun onResume() {
+        super.onResume()
+        if (!isLoading) {
+            isLoading = true
+            refresh()
+            presenter!!.initCardlib(this)
+        }
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (isLoading) {
+                return false
+            }
+            when (event.keyCode) {
+                KeyEvent.KEYCODE_DEL -> {
+                    AppExitUtil.exit()
+                }
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    private fun refresh() {
+        AuxScreenController.getInstance().refreshTitle("卡库初始化")
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime())
+        AuxScreenController.getInstance().refreshContent(listOf("加载硬件驱动", "请稍等..."))
+    }
+
+    override fun showInitCardlibResult(issuccess: Boolean, msg: String) {
+        if (issuccess) {
+            val record = pos.getConfigPara()
+            if (record != null && record.initOK) {
+                jumpActivity(LoadActivity::class.java)
+            } else {
+                jumpActivity(InitActivity::class.java)
+            }
+        } else {
+            vResult!!.text = msg
+            vResult!!.visibility = View.VISIBLE
+            AuxScreenController.getInstance().refreshTitle("卡库初始化")
+            AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime())
+            AuxScreenController.getInstance().refreshContent(listOf("请联系管理员", "加载驱动失败", "原因:", msg))
+        }
+        isLoading = false
+    }
+
+    private var dialogProgress: BigProgressDialog? = null
+
+    override fun showProgressDialog(msg: String) {
+        if (dialogProgress == null) {
+            dialogProgress = BigProgressDialog(this, msg, false)
+        }
+        dialogProgress!!.setMsg(msg)
+        dialogProgress!!.show()
+    }
+
+    override fun closeProgressDialog() {
+        dialogProgress?.dismiss()
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/cardlib/CardlibPresenter.kt b/app/src/main/java/com/supwisdom/activities/cardlib/CardlibPresenter.kt
new file mode 100644
index 0000000..d843183
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/cardlib/CardlibPresenter.kt
@@ -0,0 +1,98 @@
+package com.supwisdom.activities.cardlib
+
+import android.app.Activity
+import android.os.AsyncTask
+import android.os.Handler
+import android.os.Looper
+import android.os.Message
+import com.supwisdom.epaycard.Cardlib
+import com.supwisdom.exception.CardlibInitError
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.ThreadPool
+
+/**
+ * Created by zzq on 2017/11/7.
+ */
+class CardlibPresenter constructor(iCardlibView: ICardlibView) {
+    private val iCardlibView = iCardlibView
+    private val handler: Handler
+    @Volatile
+    private var cardlibStat = CardLibStatus.INIT
+    private var cardlibResult: String? = null
+
+    init {
+        handler = object : Handler(Looper.getMainLooper()) {
+            override fun handleMessage(msg: Message?) {
+                when (msg!!.what) {
+                    1 ->
+                        iCardlibView.showProgress(msg.obj as Int)
+                    2 -> {
+                        if (CardLibStatus.SUCCESS == cardlibStat) {
+                            iCardlibView.showInitCardlibResult(true, cardlibResult!!)
+                        } else {
+                            iCardlibView.showInitCardlibResult(false, cardlibResult!!)
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    fun initCardlib(acy: Activity) {
+        doProgressBar()
+        AsyncInitCardlib().execute(acy)
+    }
+
+    private inner class AsyncInitCardlib : AsyncTask<Activity, Unit, CardlibInitError?>() {
+        override fun onPostExecute(result: CardlibInitError?) {
+            if (result != null) {
+                cardlibStat = CardLibStatus.FAIL
+                cardlibResult = result.toString()
+            } else {
+                cardlibStat = CardLibStatus.SUCCESS
+                cardlibResult = "加载读卡库成功"
+            }
+        }
+
+        override fun doInBackground(vararg p0: Activity?): CardlibInitError? {
+            return try {
+                Cardlib.instance.init()
+                null
+            } catch (ex: CardlibInitError) {
+                ex
+            }
+        }
+    }
+
+    private fun doProgressBar() {
+        ThreadPool.getShortPool().execute(Runnable {
+            var i = 0
+            while (cardlibStat == CardLibStatus.INIT) {
+                CommonUtil.doSleep(100)
+                i++
+                if (i > 100) {
+                    i = 100
+                }
+                sendMsg(1, i)
+            }
+            while (i < 100) {
+                CommonUtil.doSleep(20)
+                sendMsg(1, i++)
+            }
+            sendMsg(2, 100)
+        })
+    }
+
+    private fun sendMsg(retcode: Int, retmsg: Any) {
+        val msg = Message()
+        msg.what = retcode
+        msg.obj = retmsg
+        handler.sendMessage(msg)
+    }
+}
+
+private enum class CardLibStatus(num: Int) {
+    INIT(0),
+    SUCCESS(1),
+    FAIL(2)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/cardlib/ICardlibView.kt b/app/src/main/java/com/supwisdom/activities/cardlib/ICardlibView.kt
new file mode 100644
index 0000000..bdb8c6c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/cardlib/ICardlibView.kt
@@ -0,0 +1,14 @@
+package com.supwisdom.activities.cardlib
+
+/**
+ * Created by zzq on 2017/11/7.
+ */
+interface ICardlibView {
+    fun showProgressDialog(msg: String)
+
+    fun closeProgressDialog()
+
+    fun showInitCardlibResult(issuccess: Boolean, msg: String)
+
+    fun showProgress(progress: Int)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/checkMngpwd/CheckMngpwdActivity.kt b/app/src/main/java/com/supwisdom/activities/checkMngpwd/CheckMngpwdActivity.kt
new file mode 100644
index 0000000..007c9cd
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/checkMngpwd/CheckMngpwdActivity.kt
@@ -0,0 +1,138 @@
+package com.supwisdom.activities.checkMngpwd
+
+import android.content.Intent
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.view.KeyEvent
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.manage.ManageActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.CommonUtil
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class CheckMngpwdActivity : BaseActivity() {
+    private var tmpPwd: String = ""
+    private lateinit var vTitle: TextView
+    private var password: String = ""
+    private var mode: String? = null
+    private var keyActive = true
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        this.setContentView(R.layout.activity_check_mngpwd)
+        initView()
+    }
+
+    private fun initView() {
+        vTitle = findViewById<TextView>(R.id.title)
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (!keyActive) {
+                return super.dispatchKeyEvent(event)
+            }
+            resetCounter(200)
+
+            val keyCode = event.keyCode
+            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 -> {
+                    tmpPwd += keyCode - KeyEvent.KEYCODE_0
+                    if (tmpPwd.length >= 6) {
+                        if (checkMngPwd(tmpPwd)) {
+                            jumpActivity(ManageActivity::class.java)
+                        } else {
+                            AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("维护密码:", "密码错误"))
+                        }
+                        tmpPwd = ""
+                    } else {
+                        AuxScreenController.getInstance()
+                            .refreshContent(Arrays.asList("维护密码:", CommonUtil.getPasswordStar(tmpPwd.length)))
+                    }
+                }
+                KeyEvent.KEYCODE_DEL -> {
+                    //cancel
+                    val len = tmpPwd.length
+                    when {
+                        len == 1 -> {
+                            tmpPwd = ""
+                            AuxScreenController.getInstance()
+                                .refreshContent(Arrays.asList("维护密码:", CommonUtil.getPasswordStar(tmpPwd.length)))
+                        }
+                        len > 1 -> {
+                            tmpPwd = tmpPwd.substring(0, len - 1)
+                            AuxScreenController.getInstance()
+                                .refreshContent(Arrays.asList("维护密码:", CommonUtil.getPasswordStar(tmpPwd.length)))
+                        }
+                        else -> finish()
+                    }
+                }
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        keyActive = true
+        password = this.intent.getStringExtra("password")
+        mode = this.intent.getStringExtra("mode")
+        refresh()
+    }
+
+    override fun onNewIntent(intent: Intent) {
+        super.onNewIntent(intent)
+        this.intent.putExtra("password", intent.getStringExtra("password"))
+        this.intent.putExtra("mode", intent.getStringExtra("mode"))
+    }
+
+    private fun refresh() {
+        tmpPwd = ""
+        vTitle.text = "维护密码验证"
+        AuxScreenController.getInstance().refreshTitle("维护密码验证")
+        AuxScreenController.getInstance().refreshBottom("取消键返回上页")
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("维护密码:", " "))
+    }
+
+    private fun checkMngPwd(inputPwd: String): Boolean {
+        return inputPwd == password
+    }
+
+    private var counter: ContinuePressTimer? = null
+
+    private fun resetCounter(timems: Long) {
+        counter?.cancel()
+        if (counter == null) {
+            counter = ContinuePressTimer(timems, 100)
+        }
+        keyActive = false
+        counter!!.start()
+    }
+
+    private inner class ContinuePressTimer internal constructor(millisInFuture: Long, countDownInterval: Long) :
+        CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+
+        }
+
+        override fun onFinish() {
+            keyActive = true
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/checkShoppwd/CheckShoppwdActivity.kt b/app/src/main/java/com/supwisdom/activities/checkShoppwd/CheckShoppwdActivity.kt
new file mode 100644
index 0000000..5b12e29
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/checkShoppwd/CheckShoppwdActivity.kt
@@ -0,0 +1,161 @@
+package com.supwisdom.activities.checkShoppwd
+
+import android.content.Intent
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.view.KeyEvent
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.consume.ConsumeActivity
+import com.supwisdom.activities.consume.bean.CardUserInfoBean
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.SoundUtil
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class CheckShoppwdActivity : BaseActivity() {
+    private var tmpPwd: String = ""
+    private lateinit var vTitle: TextView
+    private lateinit var vContent: TextView
+    private var keyActive = true
+    private var transdtlType: String? = null
+    private val pos = SPApplication.getInstance().getPos()
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        this.setContentView(R.layout.activity_check_mngpwd)
+        initView()
+    }
+
+    private fun initView() {
+        vTitle = findViewById<TextView>(R.id.title)
+        vContent = findViewById<TextView>(R.id.content)
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (!keyActive) {
+                return super.dispatchKeyEvent(event)
+            }
+            resetCounter(200)
+
+            val keyCode = event.keyCode
+            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 -> {
+                    tmpPwd += keyCode - KeyEvent.KEYCODE_0
+                    if (tmpPwd.length >= 6) {
+                        if (checkMngPwd(tmpPwd)) {
+                            doReverse()
+                        } else {
+                            AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("商户密码:", "密码错误"))
+                        }
+                        tmpPwd = ""
+                    } else {
+                        AuxScreenController.getInstance()
+                            .refreshContent(Arrays.asList("商户密码:", CommonUtil.getPasswordStar(tmpPwd.length)))
+                    }
+                }
+                KeyEvent.KEYCODE_DEL -> {
+                    //cancel
+                    val len = tmpPwd.length
+                    when {
+                        len == 1 -> {
+                            tmpPwd = ""
+                            AuxScreenController.getInstance()
+                                .refreshContent(Arrays.asList("商户密码:", CommonUtil.getPasswordStar(tmpPwd.length)))
+                        }
+                        len > 1 -> {
+                            tmpPwd = tmpPwd.substring(0, len - 1)
+                            AuxScreenController.getInstance()
+                                .refreshContent(Arrays.asList("商户密码:", CommonUtil.getPasswordStar(tmpPwd.length)))
+                        }
+                        else -> finish()
+                    }
+                }
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        keyActive = true
+        transdtlType = this.intent.getStringExtra("transdtlType")
+        refresh()
+    }
+
+    override fun onNewIntent(intent: Intent) {
+        super.onNewIntent(intent)
+        this.intent.putExtra("transdtlType", intent.getStringExtra("transdtlType"))
+    }
+
+    private fun refresh() {
+        tmpPwd = ""
+        vTitle.text = "手工冲正"
+        vContent.text = ""
+        AuxScreenController.getInstance().refreshTitle("商户密码验证")
+        AuxScreenController.getInstance().refreshBottom("取消键撤销输入")
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("商户密码:", " "))
+    }
+
+    private fun checkMngPwd(inputPwd: String): Boolean {
+        return inputPwd == pos.getConfigPara()!!.shopPwd
+    }
+
+    private fun doReverse() {
+
+    }
+
+    private fun showRvsSuc(info: CardUserInfoBean) {
+        val tmp = String.format("金额: %.02f元", info.payamt / 100.0f)
+        vContent.text = "冲正成功\n$tmp"
+        SoundUtil.playMusic(applicationContext, R.raw.reversal_suc)
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("冲正成功", tmp))
+        jumpActivity(ConsumeActivity::class.java)
+    }
+
+    private fun showRvsFail(errmsg: String) {
+        vContent.text = "冲正失败\n$errmsg"
+        SoundUtil.playMusic(applicationContext, R.raw.reversal_fail)
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("冲正失败", errmsg))
+        jumpActivity(ConsumeActivity::class.java)
+    }
+
+    private var counter: ContinuePressTimer? = null
+
+    private fun resetCounter(timems: Long) {
+        counter?.cancel()
+        if (counter == null) {
+            counter = ContinuePressTimer(timems, 100)
+        }
+        keyActive = false
+        counter!!.start()
+    }
+
+    private inner class ContinuePressTimer internal constructor(millisInFuture: Long, countDownInterval: Long) :
+        CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+
+        }
+
+        override fun onFinish() {
+            keyActive = true
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/communicate/CommunicateActivity.kt b/app/src/main/java/com/supwisdom/activities/communicate/CommunicateActivity.kt
new file mode 100644
index 0000000..e511752
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/communicate/CommunicateActivity.kt
@@ -0,0 +1,114 @@
+package com.supwisdom.activities.communicate
+
+import android.os.Bundle
+import android.text.TextUtils
+import android.view.KeyEvent
+import android.view.View
+import android.widget.EditText
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.PublicDef
+import com.supwisdom.view.SWToast
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc 通讯参数配置
+ **/
+class CommunicateActivity : BaseActivity() {
+    private val pos = SPApplication.getInstance().getPos()
+    private lateinit var vDevphyid: TextView
+    private lateinit var vEpayUrl: EditText
+    private lateinit var vEpayUri: EditText
+    private lateinit var vEpayPort: EditText
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_communicate)
+        initView()
+        initData()
+    }
+
+    private fun initView() {
+        vDevphyid = findViewById<View>(R.id.comm_devphyid) as TextView
+        vEpayUrl = findViewById<View>(R.id.comm_epay_url) as EditText
+        vEpayUri = findViewById<View>(R.id.comm_epay_uri) as EditText
+        vEpayPort = findViewById<View>(R.id.comm_epay_port) as EditText
+
+        this.findViewById<View>(R.id.btn_cancel).setOnClickListener { finish() }
+        this.findViewById<View>(R.id.btn_confirm).setOnClickListener(View.OnClickListener {
+            val record = pos.getConfigPara()
+            val url = CommonUtil.getEditView(vEpayUrl)
+            if (TextUtils.isEmpty(url)) {
+                showSWToastInfo("服务器地址不能为空", PublicDef.TOAST_SHOW_CRY)
+                return@OnClickListener
+            }
+            record!!.epayIP = url
+
+            val uri = CommonUtil.getEditView(vEpayUri)
+            if (TextUtils.isEmpty(uri)) {
+                showSWToastInfo("服务器标识不对", PublicDef.TOAST_SHOW_CRY)
+                return@OnClickListener
+            }
+            record.epayUri = uri
+
+            try {
+                val port = Integer.valueOf(CommonUtil.getEditView(vEpayPort))
+                if (port > 0xFFFF) {
+                    showSWToastInfo("服务器端口太大", PublicDef.TOAST_SHOW_CRY)
+                    return@OnClickListener
+                }
+                record.epayPort = port
+            } catch (e: Exception) {
+                showSWToastInfo("服务器端口不对", PublicDef.TOAST_SHOW_CRY)
+                return@OnClickListener
+            }
+
+            if (!pos.replaceConfigPara(record)) {
+                showSWToastInfo("保存失败", PublicDef.TOAST_SHOW_CRY)
+                return@OnClickListener
+            }
+            showSWToastInfo("保存成功", PublicDef.TOAST_SHOW_SMILE)
+            finish()
+        })
+    }
+
+    public override fun onResume() {
+        super.onResume()
+        refresh()
+    }
+
+    private fun initData() {
+        val record = pos.getConfigPara()
+        vDevphyid.text = record!!.devphyid
+        vEpayUrl.setText(record.epayIP)
+        vEpayUri.setText(record.epayUri)
+        vEpayPort.setText(record.epayPort.toString())
+    }
+
+    private fun refresh() {
+        AuxScreenController.getInstance().refreshTitle("通讯参数设置")
+        AuxScreenController.getInstance().refreshBottom("确定键返回上页")
+        AuxScreenController.getInstance().refreshContent(listOf<String>("请到大屏进行配置"))
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            when (event.keyCode) {
+                KeyEvent.KEYCODE_DEL -> {
+                }
+                KeyEvent.KEYCODE_ENTER -> finish()
+            }//cancel
+            //和触屏删除键冲突
+            //                    finish();
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    private fun showSWToastInfo(msg: String, showway: Int) {
+        SWToast.show(applicationContext, msg, showway)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/BeepManager.kt b/app/src/main/java/com/supwisdom/activities/consume/BeepManager.kt
new file mode 100644
index 0000000..4973200
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/BeepManager.kt
@@ -0,0 +1,109 @@
+package com.supwisdom.activities.consume
+
+import android.app.Activity
+import android.content.Context
+import android.media.AudioManager
+import android.media.MediaPlayer
+import android.os.Vibrator
+import com.newcapec.zxinglib.PreferencesSetting
+import com.supwisdom.R
+import java.io.Closeable
+import java.io.IOException
+
+
+/**
+ * @author zzq
+ * @date 2018/4/25.
+ * @version 1.0.1
+ * @desc  滴滴声
+ */
+@Suppress("DEPRECATION")
+class BeepManager constructor(context: Context) : MediaPlayer.OnErrorListener, Closeable {
+    private val context = context
+
+    private val BEEP_VOLUME = 0.10f
+    private val VIBRATE_DURATION = 200L
+
+    private var mediaPlayer: MediaPlayer? = null
+    private var playBeep: Boolean = false
+    private var vibrate: Boolean = false
+
+    init {
+        updatePrefs()
+    }
+
+    @Synchronized
+    fun updatePrefs() {
+        //SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+        playBeep = shouldBeep(context)
+        vibrate = PreferencesSetting.PREFER_VIBRATE
+        if (playBeep && mediaPlayer == null) {
+            // The volume on STREAM_SYSTEM is not adjustable, and users found it too loud,
+            // so we now play on the music stream.
+            (context as Activity).volumeControlStream = AudioManager.STREAM_MUSIC
+            mediaPlayer = buildMediaPlayer(context)
+        }
+    }
+
+    @Synchronized
+    fun playBeepSoundAndVibrate() {
+        if (playBeep && mediaPlayer != null) {
+            mediaPlayer!!.start()
+        }
+        if (vibrate) {
+            val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
+            vibrator.vibrate(VIBRATE_DURATION)
+        }
+    }
+
+    private fun shouldBeep(activity: Context): Boolean {
+        var shouldPlayBeep = PreferencesSetting.PREFER_PLAY_BEEP
+        if (shouldPlayBeep) {
+            // See if sound settings overrides this
+            val audioService = activity.getSystemService(Context.AUDIO_SERVICE) as AudioManager
+            if (audioService.ringerMode != AudioManager.RINGER_MODE_NORMAL) {
+                shouldPlayBeep = false
+            }
+        }
+        return shouldPlayBeep
+    }
+
+    private fun buildMediaPlayer(activity: Context): MediaPlayer? {
+        val mediaPlayer = MediaPlayer()
+        return try {
+            activity.resources.openRawResourceFd(R.raw.beep).use { it ->
+                mediaPlayer.setDataSource(it.fileDescriptor, it.startOffset, it.length)
+            }
+            mediaPlayer.setOnErrorListener(this)
+            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
+            mediaPlayer.isLooping = false
+            mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME)
+            mediaPlayer.prepare()
+            mediaPlayer
+        } catch (ex: IOException) {
+            mediaPlayer.release()
+            null
+        }
+    }
+
+    @Synchronized
+    override fun onError(mp: MediaPlayer, what: Int, extra: Int): Boolean {
+        if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
+            // we are finished, so put up an appropriate error toast if required and finish
+            (context as Activity).finish()
+        } else {
+            // possibly media player error, so release and recreate
+            close()
+            updatePrefs()
+        }
+        return true
+    }
+
+    @Synchronized
+    override fun close() {
+        if (mediaPlayer != null) {
+            mediaPlayer!!.release()
+            mediaPlayer = null
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/ConsumeActivity.kt b/app/src/main/java/com/supwisdom/activities/consume/ConsumeActivity.kt
new file mode 100644
index 0000000..6308775
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/ConsumeActivity.kt
@@ -0,0 +1,547 @@
+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.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.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
+
+/**
+ ** 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 vCustname: TextView
+    private lateinit var vStuempno: TextView
+    private lateinit var vCardstatus: TextView
+    private lateinit var vBalance: TextView
+    private lateinit var vTime: TextView
+    private lateinit var vLinkLogo: ImageView
+    private lateinit var vLastResult: TextView
+    private lateinit var vLastPayamt: TextView
+    private lateinit var vLastPayway: TextView
+    private lateinit var vLastPayday: TextView
+    private lateinit var vLastPaytime: TextView
+    private lateinit var vLastPayFailreason: TextView
+    private lateinit var vLastPayFailll: LinearLayout
+    private lateinit var vLastPayamtll: LinearLayout
+    private var beepManager: BeepManager? = null
+    private val scanLock = ReentrantLock()
+    @Volatile
+    private var codeSwitchEnable = false
+    @Volatile
+    private var payStatusEnable = false
+    @Volatile
+    private var isBackRuning = false
+    private var addAmount: Int = 0
+    @Volatile
+    private var amount: Int = 0
+    private var payWay: String? = null
+    private var counter: LastPayShowTimer? = null
+    private var lastPayInfo: CardUserInfoBean? = null
+    private var dialogPurchase: DialogPurchase? = null
+
+    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) {
+                presenter.clickNoPay()
+                amountTxt.text = ""
+            }
+
+            override fun callback(code: String) {
+                //扫码和寻卡消费互斥
+                if (!codeSwitchEnable) {
+                    return
+                }
+                if (!scanLock.tryLock()) {
+                    return
+                }
+                try {
+                    //正在扣款
+                    if (dialogPurchase!!.codePaying) {
+                        return
+                    }
+                    //已扣款
+                    if (!payStatusEnable) {
+                        return
+                    }
+                    beepManager!!.playBeepSoundAndVibrate()
+                    presenter.clickNoPay()
+                    dialogPurchase!!.codePaying = true
+                    dialogPurchase!!.codePayingNoCancelEnable = true
+                    payStatusEnable = false
+                    presenter.codeToPay(code, amount)
+                } finally {
+                    scanLock.unlock()
+                }
+            }
+        })
+    }
+
+    private fun initView() {
+        vShopname = this.findViewById<TextView>(R.id.consume_shopname)
+        vLinkLogo = this.findViewById<ImageView>(R.id.consume_linklogo)
+        vLinkstat = this.findViewById<TextView>(R.id.consume_linkstat)
+        amountTxt = this.findViewById<TextView>(R.id.consume_amt)
+        vCustname = this.findViewById<TextView>(R.id.consume_custname)
+        vStuempno = this.findViewById<TextView>(R.id.consume_stuempno)
+        vCardstatus = this.findViewById<TextView>(R.id.consume_cardstatus)
+        vBalance = this.findViewById<TextView>(R.id.consume_balance)
+        vTime = this.findViewById<TextView>(R.id.consume_time)
+        vLastResult = this.findViewById<TextView>(R.id.consume_last_result)
+        vLastPayamt = this.findViewById<TextView>(R.id.consume_last_payamt)
+        vLastPayway = this.findViewById<TextView>(R.id.consume_last_payway)
+        vLastPayday = this.findViewById<TextView>(R.id.consume_last_payday)
+        vLastPaytime = this.findViewById<TextView>(R.id.consume_last_paytime)
+        vLastPayFailreason = this.findViewById<TextView>(R.id.consume_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()
+        isBackRuning = 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) {
+            val keyCode = event.keyCode
+            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'
+                    isBackRuning = 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 -> {
+                    checkAmtToPay()
+                }
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    override fun showUserInfo(info: CardUserInfoBean) {
+        CommonUtil.acquireWakeLock(this)
+        vCustname.text = info.username
+        if (info.retcode == PublicDef.SUCCESS) {
+            vCardstatus.text = "暂未实现"//PublicDef.CARD_STAT_MAP[info.cardstat]
+            if (info.cardstatus != 0) {
+                vCardstatus.setTextColor(Color.RED)
+            } else {
+                vCardstatus.setTextColor(resources.getColor(R.color.blue))
+            }
+            if (info.balance == null) {
+                vBalance.text = null
+            } else {
+                vBalance.text = String.format("%.02f 元", info.balance!! / 100.0f)
+            }
+        } else {
+            vCardstatus.text = info.retmsg
+            vCardstatus.setTextColor(Color.RED)
+            vBalance.text = null
+        }
+    }
+
+    private var lastshowtime: String? = null
+    override fun clearUserInfo(datetime: String) {
+        if (!isBackRuning) {
+            vCustname.text = null
+            vStuempno.text = null
+            vCardstatus.text = null
+            vBalance.text = null
+            val tmptime = datetime.substring(0, 16)
+            if (lastshowtime != tmptime) {
+                lastshowtime = tmptime
+                vTime.text = tmptime
+                AuxScreenController.getInstance().refreshBottom(tmptime)
+            }
+            if (dialogPurchase!!.isShowing &&
+                !dialogPurchase!!.isFixPay &&
+                payStatusEnable
+            ) {
+                beepManager!!.playBeepSoundAndVibrate()
+            }
+        }
+    }
+
+    override fun onResume() {
+        super.onResume()
+        isBackRuning = false
+        beepManager!!.updatePrefs()
+        dealIntent()
+        refresh()
+        refreshRecentDtl(lastPayInfo)
+    }
+
+    private fun dealIntent() {
+        amount = this.intent.getIntExtra("amount", 0)
+        payWay = this.intent.getStringExtra("payway")
+        this.intent.putExtra("amount", "0")
+        this.intent.putExtra("payway", "")
+    }
+
+    override fun onNewIntent(intent: Intent) {
+        this.intent.putExtra("amount", intent.getStringExtra("amount"))
+        this.intent.putExtra("payway", intent.getStringExtra("payway"))
+    }
+
+    private fun refresh() {
+        addAmount = 0
+        amountTxt.text = "0"
+        var shopname = SPApplication.getInstance().getPos().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(" 欢迎光临!", " 请刷卡..."))
+
+        val record = SPApplication.getInstance().getPos().getControlPara(PublicDef.CONTROL_FIXAMT)
+        if (record != null && PublicDef.CONTROL_NO_FIXPAY_FLAG != record.paraval) {
+            try {
+                amount = Integer.parseInt(record.paraval)
+                amountTxt.text = String.format("%.02f", amount / 100.0f)
+                presenter.clickToPay(amount)
+                showDialogPay()
+            } catch (ex: Exception) {
+                ex.printStackTrace()
+            }
+        }
+    }
+
+    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)
+    }
+
+    override fun showConsumeHint(hint: String) {
+        val amountStr = CommonUtil.showFormatAmount("金额", amount)
+        dialogPurchase!!.showProcess(hint, amountStr)
+        AuxScreenController.getInstance().refreshContent(Arrays.asList(hint, amountStr))
+    }
+
+    override fun showConsumeFail(info: CardUserInfoBean) {
+        dialogPurchase!!.showPayFail(info)
+        SoundUtil.playMusic(applicationContext, R.raw.consume_fail)
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("消费失败", "原因:", info.retmsg))
+    }
+
+    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)
+    }
+
+    override fun showReverseFail(info: CardUserInfoBean) {
+        dialogPurchase!!.showReverseFail(info)
+        SoundUtil.playMusic(applicationContext, R.raw.reversal_fail)
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("冲正失败", "原因:", info.retmsg))
+    }
+
+    private var lastShowRecentDatetime: String? = null
+    private fun refreshRecentDtl(info: CardUserInfoBean?) {
+        if (info != null) {
+            lastPayInfo = info
+            //已显示过不在显示
+            if (lastShowRecentDatetime == info.datetime) {
+                return
+            }
+            lastShowRecentDatetime = info.datetime
+
+            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
+            }
+
+            vLastPayway.text = if (info.payway == "code") {
+                "二维码"
+            } else {
+                "市民卡"
+            }
+            val sb = StringBuilder()
+            sb.append(info.datetime!!.substring(0, 4)).append("/")
+                .append(info.datetime!!.substring(4, 6)).append("/")
+                .append(info.datetime!!.substring(6, 8))
+            vLastPayday.text = sb.toString()
+            sb.setLength(0)
+            sb.append(info.datetime!!.substring(8, 10)).append(":")
+                .append(info.datetime!!.substring(10, 12)).append(":").append(info.datetime!!.substring(12))
+            vLastPaytime.text = sb.toString()
+            resetPayShowCounter(10 * 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() {
+        amount = getCurAmount() + addAmount
+        if (amount > 0) {
+            amountTxt.text = String.format("%.02f", amount / 100.0f)
+            presenter.clickToPay(amount)
+            showDialogPay()
+        } else {
+            AuxScreenController.getInstance().refreshContent(Arrays.asList("请先输入金额:", "金额不能为0"))
+        }
+    }
+
+    private fun showDialogPay() {
+        dialogPurchase!!.codePaying = false
+        dialogPurchase!!.isFixPay = false
+        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 {
+            //限制消费金额<1000
+            if (str.length < 3) {
+                amountTxt.text = "$str$value"
+            }
+        }
+        showScreenAmount()
+    }
+
+    private fun clearLastPayResult() {
+        vLastResult.text = null
+        vLastPayamt.text = null
+        vLastPayway.text = null
+        vLastPayday.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 isBackRuning(): Boolean {
+        return isBackRuning
+    }
+
+    override fun showRecentDtl(record: TransdtlUnionRecord?) {
+        if (record != null) {
+            val info = CardUserInfoBean(PublicDef.SUCCESS, "")
+            info.datetime = record.transdate + record.transtime
+            info.username = record.username
+            info.payamt = record.payamt
+            info.status = record.status
+            info.payway = record.payway
+            info.reversalFlag = record.reversalflag
+            refreshRecentDtl(info)
+        }
+    }
+
+    override fun codeScannerEnable(enable: Boolean) {
+        codeSwitchEnable = enable
+    }
+
+    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
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..268a67f
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/ConsumePresenter.kt
@@ -0,0 +1,102 @@
+package com.supwisdom.activities.consume
+
+import android.os.Handler
+import android.os.Looper
+import android.os.Message
+import com.supwisdom.activities.consume.bean.CardUserInfoBean
+import com.supwisdom.activities.consume.mode.CardPayService
+import com.supwisdom.activities.consume.mode.CodePayService
+import com.supwisdom.utils.LogUtil
+import com.supwisdom.utils.PublicDef
+import com.supwisdom.utils.ThreadPool
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class ConsumePresenter constructor(iConsumeView: IConsumeView) {
+    private val TAG = "ConsumePresenter"
+    private val iConsumeView = iConsumeView
+    private val codePayRunnable = CodePayRunnable()
+    private lateinit var handler: Handler
+    private var cardPayService: CardPayService
+    private var codePayService: CodePayService
+    @Volatile
+    private var code: String? = null
+    @Volatile
+    private var amount: Int = 0
+
+    init {
+        createHandler()
+        cardPayService = CardPayService(iConsumeView, handler)
+        codePayService = CodePayService(iConsumeView, handler)
+    }
+
+    private fun createHandler() {
+        handler = object : android.os.Handler(Looper.getMainLooper()) {
+            override fun handleMessage(msg: Message) {
+                when (msg.what) {
+                    PublicDef.MSG_CARD_PAY_SUC -> iConsumeView.showConsumeSuc(msg.obj as CardUserInfoBean)
+                    PublicDef.MSG_CARD_PAYING,
+                    PublicDef.MSG_CARD_READ_AGAIN -> iConsumeView.showConsumeHint(msg.obj as String)
+                    PublicDef.MSG_CARD_PAY_FAIL -> {
+                        val ret = msg.obj as CardUserInfoBean
+                        LogUtil.d(TAG, "pay fail,reason=${ret.retmsg}")
+                        iConsumeView.showConsumeFail(ret)
+                    }
+                    PublicDef.MSG_CARD_REVERSE_FAIL -> {
+                        val ret = msg.obj as CardUserInfoBean
+                        LogUtil.d(TAG, "reverse fail,reason=${ret.retmsg}")
+                        iConsumeView.showReverseFail(msg.obj as CardUserInfoBean)
+                    }
+                    PublicDef.MSG_CARD_REVERSE_SUC -> iConsumeView.showReverseSuc(msg.obj as CardUserInfoBean)
+                    PublicDef.MSG_USER_INFO_SHOW -> iConsumeView.showUserInfo(msg.obj as CardUserInfoBean)
+                    PublicDef.MSG_USER_INFO_CLEAR -> iConsumeView.clearUserInfo(msg.obj as String)
+                    PublicDef.MSG_LINK_STATUS -> iConsumeView.refreshLinkStatus(msg.obj as Boolean)
+                }
+            }
+        }
+    }
+
+    fun start() {
+        cardPayService.start()
+    }
+
+    fun stop() {
+        cardPayService.stop()
+    }
+
+    fun clickNoPay() {
+        cardPayService.clickNoPay()
+    }
+
+    fun clickToPay(amount: Int) {
+        cardPayService.clickToPay(amount)
+    }
+
+    fun clickToReverse(amount: Int) {
+        cardPayService.clickToReverse(amount)
+    }
+
+    fun codeToPay(code: String, amount: Int) {
+        this.code = code
+        this.amount = amount
+        ThreadPool.getShortPool().execute(codePayRunnable)
+    }
+
+    fun interruptCodePay() {
+        code = null
+        amount = 0
+        /**
+         *不能暴力取消工作线程,可能存在后台已消费而本地未收到答复
+         */
+//        ThreadPool.getShortPool().cancel(scanRunnable)
+        codePayService.interruptPay()
+    }
+
+    private inner class CodePayRunnable : Runnable {
+        override fun run() {
+            codePayService.pay(code!!, amount)
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/IConsumeView.kt b/app/src/main/java/com/supwisdom/activities/consume/IConsumeView.kt
new file mode 100644
index 0000000..b633d51
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/IConsumeView.kt
@@ -0,0 +1,35 @@
+package com.supwisdom.activities.consume
+
+import android.app.Activity
+import com.supwisdom.activities.consume.bean.CardUserInfoBean
+import com.supwisdom.entity.TransdtlUnionRecord
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+interface IConsumeView {
+    fun getActivity(): Activity
+
+    fun isBackRuning(): Boolean
+
+    fun showConsumeSuc(info: CardUserInfoBean)
+
+    fun showConsumeHint(hint: String)
+
+    fun showConsumeFail(info: CardUserInfoBean)
+
+    fun showReverseSuc(info: CardUserInfoBean)
+
+    fun showReverseFail(info: CardUserInfoBean)
+
+    fun showUserInfo(info: CardUserInfoBean)
+
+    fun clearUserInfo(datetime: String)
+
+    fun refreshLinkStatus(isOnline: Boolean)
+
+    fun showRecentDtl(record: TransdtlUnionRecord?)
+
+    fun codeScannerEnable(enable: Boolean)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/bean/CardAccountRetBean.kt b/app/src/main/java/com/supwisdom/activities/consume/bean/CardAccountRetBean.kt
new file mode 100644
index 0000000..461c16d
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/bean/CardAccountRetBean.kt
@@ -0,0 +1,14 @@
+package com.supwisdom.activities.consume.bean
+
+import com.supwisdom.bean.BaseResp
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class CardAccountRetBean : BaseResp() {
+    var username: String? = null
+    var userid: Int = 0
+    var balance: Int = 0
+    var status: String? = null
+}
\ 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..f68486f
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/bean/CardBean.kt
@@ -0,0 +1,18 @@
+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
+    var balance: Int? = null
+    var cardstatus: 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..c879a8a
--- /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? = null
+    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..2b50e3f
--- /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: String? = null
+    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..ebaf647
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/bean/CardUserInfoBean.kt
@@ -0,0 +1,22 @@
+package com.supwisdom.activities.consume.bean
+
+import com.supwisdom.bean.BaseResp
+import com.supwisdom.entity.PayStatus
+import com.supwisdom.entity.ReversalFlag
+
+/**
+ ** 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
+    var balance: Int? = null
+    var cardstatus: Int = 0
+    var amount: Int = 0
+    var payamt: Int = 0
+    var status: PayStatus? = null
+    var reversalFlag: ReversalFlag? = null
+    var datetime: String? = null
+    var payway: String? = null //card,code
+}
\ 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..3972fe6
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/mode/CardPayService.kt
@@ -0,0 +1,415 @@
+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.*
+import com.supwisdom.entity.PayStatus
+import com.supwisdom.entity.ReversalFlag
+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 TAG = "CardPayService"
+    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
+    }
+
+    fun clickNoPay() {
+        clickStat = ClickStat.INIT
+        amount = 0
+    }
+
+    fun clickToPay(amount: Int) {
+        clickStat = ClickStat.PAY
+        this.amount = amount
+    }
+
+    fun clickToReverse(amount: Int) {
+        clickStat = ClickStat.REVERSE
+        this.amount = amount
+    }
+
+    private inner class CardPayRunnable : Runnable {
+        private lateinit var onlRecord: TransdtlOnlineRecord
+        private lateinit var offRecord: TransdtlOfflineRecord
+        private var oldcardphyid: String? = null
+        private var onlineBalance = false
+        private var curLinkStatus = false
+        private var lastShowTime: Long = 0
+        private var lastUserInfoTime: Long = 0
+        private var curLinkRefreshTime: Long = 0
+        override fun run() {
+            while (!isExist) {
+                if (iConsumeView.isBackRuning()) {
+                    CommonUtil.doSleep(1000)
+                    doClear()
+                    continue
+                }
+                iConsumeView.codeScannerEnable(true)
+                CommonUtil.doSleep(100)
+                try {
+                    val cardphyid = Cardlib.instance.requestCard()
+                    iConsumeView.codeScannerEnable(false)
+                    if (oldcardphyid != cardphyid) {
+                        readCard()
+                        cardBean.cardphyid = cardphyid
+                        oldcardphyid = cardphyid
+                    }
+                    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_REVERSE_FAIL, getErrorInfo(ex.message))
+                            }
+                            clickStat = ClickStat.INIT
+                        }
+                        ClickStat.INIT -> {
+                            if (SPApplication.getInstance().isOnline() && !onlineBalance) {
+                                onlineBalance = true
+                                getAccountInfoByCard()
+                            }
+                            val curtime = System.currentTimeMillis()
+                            if (curtime < lastUserInfoTime ||
+                                curtime - lastUserInfoTime > 1000
+                            ) {
+                                lastUserInfoTime = curtime
+                                showCardUserInfo()
+                            }
+                        }
+                    }
+                } catch (ex: CardNotFoundError) {
+                    ex.printStackTrace()
+                    doClear()
+                } catch (ex: Exception) {
+                    ex.printStackTrace()
+                    doClear()
+                }
+            }
+        }
+
+        private fun getAccountInfoByCard() {
+            val resp = consumeApi.accQuery(
+                pos.getConfigPara()!!.devphyid!!,
+                cardBean.cardphyid!!,
+                cardBean.cardNo!!
+            )
+            if (resp != null && resp.retcode == HttpStatus.SC_OK) {
+                val retBean = GsonUtil.GsonToBean(resp.retjson!!, CardAccountRetBean::class.java)
+                if (retBean.retcode == PublicDef.SUCCESS) {
+                    cardBean.username = retBean.username
+                    cardBean.userid = retBean.userid
+                    cardBean.balance = retBean.balance
+                    cardBean.cardstatus = 1 //TODO
+                }
+            }
+        }
+
+        private fun showCardUserInfo() {
+            val info = CardUserInfoBean(PublicDef.SUCCESS, "账户信息")
+            info.username = cardBean.username
+            info.balance = cardBean.balance
+            info.cardstatus = cardBean.cardstatus
+            sendMsg(PublicDef.MSG_USER_INFO_SHOW, info)
+        }
+
+        private fun readCard() {
+            val cardinfo = Cardlib.instance.readCard()
+            cardBean = CardBean()
+            cardBean.cardNo = cardinfo.cardNo
+            cardBean.idCard = cardinfo.idCard
+            cardBean.expireDate = cardinfo.expireDate
+            cardBean.amount = amount
+            cardBean.datetime = DateUtil.getNowDateTimeFormat()
+            /**
+             * 用户名默认用卡号代替,在线查询更新为用户名
+             */
+            cardBean.username = cardBean.cardNo
+        }
+
+        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)
+            if (result) {
+                showSucInfo()
+            }
+            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
+            onlRecord.balance = retBean.balance
+            return true
+        }
+
+        private fun initTransdtlOnline() {
+            onlRecord = TransdtlOnlineRecord()
+            var seqno = pos.getTransdtlOnlineMaxSeqno()
+            if (seqno == 0) {
+                seqno = pos.getDynamicPara()?.onlineseqno ?: 0
+            }
+            onlRecord.devphyid = pos.getConfigPara()!!.devphyid
+            onlRecord.transdate = cardBean.datetime!!.substring(0, 8)
+            onlRecord.transtime = cardBean.datetime!!.substring(8)
+            onlRecord.devseqno = seqno + 1
+            onlRecord.cardno = cardBean.cardNo
+            onlRecord.cardphyid = cardBean.cardphyid
+            onlRecord.payamt = cardBean.amount
+            onlRecord.reversalflag = ReversalFlag.NONE
+            onlRecord.extraamt = 0
+            onlRecord.transtype = "card"
+            onlRecord.status = PayStatus.INIT
+            onlRecord.upflag = 1
+            if (!pos.saveTransdtlOnline(onlRecord)) {
+                throw CardPayFailError("保存流水失败")
+            }
+        }
+
+        private fun updateTransdtlOnline(issuccess: Boolean) {
+            if (issuccess) {
+                onlRecord.status = PayStatus.SUC
+            } else {
+                onlRecord.status = PayStatus.FAIL
+            }
+            onlRecord.upflag = 1
+            pos.updateTransdtlOnline(onlRecord)
+        }
+
+        private fun doOfflineConsume() {
+            initTransdtlOffline()
+            checkCardValid()
+            updateTransdtlOffline(true)
+        }
+
+        private fun checkCardValid() {
+            val sysRecord = pos.getSysPara()
+            if (!sysRecord!!.offlineEnable) {
+                throw CardPayFailError("禁止离线交易")
+            }
+            val ctlRecord = pos.getControlPara(PublicDef.CONTROL_OFFLINE_DAY_DISABLE)
+            if (ctlRecord == null || ctlRecord.paraval != "1") {
+                val offdate = DateUtil.getDayDateNoFormatBefore(sysRecord.maxOfflineDays)
+                val validdate = pos.getDynamicPara()!!.jwtExpire?.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.getDynamicPara()?.offlineseqno ?: 0
+            }
+            offRecord.devphyid = pos.getConfigPara()!!.devphyid
+            offRecord.transdate = cardBean.datetime!!.substring(0, 8)
+            offRecord.transtime = cardBean.datetime!!.substring(8)
+            offRecord.devseqno = seqno + 1
+            offRecord.cardno = cardBean.cardNo
+            offRecord.cardphyid = cardBean.cardphyid
+            offRecord.payamt = cardBean.amount
+            offRecord.reversalflag = ReversalFlag.NONE
+            offRecord.extraamt = 0
+            offRecord.managefeetype = "none"
+            offRecord.status = PayStatus.INIT
+            offRecord.upflag = 1
+            if (!pos.saveTransdtlOffline(offRecord)) {
+                throw CardPayFailError("保存流水失败")
+            }
+        }
+
+        private fun updateTransdtlOffline(issuccess: Boolean) {
+            if (issuccess) {
+                offRecord.status = PayStatus.SUC
+            } else {
+                offRecord.status = PayStatus.FAIL
+            }
+            offRecord.upflag = 0
+            if (!pos.updateTransdtlOffline(offRecord)) {
+                throw CardPayFailError("更新流水失败")
+            }
+        }
+
+        private fun doClear() {
+            oldcardphyid = null
+            onlineBalance = false
+            val curtime = System.currentTimeMillis()
+            if (curtime < lastShowTime ||
+                curtime - lastShowTime > 1000
+            ) {
+                lastShowTime = curtime
+                sendMsg(PublicDef.MSG_USER_INFO_CLEAR, DateUtil.getNowDateTime())
+                showLinkStatus()
+            }
+        }
+
+        private fun showLinkStatus() {
+            if (SPApplication.getInstance().isOnline()) {
+                if (!curLinkStatus) {
+                    curLinkRefreshTime = System.currentTimeMillis()
+                    curLinkStatus = true
+                    sendMsg(PublicDef.MSG_LINK_STATUS, true)
+                    return
+                }
+            } else {
+                if (curLinkStatus) {
+                    curLinkStatus = false
+                    curLinkRefreshTime = System.currentTimeMillis()
+                    sendMsg(PublicDef.MSG_LINK_STATUS, false)
+                    return
+                }
+            }
+            val t = System.currentTimeMillis()
+            if (t < curLinkRefreshTime ||
+                t - curLinkRefreshTime > 30000
+            ) {
+                curLinkRefreshTime = t
+                sendMsg(PublicDef.MSG_LINK_STATUS, SPApplication.getInstance().isOnline())
+            }
+        }
+
+        private fun showSucInfo() {
+            val info = CardUserInfoBean(PublicDef.SUCCESS, "消费成功")
+            info.showtime = pos.getSysPara()!!.sucShowtime
+            info.amount = onlRecord.payamt
+            info.payamt = onlRecord.payamt
+            info.username = onlRecord.username
+            info.datetime = onlRecord.transdate + onlRecord.transtime
+            info.payway = onlRecord.transtype
+            info.status = PayStatus.SUC
+            info.balance = onlRecord.balance
+            sendMsg(PublicDef.MSG_CARD_PAY_SUC, info)
+        }
+
+        private fun getErrorInfo(errmsg: String?): CardUserInfoBean {
+            val info = CardUserInfoBean(PublicDef.ERROR, errmsg ?: "null")
+            info.showtime = pos.getSysPara()!!.failShowtime
+            info.status = PayStatus.FAIL
+            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/activities/consume/mode/CodePayService.kt b/app/src/main/java/com/supwisdom/activities/consume/mode/CodePayService.kt
new file mode 100644
index 0000000..f69e698
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/mode/CodePayService.kt
@@ -0,0 +1,195 @@
+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.CardPayConfirmRetBean
+import com.supwisdom.activities.consume.bean.CardPayInitRetBean
+import com.supwisdom.activities.consume.bean.CardUserInfoBean
+import com.supwisdom.entity.PayStatus
+import com.supwisdom.entity.ReversalFlag
+import com.supwisdom.entity.TransdtlOnlineRecord
+import com.supwisdom.exception.CardPayFailError
+import com.supwisdom.okhttp.TransResp
+import com.supwisdom.utils.*
+import org.apache.http.HttpStatus
+
+/**
+ ** create by zzq on 2019/7/30
+ ** @desc 二维码消费
+ **/
+class CodePayService constructor(iConsumeView: IConsumeView, handler: Handler) {
+    private val TAG = "CodePayService"
+    private val iConsumeView = iConsumeView
+    private val handler = handler
+    private val pos = SPApplication.getInstance().getPos()
+    private lateinit var codeRecord: TransdtlOnlineRecord
+    private val consumeApi = ConsumeApi()
+    /**
+     * 消费过程中可按键主动取消
+     * 手动取消后不冲正,以手机消费结果为准
+     */
+    @Volatile
+    private var interruptedPay: Boolean = false
+
+    fun interruptPay() {
+        interruptedPay = true
+    }
+
+    fun pay(code: String, amount: Int) {
+        interruptedPay = false
+        try {
+            initTransdtlOnline(code, amount)
+            var resp = consumeApi.payInit(codeRecord)
+            parseInitResult(resp)
+            resp = consumeApi.payConfirm(codeRecord)
+            var result = parseConfirmResult(resp)
+            if (!result) {
+                result = payResultQuery()
+            }
+            if (result) {
+                showSucInfo()
+            }
+            updateTransdtlOnline(result)
+        } catch (ex: CardPayFailError) {
+            sendMsg(PublicDef.MSG_CARD_PAY_FAIL, getErrorInfo(ex.message))
+        }
+    }
+
+    private fun payResultQuery(): Boolean {
+        sendMsg(PublicDef.MSG_CODE_PAYING_CANCEL, "谨慎操作查询取消")
+        LogUtil.d(TAG, "扫码消费确认超时,进行查询操作:billno=${codeRecord.billno}")
+        sleepWithCancel(1500)
+        var searchCnt = 1
+        while (!interruptedPay) {
+            sendMsg(PublicDef.MSG_CARD_PAYING, String.format("正在%d次查询...", searchCnt))
+            val resp = consumeApi.payQuery(codeRecord)
+            if (resp != null) {
+                val result = parseConfirmResult(resp)
+                if (!result) {
+                    searchCnt++
+                    sendMsg(PublicDef.MSG_CARD_PAYING, String.format("等待%d次查询...", searchCnt))
+                    sleepWithCancel(5000)
+                    continue
+                }
+                return result
+            } else {
+                searchCnt++
+                sendMsg(PublicDef.MSG_CARD_PAYING, String.format("等待%d次查询...", searchCnt))
+                sleepWithCancel(3000)
+            }
+        }
+        LogUtil.d(TAG, "扫码消费确认超时,操作员手工取消查询:billno=${codeRecord.billno}")
+        return false
+    }
+
+    private fun parseConfirmResult(resp: TransResp?): Boolean {
+        if (resp == null) {
+            SPApplication.getInstance().setEpayLinking(false)
+            return false
+        }
+        if (resp.retcode != HttpStatus.SC_OK) {
+            throw CardPayFailError("错误码=${resp.retcode}")
+        }
+        val retBean = GsonUtil.GsonToBean(resp.retjson!!, CardPayConfirmRetBean::class.java)
+        if (retBean.retcode != PublicDef.SUCCESS) {
+            throw CardPayFailError(retBean.retmsg!!)
+        }
+        if (retBean.require_query) {
+            // 等待查询
+            return false
+        }
+        codeRecord.payamt = retBean.amount
+        codeRecord.extraamt = retBean.extraamt
+        codeRecord.balance = retBean.balance
+        return true
+    }
+
+    private fun parseInitResult(resp: TransResp?): Boolean {
+        if (resp == null) {
+            SPApplication.getInstance().setEpayLinking(false)
+            throw CardPayFailError("请求超时")
+        }
+        if (resp.retcode != HttpStatus.SC_OK) {
+            throw CardPayFailError("错误码=${resp.retcode}")
+        }
+        val retBean = GsonUtil.GsonToBean(resp.retjson!!, CardPayInitRetBean::class.java)
+        if (retBean.retcode != PublicDef.SUCCESS) {
+            throw CardPayFailError(retBean.retmsg!!)
+        }
+        codeRecord.billno = retBean.billno
+        codeRecord.username = retBean.username
+        return true
+    }
+
+    private fun initTransdtlOnline(code: String, amount: Int) {
+        codeRecord = TransdtlOnlineRecord()
+        var seqno = pos.getTransdtlOnlineMaxSeqno()
+        if (seqno == 0) {
+            seqno = pos.getDynamicPara()?.onlineseqno ?: 0
+        }
+        codeRecord.devphyid = pos.getConfigPara()!!.devphyid
+        codeRecord.transdate = DateUtil.getNowDateNoFormat()
+        codeRecord.transtime = DateUtil.getNowTimeNoFormat()
+        codeRecord.devseqno = seqno + 1
+        codeRecord.qrcode = code
+        codeRecord.payamt = amount
+        codeRecord.reversalflag = ReversalFlag.NONE
+        codeRecord.extraamt = 0
+        codeRecord.transtype = "code"
+        codeRecord.status = PayStatus.INIT
+        codeRecord.upflag = 1
+        if (!pos.saveTransdtlOnline(codeRecord)) {
+            throw CardPayFailError("保存流水失败")
+        }
+    }
+
+    private fun updateTransdtlOnline(issuccess: Boolean) {
+        if (issuccess) {
+            codeRecord.status = PayStatus.SUC
+        } else {
+            codeRecord.status = PayStatus.FAIL
+        }
+        codeRecord.upflag = 1
+        pos.updateTransdtlOnline(codeRecord)
+    }
+
+    private fun sleepWithCancel(ms: Long) {
+        var sum: Long = 0
+        while (!interruptedPay) {
+            CommonUtil.doSleep(100)
+            sum += 100
+            if (sum > ms) {
+                break
+            }
+        }
+    }
+
+    private fun showSucInfo() {
+        val info = CardUserInfoBean(PublicDef.SUCCESS, "消费成功")
+        info.showtime = pos.getSysPara()!!.sucShowtime
+        info.amount = codeRecord.payamt
+        info.payamt = codeRecord.payamt
+        info.username = codeRecord.username
+        info.datetime = codeRecord.transdate + codeRecord.transtime
+        info.payway = codeRecord.transtype
+        info.status = PayStatus.SUC
+        info.balance = codeRecord.balance
+        sendMsg(PublicDef.MSG_CARD_PAY_SUC, info)
+    }
+
+    private fun getErrorInfo(errmsg: String?): CardUserInfoBean {
+        val info = CardUserInfoBean(PublicDef.ERROR, errmsg ?: "null")
+        info.showtime = pos.getSysPara()!!.failShowtime
+        info.status = PayStatus.FAIL
+        return info
+    }
+
+    private fun sendMsg(code: Int, obj: Any) {
+        val msg = Message()
+        msg.what = code
+        msg.obj = obj
+        handler.sendMessage(msg)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consume/mode/ConsumeApi.kt b/app/src/main/java/com/supwisdom/activities/consume/mode/ConsumeApi.kt
new file mode 100644
index 0000000..54e6a8a
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consume/mode/ConsumeApi.kt
@@ -0,0 +1,69 @@
+package com.supwisdom.activities.consume.mode
+
+import com.supwisdom.activities.YktSession
+import com.supwisdom.entity.TransdtlOnlineRecord
+import com.supwisdom.okhttp.TransResp
+import com.supwisdom.okhttp.WebParams
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class ConsumeApi {
+    fun payInit(record: TransdtlOnlineRecord): TransResp? {
+//        val feetype = when {
+//            record.transflag and 0x60 == 0x40 -> "mealer"
+//            record.transflag and 0x60 == 0x20 -> "discount"
+//            else -> "none"
+//        }
+        val params = WebParams()
+        params.setParameter("cardno", record.cardno)
+            .setParameter("cardphyid", record.cardphyid)
+            .setParameter("qrcode", record.qrcode)
+            .setParameter("devphyid", record.devphyid)
+            .setParameter("termseqno", record.devseqno)
+            .setParameter("termdate", record.transdate)
+            .setParameter("termtime", record.transtime)
+            .setParameter("transtype", record.transtype)
+
+        return YktSession.getInstance().sendYktRequestPost("/api/pos/payinit", "", params)
+    }
+
+    fun payConfirm(record: TransdtlOnlineRecord): TransResp? {
+        val params = WebParams()
+        params.setParameter("devphyid", record.devphyid)
+            .setParameter("billno", record.billno)
+            .setParameter("amount", record.payamt)
+            .setParameter("termdate", record.transdate)
+            .setParameter("termtime", record.transtime)
+
+        return YktSession.getInstance().sendYktRequestPost("/api/pos/payconfirm", "", params)
+    }
+
+    fun payQuery(record: TransdtlOnlineRecord): TransResp? {
+        val params = WebParams()
+        params.setParameter("devphyid", record.devphyid)
+            .setParameter("billno", record.billno)
+            .setParameter("termdate", record.transdate)
+            .setParameter("termtime", record.transtime)
+
+        return YktSession.getInstance().sendYktRequestPost("/api/pos/payquery", "", params)
+    }
+
+    fun accQuery(devphyid: String, cardphyid: String, cardno: String): TransResp? {
+        val params = WebParams()
+        params.setParameter("devphyid", devphyid)
+            .setParameter("cardphyid", cardphyid)
+            .setParameter("cardno", cardno)
+
+        return YktSession.getInstance().sendYktRequestPost("/api/pos/accquery", "", params)
+    }
+
+    fun queryRevenue(devphyid: String, date: String): TransResp? {
+        val params = WebParams()
+        params.setParameter("devphyid", devphyid)
+            .setParameter("termdate", date)
+
+        return YktSession.getInstance().sendYktRequestPost("/api/pos/querysales", "", params)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/consumeMode/ConsumeModeActivity.kt b/app/src/main/java/com/supwisdom/activities/consumeMode/ConsumeModeActivity.kt
new file mode 100644
index 0000000..d7f5e32
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/consumeMode/ConsumeModeActivity.kt
@@ -0,0 +1,237 @@
+package com.supwisdom.activities.consumeMode
+
+import android.annotation.SuppressLint
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.view.KeyEvent
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.menu.MenuActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.utils.PublicDef
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class ConsumeModeActivity : BaseActivity() {
+    private lateinit var vPayamt: TextView
+    private val pos = SPApplication.getInstance().getPos()
+    private var keyActive = true
+    private var shoppwdPass = false
+    private var tmpPwd = ""
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        this.setContentView(R.layout.activity_consume_mode)
+        initView()
+    }
+
+    private fun initView() {
+        vPayamt = findViewById<TextView>(R.id.tv_consume_mode_payamt)
+    }
+
+    private fun checkShopPwd(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 -> {
+                tmpPwd += keyCode - KeyEvent.KEYCODE_0
+                if (tmpPwd.length >= 6) {
+                    if (checkShoPwdValid(tmpPwd)) {
+                        shoppwdPass = true
+                        refreshToSetAmount()
+                    } else {
+                        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("请输入商户密码:", "密码错误"))
+                    }
+                    tmpPwd = ""
+                } else {
+                    AuxScreenController.getInstance()
+                        .refreshContent(Arrays.asList("请输入商户密码:", CommonUtil.getPasswordStar(tmpPwd.length)))
+                }
+            }
+            KeyEvent.KEYCODE_DEL -> {
+                //cancel
+                val len = tmpPwd.length
+                when {
+                    len == 1 -> {
+                        tmpPwd = ""
+                        AuxScreenController.getInstance()
+                            .refreshContent(Arrays.asList("请输入商户密码:", CommonUtil.getPasswordStar(tmpPwd.length)))
+                    }
+                    len > 1 -> {
+                        tmpPwd = tmpPwd.substring(0, len - 1)
+                        AuxScreenController.getInstance()
+                            .refreshContent(Arrays.asList("请输入商户密码:", CommonUtil.getPasswordStar(tmpPwd.length)))
+                    }
+                    else -> finish()
+                }
+            }
+        }
+    }
+
+    private fun checkShoPwdValid(inputPwd: String): Boolean {
+        return inputPwd == pos.getConfigPara()!!.shopPwd
+    }
+
+    private fun setFixAmount(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 -> addValueToEdit(keyCode - KeyEvent.KEYCODE_0)
+            KeyEvent.KEYCODE_DEL ->
+                //cancel
+                delValueToEdit()
+            KeyEvent.KEYCODE_POUND, KeyEvent.KEYCODE_PERIOD -> {
+                val str = vPayamt.text.toString()
+                if (str.length < 8 && str.indexOf('.') < 0) {
+                    vPayamt.text = "$str."
+                    screenShowAmt()
+                }
+            }
+            KeyEvent.KEYCODE_ENTER -> {
+                pos.replaceControlPara(PublicDef.CONTROL_FIXAMT, getFixAmount())
+                jumpActivity(MenuActivity::class.java)
+            }
+        }
+    }
+
+    @SuppressLint("SetTextI18n")
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (!keyActive) {
+                return super.dispatchKeyEvent(event)
+            }
+            resetCounter(200)
+            if (shoppwdPass) {
+                setFixAmount(event.keyCode)
+            } else {
+                checkShopPwd(event.keyCode)
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        shoppwdPass = false
+        keyActive = true
+        refreshToCheckPasswd()
+    }
+
+    private fun refreshToCheckPasswd() {
+        AuxScreenController.getInstance().refreshTitle("消费模式设置")
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime())
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("请输入商户密码:", " "))
+    }
+
+    private fun refreshToSetAmount() {
+        val record = pos.getControlPara(PublicDef.CONTROL_FIXAMT)
+        if (record != null && PublicDef.CONTROL_NO_FIXPAY_FLAG != record.paraval) {
+            vPayamt.text = String.format("%.02f", Integer.parseInt(record.paraval) / 100.0f)
+        } else {
+            vPayamt.text = PublicDef.CONTROL_NO_FIXPAY_FLAG
+        }
+        screenShowAmt()
+    }
+
+    private fun getFixAmount(): String {
+        try {
+            return Integer.toString(CommonUtil.YuanToFen(java.lang.Double.parseDouble(vPayamt.text.toString())))
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+
+        return PublicDef.CONTROL_NO_FIXPAY_FLAG
+    }
+
+    private fun addValueToEdit(value: Int) {
+        var str = vPayamt.text.toString()
+        if ("0" == str || PublicDef.CONTROL_NO_FIXPAY_FLAG == str) {
+            str = ""
+        }
+        //如果已经有小数点,则小数点后面不能超过两位
+        if (str.indexOf(".") > 0) {
+            if (str.length - str.indexOf(".") <= 2) {
+                vPayamt.text = "$str$value"
+            } else {
+                vPayamt.text = value.toString()
+            }
+        } else {
+            //限制消费金额<1000
+            if (str.length < 3) {
+                vPayamt.text = "$str$value"
+            }
+        }
+        screenShowAmt()
+    }
+
+    private fun delValueToEdit() {
+        val str = vPayamt.text.toString()
+        if (PublicDef.CONTROL_NO_FIXPAY_FLAG != str) {
+            if (str.length <= 1) {
+                vPayamt.text = PublicDef.CONTROL_NO_FIXPAY_FLAG
+            } else {
+                vPayamt.text = str.substring(0, str.length - 1)
+            }
+        }
+        screenShowAmt()
+    }
+
+    private fun screenShowAmt() {
+        AuxScreenController.getInstance().refreshContent(
+            Arrays.asList<String>(
+                PublicDef.CONTROL_NO_FIXPAY_FLAG + "-普通消费",
+                "值-定额消费(元)",
+                String.format("金额:%s", vPayamt.text.toString())
+            )
+        )
+
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+    }
+
+    private var counter: ContinuePressTimer? = null
+
+    private fun resetCounter(timems: Long) {
+        counter?.cancel()
+        if (counter == null) {
+            counter = ContinuePressTimer(timems, 100)
+        }
+        keyActive = false
+        counter!!.start()
+    }
+
+    private inner class ContinuePressTimer internal constructor(millisInFuture: Long, countDownInterval: Long) :
+        CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+
+        }
+
+        override fun onFinish() {
+            keyActive = true
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/control/ControlActivity.kt b/app/src/main/java/com/supwisdom/activities/control/ControlActivity.kt
new file mode 100644
index 0000000..0ab3436
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/control/ControlActivity.kt
@@ -0,0 +1,118 @@
+package com.supwisdom.activities.control
+
+import android.os.Bundle
+import android.view.KeyEvent
+import android.view.View
+import android.widget.RadioButton
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.entity.ControlParaRecord
+import com.supwisdom.utils.PublicDef
+import com.supwisdom.view.SWToast
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class ControlActivity : BaseActivity() {
+    private val pos = SPApplication.getInstance().getPos()
+    private lateinit var vDebugDisable: RadioButton
+    private lateinit var vDebugEnable: RadioButton
+    private lateinit var vOfflineEnable: RadioButton
+    private lateinit var vOfflineDisable: RadioButton
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_control)
+        initView()
+    }
+
+    private fun initData() {
+        var record = pos.getControlPara(PublicDef.CONTROL_OFFLINE_DAY_DISABLE)
+        if (record != null && "1" == record.paraval) {
+            vOfflineDisable.isChecked = true
+        } else {
+            vOfflineEnable.isChecked = true
+        }
+        record = pos.getControlPara(PublicDef.CONTROL_DEBUG_ENABLE)
+        if (record != null && "1" == record.paraval) {
+            vDebugEnable.isChecked = true
+        } else {
+            vDebugDisable.isChecked = true
+        }
+    }
+
+    private fun initView() {
+        vOfflineEnable = this.findViewById<View>(R.id.rb_offline_enable) as RadioButton
+        vOfflineDisable = this.findViewById<View>(R.id.rb_offline_disable) as RadioButton
+        vDebugDisable = this.findViewById<View>(R.id.rb_debug_enable) as RadioButton
+        vDebugEnable = this.findViewById<View>(R.id.rb_debug_disable) as RadioButton
+        val ivBtn = this.findViewById<View>(R.id.btn_cancel) as TextView
+        ivBtn.setOnClickListener { this@ControlActivity.finish() }
+        //确定按钮
+        this.findViewById<TextView>(R.id.btn_save).setOnClickListener {
+            var flag = if (vOfflineDisable.isChecked) {
+                "1"
+            } else {
+                "0"
+            }
+            if (!pos.replaceControlPara(PublicDef.CONTROL_OFFLINE_DAY_DISABLE, flag)) {
+                showSWToastInfo("脱机天数判断保存失败", PublicDef.TOAST_SHOW_CRY)
+                return@setOnClickListener
+            }
+
+            flag = if (vDebugEnable.isChecked) {
+                "1"
+            } else {
+                "0"
+            }
+            if (!pos.replaceControlPara(PublicDef.CONTROL_DEBUG_ENABLE, flag)) {
+                showSWToastInfo("日志调试保存失败", PublicDef.TOAST_SHOW_CRY)
+                return@setOnClickListener
+            }
+            showSWToastInfo("保存成功", PublicDef.TOAST_SHOW_SMILE)
+            this@ControlActivity.finish()
+        }
+
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            when (event.keyCode) {
+                KeyEvent.KEYCODE_DEL -> {
+                }
+                KeyEvent.KEYCODE_ENTER -> finish()
+            }//cancel
+            //和触屏删除键冲突
+            //                    finish();
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    private fun showSWToastInfo(msg: String, showway: Int) {
+        SWToast.show(applicationContext, msg, showway)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        refresh()
+        initData()
+    }
+
+    override fun onStop() {
+        super.onStop()
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+    }
+
+    private fun refresh() {
+        AuxScreenController.getInstance().refreshTitle("控制参数设置")
+        AuxScreenController.getInstance().refreshBottom("确定键返回上页")
+        AuxScreenController.getInstance().refreshContent(listOf<String>("请到大屏进行配置"))
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/IInitView.kt b/app/src/main/java/com/supwisdom/activities/init/IInitView.kt
new file mode 100644
index 0000000..1f989f0
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/IInitView.kt
@@ -0,0 +1,15 @@
+package com.supwisdom.activities.init
+
+import android.app.Activity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+interface IInitView {
+    fun getActivity(): Activity
+
+    fun showSWToastInfo(msg: String, showway: Int)
+
+    fun jumpToNextActivity()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/InitActivity.kt b/app/src/main/java/com/supwisdom/activities/init/InitActivity.kt
new file mode 100644
index 0000000..1d773f5
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/InitActivity.kt
@@ -0,0 +1,243 @@
+package com.supwisdom.activities.init
+
+import android.app.Activity
+import android.net.nsd.NsdServiceInfo
+import android.os.Bundle
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.widget.Button
+import android.widget.EditText
+import android.widget.RadioButton
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.init.adapter.NsdServerConfigAdapter
+import com.supwisdom.activities.init.mode.NsdClient
+import com.supwisdom.activities.init.mode.NsdClientApi
+import com.supwisdom.activities.load.LoadActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.entity.ConfigParaRecord
+import com.supwisdom.service.NtpClient
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.utils.PublicDef
+import com.supwisdom.utils.ThreadPool
+import com.supwisdom.view.BigSwDialog
+import com.supwisdom.view.SWToast
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+@Suppress("DEPRECATION")
+class InitActivity : BaseActivity(), IInitView {
+    private lateinit var presenter: InitPresenter
+    private lateinit var vDevphyid: EditText
+    private lateinit var vServerIp: EditText
+    private lateinit var vUri: EditText
+    private lateinit var vPort: EditText
+    private lateinit var vNsdResult: TextView
+    private lateinit var vRadioPayMode: RadioButton
+    private lateinit var vRadioDepositMode: RadioButton
+    private lateinit var vRadioThirdPayMode: RadioButton
+    private lateinit var vRadioThirdLoginMode: RadioButton
+    private var nsdClient: NsdClient? = null
+    private var nsdServiceIp: String? = null
+    private var nsdServicePort: Int = 0
+    private var dialogNsdConfig: BigSwDialog? = null
+    private var nsdConfigAdapter: NsdServerConfigAdapter? = null
+    private val pos = SPApplication.getInstance().getPos()
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_init)
+        initView()
+        initData()
+    }
+
+    private fun initData() {
+        presenter = InitPresenter(this)
+        var record = pos.getConfigPara()
+        if (record == null) {
+            record = ConfigParaRecord()
+            record.mode = 0
+            record.devphyid = "12345678"
+            record.epayIP = "127.0.0.1"
+            record.epayPort = 8080
+            record.epayUri = "restaurant"
+        }
+        record.initOK = false
+        pos.replaceConfigPara(record)
+        val cfgRecord = pos.getConfigPara()
+
+//        when {
+//            cfgRecord.mode == PublicDef.TERMINAL_DEPOSIT_MODE -> vRadioDepositMode.isChecked = true
+//            cfgRecord.mode == PublicDef.TERMINAL_THIRD_PAY_MODE -> vRadioThirdPayMode.isChecked = true
+//            cfgRecord.mode == PublicDef.TERMINAL_GATE_MODE -> vRadioGateMode.isChecked = true
+//            cfgRecord.mode == PublicDef.TERMINAL_THIRD_LOGIN_MODE -> vRadioThirdLoginMode.isChecked = true
+//            else -> vRadioPayMode.isChecked = true
+//        }
+        vDevphyid.setText(cfgRecord!!.devphyid)
+        vServerIp.setText(cfgRecord.epayIP)
+        vUri.setText(cfgRecord.epayUri)
+        vPort.setText(cfgRecord.epayPort.toString())
+
+        nsdClient = NsdClient(this, "epay-reg-server", object : NsdClient.IServerFound {
+            override fun onServerFound(serviceInfo: NsdServiceInfo) {
+                nsdServiceIp = serviceInfo.host?.hostAddress
+                nsdServicePort = serviceInfo.port
+                if (nsdServiceIp != null) {
+                    asyncGetConfigName()
+                }
+            }
+
+            override fun onServerFail() {
+
+            }
+        })
+    }
+
+    private fun initView() {
+        this.findViewById<Button>(R.id.tv_settings).setOnClickListener {
+            //            CommonUtil.sendBroadcast(applicationContext, false)
+            CommonUtil.startNetSetting(this@InitActivity)
+        }
+        this.findViewById<TextView>(R.id.btn_save).setOnClickListener {
+            //            val mode = when {
+//                vRadioDepositMode.isChecked -> PublicDef.TERMINAL_DEPOSIT_MODE
+//                vRadioThirdPayMode.isChecked -> PublicDef.TERMINAL_THIRD_PAY_MODE
+//                vRadioThirdLoginMode.isChecked -> PublicDef.TERMINAL_THIRD_LOGIN_MODE
+//                vRadioGateMode.isChecked -> PublicDef.TERMINAL_GATE_MODE
+//                else -> PublicDef.TERMINAL_PAY_MODE
+//            }
+            presenter.saveConfigParam(
+                0,
+                CommonUtil.getEditView(vDevphyid), CommonUtil.getEditView(vServerIp),
+                CommonUtil.getEditView(vUri), CommonUtil.getEditView(vPort)
+            )
+        }
+        this.findViewById<Button>(R.id.tv_nsd_query).setOnClickListener {
+            if (nsdServiceIp == null) {
+                showSWToastInfo("nsd未连接", PublicDef.TOAST_SHOW_DOUBT)
+                return@setOnClickListener
+            }
+            asyncGetConfigName()
+        }
+        vNsdResult = this.findViewById(R.id.tv_nsd_result) as TextView
+        vRadioPayMode = this.findViewById(R.id.rb_pay_mode) as RadioButton
+        vRadioDepositMode = this.findViewById(R.id.rb_deposit_mode) as RadioButton
+        vRadioThirdPayMode = this.findViewById(R.id.rb_third_pay_mode) as RadioButton
+        vRadioThirdLoginMode = this.findViewById(R.id.rb_third_login_mode) as RadioButton
+        vDevphyid = this.findViewById(R.id.tv_devphyid) as EditText
+        vServerIp = this.findViewById(R.id.tv_server_ip) as EditText
+        vUri = this.findViewById(R.id.tv_uri_root) as EditText
+        vPort = this.findViewById(R.id.tv_server_port) as EditText
+    }
+
+    override fun onResume() {
+        super.onResume()
+        nsdClient!!.start()
+        refresh()
+    }
+
+    override fun onStop() {
+        super.onStop()
+        nsdClient!!.stop()
+    }
+
+    private fun refresh() {
+        AuxScreenController.getInstance().refreshTitle("通讯参数设置")
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime())
+        AuxScreenController.getInstance().refreshContent(Arrays.asList("设备第一次使用", "请联系管理员", "在大屏配置参数"))
+    }
+
+    private fun asyncGetConfigName() {
+        ThreadPool.getShortPool().execute(Runnable {
+            try {
+                val ret = NsdClientApi(nsdServiceIp!!, nsdServicePort).getNsdServerConfigList()
+                runOnUiThread {
+                    vNsdResult.text = ret.retmsg
+                    if (ret.retcode == PublicDef.SUCCESS) {
+                        if (ret.list!!.isEmpty()) {
+                            vNsdResult.text = "未找到配置项"
+                            return@runOnUiThread
+                        } else if (ret.list!!.size == 1) {
+                            asyncGetConfigFromNsdServer(ret.list!![0])
+                            return@runOnUiThread
+                        }
+                        vNsdResult.setTextColor(resources.getColor(R.color.light_blue2))
+                        if (dialogNsdConfig == null) {
+                            dialogNsdConfig = BigSwDialog(this, PublicDef.DIALOG_TYPE_NSD_CONFIG)
+                            val vConfigList = dialogNsdConfig!!.findViewById(R.id.rv_config_list) as RecyclerView
+                            vConfigList.layoutManager = LinearLayoutManager(this)
+                            vConfigList.addItemDecoration(NsdServerConfigAdapter.ItemDecoration(10))
+                            nsdConfigAdapter =
+                                NsdServerConfigAdapter(this, object : NsdServerConfigAdapter.ConfigNameListener {
+                                    override fun callback(configName: String) {
+                                        asyncGetConfigFromNsdServer(configName)
+                                        dialogNsdConfig!!.dismiss()
+                                    }
+                                })
+                            vConfigList.adapter = nsdConfigAdapter
+                        }
+                        nsdConfigAdapter!!.setList(ret.list)
+                        nsdConfigAdapter!!.notifyDataSetChanged()
+                        dialogNsdConfig!!.show()
+                    } else {
+                        vNsdResult.setTextColor(resources.getColor(R.color.cl_red))
+                    }
+                }
+            } catch (ex: Exception) {
+                runOnUiThread {
+                    vNsdResult.text = "异常:${ex.message}"
+                    vNsdResult.setTextColor(resources.getColor(R.color.cl_red))
+                }
+            }
+        })
+    }
+
+    private fun asyncGetConfigFromNsdServer(configName: String) {
+        ThreadPool.getShortPool().execute(Runnable {
+            try {
+                val ret = NsdClientApi(nsdServiceIp!!, nsdServicePort).getEcardConfigParam(configName)
+                NtpClient().startCalibrateTime(ret.systime)
+                runOnUiThread {
+                    vNsdResult.text = ret.retmsg
+                    if (ret.retcode == PublicDef.SUCCESS) {
+                        vNsdResult.setTextColor(resources.getColor(R.color.light_blue2))
+                        if (ret.mode == 0) {
+                            vRadioPayMode.isChecked = true
+                        } else {
+                            vRadioDepositMode.isChecked = true
+                        }
+                        vDevphyid.setText(ret.devphyid)
+                        vServerIp.setText(ret.epayIP)
+                        vUri.setText(ret.epayUri)
+                        vPort.setText(ret.epayPort.toString())
+                    } else {
+                        vNsdResult.setTextColor(resources.getColor(R.color.cl_red))
+                    }
+                }
+            } catch (ex: Exception) {
+                runOnUiThread {
+                    vNsdResult.text = "异常:${ex.message}"
+                    vNsdResult.setTextColor(resources.getColor(R.color.cl_red))
+                }
+            }
+        })
+    }
+
+    override fun jumpToNextActivity() {
+        jumpActivity(LoadActivity::class.java)
+    }
+
+    override fun getActivity(): Activity {
+        return this
+    }
+
+    override fun showSWToastInfo(msg: String, showway: Int) {
+        SWToast.show(applicationContext, msg, showway)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/InitPresenter.kt b/app/src/main/java/com/supwisdom/activities/init/InitPresenter.kt
new file mode 100644
index 0000000..0b46818
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/InitPresenter.kt
@@ -0,0 +1,78 @@
+package com.supwisdom.activities.init
+
+import android.text.TextUtils
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.YktSession
+import com.supwisdom.entity.ConfigParaRecord
+import com.supwisdom.entity.ControlParaRecord
+import com.supwisdom.entity.DynamicParaRecord
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.PublicDef
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class InitPresenter constructor(iInitView: IInitView) {
+    private val iInitView = iInitView
+    private val pos = SPApplication.getInstance().getPos()
+
+    fun saveConfigParam(mode: Int, devphyid: String, serverip: String, uri: String, port: String) {
+        val record = pos.getConfigPara() ?: ConfigParaRecord()
+        record.mode = mode
+        record.devphyid = devphyid
+        if (TextUtils.isEmpty(devphyid)) {
+            iInitView.showSWToastInfo("终端机编号不能为空!", PublicDef.TOAST_SHOW_DOUBT)
+            return
+        }
+        record.devphyid = devphyid
+
+        if (TextUtils.isEmpty(serverip)) {
+            iInitView.showSWToastInfo("服务器IP不能为空!", PublicDef.TOAST_SHOW_DOUBT)
+            return
+        }
+        record.epayIP = if (serverip.startsWith("http")) {
+            serverip
+        } else {
+            "http://$serverip"
+        }
+
+        try {
+            val tmpPort = Integer.valueOf(port)
+            if (tmpPort > 65535) {
+                iInitView.showSWToastInfo("端口不能大于65535", PublicDef.TOAST_SHOW_DOUBT)
+                return
+            }
+            record.epayPort = tmpPort
+        } catch (e: Exception) {
+            iInitView.showSWToastInfo("端口不合法,请确认!", PublicDef.TOAST_SHOW_DOUBT)
+            return
+        }
+
+        if (TextUtils.isEmpty(uri)) {
+            iInitView.showSWToastInfo("URI不能为空!", PublicDef.TOAST_SHOW_DOUBT)
+            return
+        }
+        record.initOK = false
+        record.epayUri = uri.replace(" ", "")
+        record.shopPwd = PublicDef.PASSWD_SHOP_DEFAULT
+        pos.replaceConfigPara(record)
+
+        val dyRecord = DynamicParaRecord()
+        dyRecord.cardverno = "000000000000"
+        dyRecord.appid = PublicDef.APP_ID
+        dyRecord.appsecret = PublicDef.APP_SECRET
+        pos.replaceDynamicPara(dyRecord)
+
+        YktSession.getInstance().setWebAPISession(
+            record.epayIP!!,
+            record.epayPort,
+            record.epayUri!!,
+            record.devphyid!!,
+            CommonUtil.getCommunicateTime()
+        )
+        iInitView.jumpToNextActivity()
+    }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/adapter/NsdServerConfigAdapter.kt b/app/src/main/java/com/supwisdom/activities/init/adapter/NsdServerConfigAdapter.kt
new file mode 100644
index 0000000..8f6e4f9
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/adapter/NsdServerConfigAdapter.kt
@@ -0,0 +1,70 @@
+package com.supwisdom.activities.init.adapter
+
+import android.content.Context
+import android.graphics.Rect
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.TextView
+import com.supwisdom.R
+
+/**
+ * @author zzq
+ * @date 2018/7/12
+ * @desc nsd server 参数配置列表
+ */
+class NsdServerConfigAdapter constructor(context: Context, callback: ConfigNameListener) :
+    RecyclerView.Adapter<NsdServerConfigAdapter.Holder>() {
+    private val context = context
+    private val list = ArrayList<String>()
+    private val listener = callback
+    fun setList(data: List<String>?) {
+        list.clear()
+        if (data != null) {
+            list.addAll(data)
+        }
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
+        return Holder(LayoutInflater.from(context).inflate(R.layout.item_init_nsd_config_list, parent, false))
+    }
+
+    override fun getItemCount(): Int {
+        return list.size
+    }
+
+    override fun onBindViewHolder(holder: Holder, position: Int) {
+        holder.vConfigId.text = "配置$position:"
+        holder.vConfigName.text = list[position]
+        holder.vConfig.setOnClickListener {
+            listener.callback(list[position])
+        }
+    }
+
+    inner class Holder constructor(itemView: View) : RecyclerView.ViewHolder(itemView) {
+        var vConfigName: TextView
+        var vConfigId: TextView
+        var vConfig: LinearLayout
+
+        init {
+            vConfigId = itemView.findViewById(R.id.tv_config_id) as TextView
+            vConfigName = itemView.findViewById(R.id.tv_config_name) as TextView
+            vConfig = itemView.findViewById(R.id.ll_config) as LinearLayout
+        }
+    }
+
+    class ItemDecoration constructor(space: Int) : RecyclerView.ItemDecoration() {
+        private val space = space
+        override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
+            outRect.left = space
+            outRect.right = space
+            outRect.bottom = space
+        }
+    }
+
+    interface ConfigNameListener {
+        fun callback(configName: String)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamBean.kt b/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamBean.kt
new file mode 100644
index 0000000..538dbb3
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamBean.kt
@@ -0,0 +1,17 @@
+package com.supwisdom.activities.init.bean
+
+import com.supwisdom.bean.BaseResp
+
+/**
+ * @author zzq
+ * @date 2018/7/11
+ * @desc 配置结果
+ */
+class EcardConfigParamBean constructor(retcode: Int, retmsg: String) : BaseResp(retcode, retmsg) {
+    var mode: Int = 0
+    var devphyid: String? = null
+    var epayIP: String? = null
+    var epayUri: String? = null
+    var epayPort: Int = 0
+    var systime: Long = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamRetBean.java b/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamRetBean.java
new file mode 100644
index 0000000..184c457
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/bean/EcardConfigParamRetBean.java
@@ -0,0 +1,54 @@
+package com.supwisdom.activities.init.bean;
+
+/**
+ * @author zzq
+ * @date 2018/7/12
+ * @desc nsd server返回结果
+ */
+public class EcardConfigParamRetBean {
+    private String _id;
+    private String name;
+    private String timestamp;
+    private String url;
+    private long system;
+
+    public String get_id() {
+        return _id;
+    }
+
+    public void set_id(String _id) {
+        this._id = _id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(String timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public long getSystem() {
+        return system;
+    }
+
+    public void setSystem(long system) {
+        this.system = system;
+    }
+}
diff --git a/app/src/main/java/com/supwisdom/activities/init/bean/NsdServerConfigRetBean.kt b/app/src/main/java/com/supwisdom/activities/init/bean/NsdServerConfigRetBean.kt
new file mode 100644
index 0000000..d6caa8f
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/bean/NsdServerConfigRetBean.kt
@@ -0,0 +1,12 @@
+package com.supwisdom.activities.init.bean
+
+import com.supwisdom.bean.BaseResp
+
+/**
+ * @author zzq
+ * @date 2018/7/12
+ * @desc nsd server 返回配置列表
+ */
+class NsdServerConfigRetBean constructor(retcode: Int, retmsg: String) : BaseResp(retcode, retmsg) {
+    var list: List<String>? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/mode/NsdClient.kt b/app/src/main/java/com/supwisdom/activities/init/mode/NsdClient.kt
new file mode 100644
index 0000000..2f3bf18
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/mode/NsdClient.kt
@@ -0,0 +1,106 @@
+package com.supwisdom.activities.init.mode
+
+import android.content.Context
+import android.net.nsd.NsdManager
+import android.net.nsd.NsdServiceInfo
+import android.util.Log
+
+class NsdClient constructor(context: Context, serviceName: String, callback: IServerFound) {
+    private val TAG = NsdClient::class.java.simpleName
+    /**
+     * NSD_SERVICE_NAME和NSD_SERVER_TYPE需要与服务器端完全一致
+     */
+    private val NSD_SERVER_TYPE = "_http._tcp."
+    private val context = context
+    private val serviceName = serviceName
+    private val mIServerFound = callback
+
+    private var mDiscoveryListener: NsdManager.DiscoveryListener? = null
+    private var mResolverListener: NsdManager.ResolveListener? = null
+    private var mNsdManager: NsdManager? = null
+    private var singleFlag = false
+
+
+    fun start() {
+        mNsdManager = context.getSystemService(Context.NSD_SERVICE) as NsdManager
+        initializeDiscoveryListener()
+        mNsdManager!!.discoverServices(NSD_SERVER_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener)
+        initializeResolveListener()
+    }
+
+    /**
+     * 扫描未被解析前的 NsdServiceInfo
+     * 用于服务发现的回调调用接口
+     */
+    private fun initializeDiscoveryListener() {
+        mDiscoveryListener = object : NsdManager.DiscoveryListener {
+            override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) {
+                mNsdManager!!.stopServiceDiscovery(this)
+                Log.e(TAG, "onStartDiscoveryFailed():")
+            }
+
+            override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) {
+                mNsdManager!!.stopServiceDiscovery(this)
+                Log.e(TAG, "onStopDiscoveryFailed():")
+            }
+
+            override fun onDiscoveryStarted(serviceType: String) {
+                Log.e(TAG, "onDiscoveryStarted():")
+            }
+
+            override fun onDiscoveryStopped(serviceType: String) {
+                Log.e(TAG, "onDiscoveryStopped():")
+            }
+
+            /**
+             *
+             * @param serviceInfo
+             */
+            override fun onServiceFound(serviceInfo: NsdServiceInfo) {
+
+                //根据咱服务器的定义名称,指定解析该 NsdServiceInfo
+                if (serviceInfo.serviceName == serviceName) {
+                    if (!singleFlag) {
+                        singleFlag = true
+                        mNsdManager!!.resolveService(serviceInfo, mResolverListener)
+                    }
+                }
+            }
+
+            override fun onServiceLost(serviceInfo: NsdServiceInfo) {
+                Log.e(TAG, "onServiceLost(): serviceInfo=$serviceInfo")
+            }
+        }
+    }
+
+    /**
+     * 解析未 调用未被解析的 NsdServiceInfo
+     */
+    private fun initializeResolveListener() {
+        mResolverListener = object : NsdManager.ResolveListener {
+            override fun onResolveFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {}
+
+            override fun onServiceResolved(serviceInfo: NsdServiceInfo) {
+                mIServerFound.onServerFound(serviceInfo)
+            }
+        }
+    }
+
+
+    fun stop() {
+        mNsdManager!!.stopServiceDiscovery(mDiscoveryListener)
+        singleFlag = false
+    }
+
+    interface IServerFound {
+        /**
+         * 回調 指定解析的结果
+         */
+        fun onServerFound(serviceInfo: NsdServiceInfo)
+
+        /**
+         * 無合適 回調失敗
+         */
+        fun onServerFail()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/init/mode/NsdClientApi.kt b/app/src/main/java/com/supwisdom/activities/init/mode/NsdClientApi.kt
new file mode 100644
index 0000000..5b1785c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/init/mode/NsdClientApi.kt
@@ -0,0 +1,80 @@
+package com.supwisdom.activities.init.mode
+
+import com.beust.klaxon.JsonArray
+import com.beust.klaxon.Parser
+import com.supwisdom.activities.init.bean.EcardConfigParamBean
+import com.supwisdom.activities.init.bean.EcardConfigParamRetBean
+import com.supwisdom.activities.init.bean.NsdServerConfigRetBean
+import com.supwisdom.okhttp.NetworkHandler
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.GsonUtil
+import com.supwisdom.utils.PublicDef
+import org.apache.http.HttpStatus
+
+/**
+ * @author zzq
+ * @date 2018/7/11
+ * @desc 从nsd-server获取数据
+ */
+class NsdClientApi constructor(ip: String, port: Int) {
+    private var url: String = "http://$ip:$port"
+
+    fun getEcardConfigParam(configName: String): EcardConfigParamBean {
+        val resp = NetworkHandler.getInstance().get("$url/ns/$configName", null)
+            ?: return EcardConfigParamBean(PublicDef.ERROR, "请求超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            return EcardConfigParamBean(resp.retcode, "错误码=${resp.retcode},${resp.retmsg}")
+        }
+        try {
+            val retBean = GsonUtil.GsonToBean(resp.retjson!!, EcardConfigParamRetBean::class.java)
+            val ret = EcardConfigParamBean(PublicDef.SUCCESS, "获取成功")
+            ret.systime = retBean.system
+            retBean.url!!.split("&", " ").forEach {
+                val keyValue = it.split("=")
+                when {
+                    keyValue[0].compareTo("mode", ignoreCase = true) == 0 -> {
+                        if (!CommonUtil.isNumeric(keyValue[1])) {
+                            return EcardConfigParamBean(PublicDef.ERROR, "mode不是数字")
+                        }
+                        ret.mode = keyValue[1].toInt()
+                    }
+                    keyValue[0].compareTo("id", ignoreCase = true) == 0 -> {
+                        if (!CommonUtil.isNumeric(keyValue[1])) {
+                            return EcardConfigParamBean(PublicDef.ERROR, "id不是数字")
+                        }
+                        ret.devphyid = keyValue[1]
+                    }
+                    keyValue[0].compareTo("ip", ignoreCase = true) == 0 -> {
+                        ret.epayIP = keyValue[1]
+                    }
+                    keyValue[0].compareTo("uri", ignoreCase = true) == 0 -> {
+                        ret.epayUri = keyValue[1]
+                    }
+                    keyValue[0].compareTo("port", ignoreCase = true) == 0 -> {
+                        if (!CommonUtil.isNumeric(keyValue[1])) {
+                            return EcardConfigParamBean(PublicDef.ERROR, "port不是数字")
+                        }
+                        ret.epayPort = keyValue[1].toInt()
+                    }
+                }
+            }
+            return ret
+        } catch (ex: Exception) {
+            ex.printStackTrace()
+            return EcardConfigParamBean(PublicDef.ERROR, "异常:${ex.message}")
+        }
+    }
+
+    fun getNsdServerConfigList(): NsdServerConfigRetBean {
+        val resp = NetworkHandler.getInstance().get("$url/list", null)
+            ?: return NsdServerConfigRetBean(PublicDef.ERROR, "请求超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            return NsdServerConfigRetBean(resp.retcode, "错误码=${resp.retcode},${resp.retmsg}")
+        }
+        return NsdServerConfigRetBean(PublicDef.SUCCESS, "成功").apply {
+            this.list = (Parser().parse(StringBuilder(resp.retjson)) as JsonArray<String>).map {
+                it
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/load/ILoadView.kt b/app/src/main/java/com/supwisdom/activities/load/ILoadView.kt
new file mode 100644
index 0000000..e94d5c0
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/load/ILoadView.kt
@@ -0,0 +1,17 @@
+package com.supwisdom.activities.load
+
+import android.app.Activity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+interface ILoadView {
+    fun getActivity(): Activity
+
+    fun showProgress(hint: String, clearlast: Boolean)
+
+    fun showFinish()
+
+    fun jumpToUnregister(errmsg: String)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/load/LoadActivity.kt b/app/src/main/java/com/supwisdom/activities/load/LoadActivity.kt
new file mode 100644
index 0000000..1e71cf2
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/load/LoadActivity.kt
@@ -0,0 +1,100 @@
+package com.supwisdom.activities.load
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import android.widget.TextView
+import android.widget.Toast
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.consume.ConsumeActivity
+import com.supwisdom.activities.unregister.UnregisterActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.DateUtil
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class LoadActivity : BaseActivity(), ILoadView {
+    private lateinit var presenter: LoadPresenter
+    private lateinit var vLoadPro: TextView
+    private val procontent = StringBuilder()
+    private val auxList = ArrayList<String>()
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_load)
+
+        initView()
+        initData()
+    }
+
+    override fun onResume() {
+        super.onResume()
+        presenter.start()
+        refresh()
+    }
+
+    private fun refresh() {
+        procontent.setLength(0)
+        auxList.clear()
+        AuxScreenController.getInstance().refreshTitle("设备参数加载")
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime())
+        AuxScreenController.getInstance().refreshContent(auxList)
+    }
+
+    private fun initData() {
+        presenter = LoadPresenter(this)
+    }
+
+    private fun initView() {
+        this.findViewById<View>(R.id.btn_back).setOnClickListener {
+            if (presenter.isLoading()) {
+                Toast.makeText(applicationContext, "正在加载信息", Toast.LENGTH_SHORT).show()
+            } else {
+                this@LoadActivity.finish()
+            }
+        }
+        vLoadPro = findViewById<View>(R.id.tv_load_pro) as TextView
+    }
+
+    override fun getActivity(): Activity {
+        return this
+    }
+
+    override fun showProgress(hint: String, clearlast: Boolean) {
+        procontent.append("\n").append(hint)
+        vLoadPro.text = procontent.toString()
+        if (clearlast) {
+            if (auxList.size > 0) {
+                auxList.removeAt(auxList.size - 1)
+            }
+        }
+        auxList.add(hint)
+        AuxScreenController.getInstance().refreshContent(showFormatAux())
+    }
+
+    override fun showFinish() {
+        jumpActivity(ConsumeActivity::class.java)
+    }
+
+    override fun jumpToUnregister(errmsg: String) {
+        val intent = Intent()
+        intent.putExtra("errmsg", errmsg)
+        intent.setClass(this, UnregisterActivity::class.java)
+        startActivity(intent)
+    }
+
+    private fun showFormatAux(): List<String> {
+        val list = ArrayList<String>()
+        val size = auxList.size
+        list.addAll(auxList)
+        for (i in size..4) {
+            list.add(" ")
+        }
+        return list
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/load/LoadPresenter.kt b/app/src/main/java/com/supwisdom/activities/load/LoadPresenter.kt
new file mode 100644
index 0000000..f6d0578
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/load/LoadPresenter.kt
@@ -0,0 +1,138 @@
+package com.supwisdom.activities.load
+
+import android.os.Handler
+import android.os.Looper
+import android.os.Message
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.YktSession
+import com.supwisdom.bean.AuthRetBean
+import com.supwisdom.exception.AuthEpayError
+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
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class LoadPresenter constructor(iLoadView: ILoadView) {
+    private val iLoadView = iLoadView
+    private val pos = SPApplication.getInstance().getPos()
+    private lateinit var handler: Handler
+
+    init {
+        createHandler()
+    }
+
+    private val LOAD_SUCCESS = 1
+    private val JUMP_TO_UNREGISTER = 2
+    private val LOAD_PROGRESS = 3
+    private val LOAD_DONE = 3
+
+    private var hasInit: Boolean = false
+    @Volatile
+    private var loading: Boolean = false
+
+    fun isLoading(): Boolean {
+        return loading
+    }
+
+    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 bean = try {
+                AuthEpay().login()
+            } catch (ex: AuthEpayError) {
+                AuthRetBean(PublicDef.ERROR, ex.message ?: "null")
+            }
+            if (bean.retcode != PublicDef.SUCCESS) {
+                sendMessage(LOAD_DONE, bean.retmsg!!)
+                loading = false
+                if (!hasInit) {
+                    sendMessage(JUMP_TO_UNREGISTER, "签到失败:${bean.retmsg}")
+                    return@Runnable
+                }
+            } else {
+                val dyRecord = pos.getDynamicPara()
+                dyRecord!!.deviceid = bean.deviceid
+                dyRecord.merchaccno = bean.merchaccno
+                dyRecord.shopname = bean.shopname
+                dyRecord.onlineseqno = bean.onlineseqno
+                dyRecord.offlineseqno = bean.offlineseqno
+                dyRecord.paragroupid = bean.paragroupid
+                pos.replaceDynamicPara(dyRecord)
+
+                SPApplication.getInstance().setEpayLinking(true)
+                sendMessage(LOAD_DONE, "系统签到成功")
+            }
+
+            // 设置通讯参数
+            val apiInterface = EpayApiImpl()
+            try {
+                sendMessage(LOAD_PROGRESS, "加载系统参数...")
+                apiInterface.downloadSyspara(bean.paragroupid, bean.paraverno)
+                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!!)
+            sendMessage(LOAD_SUCCESS, "加载成功")
+        })
+    }
+
+    private fun createHandler() {
+        handler = object : Handler(Looper.getMainLooper()) {
+            override fun handleMessage(msg: Message) {
+                when (msg.what) {
+                    LOAD_DONE -> iLoadView.showProgress(msg.obj as String, true)
+                    LOAD_PROGRESS -> iLoadView.showProgress(msg.obj as String, false)
+                    JUMP_TO_UNREGISTER -> iLoadView.jumpToUnregister(msg.obj as String)
+                    LOAD_SUCCESS -> {
+                        CommonUtil.doSleep(3000)
+                        iLoadView.showFinish()
+                    }
+                }
+            }
+        }
+    }
+
+    private fun sendMessage(code: Int, info: String) {
+        val msg = Message()
+        msg.what = code
+        msg.obj = info
+        handler.sendMessage(msg)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/manage/IManageView.kt b/app/src/main/java/com/supwisdom/activities/manage/IManageView.kt
new file mode 100644
index 0000000..27bb27f
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/manage/IManageView.kt
@@ -0,0 +1,11 @@
+package com.supwisdom.activities.manage
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+interface IManageView {
+    fun showOperHint(hint: String, result: String)
+
+    fun showOperResult(hint: String, result: String)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/manage/ManageActivity.kt b/app/src/main/java/com/supwisdom/activities/manage/ManageActivity.kt
new file mode 100644
index 0000000..ec4b7be
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/manage/ManageActivity.kt
@@ -0,0 +1,170 @@
+package com.supwisdom.activities.manage
+
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.view.KeyEvent
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.communicate.CommunicateActivity
+import com.supwisdom.activities.control.ControlActivity
+import com.supwisdom.activities.menu.MenuActivity
+import com.supwisdom.activities.upgrade.UpgradeActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.AppExitUtil
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class ManageActivity : BaseActivity(), IManageView {
+    private var presenter: ManagePresenter? = null
+    private var flag: Boolean = false
+    private var isRunning: Boolean = false
+    private val pos = SPApplication.getInstance().getPos()
+    @Volatile
+    private var keyActive = true
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_manage)
+        initView()
+        initData()
+    }
+
+    private fun initView() {
+
+    }
+
+    private fun initData() {
+        presenter = ManagePresenter(this)
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (isRunning || !keyActive) {
+                return super.dispatchKeyEvent(event)
+            }
+            resetCounter(200)
+
+            val keyCode = event.keyCode
+            if (flag) {
+                return if (KeyEvent.KEYCODE_DEL == keyCode) {
+                    refresh()
+                    true
+                } else {
+                    false
+                }
+            }
+            when (keyCode) {
+                KeyEvent.KEYCODE_1 -> {
+                    flag = true
+                    showShopPassword()
+                }
+                KeyEvent.KEYCODE_2 -> jumpActivity(CommunicateActivity::class.java)
+                KeyEvent.KEYCODE_3 -> {
+                    //查询流水
+                    flag = true
+                    AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("流水查询:", "暂不支持"))
+                }
+                KeyEvent.KEYCODE_4 -> {
+                    flag = true
+                    isRunning = true
+                    AuxScreenController.getInstance()
+                        .refreshContent(Arrays.asList<String>("正在导出流水", "请稍等..."))
+                    presenter!!.outTransdtl()
+                }
+                KeyEvent.KEYCODE_5 -> jumpActivity(UpgradeActivity::class.java)
+                KeyEvent.KEYCODE_6 -> {
+                    AuxScreenController.getInstance()
+                        .refreshContent(Arrays.asList<String>("应用程序已退出", "请到大屏操作"))
+                    AppExitUtil.exit()
+                }
+                KeyEvent.KEYCODE_7 -> {
+                    AuxScreenController.getInstance()
+                        .refreshContent(Arrays.asList<String>("应用程序已退出", "请到大屏操作"))
+                    CommonUtil.startNetSetting(this)
+                }
+                KeyEvent.KEYCODE_8 -> {
+                    flag = true
+                    isRunning = true
+                    AuxScreenController.getInstance()
+                        .refreshContent(Arrays.asList<String>("正在清空白名单", "请稍等..."))
+                    presenter!!.clearAndUpdateWhitelist()
+                }
+                KeyEvent.KEYCODE_9 -> jumpActivity(ControlActivity::class.java)
+                KeyEvent.KEYCODE_DEL ->
+                    //cancel
+                    jumpActivity(MenuActivity::class.java)
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    override fun showOperHint(hint: String, result: String) {
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>(hint, result))
+    }
+
+    override fun showOperResult(hint: String, result: String) {
+        flag = true
+        isRunning = false
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>(hint, result))
+    }
+
+    override fun onResume() {
+        super.onResume()
+        keyActive = true
+        refresh()
+    }
+
+    private fun refresh() {
+        flag = false
+        isRunning = false
+        AuxScreenController.getInstance().refreshTitle("设备管理界面")
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime())
+        AuxScreenController.getInstance().refreshContent(
+            Arrays.asList(
+                getString(R.string.consume_menu_shop_passwd),
+                getString(R.string.consume_menu_comm_set),
+                getString(R.string.consume_menu_unconfirm_transdtl),
+                getString(R.string.consume_menu_out_dtl),
+                getString(R.string.consume_menu_upgrade),
+                getString(R.string.consume_menu_app_exit),
+                getString(R.string.consume_menu_setting),
+                getString(R.string.consume_menu_clear_blklist),
+                getString(R.string.consume_menu_control_set)
+            )
+        )
+    }
+
+    private fun showShopPassword() {
+        AuxScreenController.getInstance()
+            .refreshContent(Arrays.asList<String>("商户密码:", pos.getConfigPara()!!.shopPwd))
+    }
+
+    private var counter: ContinuePressTimer? = null
+
+    private fun resetCounter(timems: Long) {
+        counter?.cancel()
+        if (counter == null) {
+            counter = ContinuePressTimer(timems, 100)
+        }
+        keyActive = false
+        counter!!.start()
+    }
+
+    private inner class ContinuePressTimer internal constructor(millisInFuture: Long, countDownInterval: Long) :
+        CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+
+        }
+
+        override fun onFinish() {
+            keyActive = true
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/manage/ManagePresenter.kt b/app/src/main/java/com/supwisdom/activities/manage/ManagePresenter.kt
new file mode 100644
index 0000000..cfc459c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/manage/ManagePresenter.kt
@@ -0,0 +1,93 @@
+package com.supwisdom.activities.manage
+
+import android.os.AsyncTask
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.bean.BaseResp
+import com.supwisdom.service.EpayApiImpl
+import com.supwisdom.utils.PublicDef
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class ManagePresenter constructor(iManageView: IManageView) {
+    private val iManageView = iManageView
+    private val pos = SPApplication.getInstance().getPos()
+
+    fun clearAndUpdateWhitelist() {
+        if (!SPApplication.getInstance().isOnline()) {
+            iManageView.showOperHint("重置黑名单失败", "网络未联通")
+            return
+        }
+        ClearWhiteList().execute()
+    }
+
+    fun reloadTransdtl() {
+        if (!SPApplication.getInstance().isOnline()) {
+            iManageView.showOperHint("补采流水失败", "网络未联通")
+            return
+        }
+        iManageView.showOperHint("正在补采流水", "请稍等...")
+        ReloadTransdtl().execute()
+    }
+
+    fun outTransdtl() {
+        iManageView.showOperHint("正在导出流水", "请稍等...")
+        OutTransdtl().execute()
+    }
+
+    private inner class ReloadTransdtl : AsyncTask<Void, Int, BaseResp>() {
+        override fun onPostExecute(resp: BaseResp) {
+            if (resp.retcode == PublicDef.SUCCESS) {
+                iManageView.showOperResult("补采流水成功", resp.retmsg!!)
+            } else {
+                iManageView.showOperResult("补采流水失败", resp.retmsg!!)
+            }
+        }
+
+        override fun doInBackground(vararg params: Void): BaseResp {
+            return BaseResp(PublicDef.ERROR, "暂未实现")
+        }
+    }
+
+    private inner class ClearWhiteList : AsyncTask<Void, Int, BaseResp>() {
+        override fun onPostExecute(resp: BaseResp) {
+            if (resp.retcode == PublicDef.SUCCESS) {
+                iManageView.showOperResult("黑名单更新成功", "")
+            } else {
+                iManageView.showOperResult("黑名单更新失败", resp.retmsg!!)
+            }
+        }
+
+        override fun doInBackground(vararg params: Void): BaseResp {
+            return try {
+                EpayApiImpl().downloadWhitelist("0")
+                BaseResp(PublicDef.ERROR, "更新成功")
+            } catch (ex: Exception) {
+                BaseResp(PublicDef.ERROR, ex.message)
+            }
+        }
+    }
+
+    private inner class OutTransdtl : AsyncTask<Void, Int, BaseResp>() {
+        override fun doInBackground(vararg params: Void): BaseResp {
+            var num = 0
+//            val bm1List = pos.getTransdtlBM1(null)
+//            if (bm1List != null) {
+//                num += bm1List!!.size
+//                for (i in bm1List!!.indices) {
+//                    FileUtil.writeDtlFile(bm1List!!.get(i).toString())
+//                }
+//            }
+            return BaseResp(PublicDef.SUCCESS, "共导出" + num + "笔")
+        }
+
+        override fun onPostExecute(resp: BaseResp) {
+            if (resp.retcode == PublicDef.SUCCESS) {
+                iManageView.showOperResult("导出流水成功", resp.retmsg!!)
+            } else {
+                iManageView.showOperResult("导出流水失败", resp.retmsg!!)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/menu/IMenuView.kt b/app/src/main/java/com/supwisdom/activities/menu/IMenuView.kt
new file mode 100644
index 0000000..ff202b4
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/menu/IMenuView.kt
@@ -0,0 +1,15 @@
+package com.supwisdom.activities.menu
+
+import android.app.Activity
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+interface IMenuView {
+    fun getActivity(): Activity
+
+    fun showOperHint(title: String, result: String)
+
+    fun showOperResult(title: String, result: String)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/menu/MenuActivity.kt b/app/src/main/java/com/supwisdom/activities/menu/MenuActivity.kt
new file mode 100644
index 0000000..4c92368
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/menu/MenuActivity.kt
@@ -0,0 +1,172 @@
+package com.supwisdom.activities.menu
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.view.KeyEvent
+import android.view.View
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.checkMngpwd.CheckMngpwdActivity
+import com.supwisdom.activities.consume.ConsumeActivity
+import com.supwisdom.activities.consumeMode.ConsumeModeActivity
+import com.supwisdom.activities.passwd.PasswdActivity
+import com.supwisdom.activities.revenue.RevenueActivity
+import com.supwisdom.activities.syspara.SysparaActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.DateUtil
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class MenuActivity : BaseActivity(), IMenuView {
+    private lateinit var presenter: MenuPresenter
+    private val pos = SPApplication.getInstance().getPos()
+    private var isRunning: Boolean = false
+    private var flag: Boolean = false
+    private lateinit var vReverse: TextView
+    private var keyActive = true
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        this.setContentView(R.layout.activity_menu)
+        initView()
+        initData()
+    }
+
+    private fun initData() {
+        presenter = MenuPresenter(this)
+    }
+
+    private fun initView() {
+        vReverse = this.findViewById<View>(R.id.tv_reverse) as TextView
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (isRunning || !keyActive) {
+                return super.dispatchKeyEvent(event)
+            }
+            resetCounter(200)
+
+            val keyCode = event.keyCode
+            if (flag) {
+                return if (KeyEvent.KEYCODE_DEL == keyCode) {
+                    refresh()
+                    true
+                } else {
+                    false
+                }
+            }
+            when (keyCode) {
+                KeyEvent.KEYCODE_1 -> jumpActivity(RevenueActivity::class.java)
+                KeyEvent.KEYCODE_2 -> {
+                    isRunning = true
+                    presenter.uploadTransdtl()
+                }
+                KeyEvent.KEYCODE_3 -> {
+                    isRunning = true
+                    presenter.linkCheck()
+                }
+                KeyEvent.KEYCODE_4 -> {
+                    isRunning = true
+                    presenter.manualAuth()
+                }
+                KeyEvent.KEYCODE_5 -> jumpActivity(SysparaActivity::class.java)
+                KeyEvent.KEYCODE_6 -> {
+                    val intent = Intent()
+                    intent.putExtra("password", pos.getSysPara()!!.mngPasswd)
+                    intent.setClass(this, CheckMngpwdActivity::class.java)
+                    startActivity(intent)
+                }
+                KeyEvent.KEYCODE_7 -> jumpActivity(PasswdActivity::class.java)
+                KeyEvent.KEYCODE_8 -> jumpActivity(ConsumeModeActivity::class.java)
+                KeyEvent.KEYCODE_9 -> if (isSupportReverse()) {
+                    presenter.doReverse()
+                }
+                KeyEvent.KEYCODE_DEL -> {
+                    //cancel
+                    jumpActivity(ConsumeActivity::class.java)
+                }
+                KeyEvent.KEYCODE_ENTER -> jumpActivity(ConsumeActivity::class.java)
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        keyActive = true
+        refresh()
+    }
+
+    override fun showOperHint(title: String, result: String) {
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>(title, result))
+    }
+
+    override fun showOperResult(title: String, result: String) {
+        flag = true
+        isRunning = false
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>(title, result))
+    }
+
+    override fun getActivity(): Activity {
+        return this
+    }
+
+    private fun refresh() {
+        isRunning = false
+        flag = false
+        val secList = ArrayList<String>()
+        secList.add(getString(R.string.consume_menu_revenue))
+        secList.add(getString(R.string.consume_menu_transdtl_upload))
+        secList.add(getString(R.string.consume_menu_link_check))
+        secList.add(getString(R.string.consume_menu_auth))
+        secList.add(getString(R.string.consume_menu_syspara_query))
+        secList.add(getString(R.string.consume_menu_manage))
+        secList.add(getString(R.string.consume_menu_shop_password_set))
+        secList.add(getString(R.string.consume_menu_consume_mode))
+        if (isSupportReverse()) {
+            vReverse.visibility = View.VISIBLE
+            secList.add(getString(R.string.consume_menu_reverse))
+        } else {
+            vReverse.visibility = View.GONE
+        }
+        AuxScreenController.getInstance().refreshTitle("设备管理界面")
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime())
+        AuxScreenController.getInstance().refreshContent(secList)
+    }
+
+    private fun isSupportReverse(): Boolean {
+        val sysRecord = SPApplication.getInstance().getPos().getSysPara()
+        return sysRecord != null && sysRecord.returnFlag and 0x1 == 1
+    }
+
+    private var counter: ContinuePressTimer? = null
+
+    private fun resetCounter(timems: Long) {
+        counter?.cancel()
+        if (counter == null) {
+            counter = ContinuePressTimer(timems, 100)
+        }
+        keyActive = false
+        counter!!.start()
+    }
+
+    private inner class ContinuePressTimer internal constructor(millisInFuture: Long, countDownInterval: Long) :
+        CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+
+        }
+
+        override fun onFinish() {
+            keyActive = true
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/menu/MenuPresenter.kt b/app/src/main/java/com/supwisdom/activities/menu/MenuPresenter.kt
new file mode 100644
index 0000000..cbfac25
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/menu/MenuPresenter.kt
@@ -0,0 +1,151 @@
+package com.supwisdom.activities.menu
+
+import android.content.Intent
+import android.os.AsyncTask
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.consume.ConsumeActivity
+import com.supwisdom.bean.AuthRetBean
+import com.supwisdom.bean.BaseResp
+import com.supwisdom.entity.PayStatus
+import com.supwisdom.entity.ReversalFlag
+import com.supwisdom.exception.AuthEpayError
+import com.supwisdom.exception.HeartBeatError
+import com.supwisdom.exception.TransdtlUploadError
+import com.supwisdom.service.AuthEpay
+import com.supwisdom.service.EpayApiImpl
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.utils.PublicDef
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class MenuPresenter constructor(iMenuView: IMenuView) {
+    private val iMenuView = iMenuView
+    private val pos = SPApplication.getInstance().getPos()
+    fun manualAuth() {
+        iMenuView.showOperHint("正在签到", "请稍等...")
+        AsyncAuth().execute()
+    }
+
+    fun linkCheck() {
+        iMenuView.showOperHint("正在链路检测", "请稍等...")
+        AsyncLink().execute()
+    }
+
+    private inner class AsyncAuth : AsyncTask<Void, Void, AuthRetBean>() {
+        override fun doInBackground(vararg voids: Void): AuthRetBean {
+            val retBean = try {
+                AuthEpay().login()
+            } catch (ex: AuthEpayError) {
+                AuthRetBean(PublicDef.ERROR, ex.message ?: "null")
+            }
+            if (retBean.retcode == PublicDef.SUCCESS) {
+                val record = pos.getDynamicPara()
+                record!!.deviceid = retBean.deviceid
+                record.merchaccno = retBean.merchaccno
+                record.shopname = retBean.shopname
+                record.paragroupid = retBean.paragroupid
+                pos.replaceDynamicPara(record)
+
+                SPApplication.getInstance().setEpayLinking(true)
+            } else {
+                SPApplication.getInstance().setEpayLinking(false)
+            }
+            return retBean
+        }
+
+        override fun onPostExecute(retBean: AuthRetBean?) {
+            when {
+                retBean == null -> iMenuView.showOperResult("签到失败", "请求超时")
+                retBean.retcode != PublicDef.SUCCESS -> iMenuView.showOperResult("签到失败", retBean.retmsg ?: "null")
+                else -> iMenuView.showOperResult("签到成功", " ")
+            }
+        }
+    }
+
+    private inner class AsyncLink : AsyncTask<Void, Void, BaseResp>() {
+        override fun doInBackground(vararg voids: Void): BaseResp {
+            return try {
+                EpayApiImpl().linkCheck()
+                BaseResp(PublicDef.SUCCESS, "连接成功")
+            } catch (ex: HeartBeatError) {
+                BaseResp(PublicDef.ERROR, ex.message)
+            }
+        }
+
+        override fun onPostExecute(baseResp: BaseResp) {
+            SPApplication.getInstance().setEpayLinking(baseResp.retcode == PublicDef.SUCCESS)
+            iMenuView.showOperResult("检测结果", baseResp.retmsg!!)
+        }
+    }
+
+    fun doReverse() {
+        val list = pos.getTransdtlUnion(DateUtil.getNowDateNoFormat(), 0, 0, 1)
+        if (list.isEmpty()) {
+            iMenuView.showOperResult("冲正失败", "未找到消费记录")
+            return
+        }
+        val record = list[0]
+        if (record.reversalflag == ReversalFlag.AUTO ||
+            record.reversalflag == ReversalFlag.MANUAL
+        ) {
+            iMenuView.showOperResult("冲正失败", "已冲正")
+            return
+        }
+        if (record.status != PayStatus.SUC) {
+            iMenuView.showOperResult("冲正失败", "消费失败不能冲正")
+            return
+        }
+        val t1 = DateUtil.dateFormatConvertToLong(record.transdate + record.transtime)
+        val t2 = System.currentTimeMillis()
+        if (t2 - t1 > PublicDef.REVERSE_MS_GAP) {
+            iMenuView.showOperResult("冲正失败", "消费已过期")
+            return
+        }
+        val intent = Intent()
+        intent.putExtra("datetime", DateUtil.getNowDateNoFormat())
+        intent.putExtra("amount", record.payamt.toString())
+        intent.putExtra("payway", record.payway)
+        intent.setClass(iMenuView.getActivity(), ConsumeActivity::class.java)
+        iMenuView.getActivity().startActivity(intent)
+    }
+
+    fun uploadTransdtl() {
+        iMenuView.showOperHint("正在上传流水", "请稍等...")
+        UploadTransdtl().execute()
+    }
+
+    private inner class UploadTransdtl : AsyncTask<Void, Void, BaseResp>() {
+        override fun doInBackground(vararg voids: Void): BaseResp {
+            val apiInterface = EpayApiImpl()
+            var num = 0
+            try {
+                pos.getTransdtlOfflineUnconfirm().forEach {
+                    apiInterface.uploadTransdtl(it)
+                    it.upflag = 1
+                    pos.updateTransdtlOffline(it)
+                    num += 1
+                }
+                pos.getTransdtlOnlineUnconfirm().forEach {
+                    apiInterface.uploadTransdtl(it)
+                    it.upflag = 1
+                    pos.updateTransdtlOnline(it)
+                    num += 1
+                }
+                return BaseResp(PublicDef.SUCCESS, "上传共" + num + "条")
+            } catch (ex: TransdtlUploadError) {
+                return BaseResp(PublicDef.ERROR, ex.message)
+            }
+        }
+
+        override fun onPostExecute(resp: BaseResp) {
+            if (resp.retcode == PublicDef.SUCCESS) {
+                iMenuView.showOperResult("上传流水成功", resp.retmsg!!)
+            } else {
+                iMenuView.showOperResult("上传流水失败", resp.retmsg!!)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/passwd/PasswdActivity.kt b/app/src/main/java/com/supwisdom/activities/passwd/PasswdActivity.kt
new file mode 100644
index 0000000..a288b3f
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/passwd/PasswdActivity.kt
@@ -0,0 +1,189 @@
+package com.supwisdom.activities.passwd
+
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.view.KeyEvent
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc 商户密码修改
+ **/
+class PasswdActivity : BaseActivity() {
+    private lateinit var oldPwd: String
+    private lateinit var newPwd: String
+    private lateinit var newPwd1: String
+    private lateinit var tmpPwd: String
+    private lateinit var passwdHint: String
+    private val pos = SPApplication.getInstance().getPos()
+    private var step = 0
+    private var keyActive = true
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        this.setContentView(R.layout.activity_password)
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (!keyActive) {
+                return super.dispatchKeyEvent(event)
+            }
+            resetCounter(200)
+
+            if (step == 3) {
+                refresh()
+            }
+            val keyCode = event.keyCode
+            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 -> {
+                    if (step == 4) {
+                        step = 0
+                        passwdHint = "输入原密码:"
+                    }
+                    tmpPwd += keyCode - KeyEvent.KEYCODE_0
+                    if (tmpPwd.length == 6) {
+                        when (step) {
+                            0 -> {
+                                oldPwd = tmpPwd
+                                tmpPwd = ""
+                                if (checkOldPasswd()) {
+                                    step = 1
+                                    passwdHint = "输入新密码:"
+                                    AuxScreenController.getInstance().refreshContent(Arrays.asList<String>(passwdHint, " "))
+                                    return true
+                                } else {
+                                    step = 4
+                                }
+                                return true
+                            }
+                            1 -> {
+                                newPwd = tmpPwd
+                                tmpPwd = ""
+                                step = 2
+                                passwdHint = "确认新密码:"
+                                AuxScreenController.getInstance().refreshContent(Arrays.asList<String>(passwdHint, " "))
+                                return true
+                            }
+                            2 -> {
+                                newPwd1 = tmpPwd
+                                step = 3
+                                tmpPwd = ""
+                                if (checkAndUpdate()) {
+                                    AuxScreenController.getInstance()
+                                        .refreshContent(Arrays.asList<String>("密码修改成功", " "))
+                                    step = 3
+                                    return true
+                                }
+                                step = 4
+                                return true
+                            }
+                            else -> tmpPwd = ""
+                        }
+                    }
+                    AuxScreenController.getInstance()
+                        .refreshContent(Arrays.asList(passwdHint, CommonUtil.getPasswordStar(tmpPwd.length)))
+                    return true
+                }
+                KeyEvent.KEYCODE_ENTER -> {
+                }
+                KeyEvent.KEYCODE_DEL -> {
+                    val len = tmpPwd.length
+                    when {
+                        len == 1 -> {
+                            tmpPwd = ""
+                            AuxScreenController.getInstance()
+                                .refreshContent(Arrays.asList(passwdHint, CommonUtil.getPasswordStar(tmpPwd.length)))
+                        }
+                        len > 1 -> {
+                            tmpPwd = tmpPwd.substring(0, len - 1)
+                            AuxScreenController.getInstance()
+                                .refreshContent(Arrays.asList(passwdHint, CommonUtil.getPasswordStar(tmpPwd.length)))
+                        }
+                        else -> finish()
+                    }
+                    return true
+                }
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        keyActive = true
+        refresh()
+    }
+
+    private fun refresh() {
+        step = 0
+        oldPwd = ""
+        newPwd = ""
+        newPwd1 = ""
+        tmpPwd = ""
+        passwdHint = "输入原密码"
+        AuxScreenController.getInstance().refreshTitle("商户密码修改")
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime())
+        AuxScreenController.getInstance().refreshContent(Arrays.asList<String>(passwdHint, " "))
+    }
+
+    private fun checkOldPasswd(): Boolean {
+        if (oldPwd != pos.getConfigPara()!!.shopPwd) {
+            AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("修改密码错误", "原密码错误"))
+            return false
+        }
+        return true
+    }
+
+    private fun checkAndUpdate(): Boolean {
+        if (newPwd != newPwd1) {
+            AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("修改密码错误", "新密码不一致"))
+            return false
+        }
+        val record = pos.getConfigPara()
+        record!!.shopPwd = newPwd
+        if (!pos.replaceConfigPara(record)) {
+            AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("修改密码错误", "密码保存失败"))
+            return false
+        }
+        return true
+    }
+
+    private var counter: ContinuePressTimer? = null
+
+    private fun resetCounter(timems: Long) {
+        if (counter == null) {
+            counter = ContinuePressTimer(timems, 100)
+        }
+        counter!!.cancel()
+        keyActive = false
+        counter!!.start()
+    }
+
+    private inner class ContinuePressTimer internal constructor(millisInFuture: Long, countDownInterval: Long) :
+        CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+
+        }
+
+        override fun onFinish() {
+            keyActive = true
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/revenue/IRevenueView.kt b/app/src/main/java/com/supwisdom/activities/revenue/IRevenueView.kt
new file mode 100644
index 0000000..74b4227
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/revenue/IRevenueView.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.activities.revenue
+
+import com.supwisdom.activities.revenue.bean.RevenueAmtRetBean
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+interface IRevenueView {
+    fun showRevenueFail(msg: String)
+
+    fun showRevenueSuc(record: RevenueAmtRetBean)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/revenue/RevenueActivity.kt b/app/src/main/java/com/supwisdom/activities/revenue/RevenueActivity.kt
new file mode 100644
index 0000000..895d5b4
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/revenue/RevenueActivity.kt
@@ -0,0 +1,148 @@
+package com.supwisdom.activities.revenue
+
+import android.os.Bundle
+import android.view.KeyEvent
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.menu.MenuActivity
+import com.supwisdom.activities.revenue.bean.RevenueAmtRetBean
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.DateUtil
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class RevenueActivity : BaseActivity(), IRevenueView {
+    private lateinit var vContent: TextView
+    private lateinit var vSearchDate: TextView
+    private lateinit var presenter: RevenuePresenter
+    private var isSearching: Boolean = false
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        this.setContentView(R.layout.activity_revenue)
+        initView()
+        initData()
+    }
+
+    private fun initData() {
+        presenter = RevenuePresenter(this)
+    }
+
+    private fun initView() {
+        vContent = this.findViewById<TextView>(R.id.revenue_content)
+        vSearchDate = this.findViewById<TextView>(R.id.revenue_date)
+    }
+
+    private fun refresh() {
+        AuxScreenController.getInstance().refreshTitle("营业额查询")
+        AuxScreenController.getInstance().refreshBottom("F3/F4 切换日期")
+        AuxScreenController.getInstance()
+            .refreshContent(Arrays.asList<String>("查询日期:" + DateUtil.getNowDateSpecFormat(), "正在查询.", "请稍等...", " "))
+
+        val searchDate = DateUtil.getNowDateNoFormat()
+        vSearchDate.text = searchDate
+        isSearching = false
+        presenter.queryRevenue(searchDate)
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (isSearching) {
+                return false
+            }
+            when (event.keyCode) {
+                //case KeyEvent.KEYCODE_DPAD_UP:
+                //F2
+                KeyEvent.KEYCODE_DPAD_DOWN -> {
+                    //F3
+                    movePredate()
+                    return true
+                }
+                KeyEvent.KEYCODE_DPAD_RIGHT -> {
+                    //F4
+                    moveNextDate()
+                    return true
+                }
+                KeyEvent.KEYCODE_DEL -> {
+                    //cancel
+                    jumpActivity(MenuActivity::class.java)
+                    return true
+                }
+            }//case KeyEvent.KEYCODE_ENTER:
+            //ok
+            //  return true;
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    private fun moveNextDate() {
+        val date = getSearchDate()
+        if (date >= DateUtil.getNowDateNoFormat()) {
+            return
+        }
+        isSearching = true
+        val nextdate = DateUtil.getSpecifiedDayAfter(date)
+        vSearchDate.text = nextdate
+        AuxScreenController.getInstance()
+            .refreshContent(Arrays.asList<String>("查询日期:" + convertDateToShow(nextdate), "正在查询", "请稍等...", " "))
+        presenter.queryRevenue(nextdate)
+    }
+
+    private fun movePredate() {
+        isSearching = true
+        val predate = DateUtil.getSpecifiedDayBefore(getSearchDate())
+        vSearchDate.text = predate
+        AuxScreenController.getInstance()
+            .refreshContent(Arrays.asList<String>("查询日期:" + convertDateToShow(predate), "正在查询", "请稍等...", " "))
+        presenter.queryRevenue(predate)
+    }
+
+    private fun convertDateToShow(date: String): String {
+        return date.substring(0, 4) + "/" + date.substring(4, 6) + "/" + date.substring(6)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        refresh()
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+    }
+
+    override fun showRevenueFail(msg: String) {
+        isSearching = false
+        vContent.text = "查询失败\n原因: $msg"
+        AuxScreenController.getInstance().refreshContent(
+            Arrays.asList<String>(
+                "查询日期:" + convertDateToShow(getSearchDate()),
+                "查询失败:", "原因:$msg", " "
+            )
+        )
+    }
+
+    override fun showRevenueSuc(record: RevenueAmtRetBean) {
+        isSearching = false
+        val sb = StringBuilder("查询成功\n")
+        sb.append("有效笔数 : ").append(record.salescnt).append("笔\n")
+            .append("营业汇总 : ").append(String.format("%.02f 元", record.salesamt / 100.0f))
+        vContent.text = sb.toString()
+
+        AuxScreenController.getInstance().refreshContent(
+            Arrays.asList<String>(
+                "查询日期:" + convertDateToShow(getSearchDate()),
+                "查询成功:",
+                "有效笔数:" + record.salescnt + "笔",
+                "营业汇总:" + String.format("%.02f元", record.salesamt / 100.0f)
+            )
+        )
+    }
+
+    private fun getSearchDate(): String {
+        return vSearchDate.text.toString()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/revenue/RevenuePresenter.kt b/app/src/main/java/com/supwisdom/activities/revenue/RevenuePresenter.kt
new file mode 100644
index 0000000..4ee5bd2
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/revenue/RevenuePresenter.kt
@@ -0,0 +1,42 @@
+package com.supwisdom.activities.revenue
+
+import android.os.AsyncTask
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.consume.mode.ConsumeApi
+import com.supwisdom.activities.revenue.bean.RevenueAmtRetBean
+import com.supwisdom.utils.GsonUtil
+import com.supwisdom.utils.PublicDef
+import org.apache.http.HttpStatus
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class RevenuePresenter constructor(iRevenueView: IRevenueView) {
+    private val iRevenueView = iRevenueView
+    private val pos = SPApplication.getInstance().getPos()
+
+    fun queryRevenue(date: String) {
+        AsyncRevenue().execute(pos.getConfigPara()!!.devphyid, date)
+    }
+
+    private inner class AsyncRevenue : AsyncTask<String, Void, RevenueAmtRetBean>() {
+        override fun onPostExecute(retBean: RevenueAmtRetBean) {
+            if (retBean.retcode != PublicDef.SUCCESS) {
+                iRevenueView.showRevenueFail(retBean.retmsg!!)
+            } else {
+                iRevenueView.showRevenueSuc(retBean)
+            }
+        }
+
+        override fun doInBackground(vararg strings: String): RevenueAmtRetBean {
+            val devphyid = strings[0]
+            val date = strings[1]
+            val resp = ConsumeApi().queryRevenue(devphyid, date) ?: return RevenueAmtRetBean(PublicDef.ERROR, "请求超时")
+            if (resp.retcode != HttpStatus.SC_OK) {
+                return RevenueAmtRetBean(resp.retcode, "错误码=" + resp.retcode)
+            }
+            return GsonUtil.GsonToBean(resp.retjson!!, RevenueAmtRetBean::class.java)
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/revenue/bean/RevenueAmtRetBean.kt b/app/src/main/java/com/supwisdom/activities/revenue/bean/RevenueAmtRetBean.kt
new file mode 100644
index 0000000..f18160c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/revenue/bean/RevenueAmtRetBean.kt
@@ -0,0 +1,15 @@
+package com.supwisdom.activities.revenue.bean
+
+import com.supwisdom.bean.BaseResp
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc 营业额返回
+ **/
+class RevenueAmtRetBean constructor(retcode: Int, retmsg: String) : BaseResp(retcode, retmsg) {
+    var salesdate: String? = null
+    var salesamt: Int = 0
+    var salescnt: Int = 0
+    var managefeecnt: Int = 0
+    var managefeeamt: Int = 0
+}
\ No newline at end of file
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..fd80a3a
--- /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.getNowDateTime())
+        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/activities/syspara/SysparaActivity.kt b/app/src/main/java/com/supwisdom/activities/syspara/SysparaActivity.kt
new file mode 100644
index 0000000..f2dba5f
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/syspara/SysparaActivity.kt
@@ -0,0 +1,177 @@
+package com.supwisdom.activities.syspara
+
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.view.KeyEvent
+import android.widget.ListView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.menu.MenuActivity
+import com.supwisdom.activities.syspara.adapter.SysparaAdapter
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.entity.ControlParaRecord
+import com.supwisdom.utils.CommonUtil
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class SysparaActivity : BaseActivity() {
+    private var pageno: Int = 0
+    private val PAGENUM = 3
+    private val kvMap = hashMapOf<Int, ControlParaRecord>()
+    private var index: Int = 0
+    private val pos = SPApplication.getInstance().getPos()
+    private var keyActive = true
+    private var adapter: SysparaAdapter? = null
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_syspara)
+        initView()
+        initData()
+    }
+
+    private fun initData() {
+        index = 0
+        kvMap[index++] = ControlParaRecord("软件版本>>", CommonUtil.getVersionName(applicationContext))
+        val cfgRecord = pos.getConfigPara()
+        val sysRecord = pos.getSysPara()
+        val dyRecord = pos.getDynamicPara()
+        kvMap[index++] = ControlParaRecord("物理编号>>", cfgRecord!!.devphyid!!)
+        kvMap[index++] = ControlParaRecord("服务器地址>>", cfgRecord.epayIP!!)
+        kvMap[index++] = ControlParaRecord("服务器标识>>", cfgRecord.epayUri!!)
+        kvMap[index++] = ControlParaRecord("服务器端口>>", "" + cfgRecord.epayPort)
+        kvMap[index++] =
+            ControlParaRecord("参数版本号>>", "no:" + dyRecord!!.paraverno + ",id:" + dyRecord.paragroupid)
+        kvMap[index++] = ControlParaRecord("白名单版本>>", dyRecord.cardverno!!)
+        kvMap[index++] = ControlParaRecord("通讯超时>>", String.format("%ds", CommonUtil.getCommunicateTime()))
+        if (sysRecord!!.returnFlag and 0x1 == 1) {
+            kvMap[index++] = ControlParaRecord("冲正使能>>", "启用")
+        } else {
+            kvMap[index++] = ControlParaRecord("冲正使能>>", "禁止")
+        }
+//        if (sysRecord.getSocketSwitch() === 0) {
+//            kvMap[index++] = ControlParaRecord("长连接使能>>", "禁止")
+//        } else {
+//            kvMap[index++] = ControlParaRecord("长连接使能>>", "启用")
+//        }
+        if (SPApplication.getInstance().isOnline()) {
+            kvMap[index++] = ControlParaRecord("网络状态>>", "联机")
+        } else {
+            kvMap[index++] = ControlParaRecord("网络状态>>", "脱机")
+        }
+        kvMap[index++] = ControlParaRecord("成功显时间>>", String.format("%ds", sysRecord!!.sucShowtime))
+        kvMap[index++] = ControlParaRecord("失败显时间>>", String.format("%ds", sysRecord.failShowtime))
+        kvMap[index++] = ControlParaRecord("联机流水号>>", String.format("%d", pos.getTransdtlOnlineMaxSeqno()))
+        kvMap[index++] = ControlParaRecord("离线流水号>>", String.format("%d", pos.getTransdtlOfflineMaxSeqno()))
+        kvMap[index++] = ControlParaRecord(
+            "未上传流水>>", String.format(
+                "%d", pos.getTransdtlOnlineUnconfirm()
+                        + pos.getTransdtlOfflineUnconfirm()
+            )
+        )
+        kvMap[index++] = ControlParaRecord("定额间隔时间(s)>>", "" + sysRecord.fixpayGap)
+        kvMap[index++] = ControlParaRecord("心跳间隔>>", "${sysRecord.heatBeat}s")
+    }
+
+    private fun initView() {
+        val vParamList = this.findViewById<ListView>(R.id.lv_param) as ListView
+        adapter = SysparaAdapter(this)
+        vParamList.adapter = adapter
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (!keyActive) {
+                return super.dispatchKeyEvent(event)
+            }
+            resetCounter(200)
+
+            when (event.keyCode) {
+                KeyEvent.KEYCODE_DPAD_DOWN -> {
+                    //F3
+                    pageno++
+                    if (kvMap.size <= pageno * PAGENUM) {
+                        pageno--
+                    } else {
+                        showPara()
+                    }
+                    return true
+                }
+                KeyEvent.KEYCODE_DPAD_RIGHT -> {
+                    //F4
+                    if (pageno > 0) {
+                        pageno--
+                        showPara()
+                    }
+                    return true
+                }
+                //case KeyEvent.KEYCODE_DPAD_UP:
+                //F2
+                KeyEvent.KEYCODE_DEL -> {
+                    //cancel
+                    jumpActivity(MenuActivity::class.java)
+                    return true
+                }
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        keyActive = true
+        pageno = 0
+        showPara()
+    }
+
+    private fun showPara() {
+        val paraList = ArrayList<ControlParaRecord>()
+        val auxList = ArrayList<String>()
+        for (i in 0 until PAGENUM) {
+            val index = pageno * PAGENUM + i
+            if (index < kvMap.size) {
+                auxList.add(kvMap[index]!!.paraname!!)
+                auxList.add(kvMap[index]!!.paraval!!)
+            } else {
+                auxList.add(" ")
+                auxList.add(" ")
+            }
+        }
+        for (i in 0 until kvMap.size) {
+            paraList.add(kvMap[i]!!)
+        }
+        adapter!!.setList(paraList)
+        adapter!!.notifyDataSetChanged()
+
+        AuxScreenController.getInstance().refreshTitle("设备参数查询")
+        AuxScreenController.getInstance().refreshBottom("F3/F4 切换翻页")
+        AuxScreenController.getInstance().refreshContent(auxList)
+    }
+
+    private var counter: ContinuePressTimer? = null
+
+    private fun resetCounter(timems: Long) {
+        counter?.cancel()
+        if (counter == null) {
+            counter = ContinuePressTimer(timems, 100)
+        }
+        keyActive = false
+        counter!!.start()
+    }
+
+    private inner class ContinuePressTimer internal constructor(millisInFuture: Long, countDownInterval: Long) :
+        CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+
+        }
+
+        override fun onFinish() {
+            keyActive = true
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/syspara/adapter/SysparaAdapter.kt b/app/src/main/java/com/supwisdom/activities/syspara/adapter/SysparaAdapter.kt
new file mode 100644
index 0000000..53d7b5d
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/syspara/adapter/SysparaAdapter.kt
@@ -0,0 +1,60 @@
+package com.supwisdom.activities.syspara.adapter
+
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import android.widget.BaseAdapter
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.entity.ControlParaRecord
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class SysparaAdapter constructor(context: Context) : BaseAdapter() {
+    private val context = context
+    private val list = ArrayList<ControlParaRecord>()
+
+    fun setList(data: List<ControlParaRecord>?) {
+        list.clear()
+        if (data != null && data.isNotEmpty()) {
+            list.addAll(data)
+        }
+    }
+
+    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
+        val holder: Holder
+        var view = convertView
+        if (view == null) {
+            holder = Holder()
+            view = View.inflate(context, R.layout.item_syspara, null)
+            holder.paraname = view.findViewById(R.id.tv_name) as TextView
+            holder.paraval = view.findViewById(R.id.tv_value) as TextView
+
+            view.tag = holder
+        } else {
+            holder = view.tag as Holder
+        }
+        holder.paraname.text = list[position].paraname
+        holder.paraval.text = list[position].paraval
+        return view!!
+    }
+
+    override fun getItem(position: Int): ControlParaRecord {
+        return list[position]
+    }
+
+    override fun getItemId(position: Int): Long {
+        return position.toLong()
+    }
+
+    override fun getCount(): Int {
+        return list.size
+    }
+
+    private inner class Holder {
+        lateinit var paraname: TextView
+        lateinit var paraval: TextView
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/transdtl/TransdtlActivity.kt b/app/src/main/java/com/supwisdom/activities/transdtl/TransdtlActivity.kt
new file mode 100644
index 0000000..c20049a
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/transdtl/TransdtlActivity.kt
@@ -0,0 +1,223 @@
+package com.supwisdom.activities.transdtl
+
+import android.os.AsyncTask
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.view.KeyEvent
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.consume.ConsumeActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.entity.PayStatus
+import com.supwisdom.entity.ReversalFlag
+import com.supwisdom.entity.TransdtlUnionRecord
+import com.supwisdom.utils.DateUtil
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class TransdtlActivity : BaseActivity() {
+    private val pos = SPApplication.getInstance().getPos()
+    private lateinit var vSeqno: TextView
+    private lateinit var vContent: TextView
+    private var isSearching: Boolean = false
+    @Volatile
+    private var keyActive = true
+    private val MAX_SEARCH_NUM = 19
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        this.setContentView(R.layout.activity_transdtl)
+        initView()
+    }
+
+    private fun initView() {
+        vSeqno = findViewById<TextView>(R.id.transdtl_seqno)
+        vContent = findViewById<TextView>(R.id.transdtl_content)
+    }
+
+    private fun refresh() {
+        setShowSeqno(1)
+        doSearch(1)
+    }
+
+    private fun showCustomQuery(seqno: Int) {
+        AuxScreenController.getInstance().refreshTitle("流水记录查询")
+        AuxScreenController.getInstance().refreshBottom("F3/F4 切换记录")
+        AuxScreenController.getInstance()
+            .refreshContent(Arrays.asList<String>("流水索引号:$seqno", "正在查询", "请稍等...", " ", " ", " "))
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (isSearching || !keyActive) {
+                return super.dispatchKeyEvent(event)
+            }
+            resetCounter(200)
+
+            when (event.keyCode) {
+                KeyEvent.KEYCODE_DPAD_UP -> {
+                }
+                KeyEvent.KEYCODE_DPAD_DOWN ->
+                    //F3
+                    movePreSeqno()
+                KeyEvent.KEYCODE_DPAD_RIGHT ->
+                    //F4
+                    moveNextSeqno()
+                KeyEvent.KEYCODE_DEL ->
+                    //cancel
+                    jumpActivity(ConsumeActivity::class.java)
+            }//F2
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    private fun moveNextSeqno() {
+        var seqno = getShowSeqno()
+        if (seqno > MAX_SEARCH_NUM) {
+            return
+        }
+        seqno += 1
+        setShowSeqno(seqno)
+        doSearch(seqno)
+    }
+
+    private fun movePreSeqno() {
+        var seqno = getShowSeqno()
+        if (seqno > 1) {
+            seqno -= 1
+            setShowSeqno(seqno)
+            doSearch(seqno)
+        }
+    }
+
+    private fun doSearch(seqno: Int) {
+        isSearching = true
+        showCustomQuery(seqno)
+        queryTransdtl(seqno - 1)
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+    }
+
+    override fun onResume() {
+        super.onResume()
+        keyActive = true
+        refresh()
+    }
+
+    fun showTransdtlResult(record: TransdtlUnionRecord?) {
+        isSearching = false
+        if (record == null) {
+            vContent.text = "未找到消费记录"
+            AuxScreenController.getInstance().refreshContent(
+                Arrays.asList<String>(
+                    "流水索引号:" + getShowSeqno(),
+                    "查询失败:", "未找到消费记录", " ", " ", " "
+                )
+            )
+        } else {
+            val transdatetime = StringBuilder()
+            transdatetime.append(record.transdate!!.substring(0, 4)).append("-")
+                .append(record.transdate!!.substring(4, 6)).append("-")
+                .append(record.transdate!!.substring(6)).append(" ")
+                .append(record.transtime!!.substring(0, 2)).append(":")
+                .append(record.transtime!!.substring(2, 4)).append(":")
+                .append(record.transtime!!.substring(4))
+            val result = if (record.status == PayStatus.SUC) {
+                if (record.reversalflag == ReversalFlag.AUTO ||
+                    record.reversalflag == ReversalFlag.MANUAL
+                ) {
+                    "已退款"
+                } else {
+                    "消费成功"
+                }
+            } else {
+                if (record.reversalflag == ReversalFlag.AUTO ||
+                    record.reversalflag == ReversalFlag.MANUAL
+                ) {
+                    "冲正失败"
+                } else {
+                    "消费失败"
+                }
+            }
+            val payWay = if (record.payway == "code") {
+                "二维码"
+            } else {
+                "市民卡"
+            }
+            val sb = StringBuilder("查询成功   \n")
+            sb.append("姓名: ").append(record.username).append("\n")
+                .append("支付方式: ").append(payWay).append("\n")
+                .append(String.format("支付金额: %.02f元", record.payamt / 100.0f)).append("\n")
+                .append("支付时间: ").append(transdatetime.toString()).append("\n")
+                .append("支付结果: ").append(result)
+            vContent.text = sb.toString()
+
+            AuxScreenController.getInstance().refreshContent(
+                Arrays.asList(
+                    "时间:$transdatetime",
+                    "姓名:" + record.username,
+                    String.format("金额:%.02f元", record.payamt / 100.0f),
+                    "方式:$payWay", "结果:$result"
+                )
+            )
+        }
+    }
+
+    private fun getShowSeqno(): Int {
+        return Integer.parseInt(vSeqno.text.toString())
+    }
+
+    private fun setShowSeqno(seqno: Int) {
+        vSeqno.text = seqno.toString()
+    }
+
+    private fun queryTransdtl(seqno: Int) {
+        AsyncTransdtl().execute(seqno)
+    }
+
+    private inner class AsyncTransdtl : AsyncTask<Int, Void, TransdtlUnionRecord?>() {
+        override fun onPostExecute(record: TransdtlUnionRecord?) {
+            showTransdtlResult(record)
+        }
+
+        override fun doInBackground(vararg integers: Int?): TransdtlUnionRecord? {
+            val searchSeqno = integers[0]!!
+            val list = pos.getTransdtlUnion(DateUtil.getNowDateNoFormat(), searchSeqno, 1, 1)
+            return if (list.isNotEmpty()) {
+                list[0]
+            } else {
+                null
+            }
+        }
+    }
+
+    private var counter: ContinuePressTimer? = null
+
+    private fun resetCounter(timems: Long) {
+        counter?.cancel()
+        if (counter == null) {
+            counter = ContinuePressTimer(timems, 100)
+        }
+        keyActive = false
+        counter!!.start()
+    }
+
+    private inner class ContinuePressTimer internal constructor(millisInFuture: Long, countDownInterval: Long) :
+        CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+
+        }
+
+        override fun onFinish() {
+            keyActive = true
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/unregister/UnregisterActivity.kt b/app/src/main/java/com/supwisdom/activities/unregister/UnregisterActivity.kt
new file mode 100644
index 0000000..14e8c6f
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/unregister/UnregisterActivity.kt
@@ -0,0 +1,60 @@
+package com.supwisdom.activities.unregister
+
+import android.content.Intent
+import android.os.Bundle
+import android.view.KeyEvent
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.activities.init.InitActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.utils.DateUtil
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class UnregisterActivity:BaseActivity() {
+    private lateinit var vErrmsg: TextView
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        this.setContentView(R.layout.activity_unregister)
+
+        initView()
+    }
+
+    private fun initView() {
+        val backBtn = this.findViewById(R.id.tv_back) as TextView
+        backBtn.setOnClickListener {
+            jumpActivity(InitActivity::class.java)
+        }
+        vErrmsg = this.findViewById(R.id.tv_errmsg) as TextView
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
+        return super.dispatchKeyEvent(event)
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+    }
+
+    override fun onResume() {
+        super.onResume()
+        val errmsg = intent.getStringExtra("errmsg")
+        refresh(errmsg)
+        vErrmsg.text = errmsg
+    }
+
+    private fun refresh(errmsg: String) {
+        AuxScreenController.getInstance().refreshTitle("设备注册状态")
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime())
+        AuxScreenController.getInstance().refreshContent(listOf("设备未注册", errmsg))
+    }
+
+    override fun onNewIntent(intent: Intent) {
+        super.onNewIntent(intent)
+        this.intent.putExtra("errmsg", intent.getStringExtra("errmsg"))
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/upgrade/UpgradeActivity.kt b/app/src/main/java/com/supwisdom/activities/upgrade/UpgradeActivity.kt
new file mode 100644
index 0000000..0640dc4
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/upgrade/UpgradeActivity.kt
@@ -0,0 +1,179 @@
+package com.supwisdom.activities.upgrade
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.support.v4.content.FileProvider
+import android.view.KeyEvent
+import android.widget.Button
+import android.widget.TextView
+import com.supwisdom.R
+import com.supwisdom.activities.BaseActivity
+import com.supwisdom.auxscreen.AuxScreenController
+import com.supwisdom.activities.upgrade.mode.EpayUpgradeApi
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.utils.ThreadPool
+import java.io.File
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+@Suppress("DEPRECATION")
+class UpgradeActivity : BaseActivity() {
+    private lateinit var vResult: TextView
+    private lateinit var vUpgradeMsg: TextView
+    private lateinit var vServerUrl: TextView
+    private lateinit var vPosOldVersion: TextView
+    private lateinit var vPosVersion: TextView
+    private var isUpgrading = false
+    @Volatile
+    private var keyActive = true
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_upgrade)
+        initView()
+        initData()
+    }
+
+    private fun initData() {
+        vPosOldVersion.text = CommonUtil.getVersionName(this)
+    }
+
+    private fun initView() {
+        vResult = this.findViewById(R.id.tv_result) as TextView
+        vUpgradeMsg = this.findViewById(R.id.tv_upgrade_msg) as TextView
+
+        vServerUrl = this.findViewById(R.id.tv_server_url) as TextView
+        vPosOldVersion = this.findViewById(R.id.tv_old_version) as TextView
+        vPosVersion = this.findViewById(R.id.tv_pos_version) as TextView
+        this.findViewById<Button>(R.id.tv_upgrade).setOnClickListener {
+            asyncUpgrade()
+        }
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (isUpgrading || !keyActive) {
+                return super.dispatchKeyEvent(event)
+            }
+            resetCounter(200)
+
+            when (event.keyCode) {
+                KeyEvent.KEYCODE_DEL ->
+                    //cancel
+                    finish()
+                KeyEvent.KEYCODE_ENTER -> {
+                    //ok
+                    isUpgrading = true
+                    AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("正在升级", "请稍等..."))
+                    asyncUpgrade()
+                }
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        keyActive = true
+        refresh()
+    }
+
+    private fun refresh() {
+        isUpgrading = false
+        AuxScreenController.getInstance().refreshTitle("应用在线升级")
+        AuxScreenController.getInstance().refreshBottom(DateUtil.getNowDateTime())
+        AuxScreenController.getInstance().refreshContent(
+            Arrays.asList(
+                "当前版本>>", CommonUtil.getVersionName(applicationContext),
+                "确认 --应用升级", "取消 --退出"
+            )
+        )
+    }
+
+    private val upgradeApiCallback = object : EpayUpgradeApi.CallbackInterface {
+        override fun progresss(pro: Int) {
+            runOnUiThread {
+                vUpgradeMsg.text = "$pro%"
+                vUpgradeMsg.setTextColor(resources.getColor(R.color.black))
+                AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("正在下载", "$pro%"))
+            }
+        }
+
+        override fun success(filepath: String) {
+            runOnUiThread {
+                isUpgrading = false
+                vUpgradeMsg.text = "下载成功"
+                vUpgradeMsg.setTextColor(resources.getColor(R.color.black))
+                AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("下载应用成功", "请在大屏确认升级"))
+                val apkFile = File(filepath)
+                installAPK(apkFile)
+            }
+        }
+
+        override fun failed(errmsg: String) {
+            runOnUiThread {
+                isUpgrading = false
+                vUpgradeMsg.text = errmsg
+                vUpgradeMsg.setTextColor(resources.getColor(R.color.cl_red))
+                AuxScreenController.getInstance().refreshContent(Arrays.asList<String>("升级失败", "原因:", errmsg))
+            }
+        }
+    }
+
+    /**
+     * 开始下载apk
+     */
+    fun asyncUpgrade() {
+        ThreadPool.getDownloadPool().execute(Runnable {
+            EpayUpgradeApi(upgradeApiCallback).upgrade(CommonUtil.getVersionName(this))
+        })
+    }
+
+    /**
+     * 安装apk
+     */
+    private fun installAPK(apkFile: File) {
+        val intent = Intent(Intent.ACTION_VIEW)
+        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+            val contentUri = FileProvider.getUriForFile(
+                this, "com.supwisdom.charge.fileprovider", apkFile
+            )
+            intent.setDataAndType(contentUri, "application/vnd.android.package-archive")
+        } else {
+            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive")
+        }
+        startActivity(intent)
+    }
+
+    private var counter: ContinuePressTimer? = null
+
+    private fun resetCounter(timems: Long) {
+        if (counter == null) {
+            counter = ContinuePressTimer(timems, 100)
+        }
+        counter!!.cancel()
+        keyActive = false
+        counter!!.start()
+    }
+
+    private inner class ContinuePressTimer internal constructor(millisInFuture: Long, countDownInterval: Long) :
+        CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+
+        }
+
+        override fun onFinish() {
+            keyActive = true
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/activities/upgrade/mode/EpayUpgradeApi.kt b/app/src/main/java/com/supwisdom/activities/upgrade/mode/EpayUpgradeApi.kt
new file mode 100644
index 0000000..1545002
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/activities/upgrade/mode/EpayUpgradeApi.kt
@@ -0,0 +1,177 @@
+package com.supwisdom.activities.upgrade.mode
+
+import android.text.TextUtils
+import com.supwisdom.activities.YktSession
+import com.supwisdom.bean.UpgradeInfoRetBean
+import com.supwisdom.okhttp.WebParams
+import com.supwisdom.utils.*
+import org.apache.http.HttpStatus
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
+import java.net.HttpURLConnection
+import java.net.URL
+import java.util.*
+
+/**
+ * @author zzq
+ * @date 2019/4/9
+ * @desc 在线升级
+ */
+class EpayUpgradeApi constructor(callbackInterface: CallbackInterface) {
+    private val TIMEOUT = 5 * 1000// 超时
+    private val callbackInterface = callbackInterface
+    private val POSID = "chargepos"
+
+    fun upgrade(versionName: String) {
+        val resp = getAppVersion()
+        if (resp.retcode != PublicDef.SUCCESS) {
+            callbackInterface.failed(resp.retmsg!!)
+            return
+        }
+        val updateFile = FileUtil.getUpdateFile("$POSID.zip")
+        if (updateFile == null) {
+            callbackInterface.failed("创建本地文件失败")
+            return
+        }
+        if (!downloadUpdateFile(resp.packageurl!!, updateFile, resp.packageversion!!)) {
+            return
+        }
+        parseDownloadFile(updateFile.absolutePath, resp.packageversion!!)
+    }
+
+    private fun downloadUpdateFile(downUrl: String, file: File, versionName: String): Boolean {
+//            val downStep = 1// 提示step
+        var downStep = 0// 提示step
+        val totalSize: Int// 文件总大小
+        var downloadCount = 0// 已经下载好的大小
+        var updateCount = 0// 已经上传的文件大小
+        try {
+            val url = URL(downUrl)
+            val urlConnection = url.openConnection() as HttpURLConnection
+            urlConnection.connectTimeout = TIMEOUT
+            urlConnection.readTimeout = TIMEOUT
+            urlConnection.doOutput = true
+            urlConnection.doInput = true
+            urlConnection.useCaches = false
+            // setting serialized
+            urlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object")
+            //default is GET
+            urlConnection.requestMethod = "POST"
+            urlConnection.setRequestProperty("Charsert", "UTF-8")
+            urlConnection.setRequestProperty("connection", "Keep-Alive")
+            urlConnection.addRequestProperty("version", versionName)
+
+            urlConnection.addRequestProperty("username", "supwisdom")
+            urlConnection.addRequestProperty("password", "supwisdom")
+            urlConnection.addRequestProperty("filename", "$POSID.apk")
+
+            //connect to server (tcp)
+            urlConnection.connect()
+            // 获取下载文件的size
+            totalSize = urlConnection.contentLength
+            if (urlConnection.responseCode != HttpStatus.SC_OK) {
+                urlConnection.disconnect()
+                callbackInterface.failed("下载文件失败:错误码=${urlConnection.responseCode}")
+                return false
+            }
+            val inputStream = urlConnection.inputStream
+            val outputStream = FileOutputStream(file, false)// 文件存在则覆盖掉
+            val buffer = ByteArray(1024)
+            while (true) {
+                val readSize = inputStream.read(buffer)
+                if (readSize < 0) {
+                    break
+                }
+                outputStream.write(buffer, 0, readSize)
+                downloadCount += readSize// 实时获取下载到的大小
+
+                val progress = downloadCount * 1.0 / totalSize
+                val pro = Math.round(progress * 100).toInt()
+                if (pro - downStep >= 1) {
+                    downStep++
+                    CommonUtil.doSleep(100)
+                    callbackInterface.progresss(pro)
+                }
+            }
+            urlConnection.disconnect()
+            inputStream.close()
+            outputStream.close()
+            return true
+        } catch (e: Exception) {
+            e.printStackTrace()
+            callbackInterface.failed("下载文件异常:${e.message}")
+            return false
+        }
+    }
+
+    private fun parseDownloadFile(zipFilePath: String, versionName: String): Boolean {
+        try {
+            val index = zipFilePath.lastIndexOf("/")
+            val unZipFilePath = zipFilePath.substring(0, index)
+            ZipUtil.unzip(zipFilePath, unZipFilePath, false)
+            val apkFile = File("$unZipFilePath/$POSID.apk")
+            if (!apkFile.exists()) {
+                callbackInterface.failed("未找到文件$POSID.apk")
+                return false
+            }
+
+            val fileHash256 = CryptUtil.HASH256(FileInputStream(apkFile), "nzoqPYMIu91VViA/mEIG5FtJXi8=")
+            if (fileHash256 == null) {
+                callbackInterface.failed("计算文件校验数据错误")
+                return false
+            }
+            val signFile = FileInputStream("$unZipFilePath/hash256.sign")
+            val buffer = ByteArray(1024)
+            val length = signFile.read(buffer, 0, buffer.size)
+            if (length < 0) {
+                callbackInterface.failed("读取校验文件失败")
+                return false
+            }
+            signFile.close()
+            val signHash256 = String(Arrays.copyOfRange(buffer, 0, length))
+            if (!fileHash256.equals(signHash256, ignoreCase = true)) {
+                callbackInterface.failed("文件校验错误")
+                return false
+            }
+            callbackInterface.success("$unZipFilePath/$POSID.apk")
+            return true
+        } catch (e: Exception) {
+            e.printStackTrace()
+            callbackInterface.failed("文件校验异常:${e.message}")
+            return false
+        }
+    }
+
+    private fun getAppVersion(): UpgradeInfoRetBean {
+        val params = WebParams()
+        params.setParameter("version_package_id", "com.supwisdom.$POSID")
+            .setParameter("sourcetype", "pos")
+
+        val signdata = params.getParameterString("version_package_id")
+        val resp = YktSession.getInstance().sendYktRequestPost("/common/apk/version", signdata, params)
+            ?: return UpgradeInfoRetBean(PublicDef.ERROR, "获取版本号网络超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            return UpgradeInfoRetBean(resp.retcode, resp.retmsg!!)
+        }
+        return try {
+            val bean = GsonUtil.GsonToBean(resp.retjson!!, UpgradeInfoRetBean::class.java)
+            when {
+                TextUtils.isEmpty(bean.packageversion) -> UpgradeInfoRetBean(PublicDef.ERROR, "获取版本号为空")
+                TextUtils.isEmpty(bean.packageurl) -> UpgradeInfoRetBean(PublicDef.ERROR, "获取升级链接为空")
+                else -> bean
+            }
+        } catch (e: Exception) {
+            e.printStackTrace()
+            UpgradeInfoRetBean(PublicDef.ERROR, "获取版本号JSON错误:${e.message}")
+        }
+    }
+
+    interface CallbackInterface {
+        fun progresss(pro: Int)
+
+        fun success(filepath: String)
+
+        fun failed(errmsg: String)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/AuthJwtRetBean.kt b/app/src/main/java/com/supwisdom/bean/AuthJwtRetBean.kt
new file mode 100644
index 0000000..0514140
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/AuthJwtRetBean.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/29
+ ** @desc
+ **/
+class AuthJwtRetBean : BaseResp() {
+    var jwt: String? = null
+    var expiredAt: String? = null //过期时间 UTC格式
+}
\ 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/bean/AuthTokenRetBean.kt b/app/src/main/java/com/supwisdom/bean/AuthTokenRetBean.kt
new file mode 100644
index 0000000..440ad89
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/AuthTokenRetBean.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/29
+ ** @desc
+ **/
+class AuthTokenRetBean : BaseResp() {
+    var token: String? = null
+    var timestamp: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/BaseResp.kt b/app/src/main/java/com/supwisdom/bean/BaseResp.kt
new file mode 100644
index 0000000..ac5fb29
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/BaseResp.kt
@@ -0,0 +1,17 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+open class BaseResp {
+    constructor(retcode: Int, retmsg: String?) {
+        this.retcode = retcode
+        this.retmsg = retmsg
+    }
+
+    constructor()
+
+    var retcode: Int = 0
+    var retmsg: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/HeartBeatRetBean.kt b/app/src/main/java/com/supwisdom/bean/HeartBeatRetBean.kt
new file mode 100644
index 0000000..2c68992
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/HeartBeatRetBean.kt
@@ -0,0 +1,12 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class HeartBeatRetBean : BaseResp() {
+    var systime: String? = null
+    var paragroupid: Int = 0
+    var paraverno: Int = 0
+    var cardverno: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/SystemParaItemBean.kt b/app/src/main/java/com/supwisdom/bean/SystemParaItemBean.kt
new file mode 100644
index 0000000..09beb47
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/SystemParaItemBean.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class SystemParaItemBean {
+    var paraname: String? = null
+    var paraval: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/SystemParaRetBean.kt b/app/src/main/java/com/supwisdom/bean/SystemParaRetBean.kt
new file mode 100644
index 0000000..16ed4e0
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/SystemParaRetBean.kt
@@ -0,0 +1,11 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class SystemParaRetBean : BaseResp() {
+    var paragroupid: Int = 0
+    var paraverno: Int = 0
+    var syspara: List<SystemParaItemBean>? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/TransdtlRetBean.kt b/app/src/main/java/com/supwisdom/bean/TransdtlRetBean.kt
new file mode 100644
index 0000000..2aded07
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/TransdtlRetBean.kt
@@ -0,0 +1,9 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class TransdtlRetBean : BaseResp() {
+    var termseqno: Int = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/UpgradeInfoRetBean.kt b/app/src/main/java/com/supwisdom/bean/UpgradeInfoRetBean.kt
new file mode 100644
index 0000000..d32ccff
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/UpgradeInfoRetBean.kt
@@ -0,0 +1,10 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class UpgradeInfoRetBean constructor(retcode: Int, retmsg: String) : BaseResp(retcode, retmsg) {
+    var packageversion: String? = null
+    var packageurl: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/WhiteListItemBean.kt b/app/src/main/java/com/supwisdom/bean/WhiteListItemBean.kt
new file mode 100644
index 0000000..398667c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/WhiteListItemBean.kt
@@ -0,0 +1,12 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class WhiteListItemBean {
+    var cardphyid: String? = null
+    var cardno: String? = null
+    var flag: Int = 0
+    var balance: Int = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/bean/WhiteListRetBean.kt b/app/src/main/java/com/supwisdom/bean/WhiteListRetBean.kt
new file mode 100644
index 0000000..d0a4d63
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/bean/WhiteListRetBean.kt
@@ -0,0 +1,11 @@
+package com.supwisdom.bean
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+class WhiteListRetBean : BaseResp() {
+    var cardverno: String? = null
+    var count: Int = 0
+    var whitelist: List<WhiteListItemBean>? = 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
new file mode 100644
index 0000000..8eb7e66
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/BeanPropEnum.kt
@@ -0,0 +1,110 @@
+package com.supwisdom.db
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+object BeanPropEnum {
+    enum class Syspara {
+        id,
+        returnFlag,
+        heatBeat,
+        offlineEnable,
+        maxOfflineDays,
+        mngpasswd,
+        fixpayGap,
+        consumeShowtime,
+        consumeFailShowtime,
+        commTime
+    }
+
+    enum class ConfigPara {
+        id,
+        mode,
+        devphyid,
+        psamno,
+        epayIP,
+        epayPort,
+        epayUri,
+        managePwd,
+        initOK
+    }
+
+    enum class DynamicPara {
+        id,
+        appid,
+        appsecret,
+        deviceid,
+        merchaccno,
+        shopname,
+        onlineseqno,
+        offlineseqno,
+        paraverno,
+        paragroupid,
+        cardverno,
+        jwt,
+        token
+    }
+
+    enum class ControlPara {
+        paraname,
+        paraval
+    }
+
+    enum class TransdtlOnline {
+        devphyid,
+        transdate,
+        transtime,
+        devseqno,
+        cardno,
+        cardphyid,
+        qrcode,
+        transtype,
+        payamt,
+        extraamt,
+        managefeetype,
+        username,
+        balance,
+        billno,
+        reversalflag,
+        reversalbillno,
+        status,
+        upflag
+    }
+
+    enum class TransdtlOffline {
+        devphyid,
+        transdate,
+        transtime,
+        devseqno,
+        cardno,
+        cardphyid,
+        payamt,
+        extraamt,
+        reversalflag,
+        reversalseqno,
+        reversaltransdate,
+        reversaltranstime,
+        status,
+        upflag
+    }
+
+    enum class WhiteList {
+        cardphyid,
+        cardno,
+        flag,
+        balance
+    }
+
+    enum class TransdtlUnion {
+        username,
+        transdate,
+        transtime,
+        devseqno,
+        payway,
+        reversalflag,
+        payamt,
+        status,
+        upflag
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/ConfigParaDao.kt b/app/src/main/java/com/supwisdom/db/ConfigParaDao.kt
new file mode 100644
index 0000000..cce42b8
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/ConfigParaDao.kt
@@ -0,0 +1,118 @@
+package com.supwisdom.db
+
+import android.content.ContentValues
+import android.content.Context
+import android.database.Cursor
+import com.supwisdom.entity.ConfigParaRecord
+import java.util.concurrent.locks.Lock
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class ConfigParaDao constructor(context: Context) {
+    private val INDEX = "1"
+    private val TABLE = DBLocalHelper.TABLE_NAME_CONFIGPARA
+    private val dbHelper = DBLocalHelper.getInstance(context)
+
+    fun getLock(): Lock {
+        return dbHelper.getLock()
+    }
+
+    fun replace(record: ConfigParaRecord): Boolean {
+        val db = dbHelper.readableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.replace(TABLE, null, values) > 0) {
+                db.setTransactionSuccessful()
+                return true
+            }
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun update(record: ConfigParaRecord): Boolean {
+        val db = dbHelper.writableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.update(
+                    TABLE,
+                    values,
+                    BeanPropEnum.ConfigPara.id.toString() + "=?",
+                    arrayOf(INDEX)
+                ) > 0
+            ) {
+                db.setTransactionSuccessful()
+                return true
+            }
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun get(): ConfigParaRecord? {
+        val db = dbHelper.readableDatabase
+        var cursor: Cursor? = null
+        try {
+            cursor = db.query(
+                TABLE, null, BeanPropEnum.ConfigPara.id.toString() + "=?",
+                arrayOf(INDEX), null, null, null
+            )
+            if (cursor != null && cursor.moveToNext()) {
+                return getRecord(cursor)
+            }
+        } finally {
+            cursor?.close()
+        }
+        return null
+    }
+
+    private fun getRecord(cursor: Cursor): ConfigParaRecord {
+        val record = ConfigParaRecord()
+        record.mode = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.ConfigPara.mode.toString()))
+        record.devphyid = cursor.getString(cursor.getColumnIndex(BeanPropEnum.ConfigPara.devphyid.toString()))
+        record.epayIP = cursor.getString(cursor.getColumnIndex(BeanPropEnum.ConfigPara.epayIP.toString()))
+        record.epayPort = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.ConfigPara.epayPort.toString()))
+        record.epayUri = cursor.getString(cursor.getColumnIndex(BeanPropEnum.ConfigPara.epayUri.toString()))
+        record.shopPwd = cursor.getString(cursor.getColumnIndex(BeanPropEnum.ConfigPara.managePwd.toString()))
+        val value = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.ConfigPara.initOK.toString()))
+        record.initOK = value == 1
+        return record
+    }
+
+    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 getContentValues(record: ConfigParaRecord): ContentValues {
+        val values = ContentValues()
+        values.put(BeanPropEnum.ConfigPara.id.toString(), INDEX)
+        values.put(BeanPropEnum.ConfigPara.mode.toString(), record.mode)
+        values.put(BeanPropEnum.ConfigPara.devphyid.toString(), record.devphyid)
+        values.put(BeanPropEnum.ConfigPara.epayIP.toString(), record.epayIP)
+        values.put(BeanPropEnum.ConfigPara.epayPort.toString(), record.epayPort)
+        values.put(BeanPropEnum.ConfigPara.epayUri.toString(), record.epayUri)
+        values.put(BeanPropEnum.ConfigPara.managePwd.toString(), record.shopPwd)
+        if (record.initOK) {
+            values.put(BeanPropEnum.ConfigPara.initOK.toString(), 1)
+        } else {
+            values.put(BeanPropEnum.ConfigPara.initOK.toString(), 0)
+        }
+        return values
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/ControlParaDao.kt b/app/src/main/java/com/supwisdom/db/ControlParaDao.kt
new file mode 100644
index 0000000..d683d9c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/ControlParaDao.kt
@@ -0,0 +1,118 @@
+package com.supwisdom.db
+
+import android.content.ContentValues
+import android.content.Context
+import android.database.Cursor
+import com.supwisdom.entity.ControlParaRecord
+import java.util.concurrent.locks.Lock
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class ControlParaDao constructor(context: Context) {
+    private val dbHelper = DBParaHelper.getInstance(context)
+    private val TABLE = DBParaHelper.TABLE_NAME_CONTROLPARA
+
+    fun getLock(): Lock {
+        return dbHelper.getLock()
+    }
+
+    fun replace(record: ControlParaRecord): Boolean {
+        val db = dbHelper.readableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.replace(TABLE, null, values) > 0) {
+                return false
+            }
+            db.setTransactionSuccessful()
+            return true
+        } finally {
+            db.endTransaction()
+        }
+    }
+
+    fun replace(paraname: String, paraval: String): Boolean {
+        val db = dbHelper.readableDatabase
+        val values = ContentValues()
+        values.put(BeanPropEnum.ControlPara.paraname.toString(), paraname)
+        values.put(BeanPropEnum.ControlPara.paraval.toString(), paraval)
+        try {
+            db.beginTransaction()
+            if (db.replace(TABLE, null, values) < 0) {
+                return false
+            }
+            db.setTransactionSuccessful()
+            return true
+        } finally {
+            db.endTransaction()
+        }
+    }
+
+    fun update(record: ControlParaRecord): Boolean {
+        val db = dbHelper.writableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.update(
+                    TABLE,
+                    values,
+                    BeanPropEnum.ControlPara.paraname.toString() + "=?",
+                    arrayOf(record.paraname)
+                ) > 0
+            ) {
+                db.setTransactionSuccessful()
+                return true
+            }
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun get(paraname: String): ControlParaRecord? {
+        val db = dbHelper.readableDatabase
+        var cursor: Cursor? = null
+        try {
+            cursor = db.query(
+                TABLE, null, BeanPropEnum.ControlPara.paraname.toString() + "=?",
+                arrayOf(paraname), 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): ControlParaRecord {
+        val record = ControlParaRecord()
+        record.paraname = cursor.getString(cursor.getColumnIndex(BeanPropEnum.ControlPara.paraname.toString()))
+        record.paraval = cursor.getString(cursor.getColumnIndex(BeanPropEnum.ControlPara.paraval.toString()))
+        return record
+    }
+
+    private fun getContentValues(record: ControlParaRecord): ContentValues {
+        val values = ContentValues()
+        values.put(BeanPropEnum.ControlPara.paraname.toString(), record.paraname)
+        values.put(BeanPropEnum.ControlPara.paraval.toString(), record.paraval)
+        return values
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/DBLocalHelper.kt b/app/src/main/java/com/supwisdom/db/DBLocalHelper.kt
new file mode 100644
index 0000000..a57dc71
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/DBLocalHelper.kt
@@ -0,0 +1,62 @@
+package com.supwisdom.db
+
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import android.database.sqlite.SQLiteOpenHelper
+import java.util.concurrent.locks.Lock
+import java.util.concurrent.locks.ReentrantLock
+
+/**
+ ** create by zzq on 2019/7/31
+ ** @desc 本地配置文件
+ **/
+class DBLocalHelper private constructor(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, VERSION) {
+    companion object {
+        private val DB_NAME = "db_local_config"
+        private val VERSION = 1
+        private var instance: DBLocalHelper? = null
+
+        const val TABLE_NAME_CONFIGPARA = "tb_configpara"
+
+        fun getInstance(context: Context): DBLocalHelper {
+            if (null == instance) {
+                synchronized(DBLocalHelper::class.java) {
+                    if (null == instance) {
+                        instance = DBLocalHelper(context)
+                    }
+                }
+            }
+            return instance!!
+        }
+    }
+
+    /**
+     * SQL for create table
+     */
+    private val CREATE_TABLE_NAME_CONFIGPARA = ("create table IF NOT EXISTS "
+            + TABLE_NAME_CONFIGPARA + " ( "
+            + BeanPropEnum.ConfigPara.id + " long primary key, "
+            + BeanPropEnum.ConfigPara.mode + " integer, "
+            + BeanPropEnum.ConfigPara.devphyid + " char(8), "
+            + BeanPropEnum.ConfigPara.psamno + " char(12), "
+            + BeanPropEnum.ConfigPara.epayIP + " varchar(128), "
+            + BeanPropEnum.ConfigPara.epayPort + " integer, "
+            + BeanPropEnum.ConfigPara.epayUri + " varchar(128), "
+            + BeanPropEnum.ConfigPara.managePwd + " char(6),"
+            + BeanPropEnum.ConfigPara.initOK + " integer ) ")
+    private val DROP_TABLE_NAME_CONFIGPARA = "DROP TABLE IF EXISTS $TABLE_NAME_CONFIGPARA"
+
+    private val lock = ReentrantLock()
+    fun getLock(): Lock {
+        return lock
+    }
+
+    override fun onCreate(db: SQLiteDatabase) {
+        db.execSQL(CREATE_TABLE_NAME_CONFIGPARA)
+    }
+
+    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
+        if (oldVersion < newVersion) {
+        }
+    }
+}
\ 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
new file mode 100644
index 0000000..17c542a
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/DBParaHelper.kt
@@ -0,0 +1,100 @@
+package com.supwisdom.db
+
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import android.database.sqlite.SQLiteOpenHelper
+import java.util.concurrent.locks.Lock
+import java.util.concurrent.locks.ReentrantLock
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class DBParaHelper private constructor(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, VERSION) {
+    companion object {
+        private val DB_NAME = "db_para"
+        private val VERSION = 1
+
+        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 {
+            if (null == instance) {
+                synchronized(DBParaHelper::class.java) {
+                    if (null == instance) {
+                        instance = DBParaHelper(context)
+                    }
+                }
+            }
+            return instance!!
+        }
+    }
+
+
+    /**
+     * 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 + " ( "
+            + BeanPropEnum.ControlPara.paraname + " varchar(64) primary key,"
+            + BeanPropEnum.ControlPara.paraval + " varchar(64) )")
+    private val CREATE_TABLE_NAME_DYNAMICPARA = ("create table IF NOT EXISTS "
+            + TABLE_NAME_DYNAMICPARA + " ( "
+            + BeanPropEnum.DynamicPara.id + " long primary key, "
+            + BeanPropEnum.DynamicPara.appid + " varchar(16), "
+            + BeanPropEnum.DynamicPara.appsecret + " varchar(128), "
+            + BeanPropEnum.DynamicPara.deviceid + " integer, "
+            + BeanPropEnum.DynamicPara.merchaccno + " integer, "
+            + BeanPropEnum.DynamicPara.shopname + " varchar(32), "
+            + BeanPropEnum.DynamicPara.onlineseqno + " integer, "
+            + BeanPropEnum.DynamicPara.offlineseqno + " integer, "
+            + BeanPropEnum.DynamicPara.paraverno + " integer, "
+            + BeanPropEnum.DynamicPara.paragroupid + " integer, "
+            + BeanPropEnum.DynamicPara.cardverno + " char(14),"
+            + BeanPropEnum.DynamicPara.jwt + " varchar(254),"
+            + BeanPropEnum.DynamicPara.token + " varchar(32) )")
+    private val DROP_TABLE_NAME_DYNAMICPARA = "DROP TABLE IF EXISTS $TABLE_NAME_DYNAMICPARA"
+    private val CREATE_TABLE_NAME_SYSPARA = ("create table IF NOT EXISTS "
+            + TABLE_NAME_SYSPARA + " ( "
+            + BeanPropEnum.Syspara.id + " long primary key, "
+            + BeanPropEnum.Syspara.returnFlag + " integer, "
+            + BeanPropEnum.Syspara.heatBeat + " integer, "
+            + BeanPropEnum.Syspara.offlineEnable + " integer, "
+            + BeanPropEnum.Syspara.maxOfflineDays + " integer, "
+            + BeanPropEnum.Syspara.mngpasswd + " char(6), "
+            + BeanPropEnum.Syspara.fixpayGap + " integer, "
+            + BeanPropEnum.Syspara.consumeShowtime + " integer, "
+            + BeanPropEnum.Syspara.consumeFailShowtime + " integer, "
+            + BeanPropEnum.Syspara.commTime + " integer )")
+    private val DROP_TABLE_NAME_SYSPARA = "DROP TABLE IF EXISTS $TABLE_NAME_SYSPARA"
+
+    private val lock = ReentrantLock()
+    fun getLock(): Lock {
+        return lock
+    }
+
+    override fun onCreate(db: SQLiteDatabase) {
+        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) {
+        if (oldVersion < newVersion) {
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/DBTransdtlHelper.kt b/app/src/main/java/com/supwisdom/db/DBTransdtlHelper.kt
new file mode 100644
index 0000000..aadfb8d
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/DBTransdtlHelper.kt
@@ -0,0 +1,88 @@
+package com.supwisdom.db
+
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import android.database.sqlite.SQLiteOpenHelper
+import java.util.concurrent.locks.Lock
+import java.util.concurrent.locks.ReentrantLock
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class DBTransdtlHelper private constructor(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, VERSION) {
+    companion object {
+        private val DB_NAME = "db_transdtl"
+        private val VERSION = 1
+        private var instance: DBTransdtlHelper? = null
+
+        const val TABLE_NAME_DTL_ONLINE = "tb_dtl_online"
+        const val TABLE_NAME_DTL_OFFLINE = "tb_dtl_offline"
+
+        fun getInstance(context: Context): DBTransdtlHelper {
+            if (null == instance) {
+                synchronized(DBTransdtlHelper::class.java) {
+                    if (null == instance) {
+                        instance = DBTransdtlHelper(context)
+                    }
+                }
+            }
+            return instance!!
+        }
+    }
+
+    /**
+     * SQL for create table
+     */
+    private val CRAETE_TABLE_NAME_DTL_ONLINE = ("create table IF NOT EXISTS "
+            + TABLE_NAME_DTL_ONLINE + " ( "
+            + BeanPropEnum.TransdtlOnline.devphyid + " char(8),"
+            + BeanPropEnum.TransdtlOnline.transdate + " char(8),"
+            + BeanPropEnum.TransdtlOnline.transtime + " char(6),"
+            + BeanPropEnum.TransdtlOnline.devseqno + " long primary key,"
+            + BeanPropEnum.TransdtlOnline.cardno + " varchar(32),"
+            + BeanPropEnum.TransdtlOnline.cardphyid + " varchar(32),"
+            + BeanPropEnum.TransdtlOnline.qrcode + " varchar(254),"
+            + BeanPropEnum.TransdtlOnline.transtype + " varchar(8),"
+            + BeanPropEnum.TransdtlOnline.payamt + " integer,"
+            + BeanPropEnum.TransdtlOnline.extraamt + " integer,"
+            + BeanPropEnum.TransdtlOnline.balance + " integer,"
+            + BeanPropEnum.TransdtlOnline.managefeetype + " varchar(10),"
+            + BeanPropEnum.TransdtlOnline.username + " varchar(32),"
+            + BeanPropEnum.TransdtlOnline.billno + " varchar(32),"
+            + BeanPropEnum.TransdtlOnline.reversalflag + " varchar(8),"
+            + BeanPropEnum.TransdtlOnline.reversalbillno + " varchar(32),"
+            + BeanPropEnum.TransdtlOnline.status + " varchar(8),"
+            + BeanPropEnum.TransdtlOnline.upflag + " integer )")
+    private val CRAETE_TABLE_NAME_DTL_OFFLINE = ("create table IF NOT EXISTS "
+            + TABLE_NAME_DTL_OFFLINE + " ( "
+            + BeanPropEnum.TransdtlOffline.devphyid + " char(8),"
+            + BeanPropEnum.TransdtlOffline.transdate + " char(8),"
+            + BeanPropEnum.TransdtlOffline.transtime + " char(6),"
+            + BeanPropEnum.TransdtlOffline.devseqno + " long primary key,"
+            + BeanPropEnum.TransdtlOffline.cardno + " varchar(32),"
+            + BeanPropEnum.TransdtlOffline.cardphyid + " varchar(32),"
+            + BeanPropEnum.TransdtlOffline.payamt + " integer,"
+            + BeanPropEnum.TransdtlOffline.extraamt + " integer,"
+            + BeanPropEnum.TransdtlOffline.reversalflag + " varchar(8),"
+            + BeanPropEnum.TransdtlOffline.reversalseqno + " integer,"
+            + BeanPropEnum.TransdtlOffline.reversaltransdate + " char(8),"
+            + BeanPropEnum.TransdtlOffline.reversaltranstime + " char(6),"
+            + BeanPropEnum.TransdtlOffline.status + " varchar(8),"
+            + BeanPropEnum.TransdtlOffline.upflag + " integer )")
+
+    private val lock = ReentrantLock()
+    fun getLock(): Lock {
+        return lock
+    }
+
+    override fun onCreate(db: SQLiteDatabase) {
+        db.execSQL(CRAETE_TABLE_NAME_DTL_ONLINE)
+        db.execSQL(CRAETE_TABLE_NAME_DTL_OFFLINE)
+    }
+
+    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
+        if (oldVersion < newVersion) {
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/DynamicParaDao.kt b/app/src/main/java/com/supwisdom/db/DynamicParaDao.kt
new file mode 100644
index 0000000..20ab20d
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/DynamicParaDao.kt
@@ -0,0 +1,117 @@
+package com.supwisdom.db
+
+import android.content.ContentValues
+import android.content.Context
+import android.database.Cursor
+import com.supwisdom.entity.DynamicParaRecord
+import java.util.concurrent.locks.Lock
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class DynamicParaDao constructor(context: Context) {
+    private val INDEX = "1" // 主键
+    private val dbHelper = DBParaHelper.getInstance(context)
+    private val TABLE = DBParaHelper.TABLE_NAME_DYNAMICPARA
+
+    fun getLock(): Lock {
+        return dbHelper.getLock()
+    }
+
+    fun replace(record: DynamicParaRecord): Boolean {
+        val db = dbHelper.readableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.replace(TABLE, null, values) > 0) {
+                db.setTransactionSuccessful()
+                return true
+            }
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun update(record: DynamicParaRecord): Boolean {
+        val db = dbHelper.writableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.update(TABLE, values, BeanPropEnum.DynamicPara.id.toString() + "=?", arrayOf(INDEX)) > 0) {
+                db.setTransactionSuccessful()
+                return true
+            }
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun get(): DynamicParaRecord? {
+        val db = dbHelper.readableDatabase
+        var cursor: Cursor? = null
+        try {
+            cursor = db.query(
+                TABLE, null, BeanPropEnum.DynamicPara.id.toString() + "=?",
+                arrayOf(INDEX), 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): DynamicParaRecord {
+        val record = DynamicParaRecord()
+        record.appid = cursor.getString(cursor.getColumnIndex(BeanPropEnum.DynamicPara.appid.toString()))
+        record.appsecret = cursor.getString(cursor.getColumnIndex(BeanPropEnum.DynamicPara.appsecret.toString()))
+        record.deviceid = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.DynamicPara.deviceid.toString()))
+        record.merchaccno = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.DynamicPara.merchaccno.toString()))
+        record.shopname = cursor.getString(cursor.getColumnIndex(BeanPropEnum.DynamicPara.shopname.toString()))
+        record.onlineseqno = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.DynamicPara.onlineseqno.toString()))
+        record.offlineseqno = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.DynamicPara.offlineseqno.toString()))
+        record.paraverno = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.DynamicPara.paraverno.toString()))
+        record.paragroupid = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.DynamicPara.paragroupid.toString()))
+        record.cardverno = cursor.getString(cursor.getColumnIndex(BeanPropEnum.DynamicPara.cardverno.toString()))
+        record.jwt = cursor.getString(cursor.getColumnIndex(BeanPropEnum.DynamicPara.jwt.toString()))
+        record.token = cursor.getString(cursor.getColumnIndex(BeanPropEnum.DynamicPara.token.toString()))
+        return record
+    }
+
+    private fun getContentValues(record: DynamicParaRecord): ContentValues {
+        val values = ContentValues()
+        values.put(BeanPropEnum.DynamicPara.id.toString(), INDEX)
+        values.put(BeanPropEnum.DynamicPara.appid.toString(), record.appid)
+        values.put(BeanPropEnum.DynamicPara.appsecret.toString(), record.appsecret)
+        values.put(BeanPropEnum.DynamicPara.deviceid.toString(), record.deviceid)
+        values.put(BeanPropEnum.DynamicPara.merchaccno.toString(), record.merchaccno)
+        values.put(BeanPropEnum.DynamicPara.shopname.toString(), record.shopname)
+        values.put(BeanPropEnum.DynamicPara.onlineseqno.toString(), record.onlineseqno)
+        values.put(BeanPropEnum.DynamicPara.offlineseqno.toString(), record.offlineseqno)
+        values.put(BeanPropEnum.DynamicPara.paraverno.toString(), record.paraverno)
+        values.put(BeanPropEnum.DynamicPara.paragroupid.toString(), record.paragroupid)
+        values.put(BeanPropEnum.DynamicPara.cardverno.toString(), record.cardverno)
+        values.put(BeanPropEnum.DynamicPara.jwt.toString(), record.jwt)
+        values.put(BeanPropEnum.DynamicPara.token.toString(), record.token)
+        return values
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/Pos.kt b/app/src/main/java/com/supwisdom/db/Pos.kt
new file mode 100644
index 0000000..d03277b
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/Pos.kt
@@ -0,0 +1,262 @@
+package com.supwisdom.db
+
+import android.content.Context
+import com.supwisdom.entity.*
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class Pos constructor(context: Context) {
+    private val sdContext = SDContext(context)
+    private val configParaDao = ConfigParaDao(sdContext)
+    private var cfgRecord: ConfigParaRecord? = null
+    private val dynamicParaDao = DynamicParaDao(context)
+    private var dyRecord: DynamicParaRecord? = null
+    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 val transdtlUnionDao = TransdtlUnionDao(sdContext)
+    private var onlMaxSeqno = 0
+    private var offMaxSeqno = 0
+
+    init {
+    }
+
+    /**
+     * 设备参数
+     */
+    fun replaceConfigPara(record: ConfigParaRecord): Boolean {
+        try {
+            configParaDao.getLock().lock()
+            if (configParaDao.replace(record)) {
+                cfgRecord = record
+                return true
+            }
+        } finally {
+            configParaDao.getLock().unlock()
+        }
+        return false
+    }
+
+    fun getConfigPara(): ConfigParaRecord? {
+        if (cfgRecord == null) {
+            try {
+                configParaDao.getLock().lock()
+                cfgRecord = configParaDao.get()
+            } finally {
+                configParaDao.getLock().unlock()
+            }
+        }
+        return cfgRecord
+    }
+
+    fun replaceControlPara(record: ControlParaRecord): Boolean {
+        try {
+            controlParaDao.getLock().lock()
+            return controlParaDao.replace(record)
+        } finally {
+            controlParaDao.getLock().unlock()
+        }
+    }
+
+    fun replaceControlPara(paraname: String, paraval: String): Boolean {
+        try {
+            controlParaDao.getLock().lock()
+            return controlParaDao.replace(paraname, paraval)
+        } finally {
+            controlParaDao.getLock().unlock()
+        }
+    }
+
+    fun getControlPara(paraname: String): ControlParaRecord? {
+        try {
+            controlParaDao.getLock().lock()
+            return controlParaDao.get(paraname)
+        } finally {
+            controlParaDao.getLock().unlock()
+        }
+    }
+
+    fun replaceDynamicPara(record: DynamicParaRecord): Boolean {
+        try {
+            dynamicParaDao.getLock().lock()
+            if (dynamicParaDao.replace(record)) {
+                dyRecord = record
+                return true
+            }
+        } finally {
+            dynamicParaDao.getLock().unlock()
+        }
+        return false
+    }
+
+    fun getDynamicPara(): DynamicParaRecord? {
+        if (dyRecord == null) {
+            try {
+                dynamicParaDao.getLock().lock()
+                dyRecord = dynamicParaDao.get()
+            } finally {
+                dynamicParaDao.getLock().unlock()
+            }
+        }
+        return dyRecord
+    }
+
+    fun replaceSysPara(record: SysParaRecord): Boolean {
+        try {
+            sysParaDao.getLock().lock()
+            if (sysParaDao.replace(record)) {
+                sysRecord = record
+                return true
+            }
+        } finally {
+            sysParaDao.getLock().unlock()
+        }
+        return false
+    }
+
+    fun getSysPara(): SysParaRecord? {
+        if (sysRecord == null) {
+            try {
+                sysParaDao.getLock().lock()
+                sysRecord = sysParaDao.get()
+            } finally {
+                sysParaDao.getLock().unlock()
+            }
+        }
+        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()
+            return transdtlOnlineDao.getUnconfirm()
+        } finally {
+            transdtlOnlineDao.getLock().unlock()
+        }
+    }
+
+    fun saveTransdtlOnline(record: TransdtlOnlineRecord): Boolean {
+        try {
+            transdtlOnlineDao.getLock().lock()
+            return transdtlOnlineDao.save(record)
+        } finally {
+            transdtlOnlineDao.getLock().unlock()
+        }
+    }
+
+    fun updateTransdtlOnline(record: TransdtlOnlineRecord): Boolean {
+        try {
+            transdtlOnlineDao.getLock().lock()
+            return transdtlOnlineDao.update(record)
+        } finally {
+            transdtlOnlineDao.getLock().unlock()
+        }
+    }
+
+    fun clearTransdtlOnline(date: String): Boolean {
+        try {
+            transdtlOnlineDao.getLock().lock()
+            return transdtlOnlineDao.clear(date)
+        } finally {
+            transdtlOnlineDao.getLock().unlock()
+        }
+    }
+
+    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()
+            return transdtlOfflineDao.getUnconfirm()
+        } finally {
+            transdtlOfflineDao.getLock().unlock()
+        }
+    }
+
+    fun saveTransdtlOffline(record: TransdtlOfflineRecord): Boolean {
+        try {
+            transdtlOfflineDao.getLock().lock()
+            return transdtlOfflineDao.save(record)
+        } finally {
+            transdtlOfflineDao.getLock().unlock()
+        }
+    }
+
+    fun updateTransdtlOffline(record: TransdtlOfflineRecord): Boolean {
+        try {
+            transdtlOfflineDao.getLock().lock()
+            return transdtlOfflineDao.update(record)
+        } finally {
+            transdtlOfflineDao.getLock().unlock()
+        }
+    }
+
+    fun clearTransdtlOffline(date: String): Boolean {
+        try {
+            transdtlOfflineDao.getLock().lock()
+            return transdtlOfflineDao.clear(date)
+        } finally {
+            transdtlOfflineDao.getLock().unlock()
+        }
+    }
+
+    /**
+     * @param date yyyyMMdd
+     * @param offset 流水偏移量
+     * @param flag 0--全部流水 1--成功流水 2--失败流水
+     * @param num 查询数量
+     */
+    fun getTransdtlUnion(date: String, offset: Int, flag: Int, num: Int): List<TransdtlUnionRecord> {
+        try {
+            transdtlUnionDao.getLock().lock()
+            return transdtlUnionDao.get(date, offset, flag, num)
+        } finally {
+            transdtlUnionDao.getLock().unlock()
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/SDContext.kt b/app/src/main/java/com/supwisdom/db/SDContext.kt
new file mode 100644
index 0000000..1b870a6
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/SDContext.kt
@@ -0,0 +1,58 @@
+package com.supwisdom.db
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.database.DatabaseErrorHandler
+import android.database.sqlite.SQLiteDatabase
+import java.io.File
+import java.io.IOException
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class SDContext constructor(context: Context) : ContextWrapper(context) {
+    override fun getDatabasePath(name: String): File? {
+        if (android.os.Environment.MEDIA_MOUNTED == android.os.Environment.getExternalStorageState()) {
+            //获取sd卡路径
+            var dbDir = android.os.Environment.getExternalStorageDirectory().absolutePath
+            dbDir += "/supwisdom"//数据库所在目录
+            val dbPath = "$dbDir/$name"//数据库路径
+            //判断目录是否存在,不存在则创建该目录
+            val dirFile = File(dbDir)
+            if (!dirFile.exists()) {
+                dirFile.mkdirs()
+            }
+            val dbFile = File(dbPath)
+            if (!dbFile.exists()) {
+                try {
+                    if (dbFile.createNewFile()) {
+                        return dbFile
+                    }
+                } catch (e: IOException) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace()
+                }
+            } else {
+                return dbFile
+            }
+        }
+        return null
+    }
+
+    override fun openOrCreateDatabase(
+        name: String, mode: Int,
+        factory: SQLiteDatabase.CursorFactory?
+    ): SQLiteDatabase {
+        val file = getDatabasePath(name) ?: return super.openOrCreateDatabase(name, mode, factory)
+        return SQLiteDatabase.openOrCreateDatabase(file, factory)
+    }
+
+    override fun openOrCreateDatabase(
+        name: String, mode: Int,
+        factory: SQLiteDatabase.CursorFactory?, errorHandler: DatabaseErrorHandler?
+    ): SQLiteDatabase {
+        val file = getDatabasePath(name) ?: return super.openOrCreateDatabase(name, mode, factory, errorHandler)
+        return SQLiteDatabase.openOrCreateDatabase(file, factory)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/SysParaDao.kt b/app/src/main/java/com/supwisdom/db/SysParaDao.kt
new file mode 100644
index 0000000..14872aa
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/SysParaDao.kt
@@ -0,0 +1,118 @@
+package com.supwisdom.db
+
+import android.content.ContentValues
+import android.content.Context
+import android.database.Cursor
+import com.supwisdom.entity.SysParaRecord
+import java.util.concurrent.locks.Lock
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class SysParaDao constructor(context: Context) {
+    private val INDEX = "1" // 主键
+    private val dbHelper = DBParaHelper.getInstance(context)
+    private val TABLE = DBParaHelper.TABLE_NAME_SYSPARA
+
+    fun getLock(): Lock {
+        return dbHelper.getLock()
+    }
+
+    fun replace(record: SysParaRecord): Boolean {
+        val db = dbHelper.readableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.replace(TABLE, null, values) > 0) {
+                db.setTransactionSuccessful()
+                return true
+            }
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun update(record: SysParaRecord): Boolean {
+        val db = dbHelper.writableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.update(TABLE, values, BeanPropEnum.Syspara.id.toString() + "=?", arrayOf(INDEX)) < 0) {
+                return false
+            }
+            db.setTransactionSuccessful()
+            return true
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun get(): SysParaRecord? {
+        val db = dbHelper.readableDatabase
+        var cursor: Cursor? = null
+        try {
+            cursor = db.query(
+                TABLE, null, BeanPropEnum.Syspara.id.toString() + "=?",
+                arrayOf(INDEX), 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): SysParaRecord {
+        val record = SysParaRecord()
+        record.returnFlag = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.returnFlag.toString()))
+        record.heatBeat = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.heatBeat.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()))
+        record.sucShowtime = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.consumeShowtime.toString()))
+        record.failShowtime =
+            cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.consumeFailShowtime.toString()))
+        record.commTime = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.Syspara.commTime.toString()))
+        return record
+    }
+
+    private fun getContentValues(record: SysParaRecord): ContentValues {
+        val values = ContentValues()
+        values.put(BeanPropEnum.Syspara.id.toString(), INDEX)
+        values.put(BeanPropEnum.Syspara.returnFlag.toString(), record.returnFlag)
+        values.put(BeanPropEnum.Syspara.heatBeat.toString(), record.heatBeat)
+        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)
+        values.put(BeanPropEnum.Syspara.consumeShowtime.toString(), record.sucShowtime)
+        values.put(BeanPropEnum.Syspara.consumeFailShowtime.toString(), record.failShowtime)
+        values.put(BeanPropEnum.Syspara.commTime.toString(), record.commTime)
+        return values
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/TransdtlOfflineDao.kt b/app/src/main/java/com/supwisdom/db/TransdtlOfflineDao.kt
new file mode 100644
index 0000000..20bcec1
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/TransdtlOfflineDao.kt
@@ -0,0 +1,172 @@
+package com.supwisdom.db
+
+import android.content.ContentValues
+import android.content.Context
+import android.database.Cursor
+import com.supwisdom.entity.PayStatus
+import com.supwisdom.entity.ReversalFlag
+import com.supwisdom.entity.TransdtlOfflineRecord
+import java.util.concurrent.locks.Lock
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class TransdtlOfflineDao constructor(context: Context) {
+    private val dbHelper = DBTransdtlHelper.getInstance(context)
+    private val TABLE = DBTransdtlHelper.TABLE_NAME_DTL_OFFLINE
+
+    fun getLock(): Lock {
+        return dbHelper.getLock()
+    }
+
+    fun save(record: TransdtlOfflineRecord): Boolean {
+        val db = dbHelper.readableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.replace(TABLE, null, values) > 0) {
+                db.setTransactionSuccessful()
+                return true
+            }
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun update(record: TransdtlOfflineRecord): Boolean {
+        val db = dbHelper.writableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.update(
+                    TABLE,
+                    values,
+                    BeanPropEnum.TransdtlOffline.devseqno.toString() + "=?",
+                    arrayOf(record.devseqno.toString())
+                ) > 0
+            ) {
+                db.setTransactionSuccessful()
+                return true
+            }
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun getUnconfirm(): List<TransdtlOfflineRecord> {
+        val db = dbHelper.readableDatabase
+        var cursor: Cursor? = null
+        val selection = BeanPropEnum.TransdtlOffline.upflag.toString() + "=?"
+        try {
+            cursor = db.query(TABLE, null, selection, arrayOf("0"), null, null, null)
+            val list = ArrayList<TransdtlOfflineRecord>()
+            while (cursor != null && cursor.moveToNext()) {
+                list.add(getRecord(cursor))
+            }
+            return list
+        } finally {
+            cursor?.close()
+        }
+    }
+
+    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 {
+            db.beginTransaction()
+            if (db.delete(TABLE, null, null) < 0) {
+                return false
+            }
+            db.setTransactionSuccessful()
+            return true
+        } finally {
+            db.endTransaction()
+        }
+    }
+
+    fun clear(date: String): Boolean {
+        val db = dbHelper.writableDatabase
+        val selection =
+            BeanPropEnum.TransdtlOffline.upflag.toString() + "=?" + BeanPropEnum.TransdtlOffline.transdate + "<?"
+        try {
+            db.beginTransaction()
+            if (db.delete(TABLE, selection, arrayOf("1", date)) < 0) {
+                return false
+            }
+            db.setTransactionSuccessful()
+            return true
+        } finally {
+            db.endTransaction()
+        }
+    }
+
+    private fun getRecord(cursor: Cursor): TransdtlOfflineRecord {
+        val record = TransdtlOfflineRecord()
+        record.devphyid = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.devphyid.toString()))
+        record.transdate = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.transdate.toString()))
+        record.transtime = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.transtime.toString()))
+        record.devseqno = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.devseqno.toString()))
+        record.cardno = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.cardno.toString()))
+        record.cardphyid = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.cardphyid.toString()))
+        record.payamt = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.payamt.toString()))
+        record.extraamt = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.extraamt.toString()))
+        var flag = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.reversalflag.toString()))
+        when (flag) {
+            ReversalFlag.NONE.toString() -> record.reversalflag = ReversalFlag.NONE
+            ReversalFlag.AUTO.toString() -> record.reversalflag = ReversalFlag.AUTO
+            ReversalFlag.MANUAL.toString() -> record.reversalflag = ReversalFlag.MANUAL
+            else -> record.reversalflag = ReversalFlag.NONE
+        }
+        record.reversalseqno =
+            cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.reversalseqno.toString()))
+        record.reversaltransdate =
+            cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.reversaltransdate.toString()))
+        record.reversaltranstime =
+            cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.reversaltranstime.toString()))
+        flag = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.status.toString()))
+        when (flag) {
+            PayStatus.INIT.toString() -> record.status = PayStatus.INIT
+            PayStatus.FAIL.toString() -> record.status = PayStatus.FAIL
+            PayStatus.SUC.toString() -> record.status = PayStatus.SUC
+            else -> record.status = PayStatus.INIT
+        }
+        record.upflag = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlOffline.upflag.toString()))
+        return record
+    }
+
+    private fun getContentValues(record: TransdtlOfflineRecord): ContentValues {
+        val values = ContentValues()
+        values.put(BeanPropEnum.TransdtlOffline.devphyid.toString(), record.devphyid)
+        values.put(BeanPropEnum.TransdtlOffline.transdate.toString(), record.transdate)
+        values.put(BeanPropEnum.TransdtlOffline.transtime.toString(), record.transtime)
+        values.put(BeanPropEnum.TransdtlOffline.devseqno.toString(), record.devseqno)
+        values.put(BeanPropEnum.TransdtlOffline.cardno.toString(), record.cardno)
+        values.put(BeanPropEnum.TransdtlOffline.cardphyid.toString(), record.cardphyid)
+        values.put(BeanPropEnum.TransdtlOffline.payamt.toString(), record.payamt)
+        values.put(BeanPropEnum.TransdtlOffline.extraamt.toString(), record.extraamt)
+        values.put(BeanPropEnum.TransdtlOffline.reversalflag.toString(), record.reversalflag.toString())
+        values.put(BeanPropEnum.TransdtlOffline.reversalseqno.toString(), record.reversalseqno)
+        values.put(BeanPropEnum.TransdtlOffline.reversaltransdate.toString(), record.reversaltransdate)
+        values.put(BeanPropEnum.TransdtlOffline.reversaltranstime.toString(), record.reversaltranstime)
+        values.put(BeanPropEnum.TransdtlOffline.status.toString(), record.status.toString())
+        values.put(BeanPropEnum.TransdtlOffline.upflag.toString(), record.upflag)
+        return values
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/TransdtlOnlineDao.kt b/app/src/main/java/com/supwisdom/db/TransdtlOnlineDao.kt
new file mode 100644
index 0000000..063c6e7
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/TransdtlOnlineDao.kt
@@ -0,0 +1,179 @@
+package com.supwisdom.db
+
+import android.content.ContentValues
+import android.content.Context
+import android.database.Cursor
+import com.supwisdom.entity.PayStatus
+import com.supwisdom.entity.ReversalFlag
+import com.supwisdom.entity.TransdtlOnlineRecord
+import java.util.concurrent.locks.Lock
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class TransdtlOnlineDao constructor(context: Context) {
+    private val dbHelper = DBTransdtlHelper.getInstance(context)
+    private val TABLE = DBTransdtlHelper.TABLE_NAME_DTL_ONLINE
+
+    fun getLock(): Lock {
+        return dbHelper.getLock()
+    }
+
+    fun save(record: TransdtlOnlineRecord): Boolean {
+        val db = dbHelper.readableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.replace(TABLE, null, values) > 0) {
+                db.setTransactionSuccessful()
+                return true
+            }
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun update(record: TransdtlOnlineRecord): Boolean {
+        val db = dbHelper.writableDatabase
+        val values = getContentValues(record)
+        try {
+            db.beginTransaction()
+            if (db.update(
+                    TABLE,
+                    values,
+                    BeanPropEnum.TransdtlOnline.devseqno.toString() + "=?",
+                    arrayOf(record.devseqno.toString())
+                ) > 0
+            ) {
+                db.setTransactionSuccessful()
+                return true
+            }
+        } finally {
+            db.endTransaction()
+        }
+        return false
+    }
+
+    fun getUnconfirm(): List<TransdtlOnlineRecord> {
+        val db = dbHelper.readableDatabase
+        var cursor: Cursor? = null
+        val selection = BeanPropEnum.TransdtlOnline.upflag.toString() + "=?"
+        try {
+            cursor = db.query(TABLE, null, selection, arrayOf("0"), null, null, null)
+            val list = ArrayList<TransdtlOnlineRecord>()
+            while (cursor != null && cursor.moveToNext()) {
+                list.add(getRecord(cursor))
+            }
+            return list
+        } finally {
+            cursor?.close()
+        }
+    }
+
+    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 {
+            db.beginTransaction()
+            if (db.delete(TABLE, null, null) < 0) {
+                return false
+            }
+            db.setTransactionSuccessful()
+            return true
+        } finally {
+            db.endTransaction()
+        }
+    }
+
+    fun clear(date: String): Boolean {
+        val db = dbHelper.writableDatabase
+        val selection =
+            BeanPropEnum.TransdtlOnline.upflag.toString() + "=?" + BeanPropEnum.TransdtlOnline.transdate + "<?"
+        try {
+            db.beginTransaction()
+            if (db.delete(TABLE, selection, arrayOf("1", date)) < 0) {
+                return false
+            }
+            db.setTransactionSuccessful()
+            return true
+        } finally {
+            db.endTransaction()
+        }
+    }
+
+    private fun getRecord(cursor: Cursor): TransdtlOnlineRecord {
+        val record = TransdtlOnlineRecord()
+        record.devphyid = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.devphyid.toString()))
+        record.transdate = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.transdate.toString()))
+        record.transtime = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.transtime.toString()))
+        record.devseqno = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.devseqno.toString()))
+        record.cardno = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.cardno.toString()))
+        record.cardphyid = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.cardphyid.toString()))
+        record.qrcode = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.qrcode.toString()))
+        record.transtype = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.transtype.toString()))
+        record.billno = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.billno.toString()))
+        record.managefeetype =
+            cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.managefeetype.toString()))
+        record.username = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.username.toString()))
+        record.payamt = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.payamt.toString()))
+        record.extraamt = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.extraamt.toString()))
+        record.balance = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.balance.toString()))
+        var flag = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.reversalflag.toString()))
+        when (flag) {
+            ReversalFlag.NONE.toString() -> record.reversalflag = ReversalFlag.NONE
+            ReversalFlag.AUTO.toString() -> record.reversalflag = ReversalFlag.AUTO
+            ReversalFlag.MANUAL.toString() -> record.reversalflag = ReversalFlag.MANUAL
+            else -> record.reversalflag = ReversalFlag.NONE
+        }
+        record.reversalbillno =
+            cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.reversalbillno.toString()))
+        flag = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.status.toString()))
+        when (flag) {
+            PayStatus.INIT.toString() -> record.status = PayStatus.INIT
+            PayStatus.FAIL.toString() -> record.status = PayStatus.FAIL
+            PayStatus.SUC.toString() -> record.status = PayStatus.SUC
+            else -> record.status = PayStatus.INIT
+        }
+        record.upflag = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlOnline.upflag.toString()))
+        return record
+    }
+
+    private fun getContentValues(record: TransdtlOnlineRecord): ContentValues {
+        val values = ContentValues()
+        values.put(BeanPropEnum.TransdtlOnline.devphyid.toString(), record.devphyid)
+        values.put(BeanPropEnum.TransdtlOnline.transdate.toString(), record.transdate)
+        values.put(BeanPropEnum.TransdtlOnline.transtime.toString(), record.transtime)
+        values.put(BeanPropEnum.TransdtlOnline.devseqno.toString(), record.devseqno)
+        values.put(BeanPropEnum.TransdtlOnline.cardno.toString(), record.cardno)
+        values.put(BeanPropEnum.TransdtlOnline.cardphyid.toString(), record.cardphyid)
+        values.put(BeanPropEnum.TransdtlOnline.qrcode.toString(), record.qrcode)
+        values.put(BeanPropEnum.TransdtlOnline.transtype.toString(), record.transtype)
+        values.put(BeanPropEnum.TransdtlOnline.payamt.toString(), record.payamt)
+        values.put(BeanPropEnum.TransdtlOnline.extraamt.toString(), record.extraamt)
+        values.put(BeanPropEnum.TransdtlOnline.balance.toString(), record.balance)
+        values.put(BeanPropEnum.TransdtlOnline.billno.toString(), record.billno)
+        values.put(BeanPropEnum.TransdtlOnline.managefeetype.toString(), record.managefeetype)
+        values.put(BeanPropEnum.TransdtlOnline.username.toString(), record.username)
+        values.put(BeanPropEnum.TransdtlOnline.reversalflag.toString(), record.reversalflag.toString())
+        values.put(BeanPropEnum.TransdtlOnline.reversalbillno.toString(), record.reversalbillno)
+        values.put(BeanPropEnum.TransdtlOnline.status.toString(), record.status.toString())
+        values.put(BeanPropEnum.TransdtlOnline.upflag.toString(), record.upflag)
+        return values
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/db/TransdtlUnionDao.kt b/app/src/main/java/com/supwisdom/db/TransdtlUnionDao.kt
new file mode 100644
index 0000000..78bae0c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/db/TransdtlUnionDao.kt
@@ -0,0 +1,118 @@
+package com.supwisdom.db
+
+import android.content.Context
+import android.database.Cursor
+import com.supwisdom.entity.PayStatus
+import com.supwisdom.entity.ReversalFlag
+import com.supwisdom.entity.TransdtlUnionRecord
+import java.util.concurrent.locks.Lock
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class TransdtlUnionDao constructor(context: Context) {
+    private val tablesql = StringBuilder()
+    private val dbHelper = DBTransdtlHelper.getInstance(context)
+
+    init {
+        tablesql.append("select ")
+            .append(BeanPropEnum.TransdtlOffline.transdate).append(",")
+            .append(BeanPropEnum.TransdtlOffline.transtime).append(",")
+            .append(BeanPropEnum.TransdtlOffline.devseqno).append(",")
+            .append(" 'offcard' as ").append(BeanPropEnum.TransdtlUnion.payway).append(",")
+            .append(BeanPropEnum.TransdtlOffline.reversalflag).append(",")
+            .append(BeanPropEnum.TransdtlOffline.payamt).append(",")
+            .append(BeanPropEnum.TransdtlOffline.status).append(",")
+            .append(BeanPropEnum.TransdtlOffline.cardno).append(" as ").append(BeanPropEnum.TransdtlUnion.username)
+            .append(",")
+            .append(BeanPropEnum.TransdtlOffline.upflag)
+            .append(" from ").append(DBTransdtlHelper.TABLE_NAME_DTL_OFFLINE)
+            .append(" UNION ALL select ")
+            .append(BeanPropEnum.TransdtlOnline.transdate).append(",")
+            .append(BeanPropEnum.TransdtlOnline.transtime).append(",")
+            .append(BeanPropEnum.TransdtlOnline.devseqno).append(",")
+            .append(BeanPropEnum.TransdtlOnline.transtype).append(" as ").append(BeanPropEnum.TransdtlUnion.payway)
+            .append(",")
+            .append(BeanPropEnum.TransdtlOnline.reversalflag).append(",")
+            .append(BeanPropEnum.TransdtlOnline.payamt).append(",")
+            .append(BeanPropEnum.TransdtlOnline.status).append(",")
+            .append(BeanPropEnum.TransdtlOnline.username).append(",")
+            .append(BeanPropEnum.TransdtlOnline.upflag)
+            .append(" from ").append(DBTransdtlHelper.TABLE_NAME_DTL_ONLINE)
+    }
+
+    fun getLock(): Lock {
+        return dbHelper.getLock()
+    }
+
+    fun get(date: String, offset: Int, flag: Int, num: Int): List<TransdtlUnionRecord> {
+        val db = dbHelper.readableDatabase
+        var cursor: Cursor? = null
+        var sql = when (flag) {
+            0 -> {
+                (tablesql.toString()
+                        + " where " + BeanPropEnum.TransdtlUnion.transdate + "='" + date
+                        + "' order by " + BeanPropEnum.TransdtlUnion.transtime
+                        + " desc ")
+            }
+            1 -> {
+                (tablesql.toString()
+                        + " where " + BeanPropEnum.TransdtlUnion.transdate + "='" + date
+                        + "' and " + BeanPropEnum.TransdtlUnion.status + "='"
+                        + PayStatus.SUC.toString()
+                        + "' order by " + BeanPropEnum.TransdtlUnion.transtime
+                        + " desc ")
+            }
+            else -> {
+                (tablesql.toString()
+                        + " where " + BeanPropEnum.TransdtlUnion.transdate + "='" + date
+                        + "' and " + BeanPropEnum.TransdtlUnion.status + "='"
+                        + PayStatus.FAIL.toString()
+                        + "' order by " + BeanPropEnum.TransdtlUnion.transtime
+                        + " desc ")
+            }
+        }
+        sql += if (offset > 0) {
+            " limit $num offset $offset"
+        } else {
+            " limit $num"
+        }
+        try {
+            cursor = db.rawQuery(sql, null)
+            val list = ArrayList<TransdtlUnionRecord>()
+            while (cursor != null && cursor.moveToNext()) {
+                list.add(getRecord(cursor))
+            }
+            return list
+        } finally {
+            cursor?.close()
+        }
+    }
+
+    private fun getRecord(cursor: Cursor): TransdtlUnionRecord {
+        val record = TransdtlUnionRecord()
+        record.transdate = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlUnion.transdate.toString()))
+        record.transtime = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlUnion.transtime.toString()))
+        record.devseqno = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlUnion.devseqno.toString()))
+        record.payway = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlUnion.payway.toString()))
+        record.username = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlUnion.username.toString()))
+        var flag = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlUnion.reversalflag.toString()))
+        when (flag) {
+            ReversalFlag.NONE.toString() -> record.reversalflag = ReversalFlag.NONE
+            ReversalFlag.AUTO.toString() -> record.reversalflag = ReversalFlag.AUTO
+            ReversalFlag.MANUAL.toString() -> record.reversalflag = ReversalFlag.MANUAL
+            else -> record.reversalflag = ReversalFlag.NONE
+        }
+        record.payamt = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlUnion.payamt.toString()))
+        flag = cursor.getString(cursor.getColumnIndex(BeanPropEnum.TransdtlUnion.status.toString()))
+        when (flag) {
+            PayStatus.INIT.toString() -> record.status = PayStatus.INIT
+            PayStatus.FAIL.toString() -> record.status = PayStatus.FAIL
+            PayStatus.SUC.toString() -> record.status = PayStatus.SUC
+            else -> record.status = PayStatus.INIT
+        }
+        record.upflag = cursor.getInt(cursor.getColumnIndex(BeanPropEnum.TransdtlUnion.upflag.toString()))
+        return record
+    }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..4b536ac
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/entity/ConfigParaRecord.kt
@@ -0,0 +1,16 @@
+package com.supwisdom.entity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc 本地配置参数
+ **/
+class ConfigParaRecord {
+    var mode: Int = 0//
+    var devphyid: String? = null
+    var epayIP: String? = null
+    var epayPort: Int = 0
+    var epayUri: String? = null
+    var shopPwd: String? = null //商户密码
+
+    var initOK: Boolean = false //是否初始化 true--未初始化,false--已初始化
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/entity/ControlParaRecord.kt b/app/src/main/java/com/supwisdom/entity/ControlParaRecord.kt
new file mode 100644
index 0000000..7e1ff12
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/entity/ControlParaRecord.kt
@@ -0,0 +1,19 @@
+package com.supwisdom.entity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc 本地控制参数
+ **/
+class ControlParaRecord {
+    constructor() {
+
+    }
+
+    constructor(paraname: String, paraval: String) {
+        this.paraname = paraname
+        this.paraval = paraval
+    }
+
+    var paraname: String? = null
+    var paraval: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/entity/DynamicParaRecord.kt b/app/src/main/java/com/supwisdom/entity/DynamicParaRecord.kt
new file mode 100644
index 0000000..bee1dbe
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/entity/DynamicParaRecord.kt
@@ -0,0 +1,21 @@
+package com.supwisdom.entity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc 后台动态参数
+ **/
+class DynamicParaRecord {
+    var appid: String? = null
+    var appsecret: String? = null
+    var deviceid: Int = 0 // 设备ID
+    var merchaccno: Int = 0 //商户号
+    var shopname: String? = null //商户名
+    var paraverno: Int = 0//参数版本
+    var paragroupid: Int = 0//参数组id
+    var onlineseqno: Int = 0 //后台最大联机流水号
+    var offlineseqno: Int = 0 //后台最大离线流水号
+    var cardverno: String? = null // 黑名单版本号 12byte
+    var jwt: String? = null
+    var token: String? = null
+    var jwtExpire: String? = null //jwt有效期 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
new file mode 100644
index 0000000..65e1640
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/entity/SysParaRecord.kt
@@ -0,0 +1,20 @@
+package com.supwisdom.entity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc 后台系统参数
+ **/
+class SysParaRecord {
+    var returnFlag: Int = 0// 消费撤销开关  0bit -0x1表示冲正使能
+    var heatBeat: Int = 0// 心跳间隔
+    var offlineEnable: Boolean = false // 脱机消费时限开关  false-关闭, true-开启
+    var maxOfflineDays: Int = 0// 最大脱机天数
+    var mngPasswd: String? = null// 维护密码
+    var sucShowtime: Int = 0// 消费成功显示时间
+    var failShowtime: Int = 0 //消费失败显示时间
+    var commTime: Int = 0   //通讯超时时间 默认2s
+    /**
+     * 定额消费同卡消费间隔(s)
+     */
+    var fixpayGap: Int = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/entity/TransdtlOfflineRecord.kt b/app/src/main/java/com/supwisdom/entity/TransdtlOfflineRecord.kt
new file mode 100644
index 0000000..ea0e3b4
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/entity/TransdtlOfflineRecord.kt
@@ -0,0 +1,23 @@
+package com.supwisdom.entity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc 离线流水
+ **/
+class TransdtlOfflineRecord {
+    var devphyid: String? = null
+    var transdate: String? = null
+    var transtime: String? = null
+    var devseqno: Int = 0
+    var cardno: String? = null
+    var cardphyid: String? = null
+    var payamt: Int = 0
+    var extraamt: Int = 0
+    var managefeetype: String? = null // none,discount,mealer
+    var reversalflag: ReversalFlag? = null //消费none 手动撤销 manual
+    var reversalseqno: Int = 0 //被冲正流水号
+    var reversaltransdate: String? = null //被冲正流水日期
+    var reversaltranstime: String? = null  //被冲正流水时间
+    var status: PayStatus? = null // init,fail,suc
+    var upflag: Int = 0 // 1已上传
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/entity/TransdtlOnlineRecord.kt b/app/src/main/java/com/supwisdom/entity/TransdtlOnlineRecord.kt
new file mode 100644
index 0000000..97cfa84
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/entity/TransdtlOnlineRecord.kt
@@ -0,0 +1,27 @@
+package com.supwisdom.entity
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc 联机流水
+ **/
+class TransdtlOnlineRecord {
+    var devphyid: String? = null
+    var transdate: String? = null
+    var transtime: String? = null
+    var devseqno: Int = 0
+    var cardno: String? = null
+    var cardphyid: String? = null
+    var qrcode: String? = null
+    var transtype: String? = null //card,code
+    var payamt: Int = 0
+    var extraamt: Int = 0
+    var managefeetype: String? = null // none,discount,mealer
+    var balance: Int? = null
+    var username: String? = null
+    //    var userid: Int = 0
+    var billno: String? = null
+    var reversalflag: ReversalFlag? = null //消费none 自动冲正auto 手动撤销 manual
+    var reversalbillno: String? = null //被冲正交易参考号
+    var status: PayStatus? = null // init,fail,suc
+    var upflag: Int = 0 // 1已上传
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/entity/TransdtlUnionRecord.kt b/app/src/main/java/com/supwisdom/entity/TransdtlUnionRecord.kt
new file mode 100644
index 0000000..bc78c6f
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/entity/TransdtlUnionRecord.kt
@@ -0,0 +1,39 @@
+package com.supwisdom.entity
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class TransdtlUnionRecord {
+    var username: String? = null
+    var transdate: String? = null
+    var transtime: String? = null
+    var devseqno: Int = 0
+    var payway: String? = null //card,code,offcard
+    var reversalflag: ReversalFlag? = null //消费none 自动冲正auto 手动撤销 manual
+    var payamt: Int = 0
+    var status: PayStatus? = null // init,fail,suc
+    var upflag: Int = 0
+}
+
+/**
+ * NONE -- 正常消费
+ * AUTO -- 自动冲正
+ * MANUAL -- 手动撤销
+ */
+enum class ReversalFlag {
+    NONE,
+    AUTO,
+    MANUAL
+}
+
+/**
+ * INIT -- 初始化
+ * FAIL -- 支付失败
+ * SUC --支付成功
+ */
+enum class PayStatus {
+    INIT,
+    FAIL,
+    SUC
+}
\ No newline at end of file
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..c43d6d8
--- /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(39, 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..86f0b47
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/epaycard/EpayCardlib.kt
@@ -0,0 +1,49 @@
+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()
+    private var hasInit = false
+
+    @Throws(CardlibInitError::class)
+    fun init() {
+        if (!hasInit) {
+            reader.init()
+            hasInit = true
+        }
+    }
+
+    @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("00B0950047".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/AuthEpayError.kt b/app/src/main/java/com/supwisdom/exception/AuthEpayError.kt
new file mode 100644
index 0000000..70cab0a
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/AuthEpayError.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/29
+ ** @desc
+ **/
+class AuthEpayError : Exception {
+    constructor(message: String, ex: Exception) : super(message + ex.message)
+
+    constructor(message: String) : super(message)
+
+    constructor(ex: Exception) : super(ex.message)
+}
\ 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..151ec03
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/CardNotFoundError.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardNotFoundError : Exception {
+    constructor(message: String, ex: Exception) : super(message + ex.message)
+
+    constructor(message: String) : super(message)
+
+    constructor(ex: Exception) : super(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..5c34275
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/CardPayCancelFailError.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardPayCancelFailError : Exception {
+    constructor(message: String, ex: Exception) : super(message + ex.message)
+
+    constructor(message: String) : super(message)
+
+    constructor(ex: Exception) : super(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..82e3c07
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/CardPayFailError.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardPayFailError : Exception {
+    constructor(message: String, ex: Exception) : super(message + ex.message)
+
+    constructor(message: String) : super(message)
+
+    constructor(ex: Exception) : super(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..188df3b
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/CardlibInitError.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardlibInitError : Exception {
+    constructor(message: String, ex: Exception) : super(message + ex.message)
+
+    constructor(message: String) : super(message)
+
+    constructor(ex: Exception) : super(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..09e239e
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/CardlibValueError.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/25
+ ** @desc
+ **/
+class CardlibValueError : Exception {
+    constructor(message: String, ex: Exception) : super(message + ex.message)
+
+    constructor(message: String) : super(message)
+
+    constructor(ex: Exception) : super(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..dcaa874
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/HeartBeatError.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class HeartBeatError : Exception {
+    constructor(message: String, ex: Exception) : super(message + ex.message)
+
+    constructor(message: String) : super(message)
+
+    constructor(ex: Exception) : super(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..1cdceb3
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/SysParaError.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class SysParaError : Exception {
+    constructor(message: String, ex: Exception) : super(message + ex.message)
+
+    constructor(message: String) : super(message)
+
+    constructor(ex: Exception) : super(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..ce3e7ef
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/TransdtlUploadError.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class TransdtlUploadError : Exception {
+    constructor(message: String, ex: Exception) : super(message + ex.message)
+
+    constructor(message: String) : super(message)
+
+    constructor(ex: Exception) : super(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..9c9033a
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/exception/WhiteListError.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.exception
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class WhiteListError : Exception {
+    constructor(message: String, ex: Exception) : super(message + ex.message)
+
+    constructor(message: String) : super(message)
+
+    constructor(ex: Exception) : super(ex.message)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/okhttp/ICallBackok.kt b/app/src/main/java/com/supwisdom/okhttp/ICallBackok.kt
new file mode 100644
index 0000000..0620933
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/okhttp/ICallBackok.kt
@@ -0,0 +1,9 @@
+package com.supwisdom.okhttp
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+interface ICallBackok<T> {
+    fun callback(t: T)
+}
diff --git a/app/src/main/java/com/supwisdom/okhttp/NetworkHandler.kt b/app/src/main/java/com/supwisdom/okhttp/NetworkHandler.kt
new file mode 100644
index 0000000..bf93d9b
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/okhttp/NetworkHandler.kt
@@ -0,0 +1,278 @@
+package com.supwisdom.okhttp
+
+import android.text.TextUtils
+import okhttp3.*
+import java.io.IOException
+import java.io.UnsupportedEncodingException
+import java.security.SecureRandom
+import java.security.cert.CertificateException
+import java.security.cert.X509Certificate
+import java.util.concurrent.TimeUnit
+import javax.net.ssl.*
+import com.supwisdom.okhttp.ICallBackok as ICallBack1
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+@Suppress("DEPRECATION")
+class NetworkHandler private constructor() {
+    companion object {
+        private var instance: NetworkHandler? = null
+        fun getInstance(): NetworkHandler {
+            if (instance == null) {
+                synchronized(NetworkHandler::class.java) {
+                    if (instance == null) {
+                        instance = NetworkHandler()
+                    }
+                }
+            }
+            return instance!!
+        }
+    }
+
+    private var client: OkHttpClient? = null
+    private var clientLong: OkHttpClient
+    private val JSON = MediaType.parse("application/json; charset=utf-8")
+    private val FORM_ENCODE = MediaType.parse("application/x-www-form-urlencoded;charset=utf-8")
+    private var commTime = 2
+    private var clientId: String? = null
+    private var jwt: String? = null
+
+    init {
+        client = OkHttpClient()
+            .newBuilder()
+            .retryOnConnectionFailure(false)
+            .readTimeout(commTime.toLong(), TimeUnit.SECONDS)
+            .writeTimeout(1, TimeUnit.SECONDS)
+            .connectTimeout(commTime.toLong(), TimeUnit.SECONDS)
+            .hostnameVerifier(TrustAllHostnameVerifier())
+            .sslSocketFactory(createSSLSocketFactory()!!)
+            .build()
+        clientLong = OkHttpClient()
+            .newBuilder()
+            .retryOnConnectionFailure(false)
+            .readTimeout(35, TimeUnit.SECONDS)
+            .writeTimeout(1, TimeUnit.SECONDS)
+            .connectTimeout(3, TimeUnit.SECONDS)
+            .hostnameVerifier(TrustAllHostnameVerifier())
+            .sslSocketFactory(createSSLSocketFactory())
+            .build()
+
+    }
+
+    fun setCommTime(communicateTime: Int) {
+        if (communicateTime != 0 && commTime != communicateTime) {
+            this.commTime = communicateTime
+            client = OkHttpClient()
+                .newBuilder()
+                .retryOnConnectionFailure(false)
+                .readTimeout(commTime.toLong(), TimeUnit.SECONDS)
+                .writeTimeout(1, TimeUnit.SECONDS)
+                .connectTimeout(commTime.toLong(), TimeUnit.SECONDS)
+                .hostnameVerifier(TrustAllHostnameVerifier())
+                .sslSocketFactory(createSSLSocketFactory())
+                .build()
+        }
+    }
+
+    fun setClientId(clientId: String?) {
+        this.clientId = clientId
+    }
+
+    fun setJwt(jwt: String?) {
+        if (TextUtils.isEmpty(jwt)) {
+            this.jwt = jwt
+        } else {
+            this.jwt = "Bearer $jwt"
+        }
+    }
+
+    private class TrustAllCerts : X509TrustManager {
+        @Throws(CertificateException::class)
+        override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
+        }
+
+        @Throws(CertificateException::class)
+        override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
+        }
+
+        override fun getAcceptedIssuers(): Array<X509Certificate> {
+            return arrayOf<X509Certificate>()
+        }
+    }
+
+    private class TrustAllHostnameVerifier : HostnameVerifier {
+        override fun verify(hostname: String, session: SSLSession): Boolean {
+            return true
+        }
+    }
+
+    private fun createSSLSocketFactory(): SSLSocketFactory? {
+        var ssfFactory: SSLSocketFactory? = null
+        try {
+            val sc = SSLContext.getInstance("TLS")
+            sc.init(null, arrayOf<TrustManager>(TrustAllCerts()), SecureRandom())
+            ssfFactory = sc.socketFactory
+        } catch (e: Exception) {
+        }
+
+        return ssfFactory
+    }
+
+    private fun addExtentHeader(request: Request.Builder): Request.Builder {
+        if (!TextUtils.isEmpty(clientId)) {
+            request.addHeader("X-TENANT-ID", clientId)
+        }
+        if (!TextUtils.isEmpty(jwt)) {
+            request.addHeader("Authorization", jwt)
+        }
+        return request
+    }
+
+    fun get(url: String, params: WebParams?): TransResp? {
+        val request = Request.Builder()
+            .url(geturl(url, params))
+            .addHeader("Accept", "application/json; q=0.5")
+            .addHeader("Connection", "close")
+        return getTransResp(addExtentHeader(request).build())
+    }
+
+    fun get(url: String, params: WebParams, callback: com.supwisdom.okhttp.ICallBackok<Any?>) {
+        val request = Request.Builder()
+            .url(geturl(url, params))
+            .addHeader("Accept", "application/json; q=0.5")
+            .addHeader("Connection", "close")
+        client!!.newCall(addExtentHeader(request).build()).enqueue(object : Callback {
+            override fun onFailure(call: Call, e: IOException) {
+                callback.callback(null)
+            }
+
+            override fun onResponse(call: Call, response: Response) {
+                try {
+                    val content = response.body()!!.string()
+                    val resp = TransResp(response.code(), response.message())
+                    if (response.isSuccessful) {
+                        resp.retjson = content
+                    }
+                    callback.callback(resp)
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                    callback.callback(null)
+                }
+
+            }
+        })
+    }
+
+    fun post(url: String, params: WebParams): TransResp? {
+        val builder = FormBody.Builder()
+        for (name in params.allParameterNames()) {
+            builder.add(name, params.getParameterString(name))
+        }
+        val request = Request.Builder()
+            .url(url)
+            .addHeader("Accept", "application/json; q=0.5")
+            .addHeader("Connection", "close")
+            .post(builder.build())
+        return getTransResp(addExtentHeader(request).build())
+    }
+
+    fun longPost(url: String, params: WebParams): TransResp? {
+        val builder = FormBody.Builder()
+        for (name in params.allParameterNames()) {
+            builder.add(name, params.getParameterString(name))
+        }
+        val request = Request.Builder()
+            .url(url)
+            .addHeader("Accept", "application/json; q=0.5")
+            .addHeader("Connection", "close")
+            .post(builder.build())
+        return getLongTransResp(addExtentHeader(request).build())
+    }
+
+    fun post(url: String, json: String): TransResp? {
+        val body = RequestBody.create(JSON, json)
+        val request = Request.Builder()
+            .url(url)
+            .addHeader("Accept", "application/json; q=0.5")
+            .addHeader("Connection", "close")
+            .post(body)
+        return getTransResp(addExtentHeader(request).build())
+    }
+
+    fun post(url: String, json: String, callback: com.supwisdom.okhttp.ICallBackok<Any?>) {
+        val body = RequestBody.create(JSON, json)
+        val request = Request.Builder()
+            .url(url)
+            .addHeader("Accept", "application/json; q=0.5")
+            .addHeader("Connection", "close")
+            .post(body)
+        client!!.newCall(addExtentHeader(request).build()).enqueue(object : Callback {
+            override fun onFailure(call: Call, e: IOException) {
+                callback.callback(null)
+            }
+
+            override fun onResponse(call: Call, response: Response) {
+                try {
+                    val content = response.body()!!.string()
+                    val resp = TransResp(response.code(), response.message())
+                    if (response.isSuccessful) {
+                        resp.retjson = content
+                    }
+                    callback.callback(resp)
+                } catch (e: Exception) {
+                    callback.callback(null)
+                }
+
+            }
+        })
+    }
+
+    private fun getLongTransResp(request: Request): TransResp? {
+        return try {
+            val response = clientLong.newCall(request).execute()
+            /*响应主体只能被消耗一次*/
+            val content = response.body()!!.string()
+            val resp = TransResp(response.code(), response.message())
+            if (response.isSuccessful) {
+                resp.retjson = content
+            }
+            resp
+        } catch (e: Exception) {
+            e.printStackTrace()
+            null
+        }
+
+    }
+
+    private fun getTransResp(request: Request): TransResp? {
+        return try {
+            val response = client!!.newCall(request).execute()
+            /*响应主体只能被消耗一次*/
+            val content = response.body()!!.string()
+            val resp = TransResp(response.code(), response.message())
+            if (response.isSuccessful) {
+                resp.retjson = content
+            }
+            resp
+        } catch (e: Exception) {
+            e.printStackTrace()
+            //通讯超时
+            null
+        }
+    }
+
+    private fun geturl(url: String, params: WebParams?): String {
+        val sb = StringBuilder()
+        sb.append(url)
+        if (params != null) {
+            try {
+                sb.append(params.encodeURL())
+            } catch (e: UnsupportedEncodingException) {
+                e.printStackTrace()
+            }
+        }
+        return sb.toString()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/okhttp/TransResp.kt b/app/src/main/java/com/supwisdom/okhttp/TransResp.kt
new file mode 100644
index 0000000..3215172
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/okhttp/TransResp.kt
@@ -0,0 +1,20 @@
+package com.supwisdom.okhttp
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class TransResp constructor(retcode: Int, retmsg: String?) {
+    /**
+     * HTTP返回码 retcode 200 success
+     */
+    var retcode: Int = retcode
+    /**
+     * retmsg 返回消息,如果是200 则为空,非200则为返回错误信息
+     */
+    var retmsg: String? = retmsg
+    /**
+     * 返回json信息
+     */
+    var retjson: String? = null
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/okhttp/WebAPISession.kt b/app/src/main/java/com/supwisdom/okhttp/WebAPISession.kt
new file mode 100644
index 0000000..b695ed2
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/okhttp/WebAPISession.kt
@@ -0,0 +1,40 @@
+package com.supwisdom.okhttp
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class WebAPISession : Cloneable {
+    /**
+     * appid,appsecret暂时写死在代码
+     */
+//    private val appId = PublicDef.APP_ID
+//    private val appSecret = PublicDef.APP_SECRET
+    private var termId = ""
+    private var epayurl = ""
+    private var sessionKey: String? = null
+
+    fun getEpayurl(): String {
+        return epayurl
+    }
+
+    fun setEpayurl(epayurl: String) {
+        this.epayurl = epayurl
+    }
+
+    @Throws(CloneNotSupportedException::class)
+    override fun clone(): Any {
+        val another = WebAPISession()
+        another.termId = this.termId
+        another.sessionKey = this.sessionKey
+        return another
+    }
+
+    fun getSessionKey(): String? {
+        return sessionKey
+    }
+
+    fun setSessionKey(sessionKey: String) {
+        this.sessionKey = sessionKey
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/okhttp/WebParams.kt b/app/src/main/java/com/supwisdom/okhttp/WebParams.kt
new file mode 100644
index 0000000..559123b
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/okhttp/WebParams.kt
@@ -0,0 +1,90 @@
+package com.supwisdom.okhttp
+
+import java.io.*
+import java.net.URLEncoder
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class WebParams {
+    private val mParameters = hashMapOf<String, Any?>()
+
+    fun setParameter(name: String, value: String?): WebParams {
+        mParameters[name] = value
+        return this
+    }
+
+    fun setParameter(name: String, value: Int?): WebParams {
+        mParameters[name] = value?.toString()
+        return this
+    }
+
+    fun setParameter(name: String, value: Float?): WebParams {
+        mParameters[name] = value?.toString()
+        return this
+    }
+
+    fun getParameterString(name: String): String {
+        val ret = mParameters[name]
+        if (String::class.java.isInstance(ret)) {
+            return ret as String
+        } else if (Int::class.java.isInstance(ret)) {
+            return ret.toString()
+        } else if (Double::class.java.isInstance(ret)) {
+            return ret.toString()
+        }
+        return ""
+    }
+
+    fun getParameterInt(name: String): Int {
+        val ret = mParameters[name]
+        return if (Int::class.java.isInstance(ret)) {
+            ret as Int
+        } else 0
+    }
+
+    fun getParameterFloat(name: String): Float {
+        val ret = mParameters[name]
+        return if (Float::class.java.isInstance(ret)) {
+            ret as Float
+        } else 0f
+    }
+
+    fun removeParameter(name: String) {
+        if (mParameters.containsKey(name)) {
+            mParameters.remove(name)
+        }
+    }
+
+    @Throws(UnsupportedEncodingException::class)
+    fun encodeURL(): String {
+        val result = StringBuilder()
+        for (name in mParameters.keys) {
+            val value = mParameters[name]
+            result.append(URLEncoder.encode(name, "utf-8"))
+                .append("=")
+                .append(URLEncoder.encode(value.toString(), "utf-8"))
+                .append("&")
+        }
+        return result.toString()
+    }
+
+    @Throws(IOException::class)
+    fun encodeURL(output: OutputStream): Int {
+        val byteStream = DataOutputStream(output)
+        val writer = OutputStreamWriter(byteStream, "utf-8")
+        for (name in mParameters.keys) {
+            val value = mParameters[name]
+            writer.write(URLEncoder.encode(name, "utf-8"))
+            writer.write("=")
+            writer.write(URLEncoder.encode(value.toString(), "utf-8"))
+            writer.write("&")
+        }
+        return byteStream.size()
+    }
+
+    fun allParameterNames(): Set<String> {
+        return mParameters.keys
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/service/APIInterface.kt b/app/src/main/java/com/supwisdom/service/APIInterface.kt
new file mode 100644
index 0000000..b24df22
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/service/APIInterface.kt
@@ -0,0 +1,22 @@
+package com.supwisdom.service
+
+import com.supwisdom.entity.TransdtlOfflineRecord
+import com.supwisdom.entity.TransdtlOnlineRecord
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+interface APIInterface {
+    fun heartBeat()
+
+    fun linkCheck()
+
+    fun downloadSyspara(paragroupid: Int, paraverno: Int)
+
+    fun downloadWhitelist(maxCardverno: String)
+
+    fun uploadTransdtl(record: TransdtlOnlineRecord)
+
+    fun uploadTransdtl(record: TransdtlOfflineRecord)
+}
\ 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
new file mode 100644
index 0000000..fc252ae
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/service/AuthEpay.kt
@@ -0,0 +1,150 @@
+package com.supwisdom.service
+
+import android.text.TextUtils
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.YktSession
+import com.supwisdom.bean.AuthJwtRetBean
+import com.supwisdom.bean.AuthRetBean
+import com.supwisdom.bean.AuthTokenRetBean
+import com.supwisdom.exception.AuthEpayError
+import com.supwisdom.okhttp.NetworkHandler
+import com.supwisdom.okhttp.WebParams
+import com.supwisdom.utils.CryptUtil
+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/23
+ ** @desc
+ **/
+class AuthEpay {
+    private val pos = SPApplication.getInstance().getPos()
+
+    @Throws(AuthEpayError::class)
+    fun login(): AuthRetBean {
+        val token = getAccessToken()
+        getAccessJwt(token)
+        return secureAuth()
+    }
+
+    @Throws(AuthEpayError::class)
+    fun refresh() {
+        val record = pos.getConfigPara()
+        val url = StringBuilder()
+        url.append(record!!.epayIP).append(":").append(record.epayPort)
+            .append("/").append(record.epayUri)
+            .append("/api/auth/refresh/").append(record.devphyid).append("?")
+        val resp = NetworkHandler.getInstance().get(url.toString(), null)
+            ?: throw AuthEpayError("jwt刷新请求超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            throw AuthEpayError("jwt刷新错误码=${resp.retcode}")
+        }
+        val retBean = try {
+            GsonUtil.GsonToBean(resp.retjson!!, AuthJwtRetBean::class.java)
+        } catch (ex: Exception) {
+            throw AuthEpayError("jwt json异常:${ex.message}")
+        }
+        dealSession(retBean)
+    }
+
+    private fun getAccessToken(): String {
+        val record = pos.getConfigPara()
+        val url = StringBuilder()
+        url.append(record!!.epayIP).append(":").append(record.epayPort)
+            .append("/").append(record.epayUri)
+            .append("/api/auth/gettoken/").append(record.devphyid).append("?")
+        val params = WebParams()
+        params.setParameter("appid", pos.getDynamicPara()!!.appid)
+
+        NetworkHandler.getInstance().setClientId(record.devphyid!!)
+        NetworkHandler.getInstance().setJwt(null)
+
+        val resp = NetworkHandler.getInstance().get(url.toString(), params)
+            ?: throw AuthEpayError("token请求超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            throw AuthEpayError("token错误码=${resp.retcode}")
+        }
+        val retBean = try {
+            GsonUtil.GsonToBean(resp.retjson!!, AuthTokenRetBean::class.java)
+        } catch (ex: Exception) {
+            throw AuthEpayError("token json异常:${ex.message}")
+        }
+        if (retBean.retcode != PublicDef.SUCCESS) {
+            throw AuthEpayError(retBean.retmsg!!)
+        }
+        if (TextUtils.isEmpty(retBean.token)) {
+            throw AuthEpayError("token不能为空")
+        }
+        return retBean.token!!
+    }
+
+    private fun getAccessJwt(token: String) {
+        val record = pos.getConfigPara()
+        val url = StringBuilder()
+        url.append(record!!.epayIP).append(":").append(record.epayPort)
+            .append("/").append(record.epayUri)
+            .append("/api/auth/authentication/").append(record.devphyid).append("?")
+
+        val secret = CryptUtil.HMACSHA256(pos.getDynamicPara()!!.appsecret!!, token)
+        val params = WebParams()
+        params.setParameter("appid", pos.getDynamicPara()!!.appid)
+            .setParameter("secret", secret)
+
+        val resp = NetworkHandler.getInstance().get(url.toString(), params)
+            ?: throw AuthEpayError("jwt请求超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            throw AuthEpayError("jwt错误码=${resp.retcode}")
+        }
+        val retBean = try {
+            GsonUtil.GsonToBean(resp.retjson!!, AuthJwtRetBean::class.java)
+        } catch (ex: Exception) {
+            throw AuthEpayError("jwt json异常:${ex.message}")
+        }
+        dealSession(retBean)
+    }
+
+    private fun secureAuth(): AuthRetBean {
+        val dyRecord = pos.getDynamicPara()
+        val cardverno = dyRecord!!.cardverno ?: "0"
+        val params = WebParams()
+        params.setParameter("devphyid", pos.getConfigPara()!!.devphyid)
+            .setParameter("termdate", DateUtil.getNowDateNoFormat())
+            .setParameter("termtime", DateUtil.getNowTimeNoFormat())
+            .setParameter("paragroupid", dyRecord.paragroupid)
+            .setParameter("cardverno", cardverno)
+
+        val resp = YktSession.getInstance().sendYktRequestPost("/api/pos/login", "", params)
+            ?: throw AuthEpayError("请求超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            throw AuthEpayError("错误码=${resp.retcode}")
+        }
+        val retBean = try {
+            GsonUtil.GsonToBean(resp.retjson!!, AuthRetBean::class.java)
+        } catch (ex: Exception) {
+            throw AuthEpayError("json异常:${ex.message}")
+        }
+        if (retBean.retcode != PublicDef.SUCCESS) {
+            throw AuthEpayError(retBean.retmsg!!)
+        }
+        return retBean
+    }
+
+    private fun dealSession(bean: AuthJwtRetBean) {
+        if (bean.retcode != PublicDef.SUCCESS) {
+            throw AuthEpayError(bean.retmsg!!)
+        }
+        if (TextUtils.isEmpty(bean.jwt)) {
+            throw AuthEpayError("jwt不能为空")
+        }
+        NetworkHandler.getInstance().setJwt(bean.jwt!!)
+
+        val dyRecord = pos.getDynamicPara()
+        dyRecord!!.jwt = bean.jwt
+        dyRecord.jwtExpire = DateUtil.utcToLocal(bean.expiredAt!!)
+        if (!pos.replaceDynamicPara(dyRecord)) {
+            throw AuthEpayError("保存参数失败")
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/service/BackgroundTaskService.kt b/app/src/main/java/com/supwisdom/service/BackgroundTaskService.kt
new file mode 100644
index 0000000..8a7c9f7
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/service/BackgroundTaskService.kt
@@ -0,0 +1,137 @@
+package com.supwisdom.service
+
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.entity.SysParaRecord
+import com.supwisdom.exception.AuthEpayError
+import com.supwisdom.exception.HeartBeatError
+import com.supwisdom.exception.TransdtlUploadError
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.utils.FileUtil
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+class BackgroundTaskService : Thread() {
+    private val pos = SPApplication.getInstance().getPos()
+    private val websocketProcess = WebsocketProcess()
+    private var websocketHasRun = false
+    private var apiInterface: APIInterface? = null
+    private var sysRecord: SysParaRecord? = null
+    private var transdtlClearDate: String? = null
+
+    fun getWebsocketProcess(): WebsocketProcess {
+        return websocketProcess
+    }
+
+    override fun run() {
+        var heartgap = 0
+        CommonUtil.doSleep(60 * 1000)
+        while (true) {
+            val hasInit = pos.getConfigPara()?.initOK ?: false
+            if (hasInit) {
+                break
+            }
+            CommonUtil.doSleep(1000)
+        }
+        while (true) {
+            //做一卡通心跳和流水上传
+            heartAndTransdtl()
+            //清除流水
+            clearTransdtl()
+            sysRecord = pos.getSysPara()
+//            if (sysRecord != null && sysRecord!!.getSocketSwitch() != 0) {
+//                if (!websocketHasRun) {
+//                    websocketHasRun = true
+//                    websocketProcess.start()
+//                }
+//            } else {
+//                if (websocketHasRun) {
+//                    websocketHasRun = false
+//                    websocketProcess.stop()
+//                }
+//            }
+            heartgap = if (sysRecord == null || sysRecord!!.heatBeat < 10 || sysRecord!!.heatBeat > 600) {
+                60
+            } else {
+                sysRecord!!.heatBeat
+            }
+            CommonUtil.doSleep(heartgap * 1000)
+        }
+    }
+
+    private fun heartAndTransdtl() {
+        //做一卡通的心跳以及流水上传
+        try {
+            apiInterface!!.heartBeat()
+            SPApplication.getInstance().setEpayLinking(true)
+//        /*更新通讯jwt*/
+            refreshJwt()
+            uploadTransdtl()
+        } catch (ex: HeartBeatError) {
+            SPApplication.getInstance().setEpayLinking(false)
+        }
+    }
+
+    private fun uploadTransdtl() {
+        try {
+            pos.getTransdtlOfflineUnconfirm().forEach {
+                apiInterface!!.uploadTransdtl(it)
+                it.upflag = 1
+                pos.updateTransdtlOffline(it)
+            }
+            pos.getTransdtlOnlineUnconfirm().forEach {
+                apiInterface!!.uploadTransdtl(it)
+                it.upflag = 1
+                pos.updateTransdtlOnline(it)
+            }
+        } catch (ex: TransdtlUploadError) {
+            ex.printStackTrace()
+        }
+    }
+
+    private fun refreshJwt() {
+        try {
+            val jwtExpire = pos.getDynamicPara()?.jwtExpire ?: "0"
+            if (jwtExpire < DateUtil.getNowDateTimeNoFormat()) {
+                autoAuth()
+            } else {
+                AuthEpay().refresh()
+            }
+            SPApplication.getInstance().setEpayLinking(true)
+        } catch (ex: AuthEpayError) {
+            ex.printStackTrace()
+            SPApplication.getInstance().setEpayLinking(false)
+        }
+    }
+
+    private fun autoAuth() {
+        val bean = AuthEpay().login()
+        val dyRecord = pos.getDynamicPara()
+        dyRecord!!.deviceid = bean.deviceid
+        dyRecord.merchaccno = bean.merchaccno
+        dyRecord.shopname = bean.shopname
+        dyRecord.onlineseqno = bean.onlineseqno
+        dyRecord.offlineseqno = bean.offlineseqno
+        dyRecord.paragroupid = bean.paragroupid
+        pos.replaceDynamicPara(dyRecord)
+    }
+
+    private fun clearTransdtl() {
+        val date = DateUtil.getDayDateNoFormatBefore(100)
+        if (date == transdtlClearDate) {
+            /*每天清除流水一次*/
+            return
+        }
+        pos.clearTransdtlOnline(date)
+        pos.clearTransdtlOffline(date)
+
+        transdtlClearDate = date
+
+        /*删除15天前的日志*/
+        FileUtil.removeLogFile(15)
+        FileUtil.removeCrashFile(15)
+        FileUtil.removeDtlFile(15)
+    }
+}
\ 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
new file mode 100644
index 0000000..517819d
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/service/EpayApiImpl.kt
@@ -0,0 +1,245 @@
+package com.supwisdom.service
+
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.activities.YktSession
+import com.supwisdom.bean.HeartBeatRetBean
+import com.supwisdom.bean.SystemParaRetBean
+import com.supwisdom.bean.TransdtlRetBean
+import com.supwisdom.bean.WhiteListRetBean
+import com.supwisdom.entity.*
+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
+import com.supwisdom.utils.GsonUtil
+import com.supwisdom.utils.PublicDef
+import org.apache.http.HttpStatus
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+class EpayApiImpl : APIInterface {
+    private val pos = SPApplication.getInstance().getPos()
+
+    @Throws(HeartBeatError::class)
+    override fun heartBeat() {
+        val dyRecord = pos.getDynamicPara()
+        val cardverno = dyRecord!!.cardverno ?: "0"
+        val params = WebParams()
+        params.setParameter("devphyid", pos.getConfigPara()!!.devphyid)
+            .setParameter("termdate", DateUtil.getNowDateNoFormat())
+            .setParameter("termtime", DateUtil.getNowTimeNoFormat())
+            .setParameter("paragroupid", dyRecord.paragroupid)
+            .setParameter("cardverno", cardverno)
+
+        val resp = YktSession.getInstance().sendYktRequestPost("/api/pos/heartbeat", "", params)
+            ?: throw HeartBeatError("请求超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            throw HeartBeatError("错误码=${resp.retcode}")
+        }
+        val retBean = try {
+            GsonUtil.GsonToBean(resp.retjson!!, HeartBeatRetBean::class.java)
+        } catch (ex: Exception) {
+            throw HeartBeatError("json异常:${ex.message}")
+        }
+        if (retBean.retcode != PublicDef.SUCCESS) {
+            throw HeartBeatError(retBean.retmsg!!)
+        }
+        if (cardverno < retBean.cardverno!!) {
+            try {
+                downloadWhitelist(retBean.cardverno!!)
+            } catch (ex: WhiteListError) {
+                throw HeartBeatError(ex.message ?: "null")
+            }
+        }
+        if (dyRecord.paraverno != retBean.paraverno) {
+            try {
+                downloadSyspara(retBean.paragroupid, retBean.paraverno)
+            } catch (ex: SysParaError) {
+                throw SysParaError(ex.message ?: "null")
+            }
+        }
+        /**
+         * 时钟校准
+         */
+        NtpClient().startCalibrateTime(retBean.systime!!)
+    }
+
+    @Throws(HeartBeatError::class)
+    override fun linkCheck() {
+        heartBeat()
+    }
+
+    @Throws(SysParaError::class)
+    override fun downloadSyspara(paragroupid: Int, paraverno: Int) {
+        val params = WebParams()
+        params.setParameter("devphyid", pos.getConfigPara()!!.devphyid)
+            .setParameter("termdate", DateUtil.getNowDateNoFormat())
+            .setParameter("termtime", DateUtil.getNowTimeNoFormat())
+            .setParameter("paragroupid", paragroupid)
+
+        val resp = YktSession.getInstance().sendYktRequestPost("/api/pos/systempara", "", params)
+            ?: throw SysParaError("请求超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            throw SysParaError("错误码=${resp.retcode}")
+        }
+        val retBean = try {
+            GsonUtil.GsonToBean(resp.retjson!!, SystemParaRetBean::class.java)
+        } catch (ex: Exception) {
+            throw SysParaError("json异常:${ex.message}")
+        }
+        if (retBean.retcode != PublicDef.SUCCESS) {
+            throw SysParaError(retBean.retmsg!!)
+        }
+        val record = pos.getSysPara() ?: SysParaRecord()
+        retBean.syspara?.forEach {
+            when {
+                it.paraname == "heat_beat" -> record.heatBeat = it.paraval!!.toInt()
+                it.paraname == "return_flag" -> record.returnFlag = it.paraval!!.toInt()
+                it.paraname == "consume_show_time" -> record.sucShowtime = it.paraval!!.toInt()
+                it.paraname == "consume_fail_show_time" -> record.failShowtime = it.paraval!!.toInt()
+                it.paraname == "fixpay_consume_gap" -> record.fixpayGap = it.paraval!!.toInt()
+                it.paraname == "manage_passwd" -> record.mngPasswd = it.paraval
+                it.paraname == "offline_flag" -> record.offlineEnable = it.paraval == "1"
+                it.paraname == "max_offline_days" -> record.maxOfflineDays = it.paraval!!.toInt()
+                it.paraname == "communicate_time" -> record.commTime = it.paraval!!.toInt()
+            }
+        }
+        if (!pos.replaceSysPara(record)) {
+            throw SysParaError("保存参数失败")
+        }
+    }
+
+    @Throws(WhiteListError::class)
+    override fun downloadWhitelist(maxCardverno: String) {
+        val maxcount = 20
+        do {
+            val params = WebParams()
+            params.setParameter("devphyid", pos.getConfigPara()!!.devphyid)
+                .setParameter("cardverno", pos.getDynamicPara()!!.cardverno)
+                .setParameter("maxcount", maxcount)
+
+            val resp = YktSession.getInstance().sendYktRequestPost("/api/pos/whitelist", "", params)
+                ?: throw WhiteListError("请求超时")
+            if (resp.retcode != HttpStatus.SC_OK) {
+                throw WhiteListError("错误码=${resp.retcode}")
+            }
+            val retBean = try {
+                GsonUtil.GsonToBean(resp.retjson!!, WhiteListRetBean::class.java)
+            } catch (ex: Exception) {
+                throw WhiteListError("json异常:${ex.message}")
+            }
+            if (retBean.retcode != PublicDef.SUCCESS) {
+                throw WhiteListError(retBean.retmsg!!)
+            }
+            if (retBean.count != retBean.whitelist?.size) {
+                throw WhiteListError("白名单数量不对[${retBean.count},${retBean.whitelist?.size}]")
+            }
+            val list = ArrayList<WhiteListRecord>()
+            retBean.whitelist?.forEach {
+                val record = WhiteListRecord()
+                record.cardphyid = it.cardphyid
+                record.cardno = it.cardno
+                record.flag = it.flag
+                record.balance = it.balance
+                list.add(record)
+            }
+            if (!pos.saveWhiteList(list)) {
+                throw WhiteListError("保存白名单失败")
+            }
+            val dyRecord = pos.getDynamicPara()
+            dyRecord!!.cardverno = retBean.cardverno
+            if (!pos.replaceDynamicPara(dyRecord)) {
+                throw WhiteListError("保存参数失败")
+            }
+        } while (retBean.count == maxcount)
+    }
+
+    @Throws(TransdtlUploadError::class)
+    override fun uploadTransdtl(record: TransdtlOnlineRecord) {
+        var reversalflag = "false"
+        if (record.reversalflag == ReversalFlag.AUTO ||
+            record.reversalflag == ReversalFlag.MANUAL
+        ) {
+            reversalflag = "true"
+        }
+
+        val params = WebParams()
+        params.setParameter("devphyid", record.devphyid)
+            .setParameter("transdate", record.transdate)
+            .setParameter("transtime", record.transtime)
+            .setParameter("termseqno", record.devseqno)
+            .setParameter("cardno", record.cardno)
+            .setParameter("cardphyid", record.cardphyid)
+            .setParameter("qrcode", record.qrcode)
+            .setParameter("transtype", record.transtype)
+            .setParameter("amount", record.payamt)
+            .setParameter("extraamt", record.extraamt)
+            .setParameter("managefeetype", record.managefeetype)
+            .setParameter("managefeetype", record.managefeetype)
+            .setParameter("billno", record.billno)
+            .setParameter("reversalflag", reversalflag)
+            .setParameter("status", record.status.toString())
+        val resp = YktSession.getInstance().sendYktRequestPost("/api/pos/paycancel", "", params)
+            ?: throw TransdtlUploadError("请求超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            throw TransdtlUploadError("错误码=${resp.retcode}")
+        }
+        val retBean = try {
+            GsonUtil.GsonToBean(resp.retjson!!, TransdtlRetBean::class.java)
+        } catch (ex: Exception) {
+            throw TransdtlUploadError("json异常:${ex.message}")
+        }
+        if (retBean.retcode != PublicDef.SUCCESS) {
+            throw TransdtlUploadError(retBean.retmsg!!)
+        }
+        if (retBean.termseqno != record.devseqno) {
+            throw TransdtlUploadError("返回流水号不一致")
+        }
+    }
+
+    @Throws(TransdtlUploadError::class)
+    override fun uploadTransdtl(record: TransdtlOfflineRecord) {
+        val params = WebParams()
+        var reversalflag = "false"
+        if (record.reversalflag == ReversalFlag.AUTO ||
+            record.reversalflag == ReversalFlag.MANUAL
+        ) {
+            reversalflag = "true"
+        }
+        params.setParameter("devphyid", record.devphyid)
+            .setParameter("termseqno", record.devseqno)
+            .setParameter("transdate", record.transdate)
+            .setParameter("transtime", record.transtime)
+            .setParameter("cardno", record.cardno)
+            .setParameter("cardphyid", record.cardphyid)
+            .setParameter("amount", record.payamt)
+            .setParameter("extraamt", record.extraamt)
+            .setParameter("managefeetype", record.managefeetype)
+            .setParameter("reversalflag", reversalflag)
+            .setParameter("reversaltermseqno", record.reversalseqno)
+            .setParameter("reversaltransdate", record.reversaltransdate)
+            .setParameter("reversaltransdate", record.reversaltranstime)
+            .setParameter("status", record.status.toString())
+
+        val resp = YktSession.getInstance().sendYktRequestPost("/api/pos/offlinetransdtl", "", params)
+            ?: throw TransdtlUploadError("请求超时")
+        if (resp.retcode != HttpStatus.SC_OK) {
+            throw TransdtlUploadError("错误码=${resp.retcode}")
+        }
+        val retBean = try {
+            GsonUtil.GsonToBean(resp.retjson!!, TransdtlRetBean::class.java)
+        } catch (ex: Exception) {
+            throw TransdtlUploadError("json异常:${ex.message}")
+        }
+        if (retBean.retcode != PublicDef.SUCCESS) {
+            throw TransdtlUploadError(retBean.retmsg!!)
+        }
+        if (retBean.termseqno != record.devseqno) {
+            throw TransdtlUploadError("返回流水号不一致")
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/service/NtpClient.kt b/app/src/main/java/com/supwisdom/service/NtpClient.kt
new file mode 100644
index 0000000..2e4f3f0
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/service/NtpClient.kt
@@ -0,0 +1,120 @@
+package com.supwisdom.service
+
+import android.os.SystemClock
+import com.supwisdom.utils.DateUtil
+import com.supwisdom.utils.ThreadPool
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class NtpClient {
+    private val NTP_TIME_OUT_MILLISECOND = 10000
+    /**
+     * 国内ntp服务器地址集
+     */
+    private val ntpServerHost = arrayOf("cn.pool.ntp.org", "tw.pool.ntp.org")
+    private var privatelServerHost: String? = null
+
+    fun setPrivatelServerHost(privatelServerHost: String) {
+        this.privatelServerHost = privatelServerHost
+    }
+
+    private fun getTimeFromNtpServer(ntpHost: String?): Long {
+        val client = SntpClient()
+        val isSuccessful = client.requestTime(ntpHost!!, NTP_TIME_OUT_MILLISECOND)
+        return if (isSuccessful) {
+            client.getNtpTime()
+        } else {
+            -1
+        }
+    }
+
+    /**
+     * @param synctime yyyyMMddHHmmss
+     */
+    fun startCalibrateTime(synctime: String) {
+        val time = DateUtil.dateFormatConvertToLong(synctime)
+        startCalibrateTime(time)
+    }
+
+    /**
+     * @param synctime ms
+     */
+    fun startCalibrateTime(synctime: Long) {
+        val localTime = System.currentTimeMillis()
+        if (synctime > 0) {
+            if (synctime > localTime && synctime - localTime > 60000) {
+                setCurrentTimeMillis(synctime)
+            } else if (localTime > synctime && localTime - synctime > 60000) {
+                setCurrentTimeMillis(synctime)
+            }
+        }
+    }
+
+    /**
+     * 开始校准时间
+     */
+    fun startCalibrateTime() {
+        ThreadPool.getShortPool().execute(Runnable {
+            /**
+             * 优先使用专网ntp服务器地址
+             */
+            /**
+             * 优先使用专网ntp服务器地址
+             */
+            if (privatelServerHost != null) {
+                val time = getTimeFromNtpServer(privatelServerHost)
+                if (time > 0) {
+                    val isSetTimeSuccessful = setCurrentTimeMillis(time)
+                    if (isSetTimeSuccessful) {
+                        //                            LogUtil.d("set time successful");
+                        return@Runnable
+                    } else {
+                        //                            LogUtil.d("set time failure");
+                    }
+                }
+            }
+            for (itemHost in ntpServerHost) {
+                val time = getTimeFromNtpServer(itemHost)
+                if (time > 0) {
+                    val isSetTimeSuccessful = setCurrentTimeMillis(time)
+                    if (isSetTimeSuccessful) {
+                        return@Runnable
+                    } else {
+                        //                            LogUtil.d("set time failure");
+                    }
+                }
+            }
+        })
+    }
+
+    /**
+     * 设置当前的系统时间
+     *
+     * @param time
+     * @return true表示设置成功, false表示设置失败
+     */
+    //    private Boolean setCurrentTimeMillis(long time) {
+    //        try {
+    //            TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
+    //            String datetime = CommonUtil.getDatetimeStringByLong(time);
+    //            LogUtil.d("set time is: " + datetime);
+    //            Process process = Runtime.getRuntime().exec("su");
+    //            DataOutputStream os = new DataOutputStream(process.getOutputStream());
+    //            //os.writeBytes("setprop persist.sys.timezone GMT\n");
+    //            os.writeBytes("/system/bin/date -s " + datetime + "\n");
+    //            os.writeBytes("clock -w\n");
+    //            os.writeBytes("exit\n");
+    //            os.flush();
+    //            return true;
+    //        } catch (Exception ex) {
+    //            LogUtil.d("set time exception = " + CommonUtil.getExceptionStack(ex));
+    //            ex.printStackTrace();
+    //            return false;
+    //        }
+    //    }
+    private fun setCurrentTimeMillis(time: Long): Boolean {
+        return SystemClock.setCurrentTimeMillis(time)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/service/SntpClient.kt b/app/src/main/java/com/supwisdom/service/SntpClient.kt
new file mode 100644
index 0000000..d6e9ab9
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/service/SntpClient.kt
@@ -0,0 +1,202 @@
+package com.supwisdom.service
+
+import android.os.SystemClock
+import com.supwisdom.utils.unsignedToLong
+import java.net.DatagramPacket
+import java.net.DatagramSocket
+import java.net.InetAddress
+import kotlin.experimental.and
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc 时钟同步
+ **/
+class SntpClient {
+    /**
+     * 从ntp服务器中获取时间
+     * @param ntpHost ntp服务器域名地址
+     * @return 如果失败返回-1,否则返回当前的毫秒数
+     */
+    private val REFERENCE_TIME_OFFSET = 16
+    private val ORIGINATE_TIME_OFFSET = 24
+    private val RECEIVE_TIME_OFFSET = 32
+    private val TRANSMIT_TIME_OFFSET = 40
+    private val NTP_PACKET_SIZE = 48
+
+    private val NTP_PORT = 123
+    private val NTP_MODE_CLIENT = 3
+    private val NTP_VERSION = 3
+
+    // Number of seconds between Jan 1, 1900 and Jan 1, 1970
+    // 70 years plus 17 leap days
+    private val OFFSET_1900_TO_1970: Long = ((365L * 70L) + 17L) * 24L * 60L * 60L
+
+    // system time computed from NTP server response
+    private var mNtpTime: Long = 0
+
+    // value of SystemClock.elapsedRealtime() corresponding to mNtpTime
+    private var mNtpTimeReference: Long = 0
+
+    // round trip time in milliseconds
+    private var mRoundTripTime: Long = 0
+
+    /**
+     * Sends an SNTP request to the given host and processes the response.
+     *
+     * @param host    host name of the server.
+     * @param timeout network timeout in milliseconds.
+     * @return true if the transaction was successful.
+     */
+    fun requestTime(host: String, timeout: Int): Boolean {
+        var socket: DatagramSocket? = null
+        try {
+            socket = DatagramSocket()
+            socket.soTimeout = timeout
+            val address: InetAddress = InetAddress.getByName(host)
+            val buffer = ByteArray(NTP_PACKET_SIZE)
+            val request = DatagramPacket(buffer, buffer.size, address, NTP_PORT)
+
+            // set mode = 3 (client) and version = 3
+            // mode is in low 3 bits of first byte
+            // version is in bits 3-5 of first byte
+//            buffer[0] = NTP_MODE_CLIENT or (NTP_VERSION << 3)
+            buffer[0] = (NTP_MODE_CLIENT or (NTP_VERSION shl 3)).toByte()
+
+
+            // get current time and write it to the request packet
+            val requestTime = System.currentTimeMillis()
+            val requestTicks = SystemClock.elapsedRealtime()
+            writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET, requestTime)
+
+            socket.send(request)
+
+            // read the response
+            val response = DatagramPacket(buffer, buffer.size)
+            socket.receive(response)
+            val responseTicks = SystemClock.elapsedRealtime()
+            val responseTime = requestTime + (responseTicks - requestTicks)
+
+            // extract the results
+            val originateTime = readTimeStamp(buffer, ORIGINATE_TIME_OFFSET)
+            val receiveTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET)
+            val transmitTime = readTimeStamp(buffer, TRANSMIT_TIME_OFFSET)
+            val roundTripTime = responseTicks - requestTicks - (transmitTime - receiveTime)
+            // receiveTime = originateTime + transit + skew
+            // responseTime = transmitTime + transit - skew
+            // clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime))/2
+            //             = ((originateTime + transit + skew - originateTime) +
+            //                (transmitTime - (transmitTime + transit - skew)))/2
+            //             = ((transit + skew) + (transmitTime - transmitTime - transit + skew))/2
+            //             = (transit + skew - transit + skew)/2
+            //             = (2 * skew)/2 = skew
+            val clockOffset = ((receiveTime - originateTime) + (transmitTime - responseTime)) / 2
+            // save our results - use the times on this side of the network latency
+            // (response rather than request time)
+            mNtpTime = responseTime + clockOffset
+            mNtpTimeReference = responseTicks
+            mRoundTripTime = roundTripTime
+        } catch (ex: Exception) {
+            ex.printStackTrace()
+            return false
+        } finally {
+            socket?.close()
+        }
+        return true
+    }
+
+    /**
+     * Returns the time computed from the NTP transaction.
+     *
+     * @return time value computed from NTP server response.
+     */
+    fun getNtpTime(): Long {
+        return mNtpTime
+    }
+
+    /**
+     * Returns the reference clock value (value of SystemClock.elapsedRealtime())
+     * corresponding to the NTP time.
+     *
+     * @return reference clock corresponding to the NTP time.
+     */
+    fun getNtpTimeReference(): Long {
+        return mNtpTimeReference
+    }
+
+    /**
+     * Returns the round trip time of the NTP transaction
+     *
+     * @return round trip time in milliseconds.
+     */
+    fun getRoundTripTime(): Long {
+        return mRoundTripTime
+    }
+
+    /**
+     * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
+     */
+    private fun read32(buffer: ByteArray, offset: Int): Long {
+        val b0 = buffer[offset]
+        val b1 = buffer[offset + 1]
+        val b2 = buffer[offset + 2]
+        val b3 = buffer[offset + 3]
+        // convert signed bytes to unsigned values
+        var i0 = b0.unsignedToLong()
+        if (b0 and 0x80.toByte() == 0x80.toByte()) {
+            i0 = ((b0 and 0x7F.toByte()) + 0x80.toByte()).toByte().unsignedToLong()
+        }
+        var i1 = b1.unsignedToLong()
+        if (b1 and 0x80.toByte() == 0x80.toByte()) {
+            i1 = ((b1 and 0x7F.toByte()) + 0x80.toByte()).toByte().unsignedToLong()
+        }
+        var i2 = b2.unsignedToLong()
+        if (b2 and 0x80.toByte() == 0x80.toByte()) {
+            i2 = ((b2 and 0x7F.toByte()) + 0x80.toByte()).toByte().unsignedToLong()
+        }
+        var i3 = b3.unsignedToLong()
+        if (b3 and 0x80.toByte() == 0x80.toByte()) {
+            i3 = ((b3 and 0x7F.toByte()) + 0x80.toByte()).toByte().unsignedToLong()
+        }
+//        val i0 = (b0 and 0x80.toByte()) == 0x80 ? (b0 & 0x7F)+0x80 : b0)
+//        val i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F)+0x80 : b1)
+//        val i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F)+0x80 : b2)
+//        val i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F)+0x80 : b3)
+
+        return (i0 shl 24) + (i1 shl 16) + (i2 shl 8) + i3
+    }
+
+    /**
+     * Reads the NTP time stamp at the given offset in the buffer and returns
+     * it as a system time (milliseconds since January 1, 1970).
+     */
+    private fun readTimeStamp(buffer: ByteArray, offset: Int): Long {
+        val seconds = read32(buffer, offset)
+        val fraction = read32(buffer, offset + 4)
+        return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L)
+    }
+
+    /**
+     * Writes system time (milliseconds since January 1, 1970) as an NTP time stamp
+     * at the given offset in the buffer.
+     */
+    private fun writeTimeStamp(buffer: ByteArray, offset: Int, time: Long) {
+        var tmpOffset = offset
+        var seconds = time / 1000L
+        val milliseconds = time - seconds * 1000L
+        seconds += OFFSET_1900_TO_1970
+
+        // write seconds in big endian format
+        buffer[tmpOffset++] = (seconds shr 24).toByte()
+        buffer[tmpOffset++] = (seconds shr 16).toByte()
+        buffer[tmpOffset++] = (seconds shr 8).toByte()
+        buffer[tmpOffset++] = (seconds shr 0).toByte()
+
+        val fraction = milliseconds * 0x100000000L / 1000L
+        // write fraction in big endian format
+        buffer[tmpOffset++] = (fraction shr 24).toByte()
+        buffer[tmpOffset++] = (fraction shr 16).toByte()
+        buffer[tmpOffset++] = (fraction shr 8).toByte()
+        // low order bits should be random data
+        buffer[tmpOffset] = (Math.random() * 255.0).toByte()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/service/WebsocketProcess.kt b/app/src/main/java/com/supwisdom/service/WebsocketProcess.kt
new file mode 100644
index 0000000..2a8ca33
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/service/WebsocketProcess.kt
@@ -0,0 +1,327 @@
+package com.supwisdom.service
+
+import android.os.Handler
+import android.os.Message
+import com.koushikdutta.async.callback.CompletedCallback
+import com.koushikdutta.async.future.Future
+import com.koushikdutta.async.http.AsyncHttpClient
+import com.koushikdutta.async.http.WebSocket
+import com.supwisdom.activities.SPApplication
+import com.supwisdom.db.Pos
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.LogUtil
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+class WebsocketProcess {
+    private val TAG = "WebsocketProcess"
+    private var handler: Handler? = null
+    private var pos: Pos = SPApplication.getInstance().getPos()
+    private var websocketService: WebsocketService
+    private var isExit: Boolean = false
+    private var qrcodeThread: Thread? = null
+    @Volatile
+    private var isConnected: Boolean = false
+    @Volatile
+    private var connectDoing: Boolean = false
+    private var webSocket: Future<WebSocket>? = null
+    private var reLinkCnt: Int = 0
+    private var clientID = ""
+    @Volatile
+    private var hasRecv: Boolean = false
+    private var pingFailCnt: Int = 0
+
+    init {
+        websocketService = WebsocketService()
+    }
+
+    fun start() {
+        isExit = false
+        if (qrcodeThread == null) {
+            synchronized(WebsocketProcess::class.java) {
+                if (qrcodeThread == null) {
+                    qrcodeThread = Thread(websocketService)
+                    qrcodeThread!!.start()
+                }
+            }
+        }
+        clientID = SPApplication.getInstance().getPos().getConfigPara()!!.devphyid!!
+    }
+
+    fun setHandler(handler: Handler) {
+        this.handler = handler
+    }
+
+    fun stop() {
+        isExit = true
+        if (qrcodeThread != null) {
+            qrcodeThread!!.interrupt()
+        }
+        qrcodeThread = null
+    }
+
+    private inner class WebsocketService : Runnable {
+        override fun run() {
+            while (!isExit) {
+                CommonUtil.doSleep(1000)
+                if (!isConnected) {
+                    if (!connectDoing) {
+                        connectDoing = true
+                        createNewWebsocket()
+                    }
+                }
+                if (isConnected) {
+                    try {
+                        webSocket!!.get().ping(clientID)
+                    } catch (e: Exception) {
+                        e.printStackTrace()
+                        pingFailCnt++
+                    }
+
+                    if (hasRecv) {
+                        hasRecv = false
+                        pingFailCnt = 0
+                    } else {
+                        pingFailCnt++
+                        if (pingFailCnt > 10) {
+                            isConnected = false
+                            pingFailCnt = 0
+                        }
+                    }
+                }
+            }
+            if (webSocket != null) {
+                webSocket!!.cancel()
+            }
+        }
+    }
+
+//    private fun getServerUrl(): String {
+//        val sb = StringBuilder()
+//        val url = YktSession.getInstance().getWebAPISession().getEpayurl()
+//        val offset = url.lastIndexOf("/")
+//        sb.append(url.substring(0, offset))
+//            .append("/websocket/device_service")
+//        return sb.toString()
+//    }
+
+    private fun newWebsocket(url: String): Future<WebSocket> {
+        return AsyncHttpClient.getDefaultInstance().websocket(url, null,
+            AsyncHttpClient.WebSocketConnectCallback { ex, webSocket ->
+                if (ex != null) {
+                    //网络断开
+                    ex.printStackTrace()
+                    connectDoing = false
+                    isConnected = false
+                    return@WebSocketConnectCallback
+                }
+                reLinkCnt = 0
+                isConnected = true
+                connectDoing = false
+//                val loginStr = getLoginString()
+//                webSocket.send(loginStr)
+                webSocket.stringCallback = WebSocket.StringCallback { s ->
+                    //                    if (!CommonUtil.isEmpty(s)) {
+//                        try {
+//                            val retBean = GsonUtil.GsonToBean(s, WebsocketRetBean::class.java)
+//                            if (retBean.getRetcode() === PublicDef.SUCCESS) {
+//                                if ("login" == retBean.getAction()) {
+//                                    val retData = WebsocketLoginRetData()
+//                                    val data = retBean.getData() as JSONObject
+//                                    retData.setHost_time(data["host_time"] as String?)
+//                                } else if ("qrpay_in_process" == retBean.getAction()) {
+//                                    val retData = WebsockConsumeProcessRetBean()
+//                                    val data = retBean.getData() as JSONObject
+//                                    retData.setCustname(data["custname"] as String?)
+//                                    retData.setStuempno(data["stuempno"] as String?)
+//                                    retData.setClientid(data["clientid"] as String?)
+//                                    retData.setDevphyid(data["devphyid"] as String?)
+//                                    retData.setTransdatetime(data["transdatetime"] as String?)
+//
+//                                    sendMsg(PublicDef.MSG_CONSUME_PAYING, "扫码付款中...")
+//                                    webSocket.send(
+//                                        getQRProcessResp(
+//                                            retBean.getAction(),
+//                                            retBean.getRequestid(),
+//                                            retData
+//                                        )
+//                                    )
+//                                } else if ("qrpay_finish" == retBean.getAction()) {
+//                                    val retData = WebsockConsumeFinishRetBean()
+//                                    val data = retBean.getData() as JSONObject
+//                                    retData.setCustname(data["custname"] as String?)
+//                                    retData.setStuempno(data["stuempno"] as String?)
+//                                    retData.setDevphyid(data["devphyid"] as String?)
+//                                    retData.setRefno(data["refno"] as String?)
+//                                    retData.setStatus(data["status"] as String?)
+//                                    retData.setAmount(data["amount"] as Int?)
+//                                    retData.setAvailbal(data["availbal"] as Int?)
+//                                    retData.setTransdatetime(data["transdatetime"] as String?)
+//
+//                                    if ("succ" == retData.getStatus()) {
+//                                        val info = UserCardInfo(PublicDef.SUCCESS, "付款成功")
+//                                        info.setDatetime(retData.getTransdatetime())
+//                                        info.setUsername(retData.getCustname())
+//                                        info.setStuempno(retData.getStuempno())
+//                                        info.setPayamt(retData.getAmount())
+//                                        info.setAmount(retData.getAmount())
+//                                        info.setBalance(retData.getAvailbal())
+//                                        info.setShowtime(pos.getSysPara().getSucShowtime())
+//                                        info.setFlag(PublicDef.TRANSFLAG_NORMAL_CONSUME or PublicDef.TRANSFLAG_WRITE_CARD_SUCCESS)
+//                                        info.setConsumeType(PublicDef.CONSUME_TYPE_BAR)
+//                                        SPApplication.getInstance().setLastInfo(info)
+//                                        sendMsg(PublicDef.MSG_CONSUME_QR_SUC, info)
+//
+//                                        saveTransdtlOnline(info)
+//                                    }
+//                                    webSocket.send(
+//                                        getQRSuccessResp(
+//                                            retBean.getAction(),
+//                                            retBean.getRequestid(),
+//                                            retData
+//                                        )
+//                                    )
+//                                }
+//                            }
+//                        } catch (e: Exception) {
+//                            e.printStackTrace()
+//                        }
+//
+//                    }
+                }
+                webSocket.closedCallback = CompletedCallback {
+                    //主动断网,关服务
+                    //                        isConnected = false;
+                    //                        connectDoing = false;
+                }
+                webSocket.endCallback = CompletedCallback {
+                    //主动断网,关服务
+                    //                        isConnected = false;
+                    //                        connectDoing = false;
+                }
+                webSocket.pongCallback = WebSocket.PongCallback { hasRecv = true }
+                webSocket.setPingCallback { hasRecv = true }
+            })
+    }
+
+    private fun doSleep() {
+        reLinkCnt *= 2
+        if (reLinkCnt < 2 || reLinkCnt > 128) {
+            reLinkCnt = 2
+        }
+        CommonUtil.doSleep(reLinkCnt * 1000)
+    }
+
+//    private fun buildServerUrl(clientId: String): String {
+//        val nowtime = CommonUtil.getNowDateTimeNoFormat()
+//        val signdata = StringBuilder()
+//        signdata.append(PublicDef.APP_ID).append(clientId).append(nowtime)
+//        val sign = Encrypt.HMACSHA1(signdata.toString(), PublicDef.APP_SECRET)
+//
+//        val uri = StringBuilder()
+//        uri.append("?local_time=").append(DateUtil.getNowDateTimeNoFormat()).append("&appid=")
+//            .append(PublicDef.APP_ID)
+//            .append("&clientid=").append(clientId).append("&sign=").append(sign)
+//        return getServerUrl() + uri.toString()
+//    }
+
+    private fun tryCloseWebsocket(sc: Future<WebSocket>?) {
+        if (sc != null) {
+            if (sc.cancel()) {
+                LogUtil.d(
+                    TAG,
+                    clientID + " websocket cancel fail,exception=" + CommonUtil.getExceptionStack(sc.tryGetException())
+                )
+            } else {
+                LogUtil.d(TAG, "$clientID websocket cancel success")
+            }
+        }
+    }
+
+    private fun createNewWebsocket() {
+        doSleep()
+        tryCloseWebsocket(webSocket)
+//        webSocket = newWebsocket(buildServerUrl(clientID))
+    }
+
+//    private fun getQRProcessResp(action: String, requestid: String, retData: WebsockConsumeProcessRetBean): String {
+//        val data = WebsockConsumeProcessRespBean.Content()
+//        data.setDevphyid(retData.getDevphyid())
+//        val resp = WebsockConsumeProcessRespBean()
+//        resp.setRetcode(PublicDef.SUCCESS)
+//        resp.setRetmsg("推流成功")
+//        resp.setAction(action)
+//        resp.setRequestid(requestid)
+//        resp.setData(data)
+//        return GsonUtil.GsonString(resp)
+//    }
+//
+//    private fun getQRSuccessResp(action: String, requestid: String, retData: WebsockConsumeFinishRetBean): String {
+//        val data = WebsockConsumeFinishRespBean.Content()
+//        data.setDevphyid(retData.getDevphyid())
+//        val resp = WebsockConsumeFinishRespBean()
+//        resp.setRetcode(PublicDef.SUCCESS)
+//        resp.setRetmsg("推流成功")
+//        resp.setAction(action)
+//        resp.setRequestid(requestid)
+//        resp.setData(data)
+//        return GsonUtil.GsonString(resp)
+//    }
+//
+//    fun getLoginString(): String {
+//        val data = WebsocketLoginDataReqBean()
+//        data.setClientid(clientID)
+//        data.setLocal_time(CommonUtil.getNowDateTimeNoFormat())
+//
+//        val req = WebsocketLoginReqBean()
+//        req.setAction("login")
+//        req.setNeedresp("true")
+//        req.setRequestid(getRandom())
+//        req.setData(data)
+//        return GsonUtil.GsonString(req)
+//    }
+//
+//    private fun getRandom(): String {
+//        val rand = Random()
+//        rand.setSeed(System.currentTimeMillis())
+//        return String.format("%010d", rand.nextInt(999999999))
+//    }
+//
+//    private fun saveTransdtlOnline(info: UserCardInfo): Boolean {
+//        val record = TransdtlOnlineRecord()
+//        var seqno = pos.getTransdtlOnlineSeqno()
+//        if (seqno == 0) {
+//            val ctlRecord = pos.getControlPara(PublicDef.CONTROL_TRANSDTLONL_SEQNO)
+//            if (ctlRecord != null) {
+//                seqno = Integer.valueOf(ctlRecord!!.getValue())
+//            }
+//        }
+//        record.setDevseqno(seqno + 1)
+//        record.setCustname(info.getUsername())
+//        record.setStuempno(info.getStuempno())
+//        record.setTransdate(info.getDatetime().substring(0, 8))
+//        record.setTranstime(info.getDatetime().substring(8))
+//        record.setDevphyid(pos.getConfigPara().getDevphyid())
+//        record.setPayamt(info.getAmount())
+//        record.setConsumetype(PublicDef.CONSUME_TYPE_BAR)
+//        record.setFlag(PublicDef.TRANSFLAG_NORMAL_CONSUME or PublicDef.TRANSFLAG_WRITE_CARD_SUCCESS)
+//        record.setUpflag(1)
+//        return pos.saveTransdtlOnline(record)
+//    }
+
+    private fun sendMsg(code: Int, o: Any) {
+        if (handler == null) {
+            return
+        }
+        try {
+            val msg = Message()
+            msg.what = code
+            msg.obj = o
+            handler!!.sendMessage(msg)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/AppExitUtil.kt b/app/src/main/java/com/supwisdom/utils/AppExitUtil.kt
new file mode 100644
index 0000000..d9f3f3a
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/AppExitUtil.kt
@@ -0,0 +1,53 @@
+package com.supwisdom.utils
+
+import android.app.Activity
+import java.util.*
+
+/**
+ * @author zzq
+ * @date 2018/3/20.
+ * @version 1.0.1
+ * @desc : activity管理
+ */
+object AppExitUtil {
+    private val acys = HashSet<Activity>()
+
+    fun add(acy: Activity) {
+        acys.add(acy)
+    }
+
+    fun remove(acy: Activity) {
+        acys.remove(acy)
+        if (!acy.isFinishing) {
+            acy.finish()
+        }
+        if (acys.size == 0) {
+            killprocess()
+        }
+    }
+
+    fun exit() {
+        val iter = acys.iterator()
+        val arrs = arrayOfNulls<Activity>(acys.size)
+        var i = 0
+        while (iter.hasNext()) {
+            arrs[i] = iter.next()
+            i += 1
+        }
+        acys.clear()
+        for (j in arrs.indices) {
+            if (arrs[j] != null && !arrs[j]!!.isFinishing) {
+                arrs[j]!!.finish()
+                arrs[j] = null
+            }
+        }
+        killprocess()
+    }
+
+    private fun killprocess() {
+        ThreadPool.getShortPool().execute(Runnable {
+            CommonUtil.doSleep(2000)
+            android.os.Process.killProcess(android.os.Process.myPid())
+        })
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/CommonUtil.kt b/app/src/main/java/com/supwisdom/utils/CommonUtil.kt
new file mode 100644
index 0000000..917f39c
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/CommonUtil.kt
@@ -0,0 +1,194 @@
+@file:Suppress("DEPRECATION")
+
+package com.supwisdom.utils
+
+import android.annotation.SuppressLint
+import android.app.Activity
+import android.app.ActivityManager
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.net.Uri
+import android.os.Build
+import android.os.PowerManager
+import android.provider.Settings
+import android.widget.EditText
+import com.supwisdom.activities.SPApplication
+import java.io.File
+import java.io.FileOutputStream
+import java.io.PrintWriter
+import java.io.StringWriter
+import java.util.regex.Pattern
+
+/**
+ * @author zzq
+ * @date 2018/5/9.
+ * @version 1.0.1
+ * @desc  公共类
+ */
+object CommonUtil {
+    fun doSleep(ms: Int) {
+        try {
+            Thread.sleep(ms.toLong())
+        } catch (e: InterruptedException) {
+            e.printStackTrace()
+        }
+    }
+
+    fun getEditView(et: EditText): String {
+        return et.text.toString().trim { it <= ' ' }.replace(" ", "")
+    }
+
+    fun getCommunicateTime(): Int {
+        var commTime = 2
+        val sysRecord = SPApplication.getInstance().getPos().getSysPara()
+        if (sysRecord != null) {
+            commTime = sysRecord.commTime
+            if (commTime == 0) {
+                commTime = 2
+            }
+        }
+        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()
+    }
+
+    fun upgrade(context: Context, filename: String) {
+        val intent = Intent(Intent.ACTION_VIEW)
+        val uri = Uri.fromFile(File(filename))
+        intent.setDataAndType(uri, "application/vnd.android.package-archive")
+        (context as Activity).startActivityForResult(intent, 0)
+    }
+
+    fun isNumeric(str: String): Boolean {
+        val pattern = Pattern.compile("[0-9]*")
+        val isNum = pattern.matcher(str)
+        return isNum.matches()
+    }
+
+    fun showFormatAmount(preHint: String, amount: Int): String {
+        return String.format("%s: %.02f元", preHint, amount / 100.0f)
+    }
+
+    /*优化a811扫码*/
+    fun writeLinnuuxParams() {
+        try {
+            val fos = FileOutputStream("/sys/module/gc0308/parameters/exposure")
+            fos.write("20".toByteArray())
+            fos.close()
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    /**
+     * 判断服务是否开启
+     *
+     * @param mContext
+     * @param serviceName
+     * @return
+     */
+    fun isServiceWork(mContext: Context, serviceName: String): Boolean {
+        val myAM = mContext
+            .getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
+        val myList = myAM.getRunningServices(40)
+        if (myList.size <= 0) {
+            return false
+        }
+        for (i in myList.indices) {
+            val mName = myList[i].service.className.toString()
+            if (mName == serviceName) {
+                return true
+            }
+        }
+        return false
+    }
+
+    fun getExceptionStack(e: Exception?): String {
+        if (e == null) {
+            return "null"
+        }
+        val sw = StringWriter()
+        val pw = PrintWriter(sw)
+        e.printStackTrace(pw)
+        return sw.toString()
+    }
+
+    /**
+     * get App versionName
+     *
+     * @param context
+     * @return
+     */
+    fun getVersionName(context: Context): String {
+        return try {
+            val packageManager = context.packageManager
+            val packageInfo = packageManager.getPackageInfo(context.packageName, 0)
+            packageInfo.versionName
+        } catch (e: PackageManager.NameNotFoundException) {
+            e.printStackTrace()
+            "error:" + e.message
+        }
+
+    }
+
+    /**
+     * 跳转网络设置页;
+     */
+    fun startNetSetting(context: Context) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            context.startActivity(Intent(Settings.ACTION_SETTINGS))
+        } else {
+            context.startActivity(Intent(Settings.ACTION_WIRELESS_SETTINGS))
+        }
+    }
+
+    /**
+     * 唤醒屏幕
+     */
+    fun acquireWakeLock(context: Context) {
+        /*FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度
+          ACQUIRE_CAUSES_WAKEUP:强制使屏幕亮起,这种锁主要针对一些必须通知用户的操作.
+          ON_AFTER_RELEASE:当锁被释放时,保持屏幕亮起一段时间*/
+        try {
+            val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
+            @SuppressLint("InvalidWakeLockTag") val wakeLock = pm.newWakeLock(
+                PowerManager.ON_AFTER_RELEASE
+                        or PowerManager.ACQUIRE_CAUSES_WAKEUP
+                        or PowerManager.FULL_WAKE_LOCK, "Tag"
+            )
+            wakeLock.acquire()
+            wakeLock.release()
+        } catch (ex: Exception) {
+            ex.printStackTrace()
+        }
+
+    }
+
+    fun getPasswordStar(len: Int): String {
+        return when (len) {
+            0 -> " "
+            1 -> "*"
+            2 -> "**"
+            3 -> "***"
+            4 -> "****"
+            5 -> "*****"
+            6 -> "******"
+            else -> " "
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/CryptUtil.kt b/app/src/main/java/com/supwisdom/utils/CryptUtil.kt
new file mode 100644
index 0000000..b3d7f97
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/CryptUtil.kt
@@ -0,0 +1,142 @@
+package com.supwisdom.utils
+
+import java.io.InputStream
+import java.io.UnsupportedEncodingException
+import java.security.InvalidKeyException
+import java.security.MessageDigest
+import java.security.NoSuchAlgorithmException
+import javax.crypto.Mac
+import javax.crypto.spec.SecretKeySpec
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+object CryptUtil {
+    fun HASH256(text: String): String? {
+        return algorithm2(text, "SHA-256", true)
+    }
+
+    fun HASH256(fis: InputStream): String? {
+        return algorithm(fis, "SHA-256")
+    }
+
+    fun HASH256(fis: InputStream, extData: String): String? {
+        return algorithm(fis, "SHA-256", extData)
+    }
+
+    fun HASH512(text: String): String? {
+        return algorithm2(text, "SHA-512", true)
+    }
+
+    fun MD5(text: String): String? {
+        return algorithm2(text, "MD5", false)
+    }
+
+    fun HMACSHA1(data: String, key: String): String? {
+        try {
+            val algorithm = "HmacSHA1"
+            val mac = Mac.getInstance(algorithm)
+            val spec = SecretKeySpec(key.toByteArray(), algorithm)
+            mac.init(spec)
+            val byteHMAC = mac.doFinal(data.toByteArray())
+            return byteHMAC.encodeHex()
+        } catch (e: InvalidKeyException) {
+            e.printStackTrace()
+        } catch (ignore: NoSuchAlgorithmException) {
+            ignore.printStackTrace()
+        }
+        return null
+    }
+
+    fun HMACSHA256(data: String, key: String): String? {
+        try {
+            val algorithm = "HmacSHA256"
+            val mac = Mac.getInstance(algorithm)
+            val spec = SecretKeySpec(key.toByteArray(), algorithm)
+            mac.init(spec)
+            val byteHMAC = mac.doFinal(data.toByteArray())
+            return byteHMAC.encodeHex()
+        } catch (e: InvalidKeyException) {
+            e.printStackTrace()
+        } catch (ignore: NoSuchAlgorithmException) {
+            ignore.printStackTrace()
+        }
+        return null
+    }
+
+    private fun algorithm2(text: String?, algorithm: String, isUpperCase: Boolean): String? {
+        if (text != null && text.isNotEmpty()) {
+            try {
+                //创建具有指定算法名称的信息摘要
+                val md = MessageDigest.getInstance(algorithm)
+                //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
+                val results = md.digest(text.toByteArray(charset("UTF-8")))
+                //将得到的字节数组变成字符串返回
+                val resultString = results.encodeHex()
+                return if (isUpperCase) {
+                    resultString.toUpperCase()
+                } else {
+                    resultString.toLowerCase()
+                }
+            } catch (ex: NoSuchAlgorithmException) {
+                ex.printStackTrace()
+            } catch (ex: UnsupportedEncodingException) {
+                ex.printStackTrace()
+            }
+        }
+        return null
+    }
+
+    private fun algorithm(fis: InputStream, algorithm: String): String? {
+        try {
+            //拿到一个MD5转换器,如果想使用SHA-1或SHA-256,则传入SHA-1,SHA-256
+            val md = MessageDigest.getInstance(algorithm)
+
+            //分多次将一个文件读入,对于大型文件而言,比较推荐这种方式,占用内存比较少。
+            val buffer = ByteArray(1024)
+            var length: Int
+            while (true) {
+                length = fis.read(buffer, 0, 1024)
+                if (length < 0) {
+                    break
+                }
+                md.update(buffer, 0, length)
+            }
+            fis.close()
+            //转换并返回包含16个元素字节数组,返回数值范围为-128到127
+            return md.digest().encodeHex()
+        } catch (e: Exception) {
+            e.printStackTrace()
+            return null
+        }
+
+    }
+
+    private fun algorithm(fis: InputStream, algorithm: String, extData: String): String? {
+        try {
+            //拿到一个MD5转换器,如果想使用SHA-1或SHA-256,则传入SHA-1,SHA-256
+            val md = MessageDigest.getInstance(algorithm)
+
+            //分多次将一个文件读入,对于大型文件而言,比较推荐这种方式,占用内存比较少。
+            val buffer = ByteArray(1024)
+            var length: Int
+            while (true) {
+                length = fis.read(buffer, 0, 1024)
+                if (length < 0) {
+                    break
+                }
+                md.update(buffer, 0, length)
+            }
+            fis.close()
+            md.update(extData.toByteArray(charset("UTF-8")))
+
+            //转换并返回包含16个元素字节数组,返回数值范围为-128到127
+            return md.digest().encodeHex()
+        } catch (e: Exception) {
+            e.printStackTrace()
+            return null
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/DateUtil.kt b/app/src/main/java/com/supwisdom/utils/DateUtil.kt
new file mode 100644
index 0000000..6ce7a41
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/DateUtil.kt
@@ -0,0 +1,322 @@
+package com.supwisdom.utils
+
+import java.text.ParseException
+import java.text.SimpleDateFormat
+import java.util.*
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+object DateUtil {
+    private val FORMAT_yyyyMMdd = org.apache.commons.lang3.time.FastDateFormat.getInstance("yyyyMMdd")
+    private val FORMAT_yyMMddHHmmss = org.apache.commons.lang3.time.FastDateFormat.getInstance("yyMMddHHmmss")
+    private val FORMAT_yyMMddHHmmss2 = org.apache.commons.lang3.time.FastDateFormat.getInstance("yy-MM-dd HH:mm:ss")
+    private val FORMAT_HHmmss = org.apache.commons.lang3.time.FastDateFormat.getInstance("HHmmss")
+    private val FORMAT_MMdd = org.apache.commons.lang3.time.FastDateFormat.getInstance("MMdd")
+    private val FORMAT_MM_dd = org.apache.commons.lang3.time.FastDateFormat.getInstance("MM-dd")
+    private val FORMAT_yyyyMMddHHmmss = org.apache.commons.lang3.time.FastDateFormat.getInstance("yyyyMMddHHmmss")
+    private val FORMAT_yyyyMMddHHmm = org.apache.commons.lang3.time.FastDateFormat.getInstance("yyyyMMddHHmm")
+    private val FORMAT_MMddHHmmyy = org.apache.commons.lang3.time.FastDateFormat.getInstance("MMddHHmmyy")
+    private val FORMAT_yyyy_MM_dd_HH_mm_ss =
+        org.apache.commons.lang3.time.FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss")
+    private val FORMAT_yyyy_MM_dd = org.apache.commons.lang3.time.FastDateFormat.getInstance("yyyy-MM-dd")
+    private val FORMAT_HH_mm_ss = org.apache.commons.lang3.time.FastDateFormat.getInstance("HH:mm:ss")
+
+    /**
+     * @return yyyy-MM-dd HH:mm:ss
+     */
+    fun getNow(): String {
+        return FORMAT_yyyy_MM_dd_HH_mm_ss.format(Date())
+    }
+
+    fun getNowDateSpecFormat(): String {
+        return FORMAT_yyyy_MM_dd.format(Date())
+    }
+
+    fun utcToLocal(utctime: String): String {
+        val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+        sdf.timeZone = TimeZone.getTimeZone("UTC")
+        return try {
+            val utcDate = sdf.parse(utctime)
+            sdf.timeZone = TimeZone.getDefault()
+            val localTime = sdf.format(utcDate.time)
+            val localDate = sdf.parse(localTime)
+            FORMAT_yyyyMMddHHmmss.format(localDate.time)
+        } catch (ex: ParseException) {
+            ex.printStackTrace()
+            ""
+        }
+    }
+
+    /**
+     * @param date yyyyMMdd
+     * @return yyyy-MM-dd
+     */
+    fun getNowDateFromNoFormat(date: String): String {
+        try {
+            return date.substring(0, 4) + "-" +
+                    date.substring(4, 6) + "-" +
+                    date.substring(6, 8)
+        } catch (ex: Exception) {
+        }
+        return ""
+    }
+
+    /**
+     * @return HH:mm:ss
+     */
+    fun getNowTimeWithArg(date: Date): String? {
+        return try {
+            FORMAT_HH_mm_ss.format(date)
+        } catch (e: Exception) {
+            null
+        }
+    }
+
+    /**
+     * @param time HHmm
+     * @return HH:mm
+     */
+    fun formatTime(time: String): String? {
+        return try {
+            val sb = StringBuilder()
+            sb.append(time.substring(0, 2)).append(":")
+                .append(time.substring(2, 4))
+            sb.toString()
+        } catch (e: Exception) {
+            null
+        }
+    }
+
+    /**
+     * @return MMdd
+     */
+    fun getDateMMdd(): String? {
+        return try {
+            FORMAT_MMdd.format(Date())
+        } catch (e: Exception) {
+            e.printStackTrace()
+            null
+        }
+    }
+
+    /**
+     * @return MM-dd
+     */
+    fun getDate_MMdd(): String? {
+        try {
+            return FORMAT_MM_dd.format(Date())
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return null
+    }
+
+    /**
+     * @return yyyy-MM-dd HH:mm:ss
+     */
+    fun getNowDateTime(): String {
+        return FORMAT_yyyy_MM_dd_HH_mm_ss.format(Date())
+    }
+
+    /**
+     * @return yyyy-MM-dd
+     */
+    fun getNowDate(): String {
+        return FORMAT_yyyy_MM_dd.format(Date())
+    }
+
+    /**
+     * @param dateStr yyyy-MM-dd
+     * @return
+     */
+    fun getNowDateTime(dateStr: String): Date? {
+        try {
+            return FORMAT_yyyy_MM_dd.parse(dateStr)
+        } catch (e: ParseException) {
+            e.printStackTrace()
+        }
+        return null
+    }
+
+    /**
+     * @return HH:mm:ss
+     */
+    fun getNowTime(): String {
+        return FORMAT_HH_mm_ss.format(Date())
+    }
+
+    /**
+     * @return format
+     */
+    fun getDayofWeek(offsetWeek: Int, dayOfWeek: Int, format: String): String {
+        val cal = Calendar.getInstance()
+        // n为推迟的周数,1本周,-1向前推迟一周,2下周,依次类推
+        val retday: String
+        cal.add(Calendar.DATE, offsetWeek * 7)
+        cal.set(Calendar.DAY_OF_WEEK, dayOfWeek)
+        retday = org.apache.commons.lang3.time.FastDateFormat.getInstance(format).format(cal.time)
+        return retday
+    }
+
+    /**
+     * 计算超时时间,精确到毫秒
+     *
+     * @param milliSeconds
+     * @return L
+     */
+    fun getExpireTime(milliSeconds: Long): Long {
+        return Date().time + milliSeconds
+    }
+
+    /**
+     * @return yyyyMMddHHmmss
+     */
+    fun getNowDateTimeNoFormat(): String {
+        return FORMAT_yyyyMMddHHmmss.format(Date())
+    }
+
+    /**
+     * @return yyyyMMdd
+     */
+    fun getNowDateNoFormat(): String {
+        return FORMAT_yyyyMMdd.format(Date())
+    }
+
+    /**
+     * @param date
+     * @return yyyyMMdd
+     */
+    fun getNowDateNoFormat(date: Date): String? {
+        try {
+            return FORMAT_yyyyMMdd.format(date)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+        return null
+    }
+
+    /**
+     * @return HHmmss
+     */
+    fun getNowTimeNoFormat(): String {
+        return FORMAT_HHmmss.format(Date())
+    }
+
+    /**
+     * @param datetime yyyyMMddHHmmss
+     * @return ms
+     * @desc 将日期格式的字符串转换为长整型
+     */
+    fun dateFormatConvertToLong(datetime: String): Long {
+        return try {
+            FORMAT_yyyyMMddHHmmss.parse(datetime).time
+        } catch (ex: ParseException) {
+            0L
+        }
+    }
+
+    /**
+     * @param time ms
+     * @return yyyyMMddHHmmss
+     * @desc 将长整型数字转换为日期格式的字符串
+     */
+    fun dateLongConvertToFormat(time: Long): String {
+        return if (time > 0L) {
+            FORMAT_yyyyMMddHHmmss.format(Date(time))
+        } else ""
+    }
+
+    /**
+     * @param time ms
+     * @return MMddHHmmyy
+     * @desc 将长整型数字转换为日期格式的字符串
+     */
+    fun dateLongConvertToFormat2(time: Long): String {
+        return if (time > 0L) {
+            FORMAT_MMddHHmmyy.format(Date(time))
+        } else ""
+    }
+
+    /**
+     * @param datetime yyyy-MM-dd HH:mm:ss
+     * @return
+     * @desc 将日期格式的字符串转换为长整型
+     */
+    fun dateFormatConvertToDate(datetime: String): Date? {
+        return try {
+            FORMAT_yyyy_MM_dd_HH_mm_ss.parse(datetime)
+        } catch (ex: ParseException) {
+            null
+        }
+    }
+
+    /**
+     * @param daynum 天数
+     * @return 返回当前日期的第 daynum 天前的日期  yyyyMMdd
+     */
+    fun getDayDateNoFormatBefore(daynum: Int): String {
+        val calendar = Calendar.getInstance()
+        calendar.add(Calendar.DATE, -daynum)
+        return FORMAT_yyyyMMdd.format(calendar.time)
+    }
+
+    /**
+     * 获得指定日期的前一天
+     *
+     * @param specifiedDay yyyyMMdd
+     * @return yyyyMMdd
+     */
+    fun getSpecifiedDayBefore(specifiedDay: String): String {
+        return try {
+            val c = Calendar.getInstance()
+            val date = FORMAT_yyyyMMdd.parse(specifiedDay)
+            c.time = date
+            val day = c.get(Calendar.DATE)
+            c.set(Calendar.DATE, day - 1)
+            FORMAT_yyyyMMdd.format(c.time)
+        } catch (e: ParseException) {
+            ""
+        }
+    }
+
+    /**
+     * 获得指定日期的前一天
+     *
+     * @param dayBefore 往前推迟的天数
+     * @return Date
+     */
+    fun getSomeDayBefore(dayBefore: Int): Date {
+        val c = Calendar.getInstance()
+        c.add(Calendar.DAY_OF_MONTH, -dayBefore)
+        return c.time
+    }
+
+    /**
+     * 获得指定日期的后一天
+     *
+     * @param specifiedDay yyyyMMdd
+     * @return yyyyMMdd
+     */
+    fun getSpecifiedDayAfter(specifiedDay: String): String {
+        return try {
+            val c = Calendar.getInstance()
+            val date = FORMAT_yyyyMMdd.parse(specifiedDay)
+            c.time = date
+            val day = c.get(Calendar.DATE)
+            c.set(Calendar.DATE, day + 1)
+            FORMAT_yyyyMMdd.format(c.time)
+        } catch (e: ParseException) {
+            ""
+        }
+    }
+
+    /**
+     * @return yyyyMMddHHmmss
+     */
+    fun getNowDateTimeFormat(): String {
+        return FORMAT_yyyyMMddHHmmss.format(Date())
+    }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/FileUtil.kt b/app/src/main/java/com/supwisdom/utils/FileUtil.kt
new file mode 100644
index 0000000..103d889
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/FileUtil.kt
@@ -0,0 +1,142 @@
+package com.supwisdom.utils
+
+import android.os.Environment
+import java.io.*
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+object FileUtil {
+    private val ROOT_DIR = "/a711/pos/"
+    private val ROOT_PRIVATE_DIR = "/supwisdom/"
+    private val CACHE_FILE_DIR = ROOT_DIR + "cache/"
+    private val CRASH_FILE_DIR = ROOT_DIR + "crash/"
+    private val CRASH_FILE_PRE = "crash-"
+    private val LOG_FILE_DIR = ROOT_DIR + "log/"
+    private val LOG_FILE_PRE = "log-"
+    private val DTL_FILE_DIR = ROOT_DIR + "dtl/"
+    private val DTL_FILE_PRE = "dtl-"
+
+    fun getUpdateFile(fileName: String): File? {
+        return createFile(CACHE_FILE_DIR, fileName)
+    }
+
+    fun getCfgFile(fileName: String): File? {
+        return createFile(ROOT_PRIVATE_DIR, fileName)
+    }
+
+    fun getCfgFileStream(fileName: String): InputStream? {
+        if (android.os.Environment.MEDIA_MOUNTED == android.os.Environment.getExternalStorageState()) {
+            val rootFile = File(Environment.getExternalStorageDirectory().toString() + ROOT_PRIVATE_DIR)
+            if (!rootFile.exists()) {
+                return null
+            }
+            val retFile = File(rootFile, fileName)
+            if (retFile.exists()) {
+                try {
+                    return FileInputStream(retFile)
+                } catch (e: FileNotFoundException) {
+                    e.printStackTrace()
+                }
+
+            }
+        }
+        return null
+    }
+
+    fun removeDtlFile(beforeday: Int) {
+        removeFile(DTL_FILE_DIR, DTL_FILE_PRE, beforeday)
+    }
+
+    fun removeLogFile(beforeday: Int) {
+        removeFile(LOG_FILE_DIR, LOG_FILE_PRE, beforeday)
+    }
+
+    fun removeCrashFile(beforeday: Int) {
+        removeFile(CRASH_FILE_DIR, CRASH_FILE_PRE, beforeday)
+    }
+
+
+    fun writeDtlFile(msg: String) {
+        val pathfile = DTL_FILE_DIR + DTL_FILE_PRE + DateUtil.getNowDateNoFormat() + ".txt"
+        writeFile(pathfile, msg, true)
+    }
+
+    fun writeCrashFile(msg: String) {
+        val pathfile = CRASH_FILE_DIR + CRASH_FILE_PRE + DateUtil.getNowDateNoFormat() + ".txt"
+        writeFile(pathfile, msg, true)
+    }
+
+    fun writeLogFile(msg: String) {
+        val pathfile = LOG_FILE_DIR + LOG_FILE_PRE + DateUtil.getNowDateNoFormat() + ".txt"
+        writeFile(pathfile, msg, true)
+    }
+
+    private fun writeFile(targetPath: String, msg: String, append: Boolean) {
+        if (android.os.Environment.MEDIA_MOUNTED == android.os.Environment.getExternalStorageState()) {
+            val targetFile = File(Environment.getExternalStorageDirectory().toString() + targetPath)
+            if (!targetFile.parentFile.exists()) {
+                targetFile.parentFile.mkdirs()
+            }
+            try {
+                val osw = OutputStreamWriter(
+                    FileOutputStream(targetFile, append), "utf-8"
+                )
+                try {
+                    osw.write(msg)
+                    osw.write("</br>\n")
+                    osw.flush()
+                    osw.close()
+                } catch (e: IOException) {
+                    e.printStackTrace()
+                }
+
+            } catch (e1: UnsupportedEncodingException) {
+                e1.printStackTrace()
+            } catch (e1: FileNotFoundException) {
+                e1.printStackTrace()
+            }
+
+        }
+    }
+
+    private fun removeFile(targetPath: String, prefile: String, beforeday: Int) {
+        if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()) {
+            val rootFile = File(Environment.getExternalStorageDirectory().toString() + targetPath)
+            if (!rootFile.exists()) {
+                return
+            }
+            val logname = prefile + DateUtil.getDayDateNoFormatBefore(beforeday) + ".txt"
+            val files = rootFile.listFiles()
+            for (file in files!!) {
+                val fullfilename = file.absolutePath
+                val filename = fullfilename.substring(fullfilename.lastIndexOf('/') + 1)
+                if (filename.startsWith(prefile) && filename.endsWith(".txt")) {
+                    if (filename.compareTo(logname) < 0) {
+                        file.delete()
+                    }
+                }
+            }
+        }
+    }
+
+    private fun createFile(path: String, fileName: String): File? {
+        if (android.os.Environment.MEDIA_MOUNTED == android.os.Environment.getExternalStorageState()) {
+            val rootFile = File(Environment.getExternalStorageDirectory().toString() + path)
+            if (!rootFile.exists()) {
+                rootFile.mkdirs()
+            }
+            val retFile = File(rootFile, fileName)
+            if (!retFile.exists()) {
+                try {
+                    retFile.createNewFile()
+                } catch (e: IOException) {
+                    return null
+                }
+            }
+            return retFile
+        }
+        return null
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/GsonUtil.kt b/app/src/main/java/com/supwisdom/utils/GsonUtil.kt
new file mode 100644
index 0000000..12e9209
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/GsonUtil.kt
@@ -0,0 +1,34 @@
+package com.supwisdom.utils
+
+import com.google.gson.Gson
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+object GsonUtil {
+    private val gson = Gson()
+
+    /**
+     * 转成json
+     *
+     * @param object
+     * @return
+     */
+    fun GsonString(obj: Any): String {
+        return gson.toJson(obj)
+//        return JSON.toJSONString(obj)
+    }
+
+    /**
+     * 转成bean
+     *
+     * @param gsonString
+     * @param cls
+     * @return
+     */
+    fun <T> GsonToBean(gsonString: String, cls: Class<T>): T {
+        return gson.fromJson(gsonString, cls)
+//        return JSON.parseObject(gsonString, cls)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/LogUtil.kt b/app/src/main/java/com/supwisdom/utils/LogUtil.kt
new file mode 100644
index 0000000..210fbd1
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/LogUtil.kt
@@ -0,0 +1,39 @@
+package com.supwisdom.utils
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+object LogUtil {
+    private val DEBUG = 3
+    private val INFO = 2
+    private val ERROR = 1
+    private var curlevel = DEBUG
+
+    fun setLevel(level: Int) {
+        curlevel = level
+    }
+
+    fun d(tag: String, msg: String) {
+        if (curlevel >= DEBUG) {
+            writeLog(tag, msg)
+        }
+    }
+
+    fun i(tag: String, msg: String) {
+        if (curlevel >= INFO) {
+            writeLog(tag, msg)
+        }
+    }
+
+    fun e(tag: String, msg: String) {
+        if (curlevel >= ERROR) {
+            writeLog(tag, msg)
+        }
+    }
+
+    private fun writeLog(tag: String, msg: String) {
+        val time = DateUtil.getNowDateTime() + "--"
+        FileUtil.writeLogFile("$tag:$time--$msg")
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/PublicDef.kt b/app/src/main/java/com/supwisdom/utils/PublicDef.kt
new file mode 100644
index 0000000..b67e05b
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/PublicDef.kt
@@ -0,0 +1,91 @@
+package com.supwisdom.utils
+
+/**
+ * @author zzq
+ * @date 2018/4/26.
+ * @version 1.0.1
+ * @desc  APP module常量定义
+ */
+object PublicDef {
+    /**
+     * 错误码
+     */
+    const val SUCCESS = 0
+    const val ERROR = 1
+    /**
+     * 商户默认密码 111111
+     * 维护默认密码 914387
+     */
+    const val PASSWD_SHOP_DEFAULT = "111111"
+    const val PASSWD_ADMIN_DEFAULT = "914387"
+
+    /**************************************************************/
+    /*************************handler 状态码***********************/
+    const val MSG_CARD_PAYING = 10
+    const val MSG_CARD_READ_AGAIN = 11
+    const val MSG_CARD_PAY_FAIL = 12
+    const val MSG_CARD_PAY_SUC = 13
+    const val MSG_CARD_PAY_QUERY = 14
+    const val MSG_CARD_REVERSE_FAIL = 15
+    const val MSG_CARD_REVERSE_SUC = 16
+    const val MSG_USER_INFO_SHOW = 17
+    const val MSG_USER_INFO_CLEAR = 18
+    const val MSG_LINK_STATUS = 19
+    const val MSG_CODE_PAYING_CANCEL = 19
+    /*************************不能重复*****************************/
+    /**
+     * 卡消费标志(1 byte)
+     */
+    /*high 4 bit*/
+    const val TRANSFLAG_NORMAL_CONSUME = 0x80 // 正常消费
+    const val TRANSFLAG_MEALER_CONSUME = 0xC0 // 搭伙
+    const val TRANSFLAG_DISCNT_CONSUME = 0xA0 // 折扣
+    const val TRANSFLAG_REVS_ML_CONSUME = 0x40 //冲正带搭伙
+    const val TRANSFLAG_REVS_DST_CONSUME = 0x20 // 冲正带折扣
+    const val TRANSFLAG_REVERSE_AUTO_CONSUME = 0x10 // 自动撤销 (0x00 手动冲正)
+    const val TRANSFLAG_REVERSE_CONSUME = 0x00 //&0x80 最高位0标识冲正(统一标识)
+    /*low 4 bit*/
+    const val TRANSFLAG_WRITE_CARD_SUCCESS = 0x01 // 写卡成功
+    const val TRANSFLAG_WRITE_CARD_HALFAWAY = 0x02 // 中途拔卡
+    const val TRANSFLAG_UNWRITE_CARD = 0x03 // 未写卡
+    const val TRANSFLAG_PWD_CONSUME = 0x04 // 密码消费
+
+    const val BG_SERVICE_NAME = "com.supwisdom.service.BackgroundTaskService"
+
+    /**
+     * Toast show
+     */
+    const val TOAST_SHOW_CRY = 1
+    const val TOAST_SHOW_SMILE = 2
+    const val TOAST_SHOW_DOUBT = 3
+
+    const val DIALOG_TYPE_BIG_PICTURE = 1
+    const val DIALOG_TYPE_PURCHASE = 2
+    const val DIALOG_TYPE_PASSWORD = 3
+    const val DIALOG_TYPE_SELECT_ORDER = 4
+    const val DIALOG_TYPE_DPS_CONFIRM = 5
+    const val DIALOG_TYPE_SCAN_RVS_CONFIRM = 6
+    const val DIALOG_TYPE_ORDINARY_CONSUME = 7
+    const val DIALOG_TYPE_DEPOSIT = 8
+    const val DIALOG_TYPE_NSD_CONFIG = 9
+
+    /**
+     * 本地全局控制参数
+     */
+    const val CONTROL_FIXAMT = "fixamt"
+    const val CONTROL_OFFLINE_DAY_DISABLE = "offdaydisable"
+    const val CONTROL_DEBUG_ENABLE = "debugenable"
+    /**
+     * 非定额消费标识
+     */
+    const val CONTROL_NO_FIXPAY_FLAG = "none"
+    /**
+     * 消费冲正时限
+     */
+    const val REVERSE_MS_GAP = 600000
+    /**
+     *
+     */
+    const val APP_ID = "3000004"
+    const val APP_SECRET = "c9ae5b4fe5014b5b9eb19e1a0797a3a3"
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/SoundUtil.kt b/app/src/main/java/com/supwisdom/utils/SoundUtil.kt
new file mode 100644
index 0000000..2c80655
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/SoundUtil.kt
@@ -0,0 +1,70 @@
+package com.supwisdom.utils
+
+import android.content.Context
+import android.media.AudioManager
+import android.media.SoundPool
+import com.supwisdom.R
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc
+ **/
+@Suppress("DEPRECATION")
+object SoundUtil {
+    private var soundId: Int = 0
+    private var soundPool: SoundPool? = null
+    private val soundMap = hashMapOf<Int, Int>()
+    private var keyEnable = false
+
+    fun playMusic(context: Context, mid: Int) {
+        if (!keyEnable && isKeyPlay(mid)) {
+            return
+        }
+        if (soundPool == null) {
+            soundPool = SoundPool(30, AudioManager.STREAM_MUSIC, 0) //分别对应声音池数量,AudioManager.STREAM_MUSIC 和 0
+        }
+        if (soundMap.containsKey(mid)) {
+            soundPool!!.play(soundMap[mid]!!, 1.0f, 1.0f, 1, 0, 1.0f)
+        } else {
+            soundId = soundPool!!.load(context, mid, 1)
+            soundPool!!.setOnLoadCompleteListener { pool, sampleId, status ->
+                soundMap[mid] = soundId
+                //  加载完成
+                pool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f)
+            }
+        }
+    }
+
+    fun releaseMusic() {
+        if (soundPool != null) {
+            soundPool!!.release()
+            soundPool = null
+        }
+        soundMap.clear()
+    }
+
+    fun setKeyPlay(enable: Boolean) {
+        keyEnable = enable
+    }
+
+    private fun isKeyPlay(mid: Int): Boolean {
+        return mid == R.raw.key_one ||
+                mid == R.raw.key_two ||
+                mid == R.raw.key_three ||
+                mid == R.raw.key_four ||
+                mid == R.raw.key_five ||
+                mid == R.raw.key_six ||
+                mid == R.raw.key_seven ||
+                mid == R.raw.key_eight ||
+                mid == R.raw.key_nine ||
+                mid == R.raw.key_zero ||
+                mid == R.raw.key_dot ||
+                mid == R.raw.key_add ||
+                mid == R.raw.key_clear ||
+                mid == R.raw.key_enter ||
+                mid == R.raw.key_fone ||
+                mid == R.raw.key_ftwo ||
+                mid == R.raw.key_fthree ||
+                mid == R.raw.key_ffour
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/ThreadPool.kt b/app/src/main/java/com/supwisdom/utils/ThreadPool.kt
new file mode 100644
index 0000000..eab9150
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/ThreadPool.kt
@@ -0,0 +1,170 @@
+package com.supwisdom.utils
+
+import java.util.concurrent.Executors
+import java.util.concurrent.LinkedBlockingQueue
+import java.util.concurrent.ThreadPoolExecutor
+import java.util.concurrent.TimeUnit
+
+/**
+ ** create by zzq on 2019/7/23
+ ** @desc
+ **/
+object ThreadPool {
+    private val DEFAULT_SINGLE_POOL_NAME = "DEFAULT_SINGLE_POOL_NAME"
+
+    private var mLongPool: ThreadPoolProxy? = null
+    private var mShortPool: ThreadPoolProxy? = null
+    private var mDownloadPool: ThreadPoolProxy? = null
+    private val mMap = hashMapOf<String, ThreadPoolProxy>()
+
+    /**
+     * 获取下载线程
+     */
+    fun getDownloadPool(): ThreadPoolProxy {
+        if (mDownloadPool == null) {
+            synchronized(ThreadPool::class.java) {
+                if (mDownloadPool == null) {
+                    //获取CPU核数
+                    val num = Runtime.getRuntime().availableProcessors()
+                    val corePoolSize = num + 1
+                    val maximumPoolSize = 2 * num + 1
+                    mDownloadPool = ThreadPoolProxy(corePoolSize, maximumPoolSize, 1L)
+                }
+            }
+        }
+        return mDownloadPool!!
+    }
+
+    /**
+     * 获取一个用于执行长耗时任务的线程池,避免和短耗时任务处在同一个队列而阻塞了重要的短耗时任务,通常用来联网操作
+     */
+
+    fun getLongPool(): ThreadPoolProxy {
+        if (mLongPool == null) {
+            synchronized(ThreadPool::class.java) {
+                if (mLongPool == null) {
+                    //获取CPU核数
+                    val num = Runtime.getRuntime().availableProcessors()
+                    val corePoolSize = num + 1
+                    val maximumPoolSize = 2 * num + 1
+                    mLongPool = ThreadPoolProxy(corePoolSize, maximumPoolSize, 1L)
+                }
+            }
+        }
+        return mLongPool!!
+    }
+
+    /**
+     * 获取一个用于执行短耗时任务的线程池,避免因为和耗时长的任务处在同一个队列而长时间得不到执行,通常用来执行本地的IO/SQL
+     */
+    fun getShortPool(): ThreadPoolProxy {
+        if (mShortPool == null) {
+            synchronized(ThreadPool::class.java) {
+                if (mShortPool == null) {
+                    //获取CPU核数
+                    val num = Runtime.getRuntime().availableProcessors()
+                    val corePoolSize = num + 1
+                    val maximumPoolSize = 2 * num + 1
+                    mShortPool = ThreadPoolProxy(corePoolSize, maximumPoolSize, 1L)
+                }
+            }
+        }
+        return mShortPool!!
+    }
+
+    /**
+     * 获取一个单线程池,所有任务将会被按照加入的顺序执行,免除了同步开销的问题
+     */
+    fun getSinglePool(): ThreadPoolProxy {
+        return getSinglePool(DEFAULT_SINGLE_POOL_NAME)
+    }
+
+    /**
+     * 获取一个单线程池,所有任务将会被按照加入的顺序执行,免除了同步开销的问题
+     */
+    fun getSinglePool(name: String): ThreadPoolProxy {
+        synchronized(ThreadPool::class.java) {
+            var singlePool: ThreadPoolProxy? = mMap[name]
+            if (singlePool == null) {
+                singlePool = ThreadPoolProxy(1, 1, 1L)
+                mMap[name] = singlePool
+            }
+            return singlePool
+        }
+    }
+
+    class ThreadPoolProxy constructor(
+        private val mCorePoolSize: Int,
+        private val mMaximumPoolSize: Int,
+        private val mKeepAliveTime: Long
+    ) {
+        private var mPool: ThreadPoolExecutor? = null
+
+        /**
+         * 执行任务,当线程池处于关闭,将会重新创建新的线程池
+         */
+        @Synchronized
+        fun execute(run: Runnable) {
+            if (mPool == null || mPool!!.isShutdown) {
+                //参数说明
+                //当线程池中的线程小于mCorePoolSize,直接创建新的线程加入线程池执行任务
+                //当线程池中的线程数目等于mCorePoolSize,将会把任务放入任务队列BlockingQueue中
+                //当BlockingQueue中的任务放满了,将会创建新的线程去执行,
+                //但是当总线程数大于mMaximumPoolSize时,将会抛出异常,交给RejectedExecutionHandler处理
+                //mKeepAliveTime是线程执行完任务后,且队列中没有可以执行的任务,存活的时间,后面的参数是时间单位
+                //ThreadFactory是每次创建新的线程工厂
+                mPool = ThreadPoolExecutor(
+                    mCorePoolSize,
+                    mMaximumPoolSize,
+                    mKeepAliveTime,
+                    TimeUnit.MILLISECONDS,
+                    LinkedBlockingQueue(),
+                    Executors.defaultThreadFactory(),
+                    ThreadPoolExecutor.AbortPolicy()
+                )
+            }
+            mPool!!.execute(run)
+        }
+
+        /**
+         * 取消线程池中某个还未执行的任务
+         */
+        @Synchronized
+        fun cancel(run: Runnable) {
+            if (mPool != null && (!mPool!!.isShutdown || mPool!!.isTerminating)) {
+                mPool!!.queue.remove(run)
+            }
+        }
+
+        /**
+         * 取消线程池中某个还未执行的任务
+         */
+        @Synchronized
+        operator fun contains(run: Runnable): Boolean {
+            return if (mPool != null && (!mPool!!.isShutdown || mPool!!.isTerminating)) {
+                mPool!!.queue.contains(run)
+            } else {
+                false
+            }
+        }
+
+        /**
+         * 立刻关闭线程池,并且正在执行的任务也将会被中断
+         */
+        fun stop() {
+            if (mPool != null && (!mPool!!.isShutdown || mPool!!.isTerminating)) {
+                mPool!!.shutdownNow()
+            }
+        }
+
+        /**
+         * 平缓关闭单任务线程池,但是会确保所有已经加入的任务都将会被执行完毕才关闭
+         */
+        @Synchronized
+        fun shutdown() {
+            if (mPool != null && (!mPool!!.isShutdown || mPool!!.isTerminating)) {
+                mPool!!.shutdownNow()
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/utils/Util.kt b/app/src/main/java/com/supwisdom/utils/Util.kt
new file mode 100644
index 0000000..e9fb0df
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/Util.kt
@@ -0,0 +1,167 @@
+package com.supwisdom.utils
+
+import java.lang.Exception
+import java.util.regex.Pattern
+
+/**
+ * @author zzq
+ * @date 2018/3/20.
+ * @version 1.0.1
+ * @desc  TODO
+ */
+fun ByteArray.encodeHex(): String {
+    val res = StringBuilder()
+    forEach {
+        res.append("%02X".format(it.toInt() and 0xFF))
+    }
+    return res.toString()
+}
+
+fun String.decodeHex(): ByteArray {
+    if (this.isEmpty() || this.length % 2 != 0) {
+        throw Exception("不合法的数据")
+    }
+    return (0 until this.length step 2).map {
+        val v = this.substring(it, it + 2).toInt(16)
+        (v and 0xFF).toByte()
+    }.toByteArray()
+}
+
+fun String.encodeBCD(): ByteArray {
+    if (this.isEmpty() || this.length % 2 != 0) {
+        throw Exception("不合法的数据")
+    }
+    return (0 until this.length step 2).map {
+        val d = this.substring(it, it + 2)
+        val b1 = d[0].toInt() - 0x30
+        val b2 = d[1].toInt() - 0x30
+        if (b1 !in 0..9 || b2 !in 0..9) {
+            throw Exception("不合法的BCD格式数据<$this>")
+        }
+        ((b1.shl(4) or b2) and 0xFF).toByte()
+    }.toByteArray()
+}
+
+fun ByteArray.decodeBCD(): String {
+    return joinToString(separator = "") {
+        val b1 = it.unsignedToInt().shr(4)
+        val b2 = it.unsignedToInt() and 0x0F
+        if (b1 !in 0..9 || b2 !in 0..9) {
+            throw Exception("不合法的数据")
+        }
+        "%01d%01d".format(b1, b2)
+    }
+}
+
+fun byteArrayTohex(data: ByteArray, startPos: Int, byteLength: Int): String {
+    val res = StringBuilder()
+    data.forEachIndexed { index, s ->
+        if (index >= startPos && index < startPos + byteLength) {
+            res.append("%02X".format(s.unsignedToInt() and 0xFF))
+        }
+    }
+    return res.toString()
+}
+
+fun Byte.unsignedToInt(): Int {
+    return this.toInt() and 0xFF
+}
+
+fun Byte.unsignedToLong(): Long {
+    return this.toLong() and 0xFF
+}
+
+fun byteArrayToIntLe(data: ByteArray, startPos: Int, byteLength: Int): Int {
+    var res = 0
+    data.forEachIndexed { index, s ->
+        if (index >= startPos && index < startPos + byteLength) {
+            res = res or (s.unsignedToInt() shl ((index - startPos) shl 3))
+        }
+    }
+    return res
+}
+
+fun byteArrayToIntBe(data: ByteArray, startPos: Int, byteLength: Int): Int {
+    var res = 0
+    data.forEachIndexed { index, s ->
+        if (index >= startPos && index < startPos + byteLength) {
+            res = (res shl 8) or s.unsignedToInt()
+        }
+    }
+    return res
+}
+
+fun byteArrayToLongBe(data: ByteArray, startPos: Int, byteLength: Int): Long {
+    var res: Long = 0
+    data.forEachIndexed { index, s ->
+        if (index >= startPos && index < startPos + byteLength) {
+            res = (res shl 8) or s.toLong()
+        }
+    }
+    return res
+}
+
+fun byteArrayToLongLe(data: ByteArray): Long {
+    var res: Long = 0
+    data.forEachIndexed { index, s ->
+        res = res or ((s.toLong() and 0xFF) shl (index shl 3))
+    }
+    return res
+}
+
+
+fun intBeToByteArray(value: Int, byteLen: Int = 4): ByteArray {
+    if (byteLen !in 1..4) {
+        throw Exception("数据长度错误")
+    }
+    val res = "%08X".format(value).decodeHex()
+    return res.copyOfRange(4 - byteLen, 4)
+}
+
+fun intBeToByteArray(value: Int, data: ByteArray, startPos: Int, byteLen: Int) {
+    if (byteLen !in 1..4) {
+        throw Exception("数据长度错误")
+    }
+    val res = "%08X".format(value).decodeHex()
+    (startPos until startPos + byteLen).forEach {
+        data[it] = res[4 - byteLen + it - startPos]
+    }
+
+}
+
+fun longBeToByteArray(value: Long, byteLen: Int = 4): ByteArray {
+    if (byteLen !in 1..8) {
+        throw Exception("数据长度错误")
+    }
+    val res = ByteArray(8) { 0x00 }
+    (0..7).forEach {
+        res[it] = ((value shr ((7 - it) shl 3)) and 0xFF).toByte()
+    }
+    return res.copyOfRange(8 - byteLen, 8)
+}
+
+fun intLeToByteArray(value: Int, byteLen: Int = 4): ByteArray {
+    if (byteLen !in 1..4) {
+        throw Exception("数据长度错误")
+    }
+    val res = ByteArray(4) { 0x00 }
+    (0..3).forEach {
+        res[it] = ((value shr (it shl 3)) and 0xFF).toByte()
+    }
+    return res.copyOfRange(0, byteLen)
+}
+
+fun intLeToByteArray(value: Int, data: ByteArray, startPos: Int, byteLen: Int) {
+    if (byteLen !in 1..4) {
+        throw Exception("数据长度错误")
+    }
+    (0..3).forEach {
+        data[it + startPos] = ((value shr (it shl 3)) and 0xFF).toByte()
+    }
+}
+
+/**验证IP格式*/
+fun verifyIpFormat(ip: String): Boolean {
+    val pattern = Pattern.compile("")
+    return pattern.matcher(ip).matches()
+}
diff --git a/app/src/main/java/com/supwisdom/utils/ZipUtil.kt b/app/src/main/java/com/supwisdom/utils/ZipUtil.kt
new file mode 100644
index 0000000..37f1d09
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/utils/ZipUtil.kt
@@ -0,0 +1,194 @@
+package com.supwisdom.utils
+
+import org.apache.commons.lang3.StringUtils
+import java.io.*
+import java.util.*
+import java.util.zip.*
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+object ZipUtil {
+    /**
+     * 递归压缩文件夹
+     *
+     * @param srcRootDir 压缩文件夹根目录的子路径
+     * @param file       当前递归压缩的文件或目录对象
+     * @param zos        压缩文件存储对象
+     * @throws Exception
+     */
+    @Throws(Exception::class)
+    private fun zip(srcRootDir: String, file: File?, zos: ZipOutputStream) {
+        if (file == null) {
+            throw Exception("file is null")
+        }
+
+        //如果是文件,则直接压缩该文件
+        if (file.isFile) {
+            var count: Int
+            val bufferLen = 1024
+            val data = ByteArray(bufferLen)
+
+            //获取文件相对于压缩文件夹根目录的子路径
+            var subPath = file.absolutePath
+            val index = subPath.indexOf(srcRootDir)
+            if (index != -1) {
+                subPath = subPath.substring(srcRootDir.length + File.separator.length)
+            }
+            val entry = ZipEntry(subPath)
+            zos.putNextEntry(entry)
+            val bis = BufferedInputStream(FileInputStream(file))
+            while (true) {
+                count = bis.read(data, 0, bufferLen)
+                if (count < 0) {
+                    break
+                }
+                zos.write(data, 0, count)
+            }
+            bis.close()
+            zos.closeEntry()
+        } else {
+            //压缩目录中的文件或子目录
+            val childFileList = file.listFiles()
+            for (aChildFileList in childFileList!!) {
+                aChildFileList.absolutePath.indexOf(file.absolutePath)
+                zip(srcRootDir, aChildFileList, zos)
+            }
+        }//如果是目录,则压缩整个目录
+    }
+
+    /**
+     * 对文件或文件目录进行压缩
+     *
+     * @param srcPath     要压缩的源文件路径。如果压缩一个文件,则为该文件的全路径;如果压缩一个目录,则为该目录的顶层目录路径
+     * @param zipPath     压缩文件保存的路径。注意:zipPath不能是srcPath路径下的子文件夹
+     * @param zipFileName 压缩文件名
+     * @throws Exception
+     */
+    @Throws(Exception::class)
+    fun zip(srcPath: String, zipPath: String, zipFileName: String) {
+        if (StringUtils.isEmpty(srcPath) || StringUtils.isEmpty(zipPath) || StringUtils.isEmpty(zipFileName)) {
+            throw Exception("传入参数为空")
+        }
+        try {
+            val srcFile = File(srcPath)
+            //判断压缩文件保存的路径是否为源文件路径的子文件夹,如果是,则抛出异常(防止无限递归压缩的发生)
+            if (srcFile.isDirectory && zipPath.contains(srcPath)) {
+                throw Exception("zipPath must not be the child directory of srcPath.")
+            }
+
+            //判断压缩文件保存的路径是否存在,如果不存在,则创建目录
+            val zipDir = File(zipPath)
+            if (!zipDir.exists() || !zipDir.isDirectory) {
+                zipDir.mkdirs()
+            }
+
+            //创建压缩文件保存的文件对象
+            val zipFilePath = zipPath + File.separator + zipFileName
+            val zipFile = File(zipFilePath)
+            if (zipFile.exists()) {
+                //检测文件是否允许删除,如果不允许删除,将会抛出SecurityException
+                val securityManager = SecurityManager()
+                securityManager.checkDelete(zipFilePath)
+                //删除已存在的目标文件
+                zipFile.delete()
+            }
+
+            val cos = CheckedOutputStream(FileOutputStream(zipFile), CRC32())
+            val zos = ZipOutputStream(cos)
+
+            //如果只是压缩一个文件,则需要截取该文件的父目录
+            var srcRootDir = srcPath
+            if (srcFile.isFile) {
+                val index = srcPath.lastIndexOf(File.separator)
+                if (index != -1) {
+                    srcRootDir = srcPath.substring(0, index)
+                }
+            }
+            //调用递归压缩方法进行目录或文件压缩
+            zip(srcRootDir, srcFile, zos)
+            zos.flush()
+            zos.close()
+        } catch (e: Exception) {
+            throw e
+        }
+
+    }
+
+    /**
+     * 解压缩zip包
+     *
+     * @param zipFilePath        zip文件的全路径
+     * @param unzipFilePath      解压后的文件保存的路径
+     * @param includeZipFileName 解压后的文件保存的路径是否包含压缩文件的文件名。true-包含;false-不包含
+     */
+    @Throws(Exception::class)
+    fun unzip(zipFilePath: String, unzipFilePath: String, includeZipFileName: Boolean) {
+        var unzipFilePath = unzipFilePath
+        if (StringUtils.isEmpty(zipFilePath) || StringUtils.isEmpty(unzipFilePath)) {
+            throw Exception("传入参数为空")
+        }
+        val zipFile = File(zipFilePath)
+        //如果解压后的文件保存路径包含压缩文件的文件名,则追加该文件名到解压路径
+        if (includeZipFileName) {
+            var fileName = zipFile.name
+            if (StringUtils.isNotEmpty(fileName)) {
+                fileName = fileName.substring(0, fileName.lastIndexOf("."))
+            }
+            unzipFilePath = unzipFilePath + File.separator + fileName
+        }
+        //创建解压缩文件保存的路径
+        val unzipFileDir = File(unzipFilePath)
+        if (!unzipFileDir.exists() || !unzipFileDir.isDirectory) {
+            unzipFileDir.mkdirs()
+        }
+
+        //开始解压
+        val bufferSize = 1024
+        val buffer = ByteArray(bufferSize)
+        val zip = ZipFile(zipFile)
+        val entries = zip.entries() as Enumeration<ZipEntry>
+        //循环对压缩包里的每一个文件进行解压
+        while (entries.hasMoreElements()) {
+            val entry = entries.nextElement()
+            //构建压缩包中一个文件解压后保存的文件全路径
+            val entryFilePath = unzipFilePath + File.separator + entry.name
+            //构建解压后保存的文件夹路径
+            val index = entryFilePath.lastIndexOf(File.separator)
+            var entryDirPath = ""
+            if (index != -1) {
+                entryDirPath = entryFilePath.substring(0, index)
+            }
+            val entryDir = File(entryDirPath)
+            //如果文件夹路径不存在,则创建文件夹
+            if (!entryDir.exists() || !entryDir.isDirectory) {
+                entryDir.mkdirs()
+            }
+
+            //创建解压文件
+            val entryFile = File(entryFilePath)
+            if (entryFile.exists()) {
+                //检测文件是否允许删除,如果不允许删除,将会抛出SecurityException
+                val securityManager = SecurityManager()
+                securityManager.checkDelete(entryFilePath)
+                //删除已存在的目标文件
+                entryFile.delete()
+            }
+
+            //写入文件
+            val bos = BufferedOutputStream(FileOutputStream(entryFile))
+            val bis = BufferedInputStream(zip.getInputStream(entry))
+            var count: Int
+            while (true) {
+                count = bis.read(buffer, 0, bufferSize)
+                if (count < 0) {
+                    break
+                }
+                bos.write(buffer, 0, count)
+            }
+            bos.flush()
+            bos.close()
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/BigProgressDialog.kt b/app/src/main/java/com/supwisdom/view/BigProgressDialog.kt
new file mode 100644
index 0000000..9fd9825
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/BigProgressDialog.kt
@@ -0,0 +1,47 @@
+package com.supwisdom.view
+
+import android.app.Activity
+import android.app.ProgressDialog
+import android.content.Context
+import android.view.Gravity
+import android.widget.TextView
+import com.supwisdom.R
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+@Suppress("DEPRECATION")
+class BigProgressDialog constructor(context: Context, strMessage: String, cancelable: Boolean) :
+    ProgressDialog(context) {
+    private var tvMsg: TextView
+
+    init {
+        this.show()
+        this.setContentView(R.layout.dialog_progress)
+        this.window!!.attributes.gravity = Gravity.CENTER
+        tvMsg = this.findViewById<TextView>(R.id.loadingmsg)
+        this.setCancelable(cancelable)
+        setCanceledOnTouchOutside(false)
+        tvMsg.text = strMessage
+    }
+
+    fun setMsg(msg: String) {
+        tvMsg.text = msg
+    }
+
+    override fun show() {
+        if (!(context as Activity).isFinishing) {
+            //防止activity处于销毁状态
+            //android.view.WindowManager$BadTokenException: Unable to add window
+            // -- token android.os.BinderProxy@41b43ec0 is not valid; is your activity running
+            super.show()
+        }
+    }
+
+    override fun dismiss() {
+        if (!(context as Activity).isFinishing) {
+            super.dismiss()
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/BigSwDialog.kt b/app/src/main/java/com/supwisdom/view/BigSwDialog.kt
new file mode 100644
index 0000000..45fa8f3
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/BigSwDialog.kt
@@ -0,0 +1,30 @@
+package com.supwisdom.view
+
+import android.content.Context
+import android.view.KeyEvent
+import com.supwisdom.R
+import com.supwisdom.utils.PublicDef
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+class BigSwDialog constructor(context: Context, dialogType: Int) : DialogBase(context) {
+    init {
+        when (dialogType) {
+            PublicDef.DIALOG_TYPE_PASSWORD -> this.setContentView(R.layout.dialog_password)
+            PublicDef.DIALOG_TYPE_NSD_CONFIG -> this.setContentView(R.layout.dialog_init_nsd_config)
+        }
+        this.setCancelable(false)
+        this.setCanceledOnTouchOutside(false)
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            when (event.keyCode) {
+                KeyEvent.KEYCODE_DEL -> dismiss()
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/DialogBase.kt b/app/src/main/java/com/supwisdom/view/DialogBase.kt
new file mode 100644
index 0000000..bb6d40b
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/DialogBase.kt
@@ -0,0 +1,47 @@
+package com.supwisdom.view
+
+import android.app.Activity
+import android.app.Dialog
+import android.content.Context
+import com.supwisdom.R
+
+/**
+ * @author zzq
+ * @date 2018/6/7
+ * @desc 基类dialog
+ */
+open class DialogBase constructor(context: Context) : Dialog(context, R.style.FloatingDialog) {
+    private val ctx = context
+
+    override fun show() {
+        if (ctx is Activity) {
+            if (!ctx.isFinishing) {
+                //防止activity处于销毁状态
+                //android.view.WindowManager$BadTokenException: Unable to add window
+                // -- token android.os.BinderProxy@41b43ec0 is not valid; is your activity running
+                super.show()
+            }
+        } else {
+//            val activity = (ctx as ContextWrapper).baseContext as Activity
+//            if (!activity.isFinishing) {
+            //防止activity处于销毁状态
+            //android.view.WindowManager$BadTokenException: Unable to add window
+            // -- token android.os.BinderProxy@41b43ec0 is not valid; is your activity running
+            super.show()
+//            }
+        }
+    }
+
+    override fun dismiss() {
+        if (ctx is Activity) {
+            if (!ctx.isFinishing) {
+                super.dismiss()
+            }
+        } else {
+//            val activity = (ctx as ContextWrapper).baseContext as Activity
+//            if (!activity.isFinishing) {
+            super.dismiss()
+//            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/DialogPurchase.kt b/app/src/main/java/com/supwisdom/view/DialogPurchase.kt
new file mode 100644
index 0000000..39b5806
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/DialogPurchase.kt
@@ -0,0 +1,223 @@
+package com.supwisdom.view
+
+import android.content.Context
+import android.graphics.Color
+import android.os.CountDownTimer
+import android.view.KeyEvent
+import android.view.View
+import android.widget.TextView
+import com.google.zxing.Result
+import com.newcapec.zxinglib.IDecoderAcquirer
+import com.newcapec.zxinglib.PosDecoder
+import com.supwisdom.R
+import com.supwisdom.activities.consume.bean.CardUserInfoBean
+import com.supwisdom.utils.CommonUtil
+import com.supwisdom.utils.LogUtil
+
+/**
+ ** create by zzq on 2019/7/26
+ ** @desc 消费弹窗
+ **/
+class DialogPurchase constructor(context: Context, callBack: ICallBack) : DialogBase(context), IDecoderAcquirer {
+    private val TAG = "DialogPurchase"
+    private val callBack = callBack
+    private var vCount: TextView
+    private var vPayhint: TextView
+    private var vPayamt: TextView
+    private var vBalance: TextView
+    private var posDec: PosDecoder? = null
+    private var lastFixpayDecoderOpenTime: Long = 0
+    private val waitTime = 60
+    var codePayingNoCancelEnable = false
+    var codePaying = false
+    var isFixPay = false
+
+    init {
+        setContentView(R.layout.dialog_purchase)
+
+        vCount = this.findViewById(R.id.tv_close_count) as TextView
+        vPayhint = this.findViewById(R.id.tv_pay_hint) as TextView
+        vPayamt = this.findViewById(R.id.tv_pay_amount) as TextView
+        vBalance = this.findViewById(R.id.tv_pay_balance) as TextView
+
+        posDec = PosDecoder(this)
+    }
+
+    override fun onFailed() {
+
+    }
+
+    override fun onDecoded(result: String?) {
+
+    }
+
+    override fun onDecoded(result: Result?) {
+        val rawSize = result?.rawBytes?.size ?: 0
+        if (rawSize > 0) {
+            callBack.callback(result!!.text)
+        }
+    }
+
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.action == KeyEvent.ACTION_DOWN) {
+            if (codePayingNoCancelEnable) {
+                return super.dispatchKeyEvent(event)
+            }
+            when (event.keyCode) {
+                KeyEvent.KEYCODE_DEL -> {
+                    finish(true)
+                }
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    fun show(hint: String, amount: String) {
+        vPayhint.text = hint
+        vPayhint.setTextColor(Color.BLACK)
+        vPayamt.text = amount
+        vPayamt.visibility = View.VISIBLE
+
+        vBalance.visibility = View.GONE
+        show()
+        asyncOpenDecoder()
+        resetCounter(waitTime)
+    }
+
+    fun showProcess(hint: String, amount: String) {
+        vPayhint.text = hint
+        vPayhint.setTextColor(Color.RED)
+        vPayamt.text = amount
+        vPayamt.visibility = View.VISIBLE
+
+        vBalance.visibility = View.GONE
+        resetCounter(waitTime)
+    }
+
+    fun showPaySuccess(info: CardUserInfoBean) {
+        vPayhint.text = info.retmsg
+        vPayhint.setTextColor(Color.GREEN)
+        vPayamt.text = CommonUtil.showFormatAmount("金额", info.payamt)
+        vPayamt.visibility = View.VISIBLE
+        if (info.balance == null) {
+            vBalance.visibility = View.GONE
+        } else {
+            vBalance.text = CommonUtil.showFormatAmount("余额", info.balance!!)
+            vBalance.visibility = View.VISIBLE
+        }
+        show()
+        resetCounter(info.showtime)
+    }
+
+    fun showPayFail(info: CardUserInfoBean) {
+        vPayhint.text = "消费失败"
+        vPayhint.setTextColor(Color.RED)
+        vPayamt.text = info.retmsg
+        vPayamt.visibility = View.VISIBLE
+        vBalance.visibility = View.GONE
+        show()
+        resetCounter(info.showtime)
+    }
+
+    fun showReverseSuccess(info: CardUserInfoBean) {
+        vPayhint.text = info.retmsg
+        vPayhint.setTextColor(Color.GREEN)
+        vPayamt.text = CommonUtil.showFormatAmount("金额", info.amount)
+        vPayamt.visibility = View.VISIBLE
+        vBalance.visibility = View.GONE
+        show()
+        resetCounter(info.showtime)
+    }
+
+    fun showReverseFail(info: CardUserInfoBean) {
+        vPayhint.text = "冲正失败"
+        vPayhint.setTextColor(Color.RED)
+        vPayamt.text = info.retmsg
+        vPayamt.visibility = View.VISIBLE
+        vBalance.visibility = View.GONE
+        show()
+        resetCounter(info.showtime)
+    }
+
+    private fun asyncOpenDecoder() {
+        if (!isFixPay) {
+            try {
+                posDec!!.onResume()
+            } catch (ex: Exception) {
+                ex.printStackTrace()
+                LogUtil.d(TAG, "open camera exception:" + CommonUtil.getExceptionStack(ex))
+            }
+        } else {
+            val time = System.currentTimeMillis()
+            if (time < lastFixpayDecoderOpenTime ||
+                time - lastFixpayDecoderOpenTime > 120000
+            ) {
+                lastFixpayDecoderOpenTime = time
+                try {
+                    posDec!!.onPause()
+                } catch (ex: Exception) {
+                    ex.printStackTrace()
+                    LogUtil.d(TAG, "fix close camera exception:" + CommonUtil.getExceptionStack(ex))
+                }
+                try {
+                    posDec!!.onResume()
+                } catch (ex: Exception) {
+                    ex.printStackTrace()
+                    LogUtil.d(TAG, "fix open camera exception:" + CommonUtil.getExceptionStack(ex))
+                }
+            }
+        }
+    }
+
+    private fun asyncCloseDecoder() {
+        if (!isFixPay) {
+            try {
+                posDec!!.onPause()
+            } catch (ex: Exception) {
+                ex.printStackTrace()
+                LogUtil.d(TAG, "close camera exception:" + CommonUtil.getExceptionStack(ex))
+            }
+        }
+    }
+
+    private fun finish(isManualCancel: Boolean) {
+        codePaying = false
+        codePayingNoCancelEnable = false
+        dismiss()
+        callBack.callback(isManualCancel)
+        asyncCloseDecoder()
+    }
+
+    private var counter: ConsumeHintCount? = null
+
+    private fun resetCounter(times: Int) {
+        counter?.cancel()
+        counter = ConsumeHintCount((times * 1000).toLong(), 200)
+        counter?.start()
+    }
+
+    private inner class ConsumeHintCount
+    /**
+     * @param millisInFuture    The number of millis in the future from the call
+     * to [.login] until the countdown is done and [.onFinish]
+     * is called.
+     * @param countDownInterval The interval along the way to receive
+     * [.onTick] callbacks.
+     */
+        (millisInFuture: Long, countDownInterval: Long) : CountDownTimer(millisInFuture, countDownInterval) {
+
+        override fun onTick(millisUntilFinished: Long) {
+            vCount.text = "${millisUntilFinished / 1000}s"
+        }
+
+        override fun onFinish() {
+            finish(false)
+        }
+    }
+
+    interface ICallBack {
+        fun callback(isManualCancel: Boolean)
+
+        fun callback(code: String)
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/ListViewUtil.kt b/app/src/main/java/com/supwisdom/view/ListViewUtil.kt
new file mode 100644
index 0000000..cef2581
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/ListViewUtil.kt
@@ -0,0 +1,43 @@
+package com.supwisdom.view
+
+import android.widget.ListView
+
+/**
+ * @author zzq
+ * @date 2018/5/9.
+ * @version 1.0.1
+ * @desc  动态测量adapter listview的高度
+ */
+object ListViewUtil {
+    fun setListViewHeightBasedOnChildren(listView: ListView) {
+        val listAdapter = listView.adapter ?: return
+
+        var totalHeight = 0
+        for (i in 0 until listAdapter.count) {
+            val listItem = listAdapter.getView(i, null, listView)
+            listItem.measure(0, 0)
+            totalHeight += listItem.measuredHeight
+        }
+
+        val params = listView.layoutParams
+        params.height = totalHeight + listView.dividerHeight * (listAdapter.count - 1)
+        listView.layoutParams = params
+    }
+
+    fun getListViewHeightBasedOnChildren(listView: ListView): Int {
+        val listAdapter = listView.adapter
+        var totalHeight = 0
+        for (i in 0 until listAdapter.count) {
+            val listItem = listAdapter.getView(i, null, listView)
+            listItem.measure(0, 0)
+            totalHeight += listItem.measuredHeight
+        }
+        return totalHeight + listView.dividerHeight * (listAdapter.count - 1)
+    }
+
+    fun setListViewHeight(listView: ListView, height: Int) {
+        val params = listView.layoutParams
+        params.height = height
+        listView.layoutParams = params
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/RecyclerViewUtil.kt b/app/src/main/java/com/supwisdom/view/RecyclerViewUtil.kt
new file mode 100644
index 0000000..7af0cd0
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/RecyclerViewUtil.kt
@@ -0,0 +1,26 @@
+package com.supwisdom.view
+
+import android.graphics.Rect
+import android.support.v7.widget.RecyclerView
+import android.view.View
+
+/**
+ * @author zzq
+ * @date 2018/6/21
+ * @desc TODO
+ */
+object RecyclerViewUtil {
+    class ItemDecoration constructor(top: Int, bottom: Int, left: Int, right: Int) : RecyclerView.ItemDecoration() {
+        private val top = top
+        private val bottom = bottom
+        private val left = left
+        private val right = right
+        override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
+            super.getItemOffsets(outRect, view, parent, state)
+            outRect!!.top = top
+            outRect.left = left
+            outRect.bottom = bottom
+            outRect.right = right
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/SWToast.kt b/app/src/main/java/com/supwisdom/view/SWToast.kt
new file mode 100644
index 0000000..deb3fa2
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/SWToast.kt
@@ -0,0 +1,53 @@
+package com.supwisdom.view
+
+import android.content.Context
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import android.widget.Toast
+import com.supwisdom.R
+import com.supwisdom.utils.PublicDef
+
+/**
+ ** create by zzq on 2019/7/24
+ ** @desc
+ **/
+object SWToast {
+    fun show(context: Context, msg: String, showway: Int) {
+        val Inflater = LayoutInflater.from(context)
+        val layout = Inflater.inflate(R.layout.sw_toast, null)
+
+        val cry = layout.findViewById(R.id.pic_cry) as ImageView
+        val smile = layout.findViewById(R.id.pic_smile) as ImageView
+        val doubt = layout.findViewById(R.id.pic_doubt) as ImageView
+        if (showway == PublicDef.TOAST_SHOW_CRY) {
+            cry.visibility = View.VISIBLE
+            smile.visibility = View.GONE
+            doubt.visibility = View.GONE
+        } else if (showway == PublicDef.TOAST_SHOW_SMILE) {
+            cry.visibility = View.GONE
+            smile.visibility = View.VISIBLE
+            doubt.visibility = View.GONE
+        } else if (showway == PublicDef.TOAST_SHOW_DOUBT) {
+            cry.visibility = View.GONE
+            smile.visibility = View.GONE
+            doubt.visibility = View.VISIBLE
+        } else {
+            cry.visibility = View.GONE
+            smile.visibility = View.VISIBLE
+            doubt.visibility = View.GONE
+        }
+
+        // set a message
+        val toastText = layout.findViewById(R.id.toasttext) as TextView
+        toastText.text = msg
+        // Toast...
+        val toast = Toast(context)
+        toast.setGravity(Gravity.CENTER, 0, 0)
+        toast.duration = Toast.LENGTH_SHORT
+        toast.view = layout
+        toast.show()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/supwisdom/view/ToastUtil.kt b/app/src/main/java/com/supwisdom/view/ToastUtil.kt
new file mode 100644
index 0000000..7d82257
--- /dev/null
+++ b/app/src/main/java/com/supwisdom/view/ToastUtil.kt
@@ -0,0 +1,86 @@
+package com.supwisdom.view
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.CountDownTimer
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.widget.TextView
+import android.widget.Toast
+import com.supwisdom.R
+
+/**
+ * @author zzq
+ * @date 2018/3/20.
+ * @version 1.0.1
+ * @desc  界面操作提示
+ */
+@SuppressLint("StaticFieldLeak")
+object ToastUtil {
+    private var toast: Toast? = null
+    private var toastText: TextView? = null
+    private var counter: CountDownTimer? = null
+
+    private var toast1: Toast? = null
+    private var toastText1: TextView? = null
+
+    fun show(context: Context, msg: String) {
+        if (toast1 == null) {
+            toast1 = Toast(context)
+            val view = LayoutInflater.from(context).inflate(R.layout.toast_util, null)
+            toastText1 = view.findViewById(R.id.toasttext) as TextView
+            toast1!!.setGravity(Gravity.CENTER, 0, 0)
+            toast1!!.duration = Toast.LENGTH_SHORT
+            toast1!!.view = view
+        }
+        toastText1!!.text = msg
+        toast1!!.show()
+    }
+
+    fun show(context: Context, msg: String, listener: ShowListener?) {
+        if (toast == null) {
+            toast = Toast(context)
+            val view = LayoutInflater.from(context).inflate(R.layout.toast_util, null)
+
+            toastText = view.findViewById(R.id.toasttext) as TextView
+            toast!!.setGravity(Gravity.CENTER, 0, 0)
+            toast!!.duration = Toast.LENGTH_LONG
+            toast!!.view = view
+        }
+        toastText!!.text = msg
+        toast!!.show()
+        if (counter == null) {
+            counter = object : CountDownTimer(2000, 200) {
+                override fun onTick(millisUntilFinished: Long) {
+
+                }
+
+                override fun onFinish() {
+                    listener?.callback()
+                    toast!!.cancel()
+                }
+            }
+        } else {
+            counter!!.cancel()
+            counter = object : CountDownTimer(2000, 200) {
+                override fun onTick(millisUntilFinished: Long) {
+
+                }
+
+                override fun onFinish() {
+                    listener?.callback()
+                    toast!!.cancel()
+                }
+            }
+        }
+        counter!!.start()
+    }
+
+    fun cancel() {
+        toast!!.cancel()
+    }
+
+    interface ShowListener {
+        fun callback()
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/jniLibs/arm64-v8a/libalipay_code_verify.so b/app/src/main/jniLibs/arm64-v8a/libalipay_code_verify.so
new file mode 100644
index 0000000..8437590
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libalipay_code_verify.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libauxScreen.so b/app/src/main/jniLibs/arm64-v8a/libauxScreen.so
new file mode 100644
index 0000000..01741bf
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libauxScreen.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libcrypto.so b/app/src/main/jniLibs/arm64-v8a/libcrypto.so
new file mode 100644
index 0000000..e4841ff
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libcrypto.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libiccV108.so b/app/src/main/jniLibs/arm64-v8a/libiccV108.so
new file mode 100644
index 0000000..608edea
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libiccV108.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libiccV110.so b/app/src/main/jniLibs/arm64-v8a/libiccV110.so
new file mode 100644
index 0000000..c2ef8cc
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libiccV110.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libiccV115.so b/app/src/main/jniLibs/arm64-v8a/libiccV115.so
new file mode 100644
index 0000000..61635a1
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libiccV115.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libiccV116.so b/app/src/main/jniLibs/arm64-v8a/libiccV116.so
new file mode 100644
index 0000000..c2ef8cc
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libiccV116.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libpiccV108.so b/app/src/main/jniLibs/arm64-v8a/libpiccV108.so
new file mode 100644
index 0000000..c62695a
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libpiccV108.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libpiccV115.so b/app/src/main/jniLibs/arm64-v8a/libpiccV115.so
new file mode 100644
index 0000000..df17f28
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libpiccV115.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libpiccV116.so b/app/src/main/jniLibs/arm64-v8a/libpiccV116.so
new file mode 100644
index 0000000..df17f28
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libpiccV116.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libserial_port.so b/app/src/main/jniLibs/arm64-v8a/libserial_port.so
new file mode 100644
index 0000000..7cd1a8a
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libserial_port.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libssl.so b/app/src/main/jniLibs/arm64-v8a/libssl.so
new file mode 100644
index 0000000..cea745d
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libssl.so
Binary files differ
diff --git a/app/src/main/jniLibs/arm64-v8a/libswbarcode.so b/app/src/main/jniLibs/arm64-v8a/libswbarcode.so
new file mode 100644
index 0000000..f7c2d94
--- /dev/null
+++ b/app/src/main/jniLibs/arm64-v8a/libswbarcode.so
Binary files differ
diff --git a/app/src/main/jniLibs/armeabi-v7a/libalipay_code_verify.so b/app/src/main/jniLibs/armeabi-v7a/libalipay_code_verify.so
new file mode 100644
index 0000000..2419998
--- /dev/null
+++ b/app/src/main/jniLibs/armeabi-v7a/libalipay_code_verify.so
Binary files differ
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/drawable-mdpi/all_back_focus.png b/app/src/main/res/drawable-mdpi/all_back_focus.png
new file mode 100644
index 0000000..8f98e97
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/all_back_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/all_back_normal.png b/app/src/main/res/drawable-mdpi/all_back_normal.png
new file mode 100644
index 0000000..cb831ce
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/all_back_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/all_home_focus.png b/app/src/main/res/drawable-mdpi/all_home_focus.png
new file mode 100644
index 0000000..23050ea
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/all_home_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/all_home_normal.png b/app/src/main/res/drawable-mdpi/all_home_normal.png
new file mode 100644
index 0000000..db94187
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/all_home_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/arrow.png b/app/src/main/res/drawable-mdpi/arrow.png
new file mode 100644
index 0000000..24bf7da
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/arrow.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/background.jpg b/app/src/main/res/drawable-mdpi/background.jpg
new file mode 100644
index 0000000..dfeb4af
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/background.jpg
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/bak_minus_focus.png b/app/src/main/res/drawable-mdpi/bak_minus_focus.png
new file mode 100644
index 0000000..230fe76
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/bak_minus_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/bak_minus_normal.png b/app/src/main/res/drawable-mdpi/bak_minus_normal.png
new file mode 100644
index 0000000..c6c9d67
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/bak_minus_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/big_picture_count_bak.png b/app/src/main/res/drawable-mdpi/big_picture_count_bak.png
new file mode 100644
index 0000000..4b3aa81
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/big_picture_count_bak.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/btn_red_click.png b/app/src/main/res/drawable-mdpi/btn_red_click.png
new file mode 100644
index 0000000..580c410
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/btn_red_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/btn_red_normal.png b/app/src/main/res/drawable-mdpi/btn_red_normal.png
new file mode 100644
index 0000000..f447037
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/btn_red_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/btn_rf_cancel_focus.png b/app/src/main/res/drawable-mdpi/btn_rf_cancel_focus.png
new file mode 100644
index 0000000..622b075
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/btn_rf_cancel_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/btn_rf_cancel_normal.png b/app/src/main/res/drawable-mdpi/btn_rf_cancel_normal.png
new file mode 100644
index 0000000..c6dda8e
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/btn_rf_cancel_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/btn_rf_start_focus.png b/app/src/main/res/drawable-mdpi/btn_rf_start_focus.png
new file mode 100644
index 0000000..93ac164
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/btn_rf_start_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/btn_rf_start_normal.png b/app/src/main/res/drawable-mdpi/btn_rf_start_normal.png
new file mode 100644
index 0000000..2565a57
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/btn_rf_start_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/consume_cancel_focus.png b/app/src/main/res/drawable-mdpi/consume_cancel_focus.png
new file mode 100644
index 0000000..b5a7293
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/consume_cancel_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/consume_cancel_normal.png b/app/src/main/res/drawable-mdpi/consume_cancel_normal.png
new file mode 100644
index 0000000..0ce3a04
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/consume_cancel_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/consume_middle_background.png b/app/src/main/res/drawable-mdpi/consume_middle_background.png
new file mode 100644
index 0000000..4aabc91
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/consume_middle_background.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/consume_pay_focus.png b/app/src/main/res/drawable-mdpi/consume_pay_focus.png
new file mode 100644
index 0000000..f39b8b0
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/consume_pay_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/consume_pay_normal.png b/app/src/main/res/drawable-mdpi/consume_pay_normal.png
new file mode 100644
index 0000000..3488719
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/consume_pay_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/enable_btn_cancel_focus.png b/app/src/main/res/drawable-mdpi/enable_btn_cancel_focus.png
new file mode 100644
index 0000000..80a9edb
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/enable_btn_cancel_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/enable_btn_cancel_normal.png b/app/src/main/res/drawable-mdpi/enable_btn_cancel_normal.png
new file mode 100644
index 0000000..75c0087
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/enable_btn_cancel_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/enable_btn_next_focus.png b/app/src/main/res/drawable-mdpi/enable_btn_next_focus.png
new file mode 100644
index 0000000..1d0c2f4
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/enable_btn_next_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/enable_btn_next_normal.png b/app/src/main/res/drawable-mdpi/enable_btn_next_normal.png
new file mode 100644
index 0000000..4db2d60
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/enable_btn_next_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/enable_btn_next_unable.png b/app/src/main/res/drawable-mdpi/enable_btn_next_unable.png
new file mode 100644
index 0000000..0247799
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/enable_btn_next_unable.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/enable_middle_bak.png b/app/src/main/res/drawable-mdpi/enable_middle_bak.png
new file mode 100644
index 0000000..5ea5683
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/enable_middle_bak.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_offline.png b/app/src/main/res/drawable-mdpi/main_offline.png
new file mode 100644
index 0000000..a35326c
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_offline.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_online.png b/app/src/main/res/drawable-mdpi/main_online.png
new file mode 100644
index 0000000..06aed69
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_online.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_cancel_consume.png b/app/src/main/res/drawable-mdpi/main_src_cancel_consume.png
new file mode 100644
index 0000000..77d3e8e
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_cancel_consume.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_consume.png b/app/src/main/res/drawable-mdpi/main_src_consume.png
new file mode 100644
index 0000000..9d94ebf
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_consume.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_device_manage.png b/app/src/main/res/drawable-mdpi/main_src_device_manage.png
new file mode 100644
index 0000000..b0d32f1
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_device_manage.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_do_transdtl.png b/app/src/main/res/drawable-mdpi/main_src_do_transdtl.png
new file mode 100644
index 0000000..4524728
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_do_transdtl.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_hotel_consume.png b/app/src/main/res/drawable-mdpi/main_src_hotel_consume.png
new file mode 100644
index 0000000..cf50434
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_hotel_consume.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_manual_auth.png b/app/src/main/res/drawable-mdpi/main_src_manual_auth.png
new file mode 100644
index 0000000..6e69685
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_manual_auth.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_net_test.png b/app/src/main/res/drawable-mdpi/main_src_net_test.png
new file mode 100644
index 0000000..7993cae
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_net_test.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_online_order.png b/app/src/main/res/drawable-mdpi/main_src_online_order.png
new file mode 100644
index 0000000..7e0e456
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_online_order.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_query_para.png b/app/src/main/res/drawable-mdpi/main_src_query_para.png
new file mode 100644
index 0000000..b992a8d
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_query_para.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_query_revenue.png b/app/src/main/res/drawable-mdpi/main_src_query_revenue.png
new file mode 100644
index 0000000..30bb3f2
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_query_revenue.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_update_blacklist.png b/app/src/main/res/drawable-mdpi/main_src_update_blacklist.png
new file mode 100644
index 0000000..686a5a6
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_update_blacklist.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/main_src_upload_transdtl.png b/app/src/main/res/drawable-mdpi/main_src_upload_transdtl.png
new file mode 100644
index 0000000..6dc721a
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/main_src_upload_transdtl.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_big_picture_close_btn.png b/app/src/main/res/drawable-mdpi/order_big_picture_close_btn.png
new file mode 100644
index 0000000..4a21eef
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_big_picture_close_btn.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_big_picture_out_bak.png b/app/src/main/res/drawable-mdpi/order_big_picture_out_bak.png
new file mode 100644
index 0000000..6231b4b
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_big_picture_out_bak.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_btn_purchase.png b/app/src/main/res/drawable-mdpi/order_btn_purchase.png
new file mode 100644
index 0000000..416af7b
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_btn_purchase.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_clear_focus.png b/app/src/main/res/drawable-mdpi/order_clear_focus.png
new file mode 100644
index 0000000..20699ee
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_clear_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_clear_normal.png b/app/src/main/res/drawable-mdpi/order_clear_normal.png
new file mode 100644
index 0000000..4a335ec
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_clear_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_food_self_add_focus.png b/app/src/main/res/drawable-mdpi/order_food_self_add_focus.png
new file mode 100644
index 0000000..c86b446
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_food_self_add_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_food_self_add_normal.png b/app/src/main/res/drawable-mdpi/order_food_self_add_normal.png
new file mode 100644
index 0000000..75788fc
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_food_self_add_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_good_add_focus.png b/app/src/main/res/drawable-mdpi/order_good_add_focus.png
new file mode 100644
index 0000000..2d6d7f5
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_good_add_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_good_add_normal.png b/app/src/main/res/drawable-mdpi/order_good_add_normal.png
new file mode 100644
index 0000000..cf026ba
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_good_add_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_good_minus_focus.png b/app/src/main/res/drawable-mdpi/order_good_minus_focus.png
new file mode 100644
index 0000000..43a225c
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_good_minus_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_good_minus_normal.png b/app/src/main/res/drawable-mdpi/order_good_minus_normal.png
new file mode 100644
index 0000000..ac58ec1
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_good_minus_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_picture_out_bak.png b/app/src/main/res/drawable-mdpi/order_picture_out_bak.png
new file mode 100644
index 0000000..cd2a360
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_picture_out_bak.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_picture_zoom.png b/app/src/main/res/drawable-mdpi/order_picture_zoom.png
new file mode 100644
index 0000000..07558da
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_picture_zoom.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_purchase_focus.png b/app/src/main/res/drawable-mdpi/order_purchase_focus.png
new file mode 100644
index 0000000..cbf4d7f
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_purchase_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/order_purchase_normal.png b/app/src/main/res/drawable-mdpi/order_purchase_normal.png
new file mode 100644
index 0000000..6907626
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/order_purchase_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_delete_click.png b/app/src/main/res/drawable-mdpi/pass_delete_click.png
new file mode 100644
index 0000000..d05207d
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_delete_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_delete_normal.png b/app/src/main/res/drawable-mdpi/pass_delete_normal.png
new file mode 100644
index 0000000..b77fc91
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_delete_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_eight_click.png b/app/src/main/res/drawable-mdpi/pass_eight_click.png
new file mode 100644
index 0000000..c26ffd8
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_eight_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_eight_normal.png b/app/src/main/res/drawable-mdpi/pass_eight_normal.png
new file mode 100644
index 0000000..9b2ece0
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_eight_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_five_click.png b/app/src/main/res/drawable-mdpi/pass_five_click.png
new file mode 100644
index 0000000..c555169
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_five_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_five_normal.png b/app/src/main/res/drawable-mdpi/pass_five_normal.png
new file mode 100644
index 0000000..3a6460b
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_five_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_four_click.png b/app/src/main/res/drawable-mdpi/pass_four_click.png
new file mode 100644
index 0000000..8b2325f
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_four_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_four_normal.png b/app/src/main/res/drawable-mdpi/pass_four_normal.png
new file mode 100644
index 0000000..97bd59f
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_four_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_nine_click.png b/app/src/main/res/drawable-mdpi/pass_nine_click.png
new file mode 100644
index 0000000..0aec332
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_nine_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_nine_normal.png b/app/src/main/res/drawable-mdpi/pass_nine_normal.png
new file mode 100644
index 0000000..76f2f37
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_nine_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_one_click.png b/app/src/main/res/drawable-mdpi/pass_one_click.png
new file mode 100644
index 0000000..6dd704f
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_one_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_one_normal.png b/app/src/main/res/drawable-mdpi/pass_one_normal.png
new file mode 100644
index 0000000..ac0beaa
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_one_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_seven_click.png b/app/src/main/res/drawable-mdpi/pass_seven_click.png
new file mode 100644
index 0000000..b685327
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_seven_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_seven_normal.png b/app/src/main/res/drawable-mdpi/pass_seven_normal.png
new file mode 100644
index 0000000..a1431b1
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_seven_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_six_click.png b/app/src/main/res/drawable-mdpi/pass_six_click.png
new file mode 100644
index 0000000..c8501e2
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_six_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_six_normal.png b/app/src/main/res/drawable-mdpi/pass_six_normal.png
new file mode 100644
index 0000000..f4df1ff
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_six_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_three_click.png b/app/src/main/res/drawable-mdpi/pass_three_click.png
new file mode 100644
index 0000000..55959a7
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_three_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_three_normal.png b/app/src/main/res/drawable-mdpi/pass_three_normal.png
new file mode 100644
index 0000000..5a76454
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_three_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_two_click.png b/app/src/main/res/drawable-mdpi/pass_two_click.png
new file mode 100644
index 0000000..ba99d1d
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_two_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_two_normal.png b/app/src/main/res/drawable-mdpi/pass_two_normal.png
new file mode 100644
index 0000000..1a1e6e3
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_two_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_zero_click.png b/app/src/main/res/drawable-mdpi/pass_zero_click.png
new file mode 100644
index 0000000..2e72719
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_zero_click.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/pass_zero_normal.png b/app/src/main/res/drawable-mdpi/pass_zero_normal.png
new file mode 100644
index 0000000..7463c4a
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/pass_zero_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/password_pwd_frame.png b/app/src/main/res/drawable-mdpi/password_pwd_frame.png
new file mode 100644
index 0000000..52bfc7b
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/password_pwd_frame.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/qrcode_scan_line.png b/app/src/main/res/drawable-mdpi/qrcode_scan_line.png
new file mode 100644
index 0000000..ead6117
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/qrcode_scan_line.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/query_next_focus.png b/app/src/main/res/drawable-mdpi/query_next_focus.png
new file mode 100644
index 0000000..34c49d8
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/query_next_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/query_next_normal.png b/app/src/main/res/drawable-mdpi/query_next_normal.png
new file mode 100644
index 0000000..a026ed4
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/query_next_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/query_prev_focus.png b/app/src/main/res/drawable-mdpi/query_prev_focus.png
new file mode 100644
index 0000000..e4681d0
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/query_prev_focus.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/query_prev_normal.png b/app/src/main/res/drawable-mdpi/query_prev_normal.png
new file mode 100644
index 0000000..d8415b1
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/query_prev_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/star_full.png b/app/src/main/res/drawable-mdpi/star_full.png
new file mode 100644
index 0000000..e1ee5d3
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/star_full.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/star_normal.png b/app/src/main/res/drawable-mdpi/star_normal.png
new file mode 100644
index 0000000..119768c
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/star_normal.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/test_food.png b/app/src/main/res/drawable-mdpi/test_food.png
new file mode 100644
index 0000000..dedd453
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/test_food.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/test_food2.png b/app/src/main/res/drawable-mdpi/test_food2.png
new file mode 100644
index 0000000..4b14037
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/test_food2.png
Binary files differ
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..6348baa
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:aapt="http://schemas.android.com/aapt"
+        android:width="108dp"
+        android:height="108dp"
+        android:viewportHeight="108"
+        android:viewportWidth="108">
+    <path
+            android:fillType="evenOdd"
+            android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
+            android:strokeColor="#00000000"
+            android:strokeWidth="1">
+        <aapt:attr name="android:fillColor">
+            <gradient
+                    android:endX="78.5885"
+                    android:endY="90.9159"
+                    android:startX="48.7653"
+                    android:startY="61.0927"
+                    android:type="linear">
+                <item
+                        android:color="#44000000"
+                        android:offset="0.0"/>
+                <item
+                        android:color="#00000000"
+                        android:offset="1.0"/>
+            </gradient>
+        </aapt:attr>
+    </path>
+    <path
+            android:fillColor="#FFFFFF"
+            android:fillType="nonZero"
+            android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
+            android:strokeColor="#00000000"
+            android:strokeWidth="1"/>
+</vector>
diff --git a/app/src/main/res/drawable-xxhdpi/bar_progress_style.xml b/app/src/main/res/drawable-xxhdpi/bar_progress_style.xml
new file mode 100644
index 0000000..82dcdae
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/bar_progress_style.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <!--  设置背景色(蓝色)  -->
+    <item android:id="@android:id/background">
+        <shape>
+            <corners android:radius="6dp" />
+            <gradient
+                android:endColor="@color/light_gray"
+                android:startColor="@color/light_gray" />
+        </shape>
+    </item>
+
+    <!--  设置进度条颜色(红色)  -->
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <corners android:radius="6dp" />
+                <gradient
+                    android:endColor="@color/light_green2"
+                    android:startColor="@color/light_green2" />
+            </shape>
+        </clip>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/app/src/main/res/drawable-xxhdpi/numbers/1.png b/app/src/main/res/drawable-xxhdpi/numbers/1.png
new file mode 100644
index 0000000..b1bb49f
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/numbers/1.png
Binary files differ
diff --git a/app/src/main/res/drawable/anonymous.jpg b/app/src/main/res/drawable/anonymous.jpg
new file mode 100644
index 0000000..9e4672e
--- /dev/null
+++ b/app/src/main/res/drawable/anonymous.jpg
Binary files differ
diff --git a/app/src/main/res/drawable/bcg.png b/app/src/main/res/drawable/bcg.png
new file mode 100644
index 0000000..1664e83
--- /dev/null
+++ b/app/src/main/res/drawable/bcg.png
Binary files differ
diff --git a/app/src/main/res/drawable/bg_dps_corner.xml b/app/src/main/res/drawable/bg_dps_corner.xml
new file mode 100644
index 0000000..9236194
--- /dev/null
+++ b/app/src/main/res/drawable/bg_dps_corner.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#ee1"/>
+    <corners android:radius="8dip"/>
+    <stroke
+        android:width="1.0dip"
+        android:color="#e22221"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/big_progress_bg.xml b/app/src/main/res/drawable/big_progress_bg.xml
new file mode 100644
index 0000000..55134ec
--- /dev/null
+++ b/app/src/main/res/drawable/big_progress_bg.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rotate xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/loading_white"
+    android:fromDegrees="0"
+    android:interpolator="@android:anim/cycle_interpolator"
+    android:pivotX="50%"
+    android:pivotY="50%"
+    android:toDegrees="1440" />
diff --git a/app/src/main/res/drawable/btn_cancel_selector.xml b/app/src/main/res/drawable/btn_cancel_selector.xml
new file mode 100644
index 0000000..5543cba
--- /dev/null
+++ b/app/src/main/res/drawable/btn_cancel_selector.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_focused="true" android:state_pressed="false">
+        <shape>
+            <solid android:color="#cccccc" />
+            <corners android:radius="8.0dip" />
+        </shape>
+    </item>
+    <item android:state_selected="true">
+        <shape>
+            <solid android:color="#bfbfbf" />
+            <corners android:radius="8.0dip" />
+        </shape>
+    </item>
+    <item android:state_pressed="true">
+        <shape>
+            <solid android:color="#bfbfbf" />
+            <corners android:radius="8.0dip" />
+        </shape>
+    </item>
+    <item android:state_pressed="false">
+        <shape>
+            <solid android:color="#cccccc" />
+            <corners android:radius="8.0dip" />
+        </shape>
+    </item>
+
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/btn_num_selector.xml b/app/src/main/res/drawable/btn_num_selector.xml
new file mode 100644
index 0000000..498dc49
--- /dev/null
+++ b/app/src/main/res/drawable/btn_num_selector.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_focused="true" android:state_pressed="false">
+        <shape>
+            <solid android:color="#fff" />
+            <corners android:radius="8.0dip" />
+            <stroke android:width="1.0dip" android:color="#DEDBDE" />
+        </shape>
+    </item>
+    <item android:state_selected="true">
+        <shape>
+            <solid android:color="#bfbfbf" />
+            <corners android:radius="8.0dip" />
+            <stroke android:width="1.0dip" android:color="#DEDBDE" />
+        </shape>
+    </item>
+    <item android:state_pressed="true">
+        <shape>
+            <solid android:color="#bfbfbf" />
+            <corners android:radius="8.0dip" />
+            <stroke android:width="1.0dip" android:color="#DEDBDE" />
+        </shape>
+    </item>
+    <item android:state_pressed="false">
+        <shape>
+            <solid android:color="#fff" />
+            <corners android:radius="8.0dip" />
+            <stroke android:width="1.0dip" android:color="#DEDBDE" />
+        </shape>
+    </item>
+
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/btn_ok_selector.xml b/app/src/main/res/drawable/btn_ok_selector.xml
new file mode 100644
index 0000000..8ee6c40
--- /dev/null
+++ b/app/src/main/res/drawable/btn_ok_selector.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_focused="true" android:state_pressed="false">
+        <shape>
+            <solid android:color="#08ae9e" />
+            <corners android:radius="8.0dip" />
+        </shape>
+    </item>
+    <item android:state_selected="true">
+        <shape>
+            <solid android:color="#08a191" />
+            <corners android:radius="8.0dip" />
+        </shape>
+    </item>
+    <item android:state_pressed="true">
+        <shape>
+            <solid android:color="#08a191" />
+            <corners android:radius="8.0dip" />
+        </shape>
+    </item>
+    <item android:state_pressed="false">
+        <shape>
+            <solid android:color="#08ae9e" />
+            <corners android:radius="8.0dip" />
+        </shape>
+    </item>
+
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/btn_ok_selector_nocorner.xml b/app/src/main/res/drawable/btn_ok_selector_nocorner.xml
new file mode 100644
index 0000000..4cdb60c
--- /dev/null
+++ b/app/src/main/res/drawable/btn_ok_selector_nocorner.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_focused="true" android:state_pressed="false">
+        <shape>
+            <solid android:color="#08ae9e" />
+        </shape>
+    </item>
+    <item android:state_selected="true">
+        <shape>
+            <solid android:color="#08a191" />
+        </shape>
+    </item>
+    <item android:state_pressed="true">
+        <shape>
+            <solid android:color="#08a191" />
+        </shape>
+    </item>
+    <item android:state_pressed="false">
+        <shape>
+            <solid android:color="#08ae9e" />
+        </shape>
+    </item>
+
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/btn_ok_white_selector.xml b/app/src/main/res/drawable/btn_ok_white_selector.xml
new file mode 100644
index 0000000..1db82f7
--- /dev/null
+++ b/app/src/main/res/drawable/btn_ok_white_selector.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_focused="true" android:state_pressed="false">
+        <shape>
+            <solid android:color="#fff" />
+        </shape>
+    </item>
+    <item android:state_selected="true">
+        <shape>
+            <solid android:color="#fff4f4f4" />
+        </shape>
+    </item>
+    <item android:state_pressed="true">
+        <shape>
+            <solid android:color="#fff4f4f4" />
+        </shape>
+    </item>
+    <item android:state_pressed="false">
+        <shape>
+            <solid android:color="#fff" />
+        </shape>
+    </item>
+
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg.xml b/app/src/main/res/drawable/corner_bg.xml
new file mode 100644
index 0000000..40c5b82
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#80ffffff" />
+    <corners android:radius="8dip" />
+    <stroke
+        android:width="1.0dip"
+        android:color="#ffc5c5c5" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_1.xml b/app/src/main/res/drawable/corner_bg_1.xml
new file mode 100644
index 0000000..e6721a9
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_1.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#e0e0e0e0" />
+    <corners android:radius="8dip" />
+    <stroke
+        android:width="1.0dip"
+        android:color="#80ffffff" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_dialog.xml b/app/src/main/res/drawable/corner_bg_dialog.xml
new file mode 100644
index 0000000..2276ba2
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_dialog.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#e6e6e6"/>
+    <corners android:radius="12dip"/>
+    <stroke
+        android:width="1.0dip"
+        android:color="#e6e6e6"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_dps_crashbtn_focus.xml b/app/src/main/res/drawable/corner_bg_dps_crashbtn_focus.xml
new file mode 100644
index 0000000..1108b54
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_dps_crashbtn_focus.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#7e1508"/>
+    <corners android:radius="12dip"/>
+    <stroke
+        android:width="1.0dip"
+        android:color="#721307"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_dps_crashbtn_normal.xml b/app/src/main/res/drawable/corner_bg_dps_crashbtn_normal.xml
new file mode 100644
index 0000000..7b7d04f
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_dps_crashbtn_normal.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#e24c17"/>
+    <corners android:radius="12dip"/>
+    <stroke
+        android:width="1.0dip"
+        android:color="#cc4616"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_gray.xml b/app/src/main/res/drawable/corner_bg_gray.xml
new file mode 100644
index 0000000..a198688
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_gray.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/light_gray" />
+    <corners android:radius="8dip" />
+    <stroke
+        android:width="1.0dip"
+        android:color="@color/light_gray" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_keyboard_focus.xml b/app/src/main/res/drawable/corner_bg_keyboard_focus.xml
new file mode 100644
index 0000000..0f93672
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_keyboard_focus.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#807c7c"/>
+    <corners android:radius="12dip"/>
+    <stroke
+        android:width="1.0dip"
+        android:color="#807c7c"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_keyboard_normal.xml b/app/src/main/res/drawable/corner_bg_keyboard_normal.xml
new file mode 100644
index 0000000..7732d4b
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_keyboard_normal.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#ffffff"/>
+    <corners android:radius="12dip"/>
+    <stroke
+        android:width="1.0dip"
+        android:color="#ffffff"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_order_count_green.xml b/app/src/main/res/drawable/corner_bg_order_count_green.xml
new file mode 100644
index 0000000..fe44a58
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_order_count_green.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/light_green"/>
+    <corners android:radius="30dip"/>
+    <!--<stroke-->
+        <!--android:width="1.0dip"-->
+        <!--android:color="@color/light_green"/>-->
+    <gradient
+        android:angle="90"
+        android:endColor="@color/light_green2"
+        android:startColor="@color/light_green1"/>
+    <padding
+        android:bottom="1dp"
+        android:left="1dp"
+        android:right="1dp"
+        android:top="1dp"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_order_red.xml b/app/src/main/res/drawable/corner_bg_order_red.xml
new file mode 100644
index 0000000..5fa9c71
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_order_red.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <corners android:radius="30dip"/>
+    <!--<stroke-->
+        <!--android:width="1.0dip"-->
+        <!--android:color="@color/cl_red"/>-->
+    <gradient
+        android:angle="90"
+        android:endColor="@color/cl_red"
+        android:startColor="@color/light_purple1"/>
+    <padding
+        android:bottom="1dp"
+        android:left="1dp"
+        android:right="1dp"
+        android:top="1dp"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_ordinary_consume_focus.xml b/app/src/main/res/drawable/corner_bg_ordinary_consume_focus.xml
new file mode 100644
index 0000000..0f93672
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_ordinary_consume_focus.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#807c7c"/>
+    <corners android:radius="12dip"/>
+    <stroke
+        android:width="1.0dip"
+        android:color="#807c7c"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_ordinary_consume_green.xml b/app/src/main/res/drawable/corner_bg_ordinary_consume_green.xml
new file mode 100644
index 0000000..d644a75
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_ordinary_consume_green.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#E3EFFF"/>
+    <corners android:radius="12dip"/>
+    <stroke
+        android:width="1.0dip"
+        android:color="#E3EFFF"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_ordinary_consume_normal.xml b/app/src/main/res/drawable/corner_bg_ordinary_consume_normal.xml
new file mode 100644
index 0000000..19b5879
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_ordinary_consume_normal.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#e0e0e0e0"/>
+    <corners android:radius="12dip"/>
+    <stroke
+        android:width="1.0dip"
+        android:color="#e0e0e0e0"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_qrcode_hint.xml b/app/src/main/res/drawable/corner_bg_qrcode_hint.xml
new file mode 100644
index 0000000..4f37389
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_qrcode_hint.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/orange1" />
+    <corners android:radius="30dip" />
+    <!--<stroke-->
+        <!--android:width="1.0dip"-->
+        <!--android:color="@color/cl_red" />-->
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_simple_order.xml b/app/src/main/res/drawable/corner_bg_simple_order.xml
new file mode 100644
index 0000000..3fd3f7e
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_simple_order.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/light_green"/>
+    <corners android:radius="30dip"/>
+    <stroke
+        android:width="0.5dip"
+        android:color="@color/cl_red"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_simple_order_1.xml b/app/src/main/res/drawable/corner_bg_simple_order_1.xml
new file mode 100644
index 0000000..a33bba1
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_simple_order_1.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/light_yellow_3"/>
+    <corners android:radius="8dip"/>
+    <stroke
+        android:width="1.0dip"
+        android:color="@color/light_yellow_3"/>
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_simple_order_2.xml b/app/src/main/res/drawable/corner_bg_simple_order_2.xml
new file mode 100644
index 0000000..10191d2
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_simple_order_2.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/order_food_list_bak" />
+    <corners android:radius="8dip" />
+    <stroke
+        android:width="1.0dip"
+        android:color="@color/order_food_list_bak" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/corner_bg_white.xml b/app/src/main/res/drawable/corner_bg_white.xml
new file mode 100644
index 0000000..48324a8
--- /dev/null
+++ b/app/src/main/res/drawable/corner_bg_white.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@android:color/white" />
+    <corners android:radius="8dip" />
+    <stroke
+        android:width="1.0dip"
+        android:color="@android:color/white" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/dps_crash_selector.xml b/app/src/main/res/drawable/dps_crash_selector.xml
new file mode 100644
index 0000000..fa50427
--- /dev/null
+++ b/app/src/main/res/drawable/dps_crash_selector.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/corner_bg_dps_crashbtn_focus" android:state_selected="true"/>
+    <item android:drawable="@drawable/corner_bg_dps_crashbtn_focus" android:state_pressed="true"/>
+    <item android:drawable="@drawable/corner_bg_dps_crashbtn_normal"/>
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/food_corner_bg.xml b/app/src/main/res/drawable/food_corner_bg.xml
new file mode 100644
index 0000000..5c1aca5
--- /dev/null
+++ b/app/src/main/res/drawable/food_corner_bg.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#999999" />
+    <corners android:radius="8dip" />
+    <stroke
+        android:width="1.0dip"
+        android:color="#999999" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/fudan_logo.png b/app/src/main/res/drawable/fudan_logo.png
new file mode 100644
index 0000000..1a53460
--- /dev/null
+++ b/app/src/main/res/drawable/fudan_logo.png
Binary files differ
diff --git a/app/src/main/res/drawable/fudan_logo2.png b/app/src/main/res/drawable/fudan_logo2.png
new file mode 100644
index 0000000..350562b
--- /dev/null
+++ b/app/src/main/res/drawable/fudan_logo2.png
Binary files differ
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..a0ad202
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:height="108dp"
+        android:width="108dp"
+        android:viewportHeight="108"
+        android:viewportWidth="108">
+    <path android:fillColor="#008577"
+          android:pathData="M0,0h108v108h-108z"/>
+    <path android:fillColor="#00000000" android:pathData="M9,0L9,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,0L19,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M29,0L29,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M39,0L39,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M49,0L49,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M59,0L59,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M69,0L69,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M79,0L79,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M89,0L89,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M99,0L99,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,9L108,9"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,19L108,19"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,29L108,29"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,39L108,39"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,49L108,49"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,59L108,59"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,69L108,69"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,79L108,79"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,89L108,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,99L108,99"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,29L89,29"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,39L89,39"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,49L89,49"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,59L89,59"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,69L89,69"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,79L89,79"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M29,19L29,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M39,19L39,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M49,19L49,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M59,19L59,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M69,19L69,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M79,19L79,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+</vector>
diff --git a/app/src/main/res/drawable/item_pressed_selector.xml b/app/src/main/res/drawable/item_pressed_selector.xml
new file mode 100644
index 0000000..d1e814b
--- /dev/null
+++ b/app/src/main/res/drawable/item_pressed_selector.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@android:color/darker_gray" android:state_pressed="true"/>
+    <item android:drawable="@android:color/darker_gray" android:state_focused="true"/>
+    <item android:drawable="@android:color/white" android:state_enabled="true"/>
+    <item android:drawable="@android:color/white"/>
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/minus_btn_selector.xml b/app/src/main/res/drawable/minus_btn_selector.xml
new file mode 100644
index 0000000..5f5ba45
--- /dev/null
+++ b/app/src/main/res/drawable/minus_btn_selector.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:drawable="@drawable/minus_click" />
+    <item android:state_pressed="true" android:drawable="@drawable/minus_click" />
+    <item android:drawable="@drawable/corner_bg_order_red" />
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/pay_ret_dialog_bg.xml b/app/src/main/res/drawable/pay_ret_dialog_bg.xml
new file mode 100644
index 0000000..705a8f3
--- /dev/null
+++ b/app/src/main/res/drawable/pay_ret_dialog_bg.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape android:shape="rectangle"
+  xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/viewfinder_mask" />
+    <corners android:radius="6.0dip" />
+</shape>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/progress_bg.xml b/app/src/main/res/drawable/progress_bg.xml
new file mode 100644
index 0000000..55134ec
--- /dev/null
+++ b/app/src/main/res/drawable/progress_bg.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rotate xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/loading_white"
+    android:fromDegrees="0"
+    android:interpolator="@android:anim/cycle_interpolator"
+    android:pivotX="50%"
+    android:pivotY="50%"
+    android:toDegrees="1440" />
diff --git a/app/src/main/res/drawable/progress_horizontal.xml b/app/src/main/res/drawable/progress_horizontal.xml
new file mode 100644
index 0000000..8014563
--- /dev/null
+++ b/app/src/main/res/drawable/progress_horizontal.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+
+<item
+    android:id="@android:id/background"
+    android:drawable="@color/pos_theme_color">
+</item>
+<item android:id="@android:id/secondaryProgress">
+  <scale
+      android:drawable="@color/light_gray"
+      android:scaleWidth="100%" />
+</item>
+<item android:id="@android:id/progress">
+  <scale
+      android:drawable="@color/cl_red"
+      android:scaleWidth="100%" />
+</item>
+
+</layer-list>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/purchase_cardagain.jpg b/app/src/main/res/drawable/purchase_cardagain.jpg
new file mode 100644
index 0000000..ae09d7f
--- /dev/null
+++ b/app/src/main/res/drawable/purchase_cardagain.jpg
Binary files differ
diff --git a/app/src/main/res/drawable/purchase_cardread.jpg b/app/src/main/res/drawable/purchase_cardread.jpg
new file mode 100644
index 0000000..5ab9972
--- /dev/null
+++ b/app/src/main/res/drawable/purchase_cardread.jpg
Binary files differ
diff --git a/app/src/main/res/drawable/purchase_fail.jpg b/app/src/main/res/drawable/purchase_fail.jpg
new file mode 100644
index 0000000..68c4cb9
--- /dev/null
+++ b/app/src/main/res/drawable/purchase_fail.jpg
Binary files differ
diff --git a/app/src/main/res/drawable/purchase_suc.jpg b/app/src/main/res/drawable/purchase_suc.jpg
new file mode 100644
index 0000000..f39ebdb
--- /dev/null
+++ b/app/src/main/res/drawable/purchase_suc.jpg
Binary files differ
diff --git a/app/src/main/res/drawable/qr_none320.png b/app/src/main/res/drawable/qr_none320.png
new file mode 100644
index 0000000..99b9039
--- /dev/null
+++ b/app/src/main/res/drawable/qr_none320.png
Binary files differ
diff --git a/app/src/main/res/drawable/select_bg_keyboard.xml b/app/src/main/res/drawable/select_bg_keyboard.xml
new file mode 100644
index 0000000..83ae4c5
--- /dev/null
+++ b/app/src/main/res/drawable/select_bg_keyboard.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/corner_bg_keyboard_normal" android:state_selected="true"/>
+    <item android:drawable="@drawable/corner_bg_keyboard_normal" android:state_pressed="true"/>
+    <item android:drawable="@drawable/corner_bg_keyboard_focus"/>
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/select_ordinary_consume.xml b/app/src/main/res/drawable/select_ordinary_consume.xml
new file mode 100644
index 0000000..e44edf1
--- /dev/null
+++ b/app/src/main/res/drawable/select_ordinary_consume.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/corner_bg_ordinary_consume_focus" android:state_selected="true"/>
+    <item android:drawable="@drawable/corner_bg_ordinary_consume_focus" android:state_pressed="true"/>
+    <item android:drawable="@drawable/corner_bg_ordinary_consume_normal"/>
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shape_image_border.xml b/app/src/main/res/drawable/shape_image_border.xml
new file mode 100644
index 0000000..6d801b9
--- /dev/null
+++ b/app/src/main/res/drawable/shape_image_border.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content">
+    <!-- Bottom 2dp Shadow -->
+    <item>
+
+        <shape android:shape="rectangle">
+
+            <solid android:color="#BBB"/>
+
+            <corners android:radius="7dp"/>
+        </shape>
+    </item>
+
+    <!-- White Top color -->
+    <item android:bottom="3px">
+
+        <shape android:shape="rectangle">
+
+            <solid android:color="#FFF"/>
+
+            <corners android:radius="7dp"/>
+
+            <padding
+                android:bottom="5dp"
+                android:left="5dp"
+                android:right="5dp"
+                android:top="5dp"/>
+        </shape>
+    </item>
+</layer-list>
diff --git a/app/src/main/res/drawable/toast_cry.jpg b/app/src/main/res/drawable/toast_cry.jpg
new file mode 100644
index 0000000..6c54f93
--- /dev/null
+++ b/app/src/main/res/drawable/toast_cry.jpg
Binary files differ
diff --git a/app/src/main/res/drawable/toast_doubt.jpg b/app/src/main/res/drawable/toast_doubt.jpg
new file mode 100644
index 0000000..1ed3097
--- /dev/null
+++ b/app/src/main/res/drawable/toast_doubt.jpg
Binary files differ
diff --git a/app/src/main/res/drawable/toast_smile.jpg b/app/src/main/res/drawable/toast_smile.jpg
new file mode 100644
index 0000000..b74ff81
--- /dev/null
+++ b/app/src/main/res/drawable/toast_smile.jpg
Binary files differ
diff --git a/app/src/main/res/drawable/wireless_off.png b/app/src/main/res/drawable/wireless_off.png
new file mode 100644
index 0000000..c9e117e
--- /dev/null
+++ b/app/src/main/res/drawable/wireless_off.png
Binary files differ
diff --git a/app/src/main/res/drawable/wireless_on.png b/app/src/main/res/drawable/wireless_on.png
new file mode 100644
index 0000000..61a9506
--- /dev/null
+++ b/app/src/main/res/drawable/wireless_on.png
Binary files differ
diff --git a/app/src/main/res/layout/activity_cardlib.xml b/app/src/main/res/layout/activity_cardlib.xml
new file mode 100644
index 0000000..f15e962
--- /dev/null
+++ b/app/src/main/res/layout/activity_cardlib.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/head_title_out_style">
+
+    <LinearLayout style="@style/head_title_inner_style">
+
+        <TextView
+            style="@style/head_title_text_style"
+            android:text="欢迎使用智能设备" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="30dp"
+            android:gravity="center"
+            android:text="加载卡库资源"
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp"
+            android:visibility="visible" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text="请耐心等待..."
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp" />
+
+        <ProgressBar
+            android:id="@+id/cardlib_bar"
+            style="?android:attr/progressBarStyleHorizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:layout_marginRight="10dp"
+            android:layout_marginTop="10dp"
+            android:max="100"
+            android:progress="5"
+            android:progressDrawable="@drawable/bar_progress_style" />
+
+        <TextView
+            android:id="@+id/cardlib_result"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="30dp"
+            android:gravity="center"
+            android:text="加载失败:原因"
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp"
+            android:visibility="gone" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/app/src/main/res/layout/activity_check_mngpwd.xml b/app/src/main/res/layout/activity_check_mngpwd.xml
new file mode 100644
index 0000000..1394d96
--- /dev/null
+++ b/app/src/main/res/layout/activity_check_mngpwd.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/head_title_out_style">
+
+    <LinearLayout style="@style/head_title_inner_style">
+
+        <TextView
+            android:id="@+id/title"
+            style="@style/head_title_text_style"
+            android:text="密码界面" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="20dp"
+            android:layout_marginTop="10dp"
+            android:text="等待密码校验"
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp" />
+
+        <TextView
+            android:id="@+id/content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="20dp"
+            android:layout_marginTop="10dp"
+            android:text=""
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_communicate.xml b/app/src/main/res/layout/activity_communicate.xml
new file mode 100644
index 0000000..d66e4ca
--- /dev/null
+++ b/app/src/main/res/layout/activity_communicate.xml
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              style="@style/head_title_out_style">
+
+    <LinearLayout style="@style/head_title_inner_style">
+
+        <TextView
+                style="@style/head_title_text_style"
+                android:text="通讯参数设置"/>
+
+        <ScrollView
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:orientation="vertical">
+
+                <LinearLayout style="@style/comm_ll_para_style">
+
+                    <TextView
+                            style="@style/init_param_name_style"
+                            android:text="终端MODE"/>
+
+                    <RadioGroup
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content">
+
+                        <RadioButton
+                                android:id="@+id/rb_pay_mode"
+                                style="@style/comm_rb_para_style"
+                                android:checked="true"
+                                android:text="消费模式"/>
+
+                        <RadioButton
+                                android:id="@+id/rb_deposit_mode"
+                                style="@style/comm_rb_para_style"
+                                android:text="充值模式"
+                                android:visibility="gone"/>
+
+                        <RadioButton
+                                android:id="@+id/rb_third_pay_mode"
+                                style="@style/comm_rb_para_style"
+                                android:text="对接消费模式"
+                                android:visibility="gone"/>
+
+                        <RadioButton
+                                android:id="@+id/rb_third_login_mode"
+                                style="@style/comm_rb_para_style"
+                                android:text="对接签到模式"
+                                android:visibility="gone"/>
+
+                        <RadioButton
+                                android:id="@+id/rb_gate_mode"
+                                style="@style/comm_rb_para_style"
+                                android:visibility="gone"/>
+                    </RadioGroup>
+                </LinearLayout>
+
+                <LinearLayout style="@style/comm_ll_para_style">
+
+                    <TextView
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:gravity="start|center"
+                            android:text="设备编号"
+                            android:textColor="@color/light_blue2"
+                            android:textSize="@dimen/enable_devphyid_font_size"/>
+
+                    <TextView
+                            android:id="@+id/comm_devphyid"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:gravity="start|center"
+                            android:inputType="numberDecimal"
+                            android:lines="1"
+                            android:maxLength="8"
+                            android:text="00000000"
+                            android:textColor="@color/light_blue2"
+                            android:textSize="@dimen/enable_devphyid_font_size"/>
+                </LinearLayout>
+                <!--第一行-->
+                <LinearLayout style="@style/comm_ll_para_style">
+
+                    <TextView
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:gravity="start|center"
+                            android:text="服务器地址"
+                            android:textColor="@color/light_blue2"
+                            android:textSize="@dimen/enable_devphyid_font_size"/>
+
+                    <EditText
+                            android:id="@+id/comm_epay_url"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginLeft="10dp"
+                            android:gravity="start|center"
+                            android:text="172.28.201.101"
+                            android:textColor="@color/light_blue2"
+                            android:textSize="@dimen/enable_devphyid_font_size"/>
+                </LinearLayout>
+
+                <LinearLayout style="@style/comm_ll_para_style">
+
+                    <TextView
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:gravity="start|center"
+                            android:text="服务器标识"
+                            android:textColor="@color/light_blue2"
+                            android:textSize="@dimen/enable_devphyid_font_size"/>
+
+                    <EditText
+                            android:id="@+id/comm_epay_uri"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:text="epayapi"
+                            android:textColor="@color/light_blue2"
+                            android:textSize="@dimen/enable_devphyid_font_size"/>
+                </LinearLayout>
+                <!--第二行-->
+                <LinearLayout style="@style/comm_ll_para_style">
+
+                    <TextView
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:text="服务器端口"
+                            android:textColor="@color/light_blue2"
+                            android:textSize="@dimen/enable_devphyid_font_size"/>
+
+                    <EditText
+                            android:id="@+id/comm_epay_port"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:inputType="numberDecimal"
+                            android:lines="1"
+                            android:maxLength="5"
+                            android:text="9116"
+                            android:textColor="@color/light_blue2"
+                            android:textSize="@dimen/enable_devphyid_font_size"/>
+                </LinearLayout>
+
+                <LinearLayout
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:orientation="horizontal"
+                        android:padding="10dp"
+                        android:weightSum="2">
+
+                    <TextView
+                            android:id="@+id/btn_cancel"
+                            style="@style/param_item_text_btn_style"
+                            android:text="取消"/>
+
+                    <TextView
+                            android:id="@+id/btn_confirm"
+                            style="@style/param_item_text_btn_style"
+                            android:layout_marginLeft="10dp"
+                            android:text="保存"/>
+                </LinearLayout>
+
+                <TextView
+                        android:layout_width="match_parent"
+                        android:layout_height="500dp"/>
+            </LinearLayout>
+        </ScrollView>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_consume.xml b/app/src/main/res/layout/activity_consume.xml
new file mode 100644
index 0000000..b4565e0
--- /dev/null
+++ b/app/src/main/res/layout/activity_consume.xml
@@ -0,0 +1,437 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/light_blue2"
+    android:focusable="true"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="20dp"
+        android:layout_marginTop="20dp"
+        android:layout_marginRight="20dp"
+        android:background="@drawable/corner_bg_white"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="304dp"
+            android:orientation="vertical">
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="130dp"
+                android:orientation="horizontal"
+                android:padding="@dimen/consume_text_pad_size"
+                android:weightSum="3">
+
+                <LinearLayout
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_weight="2"
+                    android:orientation="horizontal">
+
+                    <ImageView
+                        android:layout_width="60dp"
+                        android:layout_height="60dp"
+                        android:layout_gravity="center"
+                        android:scaleType="fitXY"
+                        android:src="@mipmap/shop_logo" />
+
+                    <LinearLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:layout_gravity="center"
+                        android:layout_marginLeft="10dp"
+                        android:layout_marginTop="8dp"
+                        android:orientation="vertical"
+                        android:padding="1dp">
+
+                        <TextView
+                            android:id="@+id/consume_shopname"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:maxLines="2"
+                            android:text=""
+                            android:textColor="@color/blue"
+                            android:textSize="28sp" />
+
+                        <TextView
+                            android:id="@+id/consume_time"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:gravity="start"
+                            android:maxLines="1"
+                            android:text=""
+                            android:textColor="@color/blue"
+                            android:textSize="22sp" />
+                    </LinearLayout>
+                </LinearLayout>
+
+                <LinearLayout
+                    android:layout_width="0dp"
+                    android:layout_height="match_parent"
+                    android:layout_gravity="center"
+                    android:layout_weight="1"
+                    android:gravity="right"
+                    android:orientation="horizontal">
+
+                    <ImageView
+                        android:id="@+id/consume_linklogo"
+                        android:layout_width="30dp"
+                        android:layout_height="30dp"
+                        android:scaleType="fitXY"
+                        android:src="@drawable/wireless_on" />
+
+                    <TextView
+                        android:id="@+id/consume_linkstat"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:maxLines="1"
+                        android:text="已联网"
+                        android:textColor="@color/blue"
+                        android:textSize="22sp" />
+                </LinearLayout>
+            </LinearLayout>
+
+            <View
+                android:layout_width="match_parent"
+                android:layout_height="1dp"
+                android:layout_marginLeft="10dp"
+                android:layout_marginRight="10dp"
+                android:background="@color/black" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:orientation="horizontal"
+                android:padding="@dimen/consume_text_pad_size">
+
+                <TextView
+                    android:id="@+id/tv_consume_hint"
+                    android:layout_width="300dp"
+                    android:layout_height="match_parent"
+                    android:gravity="start|center"
+                    android:text="消费金额"
+                    android:textColor="@color/blue"
+                    android:textSize="50sp"
+                    android:textStyle="bold" />
+
+                <TextView
+                    android:id="@+id/consume_amt"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:gravity="center"
+                    android:maxLines="1"
+                    android:text="0"
+                    android:textColor="@color/orange1"
+                    android:textSize="65sp"
+                    android:textStyle="bold" />
+            </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="20dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginRight="20dp"
+        android:background="@drawable/corner_bg_ordinary_consume_green"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:padding="10dp">
+
+            <ImageView
+                android:layout_width="40dp"
+                android:layout_height="40dp"
+                android:scaleType="fitXY"
+                android:src="@mipmap/show_card_info" />
+
+            <TextView
+                android:id="@+id/tv_card_info"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="校园卡信息"
+                android:textColor="@color/blue"
+                android:textSize="@dimen/consume_text_size2" />
+        </LinearLayout>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:layout_marginLeft="10dp"
+            android:layout_marginTop="5dp"
+            android:layout_marginRight="10dp"
+            android:layout_marginBottom="5dp"
+            android:background="@color/black" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginLeft="10dp"
+            android:layout_marginTop="5dp"
+            android:orientation="vertical">
+
+            <ImageView
+                android:layout_width="80dp"
+                android:layout_height="80dp"
+                android:layout_gravity="center"
+                android:scaleType="fitXY"
+                android:src="@mipmap/default_photo"
+                android:visibility="gone" />
+
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:padding="@dimen/consume_text_pad_size1"
+                android:text="如需查询余额,请刷卡!"
+                android:textColor="@color/blue"
+                android:textSize="@dimen/consume_text_size2" />
+
+            <LinearLayout style="@style/consume_wait_account_ll_style">
+
+                <TextView
+                    style="@style/consume_wait_account_paraname_style"
+                    android:text="姓    名:  " />
+
+                <TextView
+                    android:id="@+id/consume_custname"
+                    style="@style/consume_wait_account_paraval_style" />
+            </LinearLayout>
+
+            <LinearLayout style="@style/consume_wait_account_ll_style">
+
+                <TextView
+                    style="@style/consume_wait_account_paraname_style"
+                    android:text="学工号:  " />
+
+                <TextView
+                    android:id="@+id/consume_stuempno"
+                    style="@style/consume_wait_account_paraval_style" />
+            </LinearLayout>
+
+            <LinearLayout style="@style/consume_wait_account_ll_style">
+
+                <TextView
+                    style="@style/consume_wait_account_paraname_style"
+                    android:text="余    额:  " />
+
+                <TextView
+                    android:id="@+id/consume_balance"
+                    style="@style/consume_wait_account_paraval_style" />
+            </LinearLayout>
+
+            <LinearLayout style="@style/consume_wait_account_ll_style">
+
+                <TextView
+                    style="@style/consume_wait_account_paraname_style"
+                    android:text="卡状态:  " />
+
+                <TextView
+                    android:id="@+id/consume_cardstatus"
+                    style="@style/consume_wait_account_paraval_style" />
+            </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginLeft="20dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginRight="20dp"
+        android:layout_marginBottom="20dp"
+        android:background="@drawable/corner_bg_ordinary_consume_green"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:padding="@dimen/consume_text_pad_size1">
+
+            <ImageView
+                android:layout_width="40dp"
+                android:layout_height="40dp"
+                android:scaleType="fitXY"
+                android:src="@mipmap/bill_lastdtl" />
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="最近一笔"
+                android:textColor="@color/blue"
+                android:textSize="@dimen/consume_text_size2" />
+        </LinearLayout>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:layout_marginLeft="10dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginRight="10dp"
+            android:layout_marginBottom="5dp"
+            android:background="@color/black" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingLeft="10dp"
+            android:paddingTop="10dp">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:text="支付结果:  "
+                android:textColor="@color/black"
+                android:textSize="@dimen/consume_text_size2" />
+
+            <TextView
+                android:id="@+id/consume_last_result"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:maxLines="1"
+                android:text=""
+                android:textColor="@color/blue"
+                android:textSize="@dimen/consume_text_size2"
+                android:textStyle="bold" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/ll_consume_last_failreason"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingLeft="10dp"
+            android:paddingTop="5dp"
+            android:visibility="gone">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:text="失败提示:  "
+                android:textColor="@color/cl_red"
+                android:textSize="@dimen/consume_text_size2" />
+
+            <TextView
+                android:id="@+id/consume_last_failreason"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:maxLines="1"
+                android:text=""
+                android:textColor="@color/cl_red"
+                android:textSize="@dimen/consume_text_size2"
+                android:textStyle="bold" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/ll_consume_last_payamt"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingLeft="10dp"
+            android:paddingTop="5dp">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:text="支付金额:  "
+                android:textColor="@color/black"
+                android:textSize="@dimen/consume_text_size2" />
+
+            <TextView
+                android:id="@+id/consume_last_payamt"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:maxLines="1"
+                android:text=""
+                android:textColor="@color/blue"
+                android:textSize="@dimen/consume_text_size2"
+                android:textStyle="bold" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingLeft="10dp"
+            android:paddingTop="5dp">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:text="支付方式:  "
+                android:textColor="@color/black"
+                android:textSize="@dimen/consume_text_size2" />
+
+            <TextView
+                android:id="@+id/consume_last_payway"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:maxLines="1"
+                android:text=""
+                android:textColor="@color/blue"
+                android:textSize="@dimen/consume_text_size2"
+                android:textStyle="bold" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingLeft="10dp"
+            android:paddingTop="5dp">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:text="支付日期:  "
+                android:textColor="@color/black"
+                android:textSize="@dimen/consume_text_size2" />
+
+            <TextView
+                android:id="@+id/consume_last_payday"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:maxLines="1"
+                android:text=""
+                android:textColor="@color/blue"
+                android:textSize="@dimen/consume_text_size2"
+                android:textStyle="bold" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingLeft="10dp"
+            android:paddingTop="5dp">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:text="支付时间:  "
+                android:textColor="@color/black"
+                android:textSize="@dimen/consume_text_size2" />
+
+            <TextView
+                android:id="@+id/consume_last_paytime"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:maxLines="1"
+                android:text=""
+                android:textColor="@color/blue"
+                android:textSize="@dimen/consume_text_size2"
+                android:textStyle="bold" />
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_consume_mode.xml b/app/src/main/res/layout/activity_consume_mode.xml
new file mode 100644
index 0000000..99e494f
--- /dev/null
+++ b/app/src/main/res/layout/activity_consume_mode.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    style="@style/head_title_out_style">
+
+    <LinearLayout style="@style/head_title_inner_style">
+
+        <TextView
+            style="@style/head_title_text_style"
+            android:text="消费模式" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="10dp"
+            android:text="0-普通消费\n非0定额消费\n单位(分)"
+            android:textColor="@color/light_blue2"
+            android:textSize="20sp" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="horizontal">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:padding="10dp"
+                android:text="金额: "
+                android:textColor="@color/light_blue2"
+                android:textSize="30sp" />
+
+            <TextView
+                android:id="@+id/tv_consume_mode_payamt"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:maxLength="6"
+                android:padding="10dp"
+                android:text="0"
+                android:textColor="@color/light_blue2"
+                android:textSize="30sp" />
+        </LinearLayout>
+
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_control.xml b/app/src/main/res/layout/activity_control.xml
new file mode 100644
index 0000000..e1168df
--- /dev/null
+++ b/app/src/main/res/layout/activity_control.xml
@@ -0,0 +1,84 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              style="@style/head_title_out_style">
+
+    <LinearLayout style="@style/head_title_inner_style">
+        <TextView
+                style="@style/head_title_text_style"
+                android:text="本地参数设置"/>
+        <ScrollView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:scrollbars="none">
+
+            <LinearLayout android:layout_width="match_parent"
+                          android:layout_height="match_parent"
+                          android:orientation="vertical">
+
+                <LinearLayout style="@style/control_item_ll_style">
+
+                    <TextView
+                            style="@style/init_param_name_style"
+                            android:text="脱机天数判断"/>
+
+                    <RadioGroup
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content">
+
+                        <RadioButton
+                                android:id="@+id/rb_offline_enable"
+                                style="@style/comm_rb_para_style"
+                                android:checked="true"
+                                android:text="开启"/>
+
+                        <RadioButton
+                                android:id="@+id/rb_offline_disable"
+                                style="@style/comm_rb_para_style"
+                                android:text="关闭"/>
+                    </RadioGroup>
+                </LinearLayout>
+
+                <LinearLayout style="@style/control_item_ll_style">
+
+                    <TextView
+                            style="@style/init_param_name_style"
+                            android:text="调试模式"/>
+
+                    <RadioGroup
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content">
+
+                        <RadioButton
+                                android:id="@+id/rb_debug_enable"
+                                style="@style/comm_rb_para_style"
+                                android:text="开启"/>
+
+                        <RadioButton
+                                android:id="@+id/rb_debug_disable"
+                                style="@style/comm_rb_para_style"
+                                android:checked="true"
+                                android:text="关闭"/>
+                    </RadioGroup>
+
+                </LinearLayout>
+            </LinearLayout>
+        </ScrollView>
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                android:orientation="horizontal"
+                android:weightSum="2">
+
+            <TextView
+                    android:id="@+id/btn_cancel"
+                    style="@style/control_text_btn_style"
+                    android:text="取消"/>
+
+            <TextView
+                    android:id="@+id/btn_save"
+                    style="@style/control_text_btn_style"
+                    android:text="保存"/>
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_init.xml b/app/src/main/res/layout/activity_init.xml
new file mode 100644
index 0000000..24c9d45
--- /dev/null
+++ b/app/src/main/res/layout/activity_init.xml
@@ -0,0 +1,160 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:tools="http://schemas.android.com/tools"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:background="@color/light_blue2"
+              tools:context="com.supwisdom.activities.init.InitActivity">
+    <!--终端编号输入界面-->
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="20dp"
+            android:background="@drawable/corner_bg_white"
+            android:gravity="center_horizontal"
+            android:orientation="vertical">
+        <!--标题-->
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:gravity="center"
+                android:text="请填写以下信息"
+                android:textColor="@color/light_blue2"
+                android:textSize="@dimen/enable_title_text_size"/>
+
+        <ScrollView
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:scrollbars="none">
+
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical"
+                    android:padding="10dp">
+
+                <LinearLayout
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:orientation="horizontal"
+                        android:weightSum="2">
+
+                    <Button
+                            android:id="@+id/tv_nsd_query"
+                            style="@style/init_param_title_btn_name_style"
+                            android:text="动态参数获取"/>
+
+                    <Button
+                            android:id="@+id/tv_settings"
+                            style="@style/init_param_title_btn_name_style"
+                            android:text="进入设置界面"/>
+                </LinearLayout>
+
+                <TextView
+                        android:id="@+id/tv_nsd_result"
+                        style="@style/init_param_name_style"/>
+
+                <TextView
+                        style="@style/init_param_name_style"
+                        android:text="终端MODE"/>
+
+                <RadioGroup
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                    <RadioButton
+                            android:id="@+id/rb_pay_mode"
+                            style="@style/init_param_mode_style"
+                            android:checked="true"
+                            android:text="消费模式"/>
+
+                    <RadioButton
+                            android:id="@+id/rb_deposit_mode"
+                            style="@style/init_param_mode_style"
+                            android:visibility="gone"
+                            android:text="充值模式"/>
+
+                    <RadioButton
+                            android:id="@+id/rb_third_pay_mode"
+                            style="@style/init_param_mode_style"
+                            android:visibility="gone"
+                            android:text="对接消费模式"/>
+
+                    <RadioButton
+                            android:id="@+id/rb_third_login_mode"
+                            style="@style/init_param_mode_style"
+                            android:visibility="gone"
+                            android:text="对接签到模式"/>
+
+                    <RadioButton
+                            android:id="@+id/rb_gate_mode"
+                            style="@style/init_param_mode_style"
+                            android:visibility="gone"
+                            android:text="闸机(入)模式(点击切换)"/>
+                </RadioGroup>
+
+                <TextView
+                        style="@style/init_param_name_style"
+                        android:text="终端物理ID"/>
+
+                <EditText
+                        android:id="@+id/tv_devphyid"
+                        style="@style/init_param_name_style"
+                        android:inputType="numberDecimal"
+                        android:maxLength="8"
+                        android:text="20000001"/>
+
+                <TextView
+                        style="@style/init_param_name_style"
+                        android:text="服务器IP"/>
+
+                <EditText
+                        android:id="@+id/tv_server_ip"
+                        style="@style/init_param_name_style"
+                        android:text="172.28.201.101"/>
+
+                <TextView
+                        style="@style/init_param_name_style"
+                        android:text="服务器URI"/>
+
+                <EditText
+                        android:id="@+id/tv_uri_root"
+                        style="@style/init_param_name_style"
+                        android:maxLines="1"
+                        android:text="epayapi"/>
+
+
+                <TextView
+                        style="@style/init_param_name_style"
+                        android:text="服务器PORT"/>
+
+                <EditText
+                        android:id="@+id/tv_server_port"
+                        style="@style/init_param_name_style"
+                        android:inputType="numberDecimal"
+                        android:maxLength="5"
+                        android:maxLines="1"
+                        android:text="9100"/>
+
+                <TextView
+                        android:id="@+id/btn_save"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center"
+                        android:layout_marginTop="20dp"
+                        android:background="@drawable/select_bg_keyboard"
+                        android:paddingLeft="20dp"
+                        android:paddingTop="10dp"
+                        android:paddingRight="20dp"
+                        android:paddingBottom="10dp"
+                        android:text="保 存"
+                        android:textColor="@color/light_blue2"
+                        android:textSize="35sp"/>
+
+                <TextView
+                        android:layout_width="match_parent"
+                        android:layout_height="500dp"/>
+            </LinearLayout>
+        </ScrollView>
+    </LinearLayout>
+</LinearLayout>
diff --git a/app/src/main/res/layout/activity_load.xml b/app/src/main/res/layout/activity_load.xml
new file mode 100644
index 0000000..b6d9c86
--- /dev/null
+++ b/app/src/main/res/layout/activity_load.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:background="@color/light_blue2">
+
+    <LinearLayout
+            android:id="@+id/ll_enable_step"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="20dp"
+            android:background="@drawable/corner_bg_white"
+            android:gravity="center_horizontal"
+            android:orientation="vertical">
+        <!--标题-->
+        <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:gravity="center"
+                android:text="正在加载设备参数"
+                android:textColor="@color/light_blue2"
+                android:textSize="@dimen/enable_title_text_size"/>
+        <!--中间内容-->
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="400dp"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginTop="20dp"
+                android:orientation="vertical"
+                android:padding="10dp">
+
+            <TextView
+                    android:id="@+id/tv_load_pro"
+                    style="@style/load_info_text_style"
+                    android:text=" "/>
+        </LinearLayout>
+        <!--底下俩按钮-->
+        <TextView
+                android:id="@+id/btn_back"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:background="@drawable/select_bg_keyboard"
+                android:paddingLeft="20dp"
+                android:paddingTop="10dp"
+                android:paddingRight="20dp"
+                android:paddingBottom="10dp"
+                android:text="返 回"
+                android:textColor="@color/light_blue2"
+                android:textSize="30sp"/>
+    </LinearLayout>
+</LinearLayout>
diff --git a/app/src/main/res/layout/activity_manage.xml b/app/src/main/res/layout/activity_manage.xml
new file mode 100644
index 0000000..7537388
--- /dev/null
+++ b/app/src/main/res/layout/activity_manage.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              style="@style/head_title_out_style">
+
+    <LinearLayout style="@style/head_title_inner_style">
+        <TextView
+                style="@style/head_title_text_style"
+                android:text="维护管理界面"/>
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_marginLeft="10dp"
+                android:orientation="vertical"
+                android:padding="10dp">
+
+            <TextView
+                    style="@style/menu_item_text_style"
+                    android:text="@string/consume_menu_shop_passwd"/>
+
+            <TextView
+                    style="@style/menu_item_text_style"
+                    android:text="@string/consume_menu_comm_set"/>
+
+            <TextView
+                    style="@style/menu_item_text_style"
+                    android:text="@string/consume_menu_unconfirm_transdtl"/>
+
+            <TextView
+                    style="@style/menu_item_text_style"
+                    android:text="@string/consume_menu_out_dtl"/>
+
+            <TextView
+                    style="@style/menu_item_text_style"
+                    android:text="@string/consume_menu_upgrade"/>
+
+            <TextView
+                    style="@style/menu_item_text_style"
+                    android:text="@string/consume_menu_app_exit"/>
+
+            <TextView
+                    style="@style/menu_item_text_style"
+                    android:text="@string/consume_menu_setting"/>
+
+            <TextView
+                    style="@style/menu_item_text_style"
+                    android:text="@string/consume_menu_clear_blklist"/>
+
+            <TextView
+                    style="@style/menu_item_text_style"
+                    android:text="@string/consume_menu_control_set"/>
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
diff --git a/app/src/main/res/layout/activity_menu.xml b/app/src/main/res/layout/activity_menu.xml
new file mode 100644
index 0000000..e938845
--- /dev/null
+++ b/app/src/main/res/layout/activity_menu.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/light_blue2"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="20dp"
+        android:background="@drawable/corner_bg_white"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text="管理界面"
+            android:textColor="@color/light_blue2"
+            android:textSize="45sp" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginLeft="10dp"
+            android:orientation="vertical"
+            android:padding="10dp">
+
+            <TextView
+                style="@style/menu_item_text_style"
+                android:text="@string/consume_menu_revenue" />
+
+            <TextView
+                style="@style/menu_item_text_style"
+                android:text="@string/consume_menu_transdtl_upload" />
+
+            <TextView
+                style="@style/menu_item_text_style"
+                android:text="@string/consume_menu_link_check" />
+
+            <TextView
+                style="@style/menu_item_text_style"
+                android:text="@string/consume_menu_auth" />
+
+            <TextView
+                style="@style/menu_item_text_style"
+                android:text="@string/consume_menu_syspara_query" />
+
+            <TextView
+                style="@style/menu_item_text_style"
+                android:text="@string/consume_menu_manage" />
+
+            <TextView
+                style="@style/menu_item_text_style"
+                android:text="@string/consume_menu_shop_password_set" />
+
+            <TextView
+                style="@style/menu_item_text_style"
+                android:text="@string/consume_menu_consume_mode" />
+
+            <TextView
+                android:id="@+id/tv_reverse"
+                style="@style/menu_item_text_style"
+                android:text="@string/consume_menu_reverse" />
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_password.xml b/app/src/main/res/layout/activity_password.xml
new file mode 100644
index 0000000..f1943ea
--- /dev/null
+++ b/app/src/main/res/layout/activity_password.xml
@@ -0,0 +1,26 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/light_blue2"
+    android:orientation="vertical">
+    <!--上半部分-->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="20dp"
+        android:background="@drawable/corner_bg_white"
+        android:orientation="vertical">
+        <!--提示文字-->
+        <TextView
+            android:id="@+id/passwd_title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text="商户密码修改"
+            android:textColor="@color/light_blue2"
+            android:textSize="@dimen/password_hint_size" />
+
+    </LinearLayout>
+</LinearLayout>
+
diff --git a/app/src/main/res/layout/activity_revenue.xml b/app/src/main/res/layout/activity_revenue.xml
new file mode 100644
index 0000000..45541ba
--- /dev/null
+++ b/app/src/main/res/layout/activity_revenue.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/light_blue2"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="10dp"
+        android:background="@drawable/corner_bg_white"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:padding="20dp"
+            android:text="营业额查询"
+            android:textColor="@color/light_blue2"
+            android:textSize="50sp" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:orientation="horizontal"
+            android:padding="10dp">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="查询日期: "
+                android:textColor="@color/light_blue2"
+                android:textSize="30sp" />
+
+            <TextView
+                android:id="@+id/revenue_date"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="20180818"
+                android:textColor="@color/light_blue2"
+                android:textSize="30sp" />
+        </LinearLayout>
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:padding="10dp"
+            android:text="查询结果: "
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp" />
+
+        <TextView
+            android:id="@+id/revenue_content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:padding="10dp"
+            android:text=""
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
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/layout/activity_syspara.xml b/app/src/main/res/layout/activity_syspara.xml
new file mode 100644
index 0000000..c2f781a
--- /dev/null
+++ b/app/src/main/res/layout/activity_syspara.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/light_blue2"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="10dp"
+        android:background="@drawable/corner_bg_white"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text="参数查询"
+            android:textColor="@color/light_blue2"
+            android:textSize="50sp" />
+
+        <ListView
+            android:id="@+id/lv_param"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:divider="@null"
+            android:dividerHeight="2dp" />
+    </LinearLayout>
+</LinearLayout>
diff --git a/app/src/main/res/layout/activity_transdtl.xml b/app/src/main/res/layout/activity_transdtl.xml
new file mode 100644
index 0000000..0c44701
--- /dev/null
+++ b/app/src/main/res/layout/activity_transdtl.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/light_blue2"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="10dp"
+        android:background="@drawable/corner_bg_white"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:padding="20dp"
+            android:text="流水查询"
+            android:textColor="@color/light_blue2"
+            android:textSize="50sp" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:orientation="horizontal"
+            android:padding="10dp">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="查询记录: "
+                android:textColor="@color/light_blue2"
+                android:textSize="30sp" />
+
+            <TextView
+                android:id="@+id/transdtl_seqno"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text=""
+                android:textColor="@color/light_blue2"
+                android:textSize="30sp" />
+        </LinearLayout>
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:padding="10dp"
+            android:text="查询结果: "
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp" />
+
+        <TextView
+            android:id="@+id/transdtl_content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="10dp"
+            android:padding="10dp"
+            android:text=""
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_unregister.xml b/app/src/main/res/layout/activity_unregister.xml
new file mode 100644
index 0000000..5bcd6cb
--- /dev/null
+++ b/app/src/main/res/layout/activity_unregister.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:background="@color/light_blue2">
+
+    <LinearLayout
+        android:id="@+id/ll_enable_step"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_margin="20dp"
+        android:background="@drawable/corner_bg_white"
+        android:gravity="center_horizontal"
+        android:orientation="vertical">
+        <!--标题-->
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:gravity="center"
+            android:text="设备未注册"
+            android:textColor="@color/light_blue2"
+            android:textSize="@dimen/enable_title_text_size" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:padding="10dp"
+            android:text="说明: 设备参数配置已保存,后续只需签到认证成功即可使用"
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:padding="10dp"
+            android:text="设备注册失败信息:"
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp" />
+
+        <TextView
+            android:id="@+id/tv_errmsg"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="10dp"
+            android:textColor="@color/cl_red"
+            android:textSize="30sp" />
+
+        <TextView
+            android:id="@+id/tv_back"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:background="@drawable/select_bg_keyboard"
+            android:paddingBottom="10dp"
+            android:paddingLeft="20dp"
+            android:paddingRight="20dp"
+            android:paddingTop="10dp"
+            android:text="返 回"
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_upgrade.xml b/app/src/main/res/layout/activity_upgrade.xml
new file mode 100644
index 0000000..f4e1fa0
--- /dev/null
+++ b/app/src/main/res/layout/activity_upgrade.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:background="@color/light_blue2"
+              android:orientation="vertical">
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="20dp"
+            android:background="@drawable/corner_bg_white"
+            android:fillViewport="true"
+            android:scrollbars="none">
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+            <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="10dp"
+                    android:gravity="center"
+                    android:text="软件在线升级"
+                    android:textColor="@color/light_blue2"
+                    android:textSize="30sp"/>
+            <TableLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
+
+                <TableRow>
+
+                    <TextView
+                            style="@style/upgrade_text_value_style"
+                            android:text="结\u3000\u3000果:"/>
+
+                    <TextView
+                            android:id="@+id/tv_result"
+                            style="@style/upgrade_text_value_style"/>
+                </TableRow>
+
+                <TableRow android:layout_marginTop="15dp">
+
+                    <TextView
+                            style="@style/upgrade_text_value_style"
+                            android:text="升级地址:"/>
+
+                    <TextView
+                            android:id="@+id/tv_server_url"
+                            style="@style/upgrade_text_value_style"/>
+                </TableRow>
+
+                <TableRow android:layout_marginTop="15dp">
+
+                    <TextView
+                            style="@style/upgrade_text_value_style"
+                            android:text="当前版本:"/>
+
+                    <TextView
+                            android:id="@+id/tv_old_version"
+                            style="@style/upgrade_text_value_style"/>
+                </TableRow>
+
+                <TableRow android:layout_marginTop="15dp">
+
+                    <TextView
+                            style="@style/upgrade_text_value_style"
+                            android:text="升级版本:"/>
+
+                    <TextView
+                            android:id="@+id/tv_pos_version"
+                            style="@style/upgrade_text_value_style"/>
+                </TableRow>
+
+                <TableRow android:layout_marginTop="15dp">
+
+                    <TextView
+                            style="@style/upgrade_text_value_style"
+                            android:text="升级进度:"/>
+
+                    <TextView
+                            android:id="@+id/tv_upgrade_msg"
+                            style="@style/upgrade_text_value_style"/>
+                </TableRow>
+            </TableLayout>
+
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="30dp"
+                    android:gravity="center_vertical"
+                    android:orientation="horizontal">
+
+                <Button
+                        android:id="@+id/tv_upgrade"
+                        style="@style/upgrade_text_value_style"
+                        android:layout_marginStart="50dp"
+                        android:layout_marginEnd="50dp"
+                        android:text="升级"/>
+
+            </LinearLayout>
+        </LinearLayout>
+    </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_init_nsd_config.xml b/app/src/main/res/layout/dialog_init_nsd_config.xml
new file mode 100644
index 0000000..301e484
--- /dev/null
+++ b/app/src/main/res/layout/dialog_init_nsd_config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="400dp"
+    android:layout_height="500dp"
+    android:layout_gravity="center"
+    android:background="@drawable/corner_bg_white"
+    android:orientation="vertical">
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="10dp"
+        android:gravity="center"
+        android:text="参数配置列表"
+        android:textColor="@color/light_blue2"
+        android:textSize="35sp"
+        android:textStyle="bold" />
+
+    <android.support.v7.widget.RecyclerView
+        android:id="@+id/rv_config_list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginTop="10dp"
+        android:orientation="vertical" />
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_password.xml b/app/src/main/res/layout/dialog_password.xml
new file mode 100644
index 0000000..7b62bbd
--- /dev/null
+++ b/app/src/main/res/layout/dialog_password.xml
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    android:id="@+id/ll_float_password"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/order_btn_purchase"
+        android:orientation="vertical">
+        <!--上半部分-->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+            android:orientation="vertical">
+            <!--提示文字-->
+            <TextView
+                android:id="@+id/tv_float_password_title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/float_password_left_word_margin_top"
+                android:text="请输入卡密码"
+                android:textColor="@color/password_hint"
+                android:textSize="@dimen/float_password_hint_size"
+                android:textStyle="bold"/>
+            <!--密码输入框-->
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/float_password_left_obj_gap"
+                android:orientation="horizontal">
+                <!--密码1-->
+                <RelativeLayout
+                    android:layout_width="@dimen/float_password_pwd_size"
+                    android:layout_height="@dimen/float_password_pwd_size">
+
+                    <ImageView
+                        android:layout_width="fill_parent"
+                        android:layout_height="fill_parent"
+                        android:background="@drawable/password_pwd_frame"/>
+
+                    <ImageView
+                        android:id="@+id/float_password_img1"
+                        android:layout_width="20dp"
+                        android:layout_height="20dp"
+                        android:layout_margin="26dp"
+                        android:layout_marginTop="26dp"
+                        android:scaleType="fitXY"
+                        android:src="@drawable/purchase_cardread"/>
+                </RelativeLayout>
+                <!--密码2-->
+                <RelativeLayout
+                    android:layout_width="@dimen/float_password_pwd_size"
+                    android:layout_height="@dimen/float_password_pwd_size"
+                    android:layout_marginLeft="@dimen/float_password_left_obj_gap">
+
+                    <ImageView
+                        android:layout_width="fill_parent"
+                        android:layout_height="fill_parent"
+                        android:background="@drawable/password_pwd_frame"/>
+
+                    <ImageView
+                        android:id="@+id/float_password_img2"
+                        android:layout_width="20dp"
+                        android:layout_height="20dp"
+                        android:layout_margin="26dp"
+                        android:layout_marginTop="26dp"
+                        android:scaleType="fitXY"
+                        android:src="@drawable/purchase_cardread"/>
+                </RelativeLayout>
+                <!--密码3-->
+                <RelativeLayout
+                    android:layout_width="@dimen/float_password_pwd_size"
+                    android:layout_height="@dimen/float_password_pwd_size"
+                    android:layout_marginLeft="@dimen/float_password_left_obj_gap">
+
+                    <ImageView
+                        android:layout_width="fill_parent"
+                        android:layout_height="fill_parent"
+                        android:background="@drawable/password_pwd_frame"/>
+
+                    <ImageView
+                        android:id="@+id/float_password_img3"
+                        android:layout_width="20dp"
+                        android:layout_height="20dp"
+                        android:layout_margin="26dp"
+                        android:layout_marginTop="26dp"
+                        android:scaleType="fitXY"
+                        android:src="@drawable/purchase_cardread"/>
+                </RelativeLayout>
+                <!--密码4-->
+                <RelativeLayout
+                    android:layout_width="@dimen/float_password_pwd_size"
+                    android:layout_height="@dimen/float_password_pwd_size"
+                    android:layout_marginLeft="@dimen/float_password_left_obj_gap">
+
+                    <ImageView
+                        android:layout_width="fill_parent"
+                        android:layout_height="fill_parent"
+                        android:background="@drawable/password_pwd_frame"/>
+
+                    <ImageView
+                        android:id="@+id/float_password_img4"
+                        android:layout_width="20dp"
+                        android:layout_height="20dp"
+                        android:layout_margin="26dp"
+                        android:layout_marginTop="26dp"
+                        android:scaleType="fitXY"
+                        android:src="@drawable/purchase_cardread"/>
+                </RelativeLayout>
+                <!--密码5-->
+                <RelativeLayout
+                    android:layout_width="@dimen/float_password_pwd_size"
+                    android:layout_height="@dimen/float_password_pwd_size"
+                    android:layout_marginLeft="@dimen/float_password_left_obj_gap">
+
+                    <ImageView
+                        android:layout_width="fill_parent"
+                        android:layout_height="fill_parent"
+                        android:background="@drawable/password_pwd_frame"/>
+
+                    <ImageView
+                        android:id="@+id/float_password_img5"
+                        android:layout_width="20dp"
+                        android:layout_height="20dp"
+                        android:layout_margin="26dp"
+                        android:layout_marginTop="26dp"
+                        android:scaleType="fitXY"
+                        android:src="@drawable/purchase_cardread"/>
+                </RelativeLayout>
+                <!--密码6-->
+                <RelativeLayout
+                    android:layout_width="@dimen/float_password_pwd_size"
+                    android:layout_height="@dimen/float_password_pwd_size"
+                    android:layout_marginLeft="@dimen/float_password_left_obj_gap">
+
+                    <ImageView
+                        android:layout_width="fill_parent"
+                        android:layout_height="fill_parent"
+                        android:background="@drawable/password_pwd_frame"/>
+
+                    <ImageView
+                        android:id="@+id/float_password_img6"
+                        android:layout_width="20dp"
+                        android:layout_height="20dp"
+                        android:layout_margin="26dp"
+                        android:layout_marginTop="26dp"
+                        android:scaleType="fitXY"
+                        android:src="@drawable/purchase_cardread"/>
+                </RelativeLayout>
+            </LinearLayout>
+        </LinearLayout>
+
+        <!--下半部分-->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="10dp"
+            android:layout_marginTop="@dimen/float_password_right_margin_top"
+            android:gravity="center_horizontal"
+            android:orientation="vertical">
+            <!--第一行按键-->
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="@dimen/float_password_btn_size"
+                android:orientation="horizontal">
+
+                <ImageView
+                    android:id="@+id/float_password_btn1"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:src="@drawable/pass_one_normal"/>
+
+                <ImageView
+                    android:id="@+id/float_password_btn2"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+                    android:src="@drawable/pass_two_normal"/>
+
+                <ImageView
+                    android:id="@+id/float_password_btn3"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+                    android:src="@drawable/pass_three_normal"/>
+            </LinearLayout>
+            <!--第二行按钮-->
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="@dimen/float_password_btn_size"
+                android:layout_marginTop="@dimen/float_password_right_btn_margin"
+                android:orientation="horizontal">
+
+                <ImageView
+                    android:id="@+id/float_password_btn4"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:src="@drawable/pass_four_normal"/>
+
+                <ImageView
+                    android:id="@+id/float_password_btn5"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+                    android:src="@drawable/pass_five_normal"/>
+
+                <ImageView
+                    android:id="@+id/float_password_btn6"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+                    android:src="@drawable/pass_six_normal"/>
+            </LinearLayout>
+            <!--第三行按钮-->
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="@dimen/float_password_btn_size"
+                android:layout_marginTop="@dimen/float_password_right_btn_margin"
+                android:orientation="horizontal">
+
+                <ImageView
+                    android:id="@+id/float_password_btn7"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:src="@drawable/pass_seven_normal"/>
+
+                <ImageView
+                    android:id="@+id/float_password_btn8"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+                    android:src="@drawable/pass_eight_normal"/>
+
+                <ImageView
+                    android:id="@+id/float_password_btn9"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+                    android:src="@drawable/pass_nine_normal"/>
+            </LinearLayout>
+            <!--第四行按钮-->
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="@dimen/float_password_btn_size"
+                android:layout_marginBottom="10dp"
+                android:layout_marginTop="@dimen/float_password_right_btn_margin"
+                android:orientation="horizontal">
+
+                <TextView
+                    android:id="@+id/float_password_cancel"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:background="@drawable/btn_red_normal"
+                    android:gravity="center"
+                    android:text="取消"
+                    android:textColor="@color/white"
+                    android:textSize="30sp"/>
+
+                <ImageView
+                    android:id="@+id/float_password_btn0"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+                    android:src="@drawable/pass_zero_normal"/>
+
+                <ImageView
+                    android:id="@+id/float_password_btn_delete"
+                    android:layout_width="@dimen/float_password_btn_size"
+                    android:layout_height="@dimen/float_password_btn_size"
+                    android:layout_marginLeft="@dimen/float_password_right_btn_margin"
+                    android:src="@drawable/pass_delete_normal"/>
+            </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+</RelativeLayout>
+
+
diff --git a/app/src/main/res/layout/dialog_progress.xml b/app/src/main/res/layout/dialog_progress.xml
new file mode 100644
index 0000000..f2c8fb8
--- /dev/null
+++ b/app/src/main/res/layout/dialog_progress.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/pay_ret_dialog_bg"
+    android:orientation="vertical"
+    android:gravity="center"
+    android:paddingTop="30dp"
+    android:paddingBottom="30dp"
+    android:paddingLeft="30dp"
+    android:paddingRight="30dp">
+
+    <ProgressBar
+        android:id="@+id/loadingImageView"
+        style="@style/myProgressBarStyleLarge"
+        android:layout_width="200dp"
+        android:layout_height="200dp"
+        android:layout_gravity="center"
+        android:padding="20dp" />
+
+    <TextView
+        android:id="@+id/loadingmsg"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:textColor="@android:color/white"
+        android:text="正在处理,请不要拿走卡片..."
+        android:textSize="30dp"
+        android:layout_marginBottom="30dp"
+        android:layout_marginTop="10dp" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_purchase.xml b/app/src/main/res/layout/dialog_purchase.xml
new file mode 100644
index 0000000..e43ef15
--- /dev/null
+++ b/app/src/main/res/layout/dialog_purchase.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="450dp"
+              android:layout_height="300dp"
+              android:background="@color/light_blue2"
+              android:layout_gravity="center"
+              android:orientation="vertical">
+    <RelativeLayout android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:layout_gravity="center"
+                    android:layout_margin="10dp"
+                    android:background="@drawable/corner_bg_white"
+                    android:gravity="center_horizontal"
+                    android:orientation="vertical">
+        <!--倒计时-->
+        <TextView
+                android:id="@+id/tv_close_count"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="15dp"
+                android:layout_marginTop="10dp"
+                android:gravity="start|center"
+                android:text="30s"
+                android:textColor="@color/blue"
+                android:textSize="30sp"/>
+        <LinearLayout
+                style="@style/purchase_ll_text_style"
+                android:layout_below="@+id/tv_close_count">
+
+            <TextView
+                    android:id="@+id/tv_pay_hint"
+                    style="@style/purchase_tv_text_hint_style"
+                    android:text="消费成功"
+                    android:textColor="@color/light_green"/>
+
+            <TextView
+                    android:id="@+id/tv_pay_amount"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="10dp"
+                    android:text="金额:  10.00元"
+                    android:textColor="@color/black"
+                    android:textSize="@dimen/ordinary_consume_text_size"/>
+
+            <TextView
+                    android:id="@+id/tv_pay_balance"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="余额:  123.00元"
+                    android:textColor="@color/black"
+                    android:textSize="@dimen/ordinary_consume_text_size"/>
+
+        </LinearLayout>
+    </RelativeLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_init_nsd_config_list.xml b/app/src/main/res/layout/item_init_nsd_config_list.xml
new file mode 100644
index 0000000..735e6f9
--- /dev/null
+++ b/app/src/main/res/layout/item_init_nsd_config_list.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/ll_config"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/corner_bg_gray"
+    android:orientation="horizontal">
+
+    <TextView
+        android:id="@+id/tv_config_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:maxLines="1"
+        android:padding="10dp"
+        android:textColor="@color/light_blue2"
+        android:textSize="30sp"
+        android:textStyle="bold" />
+
+    <TextView
+        android:id="@+id/tv_config_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="10dp"
+        android:maxLines="1"
+        android:padding="10dp"
+        android:textColor="@color/light_blue2"
+        android:textSize="30sp"
+        android:textStyle="bold" />
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_syspara.xml b/app/src/main/res/layout/item_syspara.xml
new file mode 100644
index 0000000..cdaccac
--- /dev/null
+++ b/app/src/main/res/layout/item_syspara.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="horizontal"
+              android:weightSum="2">
+
+    <TextView
+            android:id="@+id/tv_name"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp"/>
+
+    <TextView
+            android:id="@+id/tv_value"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:textColor="@color/light_blue2"
+            android:textSize="30sp"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/sw_toast.xml b/app/src/main/res/layout/sw_toast.xml
new file mode 100644
index 0000000..bdc5081
--- /dev/null
+++ b/app/src/main/res/layout/sw_toast.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:background="@drawable/corner_bg"
+              android:gravity="center"
+              android:orientation="horizontal"
+              android:padding="5dp">
+
+    <ImageView
+        android:id="@+id/pic_cry"
+        android:layout_width="60dp"
+        android:layout_height="60dp"
+        android:layout_gravity="center"
+        android:scaleType="fitXY"
+        android:src="@drawable/toast_cry"
+        android:visibility="gone"/>
+
+    <ImageView
+        android:id="@+id/pic_smile"
+        android:layout_width="60dp"
+        android:layout_height="60dp"
+        android:layout_gravity="center"
+        android:scaleType="fitXY"
+        android:src="@drawable/toast_smile"/>
+
+    <ImageView
+        android:id="@+id/pic_doubt"
+        android:layout_width="60dp"
+        android:layout_height="60dp"
+        android:layout_gravity="center"
+        android:scaleType="fitXY"
+        android:src="@drawable/toast_doubt"
+        android:visibility="gone"/>
+
+    <TextView
+        android:id="@+id/toasttext"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="链路检测失败"
+        android:textColor="@color/black"
+        android:textSize="45dp"
+        android:textStyle="bold"/>
+</LinearLayout>
diff --git a/app/src/main/res/layout/toast_util.xml b/app/src/main/res/layout/toast_util.xml
new file mode 100644
index 0000000..765f9cd
--- /dev/null
+++ b/app/src/main/res/layout/toast_util.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical">
+
+    <TextView
+            android:id="@+id/toasttext"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:background="@drawable/corner_bg"
+            android:padding="30dp"
+            android:text="测试"
+            android:textColor="@color/black"
+            android:textSize="35sp"
+            android:textStyle="bold"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..bbd3e02
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background"/>
+    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..bbd3e02
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background"/>
+    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/bill_lastdtl.png b/app/src/main/res/mipmap-hdpi/bill_lastdtl.png
new file mode 100644
index 0000000..de03aa0
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/bill_lastdtl.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/default_photo.png b/app/src/main/res/mipmap-hdpi/default_photo.png
new file mode 100644
index 0000000..ca377a9
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/default_photo.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..898f3ed
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dffca36
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/pay_with_bar.png b/app/src/main/res/mipmap-hdpi/pay_with_bar.png
new file mode 100644
index 0000000..9c1f31a
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/pay_with_bar.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/pay_with_card.png b/app/src/main/res/mipmap-hdpi/pay_with_card.png
new file mode 100644
index 0000000..1b2d929
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/pay_with_card.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/pay_with_scan.png b/app/src/main/res/mipmap-hdpi/pay_with_scan.png
new file mode 100644
index 0000000..afc2bb1
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/pay_with_scan.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/pay_with_virtualcard.png b/app/src/main/res/mipmap-hdpi/pay_with_virtualcard.png
new file mode 100644
index 0000000..f8cf8a6
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/pay_with_virtualcard.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/scan_default_photo.jpg b/app/src/main/res/mipmap-hdpi/scan_default_photo.jpg
new file mode 100644
index 0000000..34adcad
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/scan_default_photo.jpg
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/shop_logo.png b/app/src/main/res/mipmap-hdpi/shop_logo.png
new file mode 100644
index 0000000..79ba1ec
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/shop_logo.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/show_card_info.png b/app/src/main/res/mipmap-hdpi/show_card_info.png
new file mode 100644
index 0000000..c622914
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/show_card_info.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..64ba76f
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dae5e08
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..e5ed465
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..14ed0af
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b0907ca
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..d8ae031
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..2c18de9
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..beed3cd
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/raw/beep.ogg b/app/src/main/res/raw/beep.ogg
new file mode 100644
index 0000000..1419947
--- /dev/null
+++ b/app/src/main/res/raw/beep.ogg
Binary files differ
diff --git a/app/src/main/res/raw/card_passwd.wav b/app/src/main/res/raw/card_passwd.wav
new file mode 100644
index 0000000..f53ffb4
--- /dev/null
+++ b/app/src/main/res/raw/card_passwd.wav
Binary files differ
diff --git a/app/src/main/res/raw/consume_fail.wav b/app/src/main/res/raw/consume_fail.wav
new file mode 100644
index 0000000..37905b9
--- /dev/null
+++ b/app/src/main/res/raw/consume_fail.wav
Binary files differ
diff --git a/app/src/main/res/raw/consume_suc.wav b/app/src/main/res/raw/consume_suc.wav
new file mode 100644
index 0000000..29dba78
--- /dev/null
+++ b/app/src/main/res/raw/consume_suc.wav
Binary files differ
diff --git a/app/src/main/res/raw/dps_fail.wav b/app/src/main/res/raw/dps_fail.wav
new file mode 100644
index 0000000..3dd255e
--- /dev/null
+++ b/app/src/main/res/raw/dps_fail.wav
Binary files differ
diff --git a/app/src/main/res/raw/dps_feeamt_suc.wav b/app/src/main/res/raw/dps_feeamt_suc.wav
new file mode 100644
index 0000000..976f337
--- /dev/null
+++ b/app/src/main/res/raw/dps_feeamt_suc.wav
Binary files differ
diff --git a/app/src/main/res/raw/dps_login_fail.wav b/app/src/main/res/raw/dps_login_fail.wav
new file mode 100644
index 0000000..cc7f082
--- /dev/null
+++ b/app/src/main/res/raw/dps_login_fail.wav
Binary files differ
diff --git a/app/src/main/res/raw/dps_login_suc.wav b/app/src/main/res/raw/dps_login_suc.wav
new file mode 100644
index 0000000..f93d948
--- /dev/null
+++ b/app/src/main/res/raw/dps_login_suc.wav
Binary files differ
diff --git a/app/src/main/res/raw/dps_suc.wav b/app/src/main/res/raw/dps_suc.wav
new file mode 100644
index 0000000..7fc83cf
--- /dev/null
+++ b/app/src/main/res/raw/dps_suc.wav
Binary files differ
diff --git a/app/src/main/res/raw/eastcompeace_a711.json b/app/src/main/res/raw/eastcompeace_a711.json
new file mode 100644
index 0000000..c768ceb
--- /dev/null
+++ b/app/src/main/res/raw/eastcompeace_a711.json
@@ -0,0 +1,16 @@
+{
+  "desc": "东信和平(哈工程)",
+  "manufactory": "eastcompeace",
+  "fingerprint": [
+    {
+      "fingerprint": "127880B0024D540081",
+      "offset": 4,
+      "defaultRootKey": "00000000000000000000000000000000"
+    },
+    {
+      "fingerprint": "057880B002",
+      "offset": 4,
+      "defaultRootKey": "00000000000000000000000000000000"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/app/src/main/res/raw/epaycard.cfg b/app/src/main/res/raw/epaycard.cfg
new file mode 100644
index 0000000..c55ad32
--- /dev/null
+++ b/app/src/main/res/raw/epaycard.cfg
@@ -0,0 +1,122 @@
+{
+  "version": "1.0",
+  "custname": "supwisdom",
+  "id": "com.supwisdom.epaycard.cpucard.a711",
+  "desc": "新开普A711读卡器",
+  "issue_date": "20171221",
+  "custom_version": "v1.0",
+  "authcode": "08712016070002",
+  "atr_pretend": true,
+  "support_platform": [
+    "linux"
+  ],
+  "expire_date": "20300517",
+  "cardtype": [
+    {
+      "name": "SupCpuCardType",
+      "class": "com.supwisdom.epaycard.impl.SupCpuCardtype",
+      "psamcard": "sup_psamcard",
+      "keymachine": "SupKeyMachine",
+      "debug": false,
+      "fingerprint": [
+        {
+          "initializer": "com.supwisdom.epaycard.impl.FM201810Initializer",
+          "config": [
+            "classpath:res/raw/fmcos_a711.json"
+          ]
+        },
+        {
+          "config": [
+            "classpath:fingerprint/goldpac_e711.json"
+          ],
+          "initializer": "com.supwisdom.epaycard.impl.GoldPacCardInitializer"
+        }
+      ]
+    },
+    {
+      "name": "SupCpuCardTypeWithoutMac",
+      "class": "com.supwisdom.epaycard.impl.SupCardtypeRWOM",
+      "psamcard": "sup_psamcard",
+      "keymachine": "SupKeyMachine",
+      "debug": false,
+      "fingerprint": [
+        {
+          "config": [
+            "classpath:res/raw/eastcompeace_a711.json"
+          ],
+          "initializer": "com.supwisdom.epaycard.impl.GoldPacCardInitializer"
+        }
+      ]
+    },
+    {
+      "name": "SupM1Cardtype",
+      "class": "com.supwisdom.epaycard.impl.SupM1CardType",
+      "psamcard": "sup_psamcard",
+      "keymachine": "SupKeyMachine",
+      "keyalg": "normal2",
+      "version": 2008,
+      "water_packet": 6,
+      "minsect": 0,
+      "maxsect": 6,
+      "init_sections": [
+        1,
+        2,
+        4,
+        5,
+        6
+      ],
+      "debug": false
+    }
+  ],
+  "reader": [
+    {
+      "name": "a711_reader",
+      "class": "com.supwisdom.epaycard.android.A711Reader",
+      "picc_req_times": 1,
+      "rf_interval": 100,
+      "rf_timeout": 300,
+      "debug": false
+    }
+  ],
+  "psamcard": [
+    {
+      "name": "sup_psamcard",
+      "reader": "a711_reader",
+      "keymachine": "SupKeyMachine",
+      "class": "com.supwisdom.epaycard.impl.SupPsamCard",
+      "debug": false,
+      "max_sect_len": 48,
+      "fingerprint": [
+        {
+          "manufactory": "einolda",
+          "fingerprint": "FFFF",
+          "max_block": 56,
+          "offset": 4,
+          "default": true
+        },
+        {
+          "manufactory": "broadstar",
+          "fingerprint": "4253",
+          "offset": 5,
+          "defaultRootKey": "57415443484441544154696D65434F53"
+        }
+      ]
+    }
+  ],
+  "keymachine": [
+    {
+      "name": "SupKeyMachine",
+      "reader": "a711_reader",
+      "debug": false,
+      "class": "com.supwisdom.epaycard.impl.SupKeyCard"
+    }
+  ],
+  "water_setting_card": [
+    {
+      "name": "sup_watercard",
+      "reader": "a711_reader",
+      "keymachine": "SupKeyMachine",
+      "class": "com.supwisdom.epaycard.impl.SupWaterSettingCard"
+    }
+  ]
+}
diff --git a/app/src/main/res/raw/epaycard_hit.cfg b/app/src/main/res/raw/epaycard_hit.cfg
new file mode 100644
index 0000000..7b99201
--- /dev/null
+++ b/app/src/main/res/raw/epaycard_hit.cfg
@@ -0,0 +1,101 @@
+{
+  "version": "1.0",
+  "custname": "supwisdom",
+  "id": "com.supwisdom.epaycard.cpucard.a711",
+  "desc": "新开普A711读卡器",
+  "issue_date": "20171221",
+  "custom_version": "v1.0",
+  "authcode": "08712016070002",
+  "atr_pretend": true,
+  "support_platform": [
+    "linux"
+  ],
+  "expire_date": "20300517",
+  "cardtype": [
+    {
+      "name": "SupCpuCardTypeWithoutMac",
+      "class": "com.supwisdom.epaycard.impl.SupCardtypeRWOM",
+      "psamcard": "sup_psamcard",
+      "keymachine": "SupKeyMachine",
+      "debug": false,
+      "fingerprint": [
+        {
+          "config": [
+            "classpath:res/raw/eastcompeace_a711.json"
+          ],
+          "initializer": "com.supwisdom.epaycard.impl.GoldPacCardInitializer"
+        }
+      ]
+    },
+    {
+      "name": "SupM1Cardtype",
+      "class": "com.supwisdom.epaycard.impl.SupM1CardType",
+      "psamcard": "sup_psamcard",
+      "keymachine": "SupKeyMachine",
+      "keyalg": "normal2",
+      "version": 2008,
+      "water_packet": 6,
+      "minsect": 0,
+      "maxsect": 6,
+      "init_sections": [
+        1,
+        2,
+        4,
+        5,
+        6
+      ],
+      "debug": false
+    }
+  ],
+  "reader": [
+    {
+      "name": "a711_reader",
+      "class": "com.supwisdom.epaycard.android.A711Reader",
+      "picc_req_times": 1,
+      "rf_interval": 100,
+      "rf_timeout": 300,
+      "debug": false
+    }
+  ],
+  "psamcard": [
+    {
+      "name": "sup_psamcard",
+      "reader": "a711_reader",
+      "keymachine": "SupKeyMachine",
+      "class": "com.supwisdom.epaycard.impl.SupPsamCard",
+      "debug": false,
+      "max_sect_len": 48,
+      "fingerprint": [
+        {
+          "manufactory": "einolda",
+          "fingerprint": "FFFF",
+          "max_block": 56,
+          "offset": 4,
+          "default": true
+        },
+        {
+          "manufactory": "broadstar",
+          "fingerprint": "4253",
+          "offset": 5,
+          "defaultRootKey": "57415443484441544154696D65434F53"
+        }
+      ]
+    }
+  ],
+  "keymachine": [
+    {
+      "name": "SupKeyMachine",
+      "reader": "a711_reader",
+      "debug": false,
+      "class": "com.supwisdom.epaycard.impl.SupKeyCard"
+    }
+  ],
+  "water_setting_card": [
+    {
+      "name": "sup_watercard",
+      "reader": "a711_reader",
+      "keymachine": "SupKeyMachine",
+      "class": "com.supwisdom.epaycard.impl.SupWaterSettingCard"
+    }
+  ]
+}
diff --git a/app/src/main/res/raw/fmcos_a711.json b/app/src/main/res/raw/fmcos_a711.json
new file mode 100644
index 0000000..20035ee
--- /dev/null
+++ b/app/src/main/res/raw/fmcos_a711.json
@@ -0,0 +1,11 @@
+{
+  "desc" : "FM1208卡",
+  "manufactory" :"fmcos1208",
+  "fingerprint" : [
+    {
+      "fingerprint": "20900000000000",
+      "offset": 0,
+      "defaultRootKey": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/app/src/main/res/raw/gatein_fail.wav b/app/src/main/res/raw/gatein_fail.wav
new file mode 100644
index 0000000..0de1b71
--- /dev/null
+++ b/app/src/main/res/raw/gatein_fail.wav
Binary files differ
diff --git a/app/src/main/res/raw/gatein_suc.wav b/app/src/main/res/raw/gatein_suc.wav
new file mode 100644
index 0000000..56b106c
--- /dev/null
+++ b/app/src/main/res/raw/gatein_suc.wav
Binary files differ
diff --git a/app/src/main/res/raw/gateout_fail.wav b/app/src/main/res/raw/gateout_fail.wav
new file mode 100644
index 0000000..4b2c39c
--- /dev/null
+++ b/app/src/main/res/raw/gateout_fail.wav
Binary files differ
diff --git a/app/src/main/res/raw/gateout_suc.wav b/app/src/main/res/raw/gateout_suc.wav
new file mode 100644
index 0000000..e04a659
--- /dev/null
+++ b/app/src/main/res/raw/gateout_suc.wav
Binary files differ
diff --git a/app/src/main/res/raw/goldpac_a711.json b/app/src/main/res/raw/goldpac_a711.json
new file mode 100644
index 0000000..20a5f2d
--- /dev/null
+++ b/app/src/main/res/raw/goldpac_a711.json
@@ -0,0 +1,16 @@
+{
+  "desc" : "金邦达卡",
+  "manufactory" :"goldpac",
+  "fingerprint" : [
+    {
+      "fingerprint": "80318066",
+      "offset": 2,
+      "defaultRootKey": "00000000000000000000000000000000"
+    },
+    {
+      "fingerprint": "057880A002",
+      "offset": 4,
+      "defaultRootKey": "00000000000000000000000000000000"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/app/src/main/res/raw/key_add.wav b/app/src/main/res/raw/key_add.wav
new file mode 100644
index 0000000..8fe2703
--- /dev/null
+++ b/app/src/main/res/raw/key_add.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_clear.wav b/app/src/main/res/raw/key_clear.wav
new file mode 100644
index 0000000..3c29559
--- /dev/null
+++ b/app/src/main/res/raw/key_clear.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_dot.wav b/app/src/main/res/raw/key_dot.wav
new file mode 100644
index 0000000..69232dc
--- /dev/null
+++ b/app/src/main/res/raw/key_dot.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_eight.wav b/app/src/main/res/raw/key_eight.wav
new file mode 100644
index 0000000..484f755
--- /dev/null
+++ b/app/src/main/res/raw/key_eight.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_enter.wav b/app/src/main/res/raw/key_enter.wav
new file mode 100644
index 0000000..5386f86
--- /dev/null
+++ b/app/src/main/res/raw/key_enter.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_ffour.wav b/app/src/main/res/raw/key_ffour.wav
new file mode 100644
index 0000000..6b94cb9
--- /dev/null
+++ b/app/src/main/res/raw/key_ffour.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_five.wav b/app/src/main/res/raw/key_five.wav
new file mode 100644
index 0000000..830e234
--- /dev/null
+++ b/app/src/main/res/raw/key_five.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_fone.wav b/app/src/main/res/raw/key_fone.wav
new file mode 100644
index 0000000..59adfde
--- /dev/null
+++ b/app/src/main/res/raw/key_fone.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_four.wav b/app/src/main/res/raw/key_four.wav
new file mode 100644
index 0000000..5580975
--- /dev/null
+++ b/app/src/main/res/raw/key_four.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_fthree.wav b/app/src/main/res/raw/key_fthree.wav
new file mode 100644
index 0000000..1291d25
--- /dev/null
+++ b/app/src/main/res/raw/key_fthree.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_ftwo.wav b/app/src/main/res/raw/key_ftwo.wav
new file mode 100644
index 0000000..07fd91c
--- /dev/null
+++ b/app/src/main/res/raw/key_ftwo.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_nine.wav b/app/src/main/res/raw/key_nine.wav
new file mode 100644
index 0000000..7013cb5
--- /dev/null
+++ b/app/src/main/res/raw/key_nine.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_one.wav b/app/src/main/res/raw/key_one.wav
new file mode 100644
index 0000000..3b998f3
--- /dev/null
+++ b/app/src/main/res/raw/key_one.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_seven.wav b/app/src/main/res/raw/key_seven.wav
new file mode 100644
index 0000000..e5226ce
--- /dev/null
+++ b/app/src/main/res/raw/key_seven.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_six.wav b/app/src/main/res/raw/key_six.wav
new file mode 100644
index 0000000..2e25469
--- /dev/null
+++ b/app/src/main/res/raw/key_six.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_three.wav b/app/src/main/res/raw/key_three.wav
new file mode 100644
index 0000000..ad00780
--- /dev/null
+++ b/app/src/main/res/raw/key_three.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_two.wav b/app/src/main/res/raw/key_two.wav
new file mode 100644
index 0000000..56fc1de
--- /dev/null
+++ b/app/src/main/res/raw/key_two.wav
Binary files differ
diff --git a/app/src/main/res/raw/key_zero.wav b/app/src/main/res/raw/key_zero.wav
new file mode 100644
index 0000000..4fd1864
--- /dev/null
+++ b/app/src/main/res/raw/key_zero.wav
Binary files differ
diff --git a/app/src/main/res/raw/login_fail.wav b/app/src/main/res/raw/login_fail.wav
new file mode 100644
index 0000000..3e901c7
--- /dev/null
+++ b/app/src/main/res/raw/login_fail.wav
Binary files differ
diff --git a/app/src/main/res/raw/login_suc.wav b/app/src/main/res/raw/login_suc.wav
new file mode 100644
index 0000000..70a4ee2
--- /dev/null
+++ b/app/src/main/res/raw/login_suc.wav
Binary files differ
diff --git a/app/src/main/res/raw/pay_fail.wav b/app/src/main/res/raw/pay_fail.wav
new file mode 100644
index 0000000..85dbb67
--- /dev/null
+++ b/app/src/main/res/raw/pay_fail.wav
Binary files differ
diff --git a/app/src/main/res/raw/pay_suc.wav b/app/src/main/res/raw/pay_suc.wav
new file mode 100644
index 0000000..e0e8945
--- /dev/null
+++ b/app/src/main/res/raw/pay_suc.wav
Binary files differ
diff --git a/app/src/main/res/raw/query_fail.wav b/app/src/main/res/raw/query_fail.wav
new file mode 100644
index 0000000..4532286
--- /dev/null
+++ b/app/src/main/res/raw/query_fail.wav
Binary files differ
diff --git a/app/src/main/res/raw/query_suc.wav b/app/src/main/res/raw/query_suc.wav
new file mode 100644
index 0000000..d156756
--- /dev/null
+++ b/app/src/main/res/raw/query_suc.wav
Binary files differ
diff --git a/app/src/main/res/raw/reversal_done.wav b/app/src/main/res/raw/reversal_done.wav
new file mode 100644
index 0000000..72804bb
--- /dev/null
+++ b/app/src/main/res/raw/reversal_done.wav
Binary files differ
diff --git a/app/src/main/res/raw/reversal_fail.wav b/app/src/main/res/raw/reversal_fail.wav
new file mode 100644
index 0000000..2e314be
--- /dev/null
+++ b/app/src/main/res/raw/reversal_fail.wav
Binary files differ
diff --git a/app/src/main/res/raw/reversal_suc.wav b/app/src/main/res/raw/reversal_suc.wav
new file mode 100644
index 0000000..61f1c8a
--- /dev/null
+++ b/app/src/main/res/raw/reversal_suc.wav
Binary files differ
diff --git a/app/src/main/res/raw/scan_beep.ogg b/app/src/main/res/raw/scan_beep.ogg
new file mode 100644
index 0000000..1419947
--- /dev/null
+++ b/app/src/main/res/raw/scan_beep.ogg
Binary files differ
diff --git a/app/src/main/res/raw/sound_key_eight.wav b/app/src/main/res/raw/sound_key_eight.wav
new file mode 100644
index 0000000..82d8b26
--- /dev/null
+++ b/app/src/main/res/raw/sound_key_eight.wav
Binary files differ
diff --git a/app/src/main/res/raw/sound_key_five.wav b/app/src/main/res/raw/sound_key_five.wav
new file mode 100644
index 0000000..b35596c
--- /dev/null
+++ b/app/src/main/res/raw/sound_key_five.wav
Binary files differ
diff --git a/app/src/main/res/raw/sound_key_four.wav b/app/src/main/res/raw/sound_key_four.wav
new file mode 100644
index 0000000..f56c4ee
--- /dev/null
+++ b/app/src/main/res/raw/sound_key_four.wav
Binary files differ
diff --git a/app/src/main/res/raw/sound_key_nine.wav b/app/src/main/res/raw/sound_key_nine.wav
new file mode 100644
index 0000000..20722db
--- /dev/null
+++ b/app/src/main/res/raw/sound_key_nine.wav
Binary files differ
diff --git a/app/src/main/res/raw/sound_key_one.wav b/app/src/main/res/raw/sound_key_one.wav
new file mode 100644
index 0000000..faf8bdb
--- /dev/null
+++ b/app/src/main/res/raw/sound_key_one.wav
Binary files differ
diff --git a/app/src/main/res/raw/sound_key_seven.wav b/app/src/main/res/raw/sound_key_seven.wav
new file mode 100644
index 0000000..9baaafc
--- /dev/null
+++ b/app/src/main/res/raw/sound_key_seven.wav
Binary files differ
diff --git a/app/src/main/res/raw/sound_key_six.wav b/app/src/main/res/raw/sound_key_six.wav
new file mode 100644
index 0000000..cb4b14e
--- /dev/null
+++ b/app/src/main/res/raw/sound_key_six.wav
Binary files differ
diff --git a/app/src/main/res/raw/sound_key_three.wav b/app/src/main/res/raw/sound_key_three.wav
new file mode 100644
index 0000000..354a26d
--- /dev/null
+++ b/app/src/main/res/raw/sound_key_three.wav
Binary files differ
diff --git a/app/src/main/res/raw/sound_key_two.wav b/app/src/main/res/raw/sound_key_two.wav
new file mode 100644
index 0000000..87898f3
--- /dev/null
+++ b/app/src/main/res/raw/sound_key_two.wav
Binary files differ
diff --git a/app/src/main/res/raw/sound_key_zero.wav b/app/src/main/res/raw/sound_key_zero.wav
new file mode 100644
index 0000000..be4f0cb
--- /dev/null
+++ b/app/src/main/res/raw/sound_key_zero.wav
Binary files differ
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..07cae7a
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,105 @@
+<resources>
+    <color name="black_overlay">#66000000</color>
+    <color name="btn_light_blue">#5bc0de</color>
+    <color name="light_gray">#ffa2a2a2</color>
+    <color name="light_gray1">#cdcdcd</color>
+    <color name="light_green">#46d608</color>
+    <color name="light_green1">#83f800</color>
+    <color name="light_green2">#05a910</color>
+    <color name="light_blue1">#00bb9c</color>
+    <color name="light_purple">#ed07d0</color>
+    <color name="light_purple1">#f57cc3</color>
+    <color name="light_purple2">#b20469</color>
+    <color name="light_blue">#7899c4</color>
+    <color name="light_yellow">#e1cb28</color>
+    <color name="light_yellow_2">#ffffe928</color>
+    <color name="light_yellow_3">#fffe9f</color>
+    <color name="light_black">#424652</color>
+    <color name="white_gray">#f9f9f9</color>
+    <color name="white">#FFFFFF</color>
+    <color name="pwdColor">#999999</color>
+    <color name="password_hint">#666666</color>
+    <color name="orange">#FD7201</color>
+    <color name="orange1">#FF6600</color>
+    <color name="black">#000</color>
+    <color name="blue">#0c0de1</color>
+    <color name="dark_blue1">#13227a</color>
+    <color name="light_blue2">#2D95E0</color>
+    <color name="dark_blue">#0E1C36</color>
+    <color name="lit_light_gray">#23292E</color>
+    <color name="light_gray_white">#EEEEEE</color>
+    <color name="result_view">#b0000000</color>
+    <color name="viewfinder_mask">#60000000</color>
+    <color name="possible_result_points">#c0ffff00</color>
+    <color name="key_btn_color">#EEEEEE</color>
+    <color name="cl_red">#FF0000</color>
+    <color name="pos_theme_color">#08ae9e</color>
+    <color name="consume_caption">#434343</color>
+    <color name="consume_font">#666666</color>
+    <color name="consume_background">#f3f3f3</color>
+    <color name="main_back_consume_normal">#F15D5D</color>
+    <color name="main_back_consume_click">#E55A5A</color>
+    <color name="main_back_online_deposit_normal">#7E62F8</color>
+    <color name="main_back_online_deposit_click">#785EEB</color>
+    <color name="main_back_device_manage_normal">#7E62F8</color>
+    <color name="main_back_device_manage_click">#785EEB</color>
+    <!--<color custname="main_back_cancel_consume_normal">#25A3B3</color>-->
+    <!--<color custname="main_back_cancel_consume_click">#2396A6</color>-->
+    <color name="main_back_query_revenue_normal">#999999</color>
+    <!--<color custname="main_back_query_revenue_click">#85A629</color>-->
+    <color name="main_back_library_normal">#8EB32C</color>
+    <color name="main_back_library_click">#85A629</color>
+    <color name="main_back_manual_auth_normal">#8EB32C</color>
+    <color name="main_back_manual_auth_click">#85A629</color>
+    <color name="bk_set_block">#F3F3F3</color>
+    <!--<color custname="main_back_update_blacklist_normal">#7E62F8</color>-->
+    <!--<color custname="main_back_update_blacklist_click">#785EEB</color>-->
+    <color name="main_back_update_blacklist_normal">#F28923</color>
+    <color name="main_back_update_blacklist_click">#F28923</color>
+    <color name="main_back_online_order_normal">#F28923</color>
+    <color name="main_back_online_order_click">#F28923</color>
+    <color name="main_back_transdtl_normal">#20A193</color>
+    <color name="main_back_transdtl_click">#1E9486</color>
+    <!--<color custname="main_back_test_net_normal">#F15D5D</color>-->
+    <!--<color custname="main_back_test_net_click">#E55A5A</color>-->
+    <color name="main_back_test_net_normal">#F15D5D</color>
+    <color name="main_back_test_net_click">#E55A5A</color>
+
+    <color name="main_back_query_para_normal">#20A193</color>
+    <color name="main_back_query_para_click">#1E9486</color>
+    <!--<color custname="main_back_device_manage_normal">#2f87d2</color>-->
+    <!--<color custname="main_back_device_manage_click">#2b7dc4</color>-->
+    <color name="main_online_bak">#f1f1f1</color>
+    <color name="main_offline_font">#888888</color>
+    <!--启用界面-->
+    <color name="enable_text_font_color">#333333</color>
+    <color name="enable_devphyid_edit_font_color">#666666</color>
+    <color name="enable_bak">#f1f1f1</color>
+    <color name="enable_step_doing">#333333</color>
+    <color name="enable_step_fail">#ff0000</color>
+    <color name="enable_step_success">#8fccc6</color>
+    <!--设置界面-->
+    <color name="main_divide_line">#e8e8e8</color>
+    <color name="set_menu_bak_normal">#f3f3f3</color>
+    <color name="set_menu_bak_focus">#e4e4e4</color>
+    <color name="set_menu_words">#333333</color>
+    <color name="rf_words_info">#666666</color>
+    <color name="pos_theme_font_color">#333333</color>
+    <!--查询界面下一页按钮的颜色-->
+    <color name="query_next_btn_focus">#08a191</color>
+    <color name="query_next_btn_normal">#08ae9e</color>
+    <!--点餐-->
+    <color name="order_food_list_bak">#fffece</color>
+    <color name="order_picture_food_price">#434343</color>
+    <color name="order_picture_dec">#333333</color>
+    <color name="order_left_count_one">#434343</color>
+    <color name="order_left_count_over_two">#ff0000</color>
+    <color name="order_count_price_col">#ff6a00</color>
+    <color name="order_picture_price_bak">#80161616</color>
+    <color name="order_dec_btn_normal">#333333</color>
+    <color name="order_dec_btn_focus">#FF9900</color>
+    <color name="order_picture_history">#999999</color>
+    <color name="bak_order">#eeeeee</color>
+    <color name="query_font_color">#ffffff</color>
+    <color name="query_background_color">#eeeeee</color>
+</resources>
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..2d50789
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,309 @@
+<resources>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+    <!--dimen custname="activity_horizontal_margin">16dp</dimen-->
+    <dimen name="activity_vertical_margin">16dp</dimen>
+    <dimen name="key_text_size">100sp</dimen>
+    <!--密码界面-->
+    <dimen name="password_margin_horizontal">10dip</dimen>
+    <dimen name="password_margin_vertical">1dip</dimen>
+    <dimen name="password_left_width">320dip</dimen>
+    <dimen name="password_left_obj_gap">10dip</dimen>
+    <dimen name="password_left_word_margin_top">50dip</dimen>
+    <dimen name="password_hint_size">50sp</dimen>
+    <dimen name="password_char_size">80sp</dimen>
+    <dimen name="password_pwd_char_margin_top">-13dip</dimen>
+    <!--密码界面下-->
+    <dimen name="password_right_btn_margin">20dip</dimen>
+    <dimen name="password_right_margin_left">50dip</dimen>
+    <dimen name="password_pwd_size">110dip</dimen>
+    <dimen name="password_pwd_inner_size">102dip</dimen>
+    <dimen name="password_pwd_inner_length">4dip</dimen>
+    <dimen name="password_btn_size">150dip</dimen>
+    <dimen name="password_right_margin_top">30dip</dimen>
+
+    <!--消费界面左-->
+    <dimen name="consume_left_middle_height">241dip</dimen>
+    <dimen name="consume_waiting_margin_left">18dip</dimen>
+    <dimen name="consume_waiting_margin_top">104dip</dimen>
+    <dimen name="consume_waiting_size">19sp</dimen>
+    <dimen name="consume_left_middle_line_height">52dip</dimen>
+    <dimen name="consume_left_middle_line_margin_left">18dip</dimen>
+    <dimen name="consume_left_middle_line_margin_top">18dip</dimen>
+    <dimen name="consume_caption_width">78dip</dimen>
+    <dimen name="consume_caption_size">19sp</dimen>
+    <dimen name="consume_left_down_height">62dip</dimen>
+    <dimen name="consume_left_down_words_margin_left">18dip</dimen>
+    <dimen name="consume_left_down_words_margin_top">12dip</dimen>
+    <dimen name="consume_amount_margin_top">12dip</dimen>
+    <dimen name="consume_title_size">22sp</dimen>
+    <dimen name="consume_amount_size">21sp</dimen>
+    <dimen name="consume_left_width">250dip</dimen>
+    <!--消费界面右-->
+    <dimen name="consume_right_margin_left">12dip</dimen>
+    <dimen name="consume_right_line_height">67dip</dimen>
+    <dimen name="consume_key_button_width">128dip</dimen>
+    <dimen name="consume_right_down_btn_width">181dip</dimen>
+    <dimen name="main_words_size">20sp</dimen>
+    <dimen name="main_caption_size">26sp</dimen>
+    <dimen name="main_top_caption_indent">10dip</dimen>
+    <dimen name="main_icon_marginRight">27dip</dimen>
+    <dimen name="main_icon_marginBottom">45dip</dimen>
+    <!---普通消费界面-->
+    <dimen name="consume_ordinary_key_height">580dp</dimen>
+    <!--主界面-->
+    <dimen name="main_top_height">485dip</dimen>
+    <dimen name="main_top_line_height">241.5dip</dimen>
+    <dimen name="main_bottom_line_height">119.75dip</dimen>
+    <dimen name="main_bottom_icon_size">49dip</dimen>
+    <dimen name="main_transdtl_icon_size">41dip</dimen>
+    <dimen name="main_words_margin">26dip</dimen>
+    <dimen name="main_top_icon_size">100dip</dimen>
+    <dimen name="main_divide_horizontal">2dip</dimen>
+    <dimen name="main_divide_vertical">2dip</dimen>
+    <dimen name="main_online_height">69dip</dimen>
+    <dimen name="main_online_img_size">40dip</dimen>
+    <dimen name="main_online_font_size">22sp</dimen>
+    <dimen name="main_online_gap">39dip</dimen>
+    <!--主界面上-->
+    <dimen name="main_top_img_margin_top">38dip</dimen>
+    <dimen name="main_query_revenue_margin_big">29dip</dimen>
+    <dimen name="main_query_revenue_margin_title">248dip</dimen>
+    <dimen name="main_query_revenue_margin_giant">88dip</dimen>
+    <dimen name="main_query_revenue_words_gap_vertical">4dip</dimen>
+    <!--主界面上左-->
+    <dimen name="main_top_left_width">508.67dip</dimen>
+    <dimen name="main_transdtl_width">508.67dip</dimen>
+    <dimen name="main_button_width">253.33dip</dimen>
+    <dimen name="main_transdtl_hint_margin_left">156dip</dimen>
+    <dimen name="main_transdtl_hint_margin_top">98dip</dimen>
+    <dimen name="main_trussdtl_hint_margin_top">138dip</dimen>
+    <dimen name="main_transdtl_icon_marginBottom">10dip</dimen>
+    <dimen name="main_transdtl_icon_marginRight">142dip</dimen>
+    <dimen name="main_transdtl_words_marginBottom">10dip</dimen>
+    <dimen name="main_transdtl_words_marginRight">40dip</dimen>
+    <!--主界面底部-->
+    <dimen name="main_bottom_icon_margin_top">38dip</dimen>
+    <dimen name="main_bottom_icon_margin_left">8dip</dimen>
+    <dimen name="main_bottom_words_margin_left">23dip</dimen>
+    <dimen name="main_upd_blacklist_words_margin_left">15dip</dimen>
+    <dimen name="main_bottom_words_margin_top">48dip</dimen>
+    <!--查询界面-->
+    <dimen name="query_title_height">55dip</dimen>
+    <dimen name="query_thick_line_width">3dip</dimen>
+    <dimen name="query_thick_line_height">18dip</dimen>
+    <dimen name="query_content_height">55dip</dimen>
+    <dimen name="query_line_margin_top">3dip</dimen>
+    <dimen name="query_words_margin_left">144dip</dimen>
+    <dimen name="query_words_size">26sp</dimen>
+    <dimen name="query_icon_margin_left">12dip</dimen>
+    <dimen name="query_title_margin_left">6dip</dimen>
+    <dimen name="query_half_width">320dip</dimen>
+    <dimen name="query_right_block_margin_top">6dip</dimen>
+    <!--查询界面翻页按钮-->
+    <dimen name="query_turn_page_words_margin_left">6dip</dimen>
+    <dimen name="query_turn_page_btn_size">25dip</dimen>
+    <dimen name="query_turn_page_btn_margin_left">220dip</dimen>
+    <dimen name="query_prev_margin_top">230dip</dimen>
+    <!--消费流水界面-->
+    <dimen name="revenue_btn_size">35dp</dimen>
+    <dimen name="revenue_serch_text_size">30dp</dimen>
+    <dimen name="revenue_list_size">25dp</dimen>
+    <dimen name="revenue_item_size">22dp</dimen>
+    <!--设置界面通用-->
+    <dimen name="set_menu_height">100dip</dimen>
+    <dimen name="set_menu_text_size">30sp</dimen>
+    <dimen name="set_block_words_margin_left">12dip</dimen>
+    <dimen name="set_block_words_width">360dip</dimen>
+    <dimen name="set_arrow_size">19dip</dimen>
+    <dimen name="set_block_width">300dip</dimen>
+    <dimen name="set_block_margin_top">35dip</dimen>
+    <dimen name="set_block_margin_bottom">35dip</dimen>
+
+    <!--恢复出厂界面-->
+    <dimen name="rf_middle_btn_width">108dip</dimen>
+    <dimen name="rf_middle_btn_height">49dip</dimen>
+    <dimen name="rf_middle_words_height">117dip</dimen>
+    <dimen name="rf_words_size">25sp</dimen>
+    <dimen name="rf_middle_btn_margin_bottom">18dip</dimen>
+    <dimen name="rf_progress_bar_height">3dip</dimen>
+    <dimen name="rf_progress_bar_width">481dip</dimen>
+    <!--启用界面-->
+    <dimen name="enable_devphyid_line_inner_gap">15dip</dimen>
+    <dimen name="enable_title_text_size">32sp</dimen>
+    <dimen name="enable_devphyid_font_size">28sp</dimen>
+    <dimen name="enable_devphyid_line_gap">20dip</dimen>
+    <dimen name="enable_devphyid_btn_margin_top">50dip</dimen>
+    <dimen name="enable_devphyid_line_margin_top">80dip</dimen>
+    <dimen name="enable_devphyid_text_width">110dip</dimen>
+    <dimen name="enable_devphyid_edit_width">560dip</dimen>
+    <dimen name="enable_confirm_width">100dip</dimen>
+    <dimen name="enable_confirm_height">50dip</dimen>
+    <dimen name="enable_devphyid_middle_width">668dip</dimen>
+    <dimen name="enable_devphyid_middle_height">660dip</dimen>
+    <dimen name="enable_devphyid_margin_top">70dip</dimen>
+    <dimen name="enable_devphyid_middle_margin_top">20dip</dimen>
+    <dimen name="enable_btn_width">150dip</dimen>
+    <dimen name="enable_btn_height">80dip</dimen>
+    <dimen name="enable_devphyid_btn_gap">150dip</dimen>
+    <!--启用步骤页面-->
+    <dimen name="enable_step_text_size">26sp</dimen>
+    <dimen name="enable_step_line_margin_top">35dip</dimen>
+    <dimen name="enable_step_line_gap">32dip</dimen>
+    <dimen name="enable_step_words_margin_left">20dip</dimen>
+    <dimen name="enable_step_middle_width">668dip</dimen>
+    <dimen name="enable_step_middle_height">660dip</dimen>
+    <dimen name="enable_auth_btn_margin_top">520dip</dimen>
+    <dimen name="enable_auth_text_margin_top">360dip</dimen>
+    <!--设置通讯参数界面-->
+    <dimen name="set_server_line_height">120dip</dimen>
+    <dimen name="set_server_middle_width">600dip</dimen>
+    <dimen name="set_server_middle_height">570dip</dimen>
+    <dimen name="set_server_btn_width">150dip</dimen>
+    <dimen name="set_server_btn_height">60dip</dimen>
+    <dimen name="set_server_btns_text_size">22sp</dimen>
+    <dimen name="set_server_btn_margin_right">100dip</dimen>
+    <!--所有界面的返回按钮-->
+    <dimen name="all_back_line_height">72dip</dimen>
+    <dimen name="all_back_img_size">45dip</dimen>
+    <dimen name="all_back_word_width">115dip</dimen>
+    <dimen name="all_back_word_height">58dip</dimen>
+    <dimen name="all_back_word_margin_left">5dip</dimen>
+    <dimen name="all_back_words_size">30sp</dimen>
+    <dimen name="all_back_img_padtop">60dp</dimen>
+    <dimen name="all_back_img_padleft">20dp</dimen>
+    <!--本地控制参数-->
+    <dimen name="control_para_gap">10dp</dimen>
+    <dimen name="control_para_text_size">28dp</dimen>
+    <!--行间间隔-->
+    <dimen name="line_divide">20dp</dimen>
+    <!--点餐上-->
+    <dimen name="order_picture_section_line_height">252dip</dimen>
+    <dimen name="order_picture_out_width">184dip</dimen>
+    <dimen name="order_picture_inner_width">183dip</dimen>
+    <dimen name="order_picture_inner_height">196dip</dimen>
+    <dimen name="order_picture_simple_inner_width">252dip</dimen>
+    <dimen name="order_picture_simple_inner_height18">135dip</dimen>
+    <dimen name="order_picture_simple_inner_height21">115dip</dimen>
+    <dimen name="order_picture_simple_inner_height24">100dip</dimen>
+    <dimen name="order_picture_simple_inner_height27">90dip</dimen>
+    <dimen name="order_picture_simple_inner_height30">80dip</dimen>
+    <dimen name="order_picture_inner_margin">5dip</dimen>
+    <dimen name="order_picture_out_margin">2dip</dimen>
+    <dimen name="order_picture_price_margin_left">5dip</dimen>
+    <dimen name="order_picture_price_left_width">100dip</dimen>
+    <dimen name="order_picture_big_price_text_size">40sp</dimen>
+    <dimen name="order_picture_price_text_size">28sp</dimen>
+    <dimen name="order_picture_dec_text_size">20sp</dimen>
+    <dimen name="order_zoom_btn_width">57dip</dimen>
+    <dimen name="order_zoom_btn_height">67dip</dimen>
+    <dimen name="order_picture_count_text_size">28sp</dimen>
+    <dimen name="order_picture_section_height">830dip</dimen>
+    <dimen name="order_picture_food_name_height">57dip</dimen>
+    <dimen name="order_order_num_control_btn_size">55dip</dimen>
+    <dimen name="order_purchase_count_margin">10dip</dimen>
+    <dimen name="order_picture_text_si">10dip</dimen>
+    <!--点餐下-->
+    <dimen name="order_food_count_pack_margin_left">20dip</dimen>
+    <dimen name="order_food_name_margin_left">5dip</dimen>
+    <dimen name="order_down_height">200dip</dimen>
+    <dimen name="order_food_name_width">150dip</dimen>
+    <dimen name="order_food_count_width">50dip</dimen>
+    <dimen name="order_food_count_pack_width">170dip</dimen>
+    <dimen name="order_down_btn_text">45sp</dimen>
+    <dimen name="order_down_btn_margin_top">45dip</dimen>
+    <dimen name="order_down_gap">10dip</dimen>
+    <dimen name="order_down_left_width">324dip</dimen>
+    <dimen name="order_list_item_text_size">24sp</dimen>
+    <dimen name="order_total_price_text_size">48sp</dimen>
+    <dimen name="order_clear_btn_width">132dip</dimen>
+    <dimen name="order_clear_btn_height">100dip</dimen>
+    <dimen name="order_purchase_btn_width">216dip</dimen>
+    <dimen name="order_list_item_height">38dip</dimen>
+    <dimen name="order_purchase_btn_height">100dip</dimen>
+    <dimen name="order_total_price_margin_top">20dip</dimen>
+    <dimen name="order_picture_text_size1">30dip</dimen>
+    <dimen name="order_picture_text_size2">35dip</dimen>
+    <dimen name="order_picture_text_size3">40dip</dimen>
+    <!--点餐等待-->
+    <dimen name="order_purchase_star_gap">20dip</dimen>
+    <dimen name="order_purchase_title_height">100dip</dimen>
+    <dimen name="order_purchase_star_height">100dip</dimen>
+    <dimen name="order_wait_purchase_width">650dip</dimen>
+    <dimen name="order_wait_purchase_height">500dip</dimen>
+    <!--普通消费弹窗-->
+    <dimen name="ordinary_consume_home_width">600dip</dimen>
+    <dimen name="ordinary_consume_home_height">450dip</dimen>
+    <dimen name="ordinary_consume_text_size">40sp</dimen>
+    <dimen name="ordinary_consume_uint_size">30dp</dimen>
+    <!--点餐大图-->
+    <dimen name="order_big_picture_price_margin_left">25dip</dimen>
+    <dimen name="order_big_picture_margin_top">70dip</dimen>
+    <dimen name="order_add_food_btn_size">60dip</dimen>
+    <dimen name="order_big_picture_out_width">670dip</dimen>
+    <dimen name="order_big_picture_out_height">562dip</dimen>
+    <dimen name="order_big_picture_inner_width">654dip</dimen>
+    <dimen name="order_big_picture_inner_height">457dip</dimen>
+    <dimen name="order_big_picture_inner_margin">8dip</dimen>
+    <dimen name="order_big_picture_text">50sp</dimen>
+    <dimen name="order_big_picture_food_info_height">119dip</dimen>
+    <dimen name="order_big_picture_food_info_height_half">59dip</dimen>
+    <dimen name="order_big_picture_close_btn_size">75dip</dimen>
+    <dimen name="order_big_picture_confirm_btn_width">200dip</dimen>
+    <dimen name="order_big_picture_confirm_btn_height">75dip</dimen>
+    <dimen name="order_big_picture_confirm_btn_margin_left">170dip</dimen>
+    <dimen name="order_big_picture_count_width">140dip</dimen>
+    <dimen name="order_big_picture_count_height">70dip</dimen>
+    <dimen name="order_big_picture_price_width">200dip</dimen>
+    <dimen name="order_big_picture_dec_margin_left">150dip</dimen>
+    <dimen name="order_picture_history_text_size">12sp</dimen>
+    <dimen name="order_picture_minus_height">43dip</dimen>
+    <dimen name="order_picture_minus_width">80dip</dimen>
+    <dimen name="order_picture_minus_margin_right">6dip</dimen>
+    <dimen name="main_bottom_button_width">381dip</dimen>
+    <!--悬浮密码界面-->
+    <dimen name="float_password_margin_horizontal">5dip</dimen>
+    <dimen name="float_password_margin_vertical">1dip</dimen>
+    <dimen name="float_password_left_width">160dip</dimen>
+    <dimen name="float_password_left_obj_gap">5dip</dimen>
+    <dimen name="float_password_left_word_margin_top">25dip</dimen>
+    <dimen name="float_password_hint_size">35sp</dimen>
+    <dimen name="float_password_char_size">40sp</dimen>
+    <dimen name="float_password_pwd_char_margin_top">-7dip</dimen>
+    <!--悬浮密码界面下-->
+    <dimen name="float_password_right_btn_margin">20dip</dimen>
+    <dimen name="float_password_right_margin_left">25dip</dimen>
+    <dimen name="float_password_pwd_size">70dip</dimen>
+    <dimen name="float_password_pwd_inner_size">70dip</dimen>
+    <dimen name="float_password_pwd_inner_length">2dip</dimen>
+    <dimen name="float_password_btn_size">100dip</dimen>
+    <dimen name="float_password_right_margin_top">15dip</dimen>
+    <!--充值界面-->
+    <dimen name="deposit_userinfo_gap">20dp</dimen>
+    <dimen name="deposit_text_gap">15dp</dimen>
+    <dimen name="deposit_text_size">30sp</dimen>
+    <dimen name="deposit_item_size">20sp</dimen>
+    <dimen name="deposit_bg_crash_width">200dp</dimen>
+    <dimen name="deposit_bg_crash_height">80dp</dimen>
+    <dimen name="deposit_crash_size">50dp</dimen>
+    <dimen name="deposit_dialog_width">300dp</dimen>
+    <dimen name="deposit_dialog_size">40dp</dimen>
+    <dimen name="deposit_shopname_text_size_small">28sp</dimen>
+    <dimen name="deposit_shopname_text_size_normal">35sp</dimen>
+    <!--支付界面-->
+    <dimen name="pay_text_pad_size">10dp</dimen>
+    <dimen name="pay_text_marginleft">30dp</dimen>
+    <dimen name="pay_module_top_size">10dp</dimen>
+    <dimen name="pay_text_size">35sp</dimen>
+    <dimen name="pay_text_title_size">25sp</dimen>
+    <!--待机界面-->
+    <dimen name="consume_text_pad_size">10dp</dimen>
+    <dimen name="consume_text_size">25sp</dimen>
+    <dimen name="consume_text_size1">30sp</dimen>
+    <dimen name="consume_text_size2">30sp</dimen>
+    <dimen name="consume_text_pad_size1">5dp</dimen>
+    <dimen name="consume_shopname_text_size_middle">28sp</dimen>
+    <dimen name="consume_shopname_text_size_normal">35sp</dimen>
+</resources>
diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml
new file mode 100644
index 0000000..056a511
--- /dev/null
+++ b/app/src/main/res/values/ids.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+ Copyright (C) 2008 ZXing authors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<resources>
+    <!-- Messages IDs -->
+    <item name="auto_focus" type="id" />
+    <item name="decode" type="id" />
+    <item name="decode_failed" type="id" />
+    <item name="jump_to_read_card" type="id" />
+    <item name="decode_succeeded" type="id" />
+    <item name="encode_failed" type="id" />
+    <item name="encode_succeeded" type="id" />
+    <item name="launch_product_query" type="id" />
+    <item name="quit" type="id" />
+    <item name="restart_preview" type="id" />
+    <item name="return_scan_result" type="id" />
+    <item name="search_book_contents_failed" type="id" />
+    <item name="search_book_contents_succeeded" type="id" />
+
+
+    <item name="gridview" type="id" />
+    <item name="webview" type="id" />
+
+    <item name="about_version_code" type="id" />
+    <item name="split" type="id" />
+
+</resources>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..c26513d
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">消费POS机</string>
+    <string name="title_activity_base">基类</string>
+    <string name="action_settings">设置</string>
+    <string name="title_activity_main">主界面</string>
+    <string name="title_activity_psam">操作psam卡</string>
+    <string name="title_activity_readcard">读卡</string>
+    <string name="title_activity_mode">模式</string>
+    <string name="title_activity_init">初始化</string>
+    <string name="title_activity_load">加载</string>
+    <string name="title_activity_comm">通讯</string>
+    <string name="title_activity_control">控制参数</string>
+    <string name="title_activity_consumecancel">消费撤销</string>
+    <string name="title_activity_library">图书缴费</string>
+    <string name="title_activity_recharge">在线充值</string>
+    <string name="cardlib_name">supwisdom.kscpucard</string>
+    <string name="connfail">连接失败</string>
+    <string name="msg_read_card_error">读卡错误</string>
+    <string name="msg_notsupport_card_oper">不支持卡操作</string>
+    <string name="msg_card_data_error">卡数据错误</string>
+    <string name="nfc_not_support">不支持NFC</string>
+    <string name="nfc_disabled">NFC未启动</string>
+    <string name="confirm_open_nfc">是否打开NFC</string>
+    <string name="action_exit">退出</string>
+    <string name="wait_msg">请刷卡</string>
+    <string name="menu_name_set">设置</string>
+    <string name="menu_name_purchase">消费</string>
+    <string name="title_activity_set">设置</string>
+    <string name="hello_world">hello</string>
+    <string name="devtimefmt">yyyyMMddHHmmss</string>
+    <string name="title_activity_transdtl">交易流水查询</string>
+    <string name="no_mf_files">\"无MF文件\"</string>
+    <string name="creat_mf_files">创建MF文件</string>
+    <string name="creat_mf_success">创建MF文件成功</string>
+    <string name="creat_mf_fail">创建MF文件失败</string>
+    <string name="mf_exist">MF退出</string>
+    <string name="error">错误</string>
+    <string name="reset_psam1_success">重设PSAM1成功</string>
+    <string name="reset_psam1_failed">重设psam1失败</string>
+    <string name="reset_psam2_success">重设psam2成功</string>
+    <string name="reset_psam2_failed">重设psam2失败</string>
+    <string name="get_random_number_failed">获取随机数失败</string>
+    <string name="reset_import1">初始化1失败</string>
+    <string name="reset_failed_cannot_get_random_number1">不能获取随机数1</string>
+    <string name="reset_import2">重设2失败</string>
+    <string name="reset_failed_cannot_get_random_number2">获取随机数2失败</string>
+    <string name="title_activity_show_day_consume">营业额查询</string>
+    <string name="title_activity_password">密码设置</string>
+    <string name="isPasswordCancel">isPassWordCancel</string>
+    <string name="consume_img">消费</string>
+    <string name="title_activity_auth">签到</string>
+    <string name="action_saoma">扫码</string>
+    <string name="scan_text">将二维码或条码放入框内完成扫描</string>
+    <string name="home_back">返回</string>
+    <string name="title_activity_consume">普通消费</string>
+    <string name="title_activity_qrcamera">扫码</string>
+    <string name="title_activity_splash">树维pos</string>
+    <string name="waiting_msg">正在识别,请稍后…</string>
+    <string name="username">姓 名</string>
+    <string name="userStuEmpNo">学工号</string>
+    <string name="userExpireDate">有效期</string>
+    <string name="userBalance">余 额</string>
+    <string name="consumeAmount">消费额(元)</string>
+    <string name="title_activity_consume_cancel">消费撤销</string>
+    <string name="title_activity_update_blacklist">更新黑名单</string>
+    <string name="title_activity_recover_factory">恢复出厂</string>
+    <string name="dialogTitle">提示</string>
+    <string name="all_home_words">主页</string>
+    <string name="all_back_words">返回</string>
+    <string name="title_activity_order_online">在线点餐</string>
+    <string name="title_activity_query_parameter_second">查询第二页</string>
+    <string name="devphyid">终端机编号</string>
+    <string name="samNo">SAM卡号</string>
+    <string name="softVerNo">软件版本号</string>
+    <string name="feerateVerNo">收费参数版本号</string>
+    <string name="sysparaVerNo">主参数版本号</string>
+    <string name="cardverno">黑名单参数版本号</string>
+    <string name="devseqno">POS当前流水号</string>
+    <string name="opentime">开机时间</string>
+    <string name="nextPage">下一页</string>
+    <string name="queryParameters">终端参数查询</string>
+    <string name="title_activity_change_mode">更改模式</string>
+    <string name="title_activity_enable">设备启用</string>
+    <string name="offline_words">脱机状态</string>
+    <string name="online_words">联机状态</string>
+    <string name="title_activity_set_server_info">设置通讯参数</string>
+    <string name="title_activity_test_touch">TestTouchActivity</string>
+    <string name="wait_put_card_words"><![CDATA[请刷卡 >>]]></string>
+    <string name="title_activity_hotel">酒店消费</string>
+    <string name="title_activity_manage">设备管理</string>
+    <string name="title_activity_revenue">营业额</string>
+    <string name="title_activity_pay">支付</string>
+    <string name="title_activity_modifypwd">修改密码</string>
+    <string name="title_activity_syspara">系统参数</string>
+    <string name="title_activity_department">部门限制</string>
+    <string name="title_activity_sddtl">SD卡流水</string>
+    <string name="title_activity_cardlib">卡库</string>
+    <string name="title_activity_upgrade">本地升级</string>
+    <!--消费菜单-->
+    <string name="consume_menu_revenue">1-营业额</string>
+    <string name="consume_menu_transdtl_upload">2-上传流水</string>
+    <string name="consume_menu_link_check">3-链路检测</string>
+    <string name="consume_menu_auth">4-手工签到</string>
+    <string name="consume_menu_syspara_query">5-参数查询</string>
+    <string name="consume_menu_manage">6-管理功能</string>
+    <string name="consume_menu_shop_password_set">7-商户密码</string>
+    <string name="consume_menu_consume_mode">8-消费模式</string>
+    <string name="consume_menu_reverse">9-手工冲正</string>
+    <!--消费维护菜单-->
+    <string name="consume_menu_shop_passwd">1-查看商户密码</string>
+    <string name="consume_menu_comm_set">2-通讯参数设置</string>
+    <string name="consume_menu_unconfirm_transdtl">3-查询未上传流水</string>
+    <string name="consume_menu_out_dtl">4-导出本地流水</string>
+    <string name="consume_menu_upgrade">5-软件在线升级</string>
+    <string name="consume_menu_app_exit">6-退出应用程序</string>
+    <string name="consume_menu_setting">7-进入设置界面</string>
+    <string name="consume_menu_clear_blklist">8-清空黑名单</string>
+    <string name="consume_menu_control_set">9-本地参数设置</string>
+    <!--充值菜单-->
+    <string name="deposit_menu_revenue">1-营业额查询</string>
+    <string name="deposit_menu_login_out">2-退出登录</string>
+    <string name="deposit_menu_reverse">3-手工冲正</string>
+    <string name="deposit_menu_param_query">4-参数查询</string>
+    <string name="deposit_menu_param_manage">5-设备管理</string>
+    <string name="deposit_menu_param_link">6-链路检测</string>
+    <!--充值维护菜单-->
+    <string name="deposit_manage_transdtl_clear">1-清空流水</string>
+    <string name="deposit_manage_comm_set">2-参数设置</string>
+    <string name="deposit_manage_upgrade">3-在线升级</string>
+    <string name="deposit_manage_app_exit">4-退出应用</string>
+    <string name="deposit_manage_setting">5-网络设置</string>
+    <!--充值参数-->
+    <string name="deposit_param_opername">操作员</string>
+</resources>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..d16cba1
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,511 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+    </style>
+
+    <style name="FloatingDialog" parent="@android:style/Theme.Dialog">
+        <item name="android:windowFrame">@null</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
+        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:background">@android:color/transparent</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowCloseOnTouchOutside">false</item>
+        <item name="android:windowIsTranslucent">true</item>
+    </style>
+
+    <style name="CustomDialog" parent="@android:style/Theme.Dialog">
+        <item name="android:windowFrame">@null</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
+        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowCloseOnTouchOutside">false</item>
+        <item name="android:windowIsTranslucent">true</item>
+    </style>
+
+    <style name="CustomProgressDialog" parent="@style/CustomDialog">
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowNoTitle">true</item>
+    </style>
+
+    <style name="myProgressBarStyleSmal">
+        <item name="android:indeterminateDrawable">@drawable/progress_bg</item>
+        <item name="android:minWidth">100dip</item>
+        <item name="android:maxWidth">100dip</item>
+        <item name="android:minHeight">100dip</item>
+        <item name="android:maxHeight">100dip</item>
+    </style>
+
+    <style name="myProgressBarStyleLarge">
+        <item name="android:indeterminateDrawable">@drawable/big_progress_bg</item>
+        <item name="android:width">200dp</item>
+        <item name="android:height">200dp</item>
+    </style>
+
+    <style name="PayDialog" parent="@android:style/Theme.Dialog">
+        <item name="android:windowFrame">@null</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
+        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:background">@android:color/transparent</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowCloseOnTouchOutside">false</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowNoDisplay">true</item>
+    </style>
+
+    <style name="OtherDialog" parent="@android:style/Theme.Dialog">
+        <item name="android:windowFrame">@null</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
+        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:background">@android:color/transparent</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowCloseOnTouchOutside">false</item>
+        <item name="android:windowIsTranslucent">false</item>
+    </style>
+    <!--activity_deposit-->
+    <style name="deposit_user_info_layout_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:orientation">horizontal</item>
+        <item name="android:padding">5dp</item>
+    </style>
+
+    <style name="deposit_user_info_name_style">
+        <item name="android:textSize">@dimen/deposit_text_size</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/black</item>
+    </style>
+
+    <style name="deposit_user_info_value_style">
+        <item name="android:textSize">@dimen/deposit_text_size</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/blue</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:maxLines">1</item>
+    </style>
+
+    <style name="deposit_result_layout_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:orientation">horizontal</item>
+        <item name="android:paddingLeft">10dp</item>
+        <item name="android:paddingTop">5dp</item>
+    </style>
+
+    <style name="deposit_result_name_style">
+        <item name="android:textSize">@dimen/deposit_text_size</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:textColor">@color/black</item>
+        <item name="android:maxLines">1</item>
+    </style>
+
+    <style name="deposit_result_value_style">
+        <item name="android:textSize">@dimen/deposit_text_size</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/blue</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:maxLines">1</item>
+    </style>
+    <!--deposit revenue-->
+    <style name="deposit_revenue_statics_layout_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">20dp</item>
+        <item name="android:orientation">horizontal</item>
+        <item name="android:weightSum">4</item>
+    </style>
+
+    <style name="deposit_revenue_statics_name_style">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:gravity">center</item>
+        <item name="android:textColor">@color/black</item>
+        <item name="android:textSize">20sp</item>
+    </style>
+
+    <style name="deposit_revenue_statics_value_style">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:gravity">center</item>
+        <item name="android:textColor">@color/black</item>
+        <item name="android:textSize">20sp</item>
+    </style>
+
+    <style name="deposit_revenue_detail_style">
+        <item name="android:textSize">25sp</item>
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/black</item>
+        <item name="android:maxLines">1</item>
+    </style>
+
+    <style name="deposit_revenue_date_style">
+        <item name="android:textSize">@dimen/revenue_serch_text_size</item>
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:maxLines">1</item>
+        <item name="android:padding">5dp</item>
+    </style>
+
+    <style name="deposit_revenue_dtl_style">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:maxLines">1</item>
+        <item name="android:textColor">@color/black</item>
+        <item name="android:textSize">20sp</item>
+    </style>
+
+    <style name="init_param_title_btn_name_style">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">10dp</item>
+        <item name="android:gravity">center</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">28sp</item>
+    </style>
+
+    <style name="init_param_name_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">10dp</item>
+        <item name="android:gravity">start|center</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">28sp</item>
+    </style>
+
+    <style name="init_param_mode_style">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">@dimen/enable_devphyid_font_size</item>
+    </style>
+
+    <style name="deposit_dialog_result_name_style">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/black</item>
+        <item name="android:textSize">40sp</item>
+    </style>
+
+    <style name="deposit_dialog_result_unit_style">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/black</item>
+        <item name="android:textSize">30sp</item>
+        <item name="android:text">" 元"</item>
+    </style>
+
+    <style name="deposit_menu_text_style">
+        <item name="android:textSize">30sp</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/light_blue2</item>
+    </style>
+
+    <style name="deposit_param_ll_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:weightSum">3</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">10dp</item>
+        <item name="android:padding">10dp</item>
+        <item name="android:orientation">horizontal</item>
+    </style>
+
+    <style name="deposit_param_text_name_style">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">30sp</item>
+    </style>
+
+    <style name="deposit_param_text_value_style">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">30sp</item>
+    </style>
+
+    <style name="head_title_text_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center</item>
+        <item name="android:padding">20dp</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">50sp</item>
+    </style>
+
+    <style name="head_title_inner_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:layout_margin">20dp</item>
+        <item name="android:background">@drawable/corner_bg_white</item>
+        <item name="android:orientation">vertical</item>
+    </style>
+
+    <style name="head_title_out_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:background">@color/light_blue2</item>
+        <item name="android:orientation">vertical</item>
+    </style>
+    <!--菜单项-->
+    <style name="menu_item_text_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">30sp</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:paddingLeft">5dp</item>
+        <item name="android:paddingTop">5dp</item>
+    </style>
+    <!--参数查询-->
+    <style name="syspara_item_text_ll_sytle">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:orientation">horizontal</item>
+        <item name="android:padding">10dp</item>
+        <item name="android:weightSum">2</item>
+    </style>
+
+    <style name="syspara_item_text_name_sytle">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">30sp</item>
+    </style>
+
+    <style name="param_set_item_radio_style">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">30sp</item>
+        <item name="android:paddingTop">5dp</item>
+        <item name="android:paddingLeft">5dp</item>
+    </style>
+
+    <style name="param_item_text_btn_style">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:background">@drawable/select_bg_keyboard</item>
+        <item name="android:gravity">center</item>
+        <item name="android:padding">10dp</item>
+        <item name="android:textColor">@color/white</item>
+        <item name="android:textSize">@dimen/enable_devphyid_font_size</item>
+    </style>
+
+    <style name="load_info_text_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">start</item>
+        <item name="android:padding">10dp</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">@dimen/enable_step_text_size</item>
+    </style>
+
+    <style name="control_item_ll_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_gravity">center_horizontal</item>
+        <item name="android:layout_marginLeft">10dp</item>
+        <item name="android:layout_marginTop">@dimen/control_para_gap</item>
+        <item name="android:orientation">vertical</item>
+    </style>
+
+    <style name="control_item_text_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">start|center</item>
+        <item name="android:textColor">@color/enable_text_font_color</item>
+        <item name="android:textSize">@dimen/control_para_text_size</item>
+    </style>
+
+    <style name="control_text_btn_style">
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:layout_marginLeft">20dp</item>
+        <item name="android:layout_marginRight">20dp</item>
+        <item name="android:gravity">center</item>
+        <item name="android:padding">10dp</item>
+        <item name="android:background">@drawable/select_bg_keyboard</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">35sp</item>
+    </style>
+
+    <style name="gate_content_text_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:gravity">center</item>
+        <item name="android:layout_height">0dp</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:padding">@dimen/consume_text_pad_size</item>
+        <item name="android:textSize">90sp</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:textColor">@color/orange1</item>
+    </style>
+
+    <style name="gate_dialog_result_text_style">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">10dp</item>
+        <item name="android:maxLines">1</item>
+        <item name="android:textSize">@dimen/ordinary_consume_text_size</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:textColor">@color/orange1</item>
+    </style>
+
+    <style name="consume_wait_account_ll_style">
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:orientation">horizontal</item>
+        <item name="android:padding">@dimen/consume_text_pad_size1</item>
+    </style>
+
+    <style name="consume_wait_account_paraname_style">
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:textColor">@color/black</item>
+        <item name="android:textSize">@dimen/consume_text_size2</item>
+    </style>
+
+    <style name="consume_wait_account_paraval_style">
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:textColor">@color/blue</item>
+        <item name="android:textSize">@dimen/consume_text_size2</item>
+        <item name="android:maxLines">1</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
+    <style name="consume_wait_account_spec_paraval_style">
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_width">0dp</item>
+        <item name="android:ellipsize">end</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:textColor">@color/blue</item>
+        <item name="android:textSize">@dimen/consume_text_size2</item>
+        <item name="android:maxLines">1</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
+    <style name="consume_pay_way_hint_style">
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_marginTop">50dp</item>
+        <item name="android:textSize">25sp</item>
+        <item name="android:textStyle">bold</item>
+        <item name="android:textColor">@color/black</item>
+        <item name="android:gravity">center</item>
+    </style>
+
+    <style name="consume_pay_way_text_style">
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_marginLeft">20dp</item>
+        <item name="android:layout_marginTop">60dp</item>
+        <item name="android:layout_marginRight">20dp</item>
+        <item name="android:background">@drawable/corner_bg_qrcode_hint</item>
+        <item name="android:gravity">center</item>
+        <item name="android:padding">5dp</item>
+        <item name="android:textColor">@color/white</item>
+        <item name="android:textSize">30sp</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
+    <style name="consume_pay_way_layout_style">
+        <item name="android:layout_height">380dp</item>
+        <item name="android:layout_marginLeft">20dp</item>
+        <item name="android:layout_marginRight">20dp</item>
+        <item name="android:layout_marginTop">20dp</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:orientation">horizontal</item>
+        <item name="android:background">@drawable/corner_bg_white</item>
+    </style>
+
+    <style name="consume_pay_default_photo_style">
+        <item name="android:layout_width">300dp</item>
+        <item name="android:layout_height">300dp</item>
+        <item name="android:layout_gravity">center</item>
+        <item name="android:scaleType">fitXY</item>
+    </style>
+
+    <style name="activity_pay_out_ll_style">
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:background">@color/light_blue2</item>
+        <item name="android:orientation">vertical</item>
+    </style>
+
+    <style name="upgrade_text_desc_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:padding">10dp</item>
+        <item name="android:textColor">@color/black</item>
+        <item name="android:textSize">30sp</item>
+        <item name="android:maxLines">1</item>
+    </style>
+
+    <style name="upgrade_text_value_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginLeft">10dp</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">30sp</item>
+        <item name="android:maxLines">1</item>
+    </style>
+    <style name="comm_rb_para_style">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:gravity">center|start</item>
+        <item name="android:textColor">@color/light_blue2</item>
+        <item name="android:textSize">28sp</item>
+    </style>
+    <style name="comm_ll_para_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:orientation">vertical</item>
+        <item name="android:layout_marginLeft">10dp</item>
+        <item name="android:padding">10dp</item>
+    </style>
+    <style name="purchase_ll_text_style">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginLeft">80dp</item>
+        <item name="android:layout_marginTop">10dp</item>
+        <item name="android:orientation">vertical</item>
+    </style>
+    <style name="purchase_tv_text_hint_style">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">50sp</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+</resources>
diff --git a/app/src/test/java/com/supwisdom/ExampleUnitTest.kt b/app/src/test/java/com/supwisdom/ExampleUnitTest.kt
new file mode 100644
index 0000000..f32e492
--- /dev/null
+++ b/app/src/test/java/com/supwisdom/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.supwisdom
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+    @Test
+    fun addition_isCorrect() {
+        assertEquals(4, 2 + 2)
+    }
+}
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..3b61f16
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,28 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    ext.kotlin_version = '1.3.31'
+    repositories {
+        google()
+        jcenter()
+        
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.4.0'
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+        
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..85be9ea
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,15 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/keys-app.jks b/keys-app.jks
new file mode 100644
index 0000000..3331a8b
--- /dev/null
+++ b/keys-app.jks
Binary files differ
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/upgrade.py b/upgrade.py
new file mode 100644
index 0000000..8de756f
--- /dev/null
+++ b/upgrade.py
@@ -0,0 +1,48 @@
+#coding=utf-8
+#使用python做升级文件打包
+
+import hashlib
+import sys
+import zipfile
+from os import path
+import subprocess
+
+hashFileName = 'hash256.sign'
+
+	
+def sha256_checknum(apk):
+	hash256 = hashlib.sha256()
+	srcFile = open(apk,'rb')
+	with srcFile as f:
+		for block in iter(lambda:f.read(4096),b''):
+			hash256.update(block);
+	srcFile.close()
+	hash256.update(b'nzoqPYMIu91VViA/mEIG5FtJXi8=')
+	
+	hashFile = path.dirname(apk)+'/'+hashFileName
+	print('hashFile = '+hashFile)
+	destFile = open(hashFile,'w+')
+	destFile.write(hash256.hexdigest())
+	destFile.close()
+	
+def zip_file(apk):
+	fileDir = path.dirname(apk)
+	version = subprocess.check_output(['git', 'describe', '--abbrev=4','--dirty','--always','--tags']).strip().decode('utf-8')
+	zipFile = fileDir+'/posa711'+'-'+version+'.zip'
+	print('zipFile = '+zipFile)
+	
+	zf = zipfile.ZipFile(zipFile,'w',zipfile.ZIP_DEFLATED)
+	zf.write(fileDir+'/'+hashFileName,hashFileName)
+	zf.write(apk,'posa711.apk')
+	zf.close()
+
+if __name__ == '__main__':
+	appFile = './app/release/app-release.apk'
+	print('appFile = ' + appFile)
+	
+	if not path.exists(appFile):
+		print(appFile +' is not exist')
+		exit()
+	sha256_checknum(appFile)
+	zip_file(appFile)
+	print('build upgrade zip success!')
\ No newline at end of file