Jelajahi Sumber

<新系统医院版本带按钮5寸分机>

weizhengliang 4 tahun lalu
induk
melakukan
d1664f4cc7
88 mengubah file dengan 3955 tambahan dan 1033 penghapusan
  1. 5 0
      app/build.gradle
  2. 1 1
      build.gradle
  3. 0 5
      callingbed/build.gradle
  4. 2 0
      callingbed/src/main/AndroidManifest.xml
  5. 282 140
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivity.kt
  6. 95 0
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/adapter/CostItemAdapter.kt
  7. 60 0
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/adapter/NurseConfigAdpter.kt
  8. 9 0
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/agreement/CallingbedAgreement.kt
  9. 0 28
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/common/Constant.java
  10. 3 3
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/CallCareFragment.kt
  11. 3 3
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/CallNurseFragment.kt
  12. 20 6
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/CostFragment.kt
  13. 63 50
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/MainFragment.kt
  14. 15 3
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/QrCodeFragment.kt
  15. 3 3
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/SupportFragment.kt
  16. 13 2
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/helper/NetHelper.java
  17. 2 2
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/sip/SipHelper.java
  18. 5 0
      callingbed/src/main/res/drawable/selector_bottom_btn_text_color.xml
  19. 5 0
      callingbed/src/main/res/drawable/selector_call_end.xml
  20. 156 105
      callingbed/src/main/res/layout/callingbed_main_lay.xml
  21. 7 71
      callingbed/src/main/res/layout/cost_view.xml
  22. 39 0
      callingbed/src/main/res/layout/item_cost_detail.xml
  23. 38 0
      callingbed/src/main/res/layout/item_cost_main_view.xml
  24. 38 0
      callingbed/src/main/res/layout/item_nurse_config.xml
  25. 150 394
      callingbed/src/main/res/layout/main_view.xml
  26. 86 26
      callingbed/src/main/res/layout/qrcode_view.xml
  27. 17 0
      callingbed/src/main/res/layout/view_bed_name.xml
  28. 39 22
      callingbed/src/main/res/layout/view_title_layout.xml
  29. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-hdpi/bg_right.png
  30. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/bg_bottom_btn.png
  31. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/bg_empty_info.png
  32. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/bg_right.png
  33. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_bt_fail.png
  34. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_bt_success.png
  35. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_call.png
  36. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_cost.png
  37. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_daylight.png
  38. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_doctor_default.png
  39. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_ethernet_fail.png
  40. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_ethernet_success.png
  41. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_gender_female.png
  42. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_gender_male.png
  43. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_hangup_normal.png
  44. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_hangup_press.png
  45. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_home.png
  46. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_more.png
  47. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_night.png
  48. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_nurse_default.png
  49. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_order.png
  50. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_support.png
  51. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_tcp_fail.png
  52. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_tcp_success.png
  53. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_wifi_fail.png
  54. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-mdpi/ic_wifi_success.png
  55. TEMPAT SAMPAH
      callingbed/src/main/res/mipmap-xhdpi/bg_right.png
  56. 1 1
      callingbed/src/main/res/values/colors.xml
  57. 18 0
      common/build.gradle
  58. 11 0
      common/src/main/code/com/wdkl/ncs/android/lib/utils/TimeHandle.kt
  59. 28 4
      middleware/src/main/code/com/wdkl/ncs/android/middleware/api/CallingbedApi.kt
  60. 96 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/common/Constant.java
  61. 1 1
      callingbed/src/main/java/com/wdkl/app/ncs/callingbed/common/MessageEvent.java
  62. 20 2
      middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/contract/callingbed/CallingbedActivityContract.kt
  63. 6 2
      middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/contract/callingbed/CostFragmentContract.kt
  64. 6 2
      middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/contract/callingbed/MainFragmentContract.kt
  65. 57 8
      middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/callingbed/CallingbedActivityPresenter.kt
  66. 34 7
      middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/callingbed/CostFragmentPresenter.kt
  67. 29 8
      middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/callingbed/MainFragmentPresenter.kt
  68. 56 20
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dos/DeviceDO.java
  69. 364 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dos/InteractionDO.java
  70. 3 2
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dos/NurseConfigDO.java
  71. 80 86
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dos/PartSettingDO.java
  72. 31 1
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dos/NurseConfigDto.java
  73. 53 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dto/TcpSeverDTO.java
  74. 64 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/vo/BedDeviceInfoVO.java
  75. 70 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/vo/CustomerFeeConfigByGroupNameVO.java
  76. 185 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/vo/CustomerFeeConfigVO.java
  77. 99 25
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/vo/CustomerInfoVO.java
  78. 391 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/model/vo/InteractionVO.java
  79. 150 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/TcpClient.java
  80. 144 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/TcpClientHandler.java
  81. 91 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/DeviceChannel.java
  82. 15 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/DeviceUtil.java
  83. 33 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/EventUtil.java
  84. 26 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/ImUtil.java
  85. 118 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/VoiceUtil.java
  86. 210 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/dto/TcpModel.java
  87. 271 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/enums/TcpAction.java
  88. 38 0
      middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/enums/TcpType.java

+ 5 - 0
app/build.gradle

@@ -77,6 +77,11 @@ android {
 
         threadCount=8
     }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
 }
 
 dependencies {

+ 1 - 1
build.gradle

@@ -27,7 +27,7 @@ buildscript {
     /**
      * SDK最小支持版本
      */
-    ext.min_sdk_version = 17
+    ext.min_sdk_version = 24
 
     /**
      * SDK目标支持版本

+ 0 - 5
callingbed/build.gradle

@@ -84,11 +84,6 @@ dependencies {
     compile project(':sip2')
     compile project(':bedlib')
 
-    //netty
-    compile 'io.netty:netty-all:4.1.20.Final'
-    //eventbus
-    compile 'org.greenrobot:eventbus:3.0.0'
-
     if(componentTag){
         debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
         releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'

+ 2 - 0
callingbed/src/main/AndroidManifest.xml

@@ -4,6 +4,8 @@
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
 
     <application
         android:allowBackup="true"

+ 282 - 140
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivity.kt

@@ -5,9 +5,13 @@ import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
 import android.net.ConnectivityManager
+import android.os.CountDownTimer
 import android.os.Handler
 import android.os.Message
+import android.os.SystemClock
 import android.support.v4.app.Fragment
+import android.support.v7.widget.LinearLayoutManager
+import android.text.TextUtils
 import android.util.Log
 import android.view.View
 import android.view.animation.AnimationUtils
@@ -18,22 +22,30 @@ import com.wdkl.app.ncs.callingbed.sip.SipStatus
 import com.vvsip.ansip.IVvsipServiceListener
 import com.vvsip.ansip.VvsipCall
 import com.wdkl.app.ncs.callingbed.R
-import com.wdkl.app.ncs.callingbed.common.Constant
-import com.wdkl.app.ncs.callingbed.common.MessageEvent
+import com.wdkl.app.ncs.callingbed.adapter.NurseConfigAdpter
 import com.wdkl.app.ncs.callingbed.databinding.CallingbedMainLayBinding
 import com.wdkl.app.ncs.callingbed.fragment.*
 import com.wdkl.app.ncs.callingbed.helper.NetHelper
 import com.wdkl.app.ncs.callingbed.helper.SerialPortHelper
 import com.wdkl.app.ncs.callingbed.helper.SoundPoolHelper
 import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
+import com.wdkl.app.ncs.callingbed2.agreement.CallingbedAgreement
 //import com.wdkl.app.ncs.sip.service.SipService
 import com.wdkl.ncs.android.lib.base.BaseActivity
 import com.wdkl.ncs.android.lib.utils.TimeHandle
 import com.wdkl.ncs.android.lib.utils.showMessage
 import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
 import com.wdkl.ncs.android.middleware.logic.contract.callingbed.CallingbedActivityContract
 import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.CallingbedActivityPresenter
+import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
+import com.wdkl.ncs.android.middleware.model.dto.NurseConfigDto
+import com.wdkl.ncs.android.middleware.model.dto.TcpSeverDTO
+import com.wdkl.ncs.android.middleware.model.vo.BedDeviceInfoVO
 import com.wdkl.ncs.android.middleware.model.vo.CustomerInfoVO
+import com.wdkl.ncs.android.middleware.tcp.TcpClient
+import com.wdkl.ncs.android.middleware.tcp.channel.VoiceUtil
 import kotlinx.android.synthetic.main.callingbed_main_lay.*
 import kotlinx.android.synthetic.main.view_title_layout.*
 import org.greenrobot.eventbus.EventBus
@@ -51,7 +63,7 @@ import java.lang.ref.WeakReference
  */
 
 @Router(path = "/callingbed/main")
-class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMainLayBinding>(), CallingbedActivityContract.View, IVvsipServiceListener,
+class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMainLayBinding>(), CallingbedAgreement, CallingbedActivityContract.View, /*IVvsipServiceListener,*/
         SerialPortUtil.ISerialPortBedOnclickEvent, SerialPortUtil.ISerialPortBedOnclickString{
 
     private lateinit var receiver: TimeReceiver
@@ -62,20 +74,28 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
     //一定时间无操作返回主界面
     private var backTimeout = 0
 
+    private lateinit var linearLayout : LinearLayoutManager
+    private lateinit var nurseConfigAdpter : NurseConfigAdpter
+    private var configList = ArrayList<NurseConfigDto>()
+    private var sipServiceRunning :Boolean = false
+
+    //呼叫倒计时
+    lateinit var countDownTimer: CountDownTimer
+
     //主信息
     private val mainFragment = "main_fragment"
     //医嘱
-    private val doctorFragment = "doctor_fragment"
+    //private val doctorFragment = "doctor_fragment"
     //费用
     private val costFragment = "cost_fragment"
     //二维码
     private val qrCodeFragment = "qrcode_fragment"
     //请求增援
-    private val supportFragment = "support_fragment"
+    //private val supportFragment = "support_fragment"
     //呼叫护工
-    private val callCareFragment = "call_care_fragment"
+    //private val callCareFragment = "call_care_fragment"
     //呼叫护士
-    private val callNurseFragment = "call_nurse_fragment"
+    //private val callNurseFragment = "call_nurse_fragment"
 
     companion object {
         private const val TIME_WHAT = 1000
@@ -91,9 +111,15 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
 
     override fun init() {
         //开始ping网络,30秒ping一次
-        NetHelper.startNetCheck()
+        //NetHelper.startNetCheck()
+
+        //获取mac地址
+        Constant.LOCAL_MAC = NetHelper.getInstance().macAddress
+
+        presenter.loadTcpServerHost()
+
         //sip初始化
-        initSip()
+        //initSip()
         //显示日期时间
         updateDateTime()
         //注册广播
@@ -104,6 +130,13 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         SoundPoolHelper.getInstance().init(applicationContext)
         //打开手柄mic
         SerialPortHelper.setHandsMIC(true)
+
+        initCountDownTimer()
+        initNurseConfig()
+        updateNetState()
+
+        initDevice()
+
         //启动时间线程
         timeThread = TimeThread()
         timeThread.start()
@@ -116,6 +149,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
     }
 
     override fun destory() {
+        countDownTimer.cancel()
         SerialPortUtil.getInstance().closeHeart()
         SerialPortUtil.getInstance().closeSerialPort()
         SipHelper.getInstance().unRegisterSip()
@@ -125,21 +159,68 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         isTimeWorking = false
     }
 
+    fun initDevice() {
+        if (!TextUtils.isEmpty(Constant.LOCAL_MAC)) {
+            presenter.loadDeviceInfo(Constant.LOCAL_MAC)
+        }
+    }
+
+    fun initCountDownTimer() {
+        countDownTimer = object: CountDownTimer(Constant.CALL_TIMEOUT*1000L, 1000) {
+            override fun onTick(millisUntilFinished: Long) {
+                //
+            }
+
+            override fun onFinish() {
+                //呼叫超时,返回到主界面
+                showMessage("无人应答...")
+                //MediaPlayHelper.getInstance().stopMusic()
+                VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
+                endCall()
+            }
+        }
+    }
+
+    private fun initNurseConfig() {
+        //初始化默认护理项
+        for (index in 1..5) {
+            var item = NurseConfigDto()
+            item.nurseConfigName = "护理"
+            item.nurseOptionName = "暂无"
+            item.nurseColorRbg = "2F9DF1"
+            configList.add(item)
+        }
+
+        linearLayout = LinearLayoutManager(activity)
+        nurseConfigAdpter = NurseConfigAdpter(activity, configList)
+        rv_left_list.layoutManager = linearLayout
+        rv_left_list.adapter = nurseConfigAdpter
+    }
+
     //数据加载错误
     override fun onError(message: String, type: Int) {
-        dismissDialog()
+        //dismissDialog()
         showMessage(message)
+        //加载失败,重置customid
+        Constant.CUSTOM_ID = -1
     }
 
     //数据加载完成
     override fun complete(message: String, type: Int) {
-        dismissDialog()
+        //dismissDialog()
 
     }
 
     //开始获取数据
     override fun start() {
-        showDialog()
+        //showDialog()
+    }
+
+    //没有网络
+    override fun onNoNet() {
+        showMessage("没有网络")
+        //加载失败,重置customid
+        Constant.CUSTOM_ID = -1
     }
 
     //网络监听
@@ -153,11 +234,51 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         })
     }
 
-    //数据加载完成,显示数据
-    override fun showData(customInfo: CustomerInfoVO) {
-        //calling_data.setText(customInfo.named)
+    //显示设备信息
+    override fun showDeviceInfo(deviceInfo: BedDeviceInfoVO) {
+        Constant.SIP_ID = deviceInfo.sipId
+        Constant.DEVICE_ID = deviceInfo.id
+        Constant.PART_ID = deviceInfo.partId
+        Constant.BED_NAME = deviceInfo.fullName
+
+        view_title_layout_tv_hospital_name.text = deviceInfo.hospitalName + deviceInfo.partName
+        if (deviceInfo.customerId != null) {
+            Constant.CUSTOM_ID = deviceInfo.customerId
+            EventBus.getDefault().post(MessageEvent("updateCustom", Constant.EVENT_UPDATE_CUSTOM))
+            presenter.loadPartSettings(Constant.PART_ID)
+        }
+
+        //拿到sip账号之后再注册
+        if (!sipServiceRunning && !TextUtils.isEmpty(Constant.SIP_ID)) {
+            sipServiceRunning = true
+            //startSipService()
+            //StarRtcHelper.getInstance().initStarRtc()
+            initSip(Constant.SIP_HOST, Constant.SIP_ID);
+        }
+    }
+
+    override fun setPartSettings(partSetting: PartSettingDO) {
+        //Constant.CALL_TIMEOUT = partSetting.sipOvertime
     }
 
+    override fun setTcpServerHost(tcpSeverDTO: TcpSeverDTO) {
+        Constant.TCP_SERVER_URL = tcpSeverDTO.localIp
+        Constant.TCP_PORT = tcpSeverDTO.tcpPort
+        Constant.TCP_HEART_BEAT = tcpSeverDTO.readerIdleTime
+
+        //开启TCP连接
+        startTcp()
+        showMessage("tcp开始连接...host: " + Constant.TCP_SERVER_URL + ", port: " + Constant.TCP_PORT)
+    }
+
+    override fun updateNurseConfig(list: List<NurseConfigDto>) {
+        if (list.size > 0) {
+            for ((index, e) in list.withIndex()) {
+                configList.set(index, e)
+            }
+            nurseConfigAdpter.updateData(configList)
+        }
+    }
 
     override fun onStart() {
         EventBus.getDefault().register(this)
@@ -184,6 +305,13 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         switchToFragment(R.id.callingbed_main_frame, MainFragment(), mainFragment)
     }
 
+    //启动TCP连接
+    fun startTcp() {
+        if (Constant.TCP_SERVER_URL != null) {
+            Thread(Runnable { TcpClient.getInstance().init(Constant.TCP_SERVER_URL, Constant.TCP_PORT, Constant.TCP_HEART_BEAT) }).start()
+        }
+    }
+
     //设置串口监听
     private fun setSerialListner() {
         SerialPortUtil.getInstance().setOnDataReceiveListener(this)
@@ -206,24 +334,24 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         unregisterReceiver(receiver)
     }
 
-    private fun initSip() {
+    private fun initSip(ipStr: String, id: String) {
         //=============================================SIP启动服务===================================//
-        SipHelper.getInstance().initSip(this@CallingbedActivity,"192.168.101.1", getString(R.string.local_sip), getString(R.string.local_sip))
-        SipHelper.getInstance().sipStartService()
-        SipHelper.getInstance().setSipListner(this)
+        //SipHelper.getInstance().initSip(this@CallingbedActivity,ipStr, id, id)
+        //SipHelper.getInstance().sipStartService()
+        //SipHelper.getInstance().setSipListner(this)
     }
 
-    fun sendCall(sipId: String) {
+    fun sendSipCall(sipId: String) {
         //showMessage("已呼叫...")
         SipHelper.getInstance().startCall(sipId)
     }
 
-    fun endCall() {
+    fun endSipCall() {
         //showMessage("已挂断...")
         SipHelper.getInstance().endCall()
     }
 
-    override fun onNewVvsipCallEvent(call: VvsipCall?) {
+    /*override fun onNewVvsipCallEvent(call: VvsipCall?) {
         //Log.d("sip", "onNewVvsipCallEvent----")
         if (call != null) {
             SipHelper.getInstance().addCallObject(call)
@@ -272,58 +400,58 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
                 switchToMainFragment()
             }
         }
-    }
+    }*/
 
     override fun serialPortBedOnclick(buffer: ByteArray) {
         Log.d("serialPortBedOnclick", "buffer[0]:" + buffer[0] + ", buffer[1]:" + buffer[1] + ", buffer[2]:" + buffer[2]
                 + ", buffer[3]:" + buffer[3] + ", buffer[4]:" + buffer[4] + ", buffer[5]:" + buffer[5] + ", buffer[6]:" + buffer[6]
                 + ", buffer[7]:" + buffer[7] + ", buffer[8]:" + buffer[8])
-        //医嘱键短按或长按松开
+        //首页
         if (buffer[0].toInt() == 1 || buffer[0].toInt() == 2) {
             runOnUiThread {
-                clickVDoctor()
+                clickVHome()
             }
         }
 
-        //费用查询键短按或长按松开
+        //费用
         else if (buffer[1].toInt() == 1 || buffer[1].toInt() == 2) {
             runOnUiThread {
                 clickVCost()
             }
         }
 
-        //二维码键短按或长按松开
+        //更多
         else if (buffer[2].toInt() == 1 || buffer[2].toInt() == 2) {
             runOnUiThread {
                 clickVQrcode()
             }
         }
 
-        //请求增援键短按或长按松开
+        //增援
         else if (buffer[3].toInt() == 1 || buffer[3].toInt() == 2) {
             runOnUiThread {
                 clickVSupport()
             }
         }
 
-        //呼叫护工键短按或长按松开
+        //呼叫
         else if (buffer[4].toInt() == 1 || buffer[4].toInt() == 2) {
             runOnUiThread {
-                clickVCallCare()
+                clickVCall()
             }
         }
 
         //呼叫护士键短按或长按松开
         else if (buffer[5].toInt() == 1 || buffer[5].toInt() == 2) {
             runOnUiThread {
-                clickVCallNurse()
+                clickCall()
             }
         }
 
         //手柄呼叫键短按或长按松开
         else if (buffer[6].toInt() == 1 || buffer[6].toInt() == 2) {
             runOnUiThread {
-                clickVCallNurse()
+                clickCall()
             }
         }
     }
@@ -336,27 +464,21 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         return v.visibility == View.VISIBLE
     }
 
-    private fun clickVDoctor() {
+    private fun clickVHome() {
         //重置超时时间
         backTimeout = 0
-        //如果当前是医嘱界面则返回到主信息界面
-        if (doctorFragment.equals(curFragment)) {
-            switchToMainFragment()
+        if (mainFragment.equals(curFragment)) {
+            if (isVisible(right_menu)) {
+                hideRightMenu(true)
+            } else {
+                showRightMenu()
+            }
         } else {
-            if (mainFragment.equals(curFragment)) {
-                //如果当前是主信息界面且右侧菜单已经弹出则显示医嘱界面,否则弹出右侧菜单
-                if (isVisible(right_menu)) {
-                    hideRightMenu(true)
-                    switchToFragment(R.id.callingbed_main_frame, DoctorOrderFragment(), doctorFragment)
-                } else {
-                    showRightMenu()
-                }
+            if (isVisible(right_menu)) {
+                hideRightMenu(true)
+                switchToMainFragment()
             } else {
-                if (!supportFragment.equals(curFragment) && !callCareFragment.equals(curFragment) && !callNurseFragment.equals(curFragment)) {
-                    switchToFragment(R.id.callingbed_main_frame, DoctorOrderFragment(), doctorFragment)
-                } else {
-                    showMessage("请先取消当前呼叫!")
-                }
+                showRightMenu()
             }
         }
     }
@@ -364,24 +486,18 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
     private fun clickVCost() {
         //重置超时时间
         backTimeout = 0
-        //如果当前是费用查询界面则返回到主信息界面
         if (costFragment.equals(curFragment)) {
-            switchToMainFragment()
+            if (isVisible(right_menu)) {
+                hideRightMenu(true)
+            } else {
+                showRightMenu()
+            }
         } else {
-            if (mainFragment.equals(curFragment)) {
-                //如果当前是主信息界面且右侧菜单已经弹出则显示费用界面,否则弹出右侧菜单
-                if (isVisible(right_menu)) {
-                    hideRightMenu(true)
-                    switchToFragment(R.id.callingbed_main_frame, CostFragment(), costFragment)
-                } else {
-                    showRightMenu()
-                }
+            if (isVisible(right_menu)) {
+                hideRightMenu(true)
+                switchToFragment(R.id.callingbed_main_frame, CostFragment(), costFragment)
             } else {
-                if (!supportFragment.equals(curFragment) && !callCareFragment.equals(curFragment) && !callNurseFragment.equals(curFragment)) {
-                    switchToFragment(R.id.callingbed_main_frame, CostFragment(), costFragment)
-                } else {
-                    showMessage("请先取消当前呼叫!")
-                }
+                showRightMenu()
             }
         }
     }
@@ -389,24 +505,18 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
     private fun clickVQrcode() {
         //重置超时时间
         backTimeout = 0
-        //如果当前是二维码界面则返回到主信息界面
         if (qrCodeFragment.equals(curFragment)) {
-            switchToMainFragment()
+            if (isVisible(right_menu)) {
+                hideRightMenu(true)
+            } else {
+                showRightMenu()
+            }
         } else {
-            if (mainFragment.equals(curFragment)) {
-                //如果当前是主信息界面且右侧菜单已经弹出则显示二维码界面,否则弹出右侧菜单
-                if (isVisible(right_menu)) {
-                    hideRightMenu(true)
-                    switchToFragment(R.id.callingbed_main_frame, QrCodeFragment(), qrCodeFragment)
-                } else {
-                    showRightMenu()
-                }
+            if (isVisible(right_menu)) {
+                hideRightMenu(true)
+                switchToFragment(R.id.callingbed_main_frame, QrCodeFragment(), qrCodeFragment)
             } else {
-                if (!supportFragment.equals(curFragment) && !callCareFragment.equals(curFragment) && !callNurseFragment.equals(curFragment)) {
-                    switchToFragment(R.id.callingbed_main_frame, QrCodeFragment(), qrCodeFragment)
-                } else {
-                    showMessage("请先取消当前呼叫!")
-                }
+                showRightMenu()
             }
         }
     }
@@ -414,79 +524,61 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
     private fun clickVSupport() {
         //重置超时时间
         backTimeout = 0
-        //如果当前正在请求增援则取消
-        if (supportFragment.equals(curFragment)) {
-            switchToMainFragment()
+        if (isVisible(right_menu)) {
+            hideRightMenu(true)
+            showMessage("增援请求已发送!")
+            //switchToFragment(R.id.callingbed_main_frame, SupportFragment(), supportFragment)
+            //SoundPoolHelper.getInstance().playSound(2)
         } else {
-            if (mainFragment.equals(curFragment)) {
-                //如果当前是主信息界面且右侧菜单已弹出则显示请求增援界面,否则弹出右侧菜单
-                if (isVisible(right_menu)) {
-                    hideRightMenu(true)
-                    switchToFragment(R.id.callingbed_main_frame, SupportFragment(), supportFragment)
-                    SoundPoolHelper.getInstance().playSound(2)
-                } else {
-                    showRightMenu()
-                }
-            } else {
-                if (!callCareFragment.equals(curFragment) && !callNurseFragment.equals(curFragment)) {
-                    switchToFragment(R.id.callingbed_main_frame, SupportFragment(), supportFragment)
-                    SoundPoolHelper.getInstance().playSound(2)
-                } else {
-                    showMessage("请先取消当前呼叫!")
-                }
-            }
+            showRightMenu()
         }
     }
 
-    private fun clickVCallCare() {
+    private fun clickVCall() {
         //重置超时时间
         backTimeout = 0
-        //如果当前正在呼叫护工则取消
-        if (callCareFragment.equals(curFragment)) {
-            switchToMainFragment()
-        } else {
-            if (mainFragment.equals(curFragment)) {
-                //如果当前是主信息界面且右侧菜单已弹出则显示呼叫护工界面,否则弹出右侧菜单
-                if (isVisible(right_menu)) {
-                    hideRightMenu(true)
-                    switchToFragment(R.id.callingbed_main_frame, CallCareFragment(), callCareFragment)
-                    SoundPoolHelper.getInstance().playSound(2)
-                } else {
-                    showRightMenu()
-                }
+        //当前为待机状态,显示呼叫
+        if (Constant.CALL_STATE == Constant.CALL_STANDBY) {
+            if (isVisible(right_menu)) {
+                hideRightMenu(true)
+                VoiceUtil.startAudioCall(Constant.DEVICE_ID)
+                sendCall()
+                //播放铃音
+                //MediaPlayHelper.getInstance().playResMusic(R.raw.ringback, 1.0f, true)
+                SoundPoolHelper.getInstance().playSound(2)
             } else {
-                if (!supportFragment.equals(curFragment) && !callNurseFragment.equals(curFragment)) {
-                    switchToFragment(R.id.callingbed_main_frame, CallCareFragment(), callCareFragment)
-                    SoundPoolHelper.getInstance().playSound(2)
-                } else {
-                    showMessage("请先取消当前呼叫!")
-                }
+                showRightMenu()
             }
+        } else if (Constant.CALL_STATE == Constant.CALL_CALLING) {
+            //StarRtcHelper.getInstance().hangupAudioCall()
+            //VoiceUtil.handoffAudioCall(Constant.DEVICE_ID, fromId, interactionId)
+            endCall()
+        } else {
+            VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
+            endCall()
         }
     }
 
-    private fun clickVCallNurse() {
+    private fun clickCall() {
         //重置超时时间
         backTimeout = 0
-        //如果当前正在呼叫护士或在通话中则取消呼叫或通话
-        if (callNurseFragment.equals(curFragment)) {
+        //当前为待机状态,显示呼叫
+        if (Constant.CALL_STATE == Constant.CALL_STANDBY) {
+            if (isVisible(right_menu)) {
+                hideRightMenu(true)
+            }
+            VoiceUtil.startAudioCall(Constant.DEVICE_ID)
+            sendCall()
+            //播放铃音
+            //MediaPlayHelper.getInstance().playResMusic(R.raw.ringback, 1.0f, true)
+            SoundPoolHelper.getInstance().playSound(2)
+        } else if (Constant.CALL_STATE == Constant.CALL_CALLING) {
+            //StarRtcHelper.getInstance().hangupAudioCall()
+            //VoiceUtil.handoffAudioCall(Constant.DEVICE_ID, fromId, interactionId)
             endCall()
-            switchToMainFragment()
         } else {
-            if (mainFragment.equals(curFragment)) {
-                //如果当前是主信息界面则显示呼叫护士界面
-                hideRightMenu(false)
-                switchToFragment(R.id.callingbed_main_frame, CallNurseFragment(), callNurseFragment)
-                SoundPoolHelper.getInstance().playSound(2)
-            } else {
-                if (!supportFragment.equals(curFragment) && !callCareFragment.equals(curFragment)) {
-                    hideRightMenu(false)
-                    switchToFragment(R.id.callingbed_main_frame, CallNurseFragment(), callNurseFragment)
-                    SoundPoolHelper.getInstance().playSound(2)
-                } else {
-                    showMessage("请先取消当前呼叫!")
-                }
-            }
+            VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
+            endCall()
         }
     }
 
@@ -511,7 +603,36 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         right_menu.setVisibility(View.GONE)
     }
 
+    //发起呼叫
+    private fun sendCall() {
+        Constant.CALL_STATE = Constant.CALL_OUTGOING
+        ll_call_view.visibility = View.VISIBLE
+        tv_call_bed_name.text = Constant.BED_NAME
+        tv_call_state.text = "正在呼叫..."
+        voice_call_timer_view.visibility = View.INVISIBLE
+        countDownTimer.start()
+    }
+
+    //呼叫或通话结束
+    private fun endCall() {
+        voice_call_timer_view.base = SystemClock.elapsedRealtime()
+        voice_call_timer_view.stop()
+        ll_call_view.visibility = View.GONE
+        Constant.CALL_STATE = Constant.CALL_STANDBY
+        countDownTimer.cancel()
+    }
 
+    //通话中
+    private fun inCall() {
+        ll_call_view.visibility = View.VISIBLE
+        tv_call_bed_name.text = Constant.BED_NAME
+        tv_call_state.text = "通话中..."
+        voice_call_timer_view.visibility = View.VISIBLE
+        voice_call_timer_view.base = SystemClock.elapsedRealtime()
+        voice_call_timer_view.start()
+        Constant.CALL_STATE = Constant.CALL_CALLING
+        countDownTimer.cancel()
+    }
 
     @Subscribe(threadMode = ThreadMode.MAIN)
     fun onMoonEvent(messageEvent: MessageEvent) {
@@ -566,12 +687,33 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         view_title_layout_tv_time.setText(TimeHandle.getDateTime("yyyy-MM-dd HH:mm E"));
     }
 
+    private fun updateNetState() {
+        if (NetHelper.getInstance().networkType == ConnectivityManager.TYPE_WIFI) {
+            view_title_layout_iv_wifi.visibility = View.VISIBLE
+            view_title_layout_iv_wifi.setImageResource(R.mipmap.ic_wifi_success)
+            view_title_layout_iv_ethernet.visibility = View.GONE
+        } else if (NetHelper.getInstance().networkType == ConnectivityManager.TYPE_ETHERNET) {
+            view_title_layout_iv_ethernet.visibility = View.VISIBLE
+            view_title_layout_iv_ethernet.setImageResource(R.mipmap.ic_ethernet_success)
+            view_title_layout_iv_wifi.visibility = View.GONE
+        }
+
+        if (NetHelper.isBTConnected()) {
+            view_title_layout_iv_bt.visibility = View.VISIBLE
+            view_title_layout_iv_bt.setImageResource(R.mipmap.ic_bt_success)
+        } else {
+            view_title_layout_iv_bt.visibility = View.GONE
+        }
+        view_title_layout_iv_day_night.setImageResource(R.mipmap.ic_daylight)
+    }
+
     inner class TimeReceiver: BroadcastReceiver() {
         override fun onReceive(context: Context, intent: Intent) {
             if (intent.action == Intent.ACTION_TIME_TICK
                     || intent.action == Intent.ACTION_TIME_CHANGED
                     || intent.action == Intent.ACTION_TIMEZONE_CHANGED) {
                 updateDateTime()
+                updateNetState()
             }
         }
     }
@@ -604,7 +746,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
 
         override fun handleMessage(msg: Message) {
             super.handleMessage(msg)
-            // 通过  软引用  看能否得到activity示例
+            // 通过软引用看能否得到activity示例
             val handlerMemoryActivity = weakReference.get()
             // 防止内存泄露
             if (handlerMemoryActivity != null) {
@@ -622,8 +764,8 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
     fun backToMain() {
         backTimeout++
         if (backTimeout >= Constant.CALL_TIMEOUT) {
-            //医嘱、费用、二维码界面超时返回主界面
-            if (doctorFragment.equals(curFragment) || costFragment.equals(curFragment) || qrCodeFragment.equals(curFragment)) {
+            //费用、二维码界面超时返回主界面
+            if (costFragment.equals(curFragment) || qrCodeFragment.equals(curFragment)) {
                 switchToMainFragment()
             }
             //超时隐藏右侧菜单栏

+ 95 - 0
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/adapter/CostItemAdapter.kt

@@ -0,0 +1,95 @@
+package com.wdkl.app.ncs.callingbed.adapter
+
+import android.content.Context
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.ncs.android.middleware.model.vo.CustomerFeeConfigByGroupNameVO
+import com.wdkl.ncs.android.middleware.model.vo.CustomerFeeConfigVO
+
+class CostItemAdapter : RecyclerView.Adapter<CostItemAdapter.ParentViewHolder> {
+
+    private var context: Context
+    private var mainData: ArrayList<CustomerFeeConfigByGroupNameVO>
+
+    constructor(context: Context, data: ArrayList<CustomerFeeConfigByGroupNameVO>) {
+        this.context = context
+        this.mainData = data
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ParentViewHolder {
+        val view = LayoutInflater.from(parent?.context).inflate(R.layout.item_cost_main_view, parent, false)
+        val viewHolder = ParentViewHolder(view)
+
+        return viewHolder
+    }
+
+    override fun onBindViewHolder(holder: ParentViewHolder?, position: Int) {
+        holder?.costGroupName?.text = mainData.get(position).feeGroupName
+        holder?.costGroupTotal?.text = "小计: ¥" + mainData.get(position).subtotal
+
+        val layoutManager = LinearLayoutManager(context)
+        holder?.costDetail?.layoutManager = layoutManager
+        holder?.costDetail?.adapter = CostDetailAdapter(mainData.get(position).customerFeeConfigList)
+    }
+
+    override fun getItemCount(): Int {
+        return mainData.size
+    }
+
+    class ParentViewHolder : RecyclerView.ViewHolder {
+        var costGroupName : TextView
+        var costGroupTotal : TextView
+        var costDetail : RecyclerView
+
+        constructor(itemView: View): super(itemView) {
+            costGroupName = itemView.findViewById(R.id.tv_cost_group_name)
+            costGroupTotal = itemView.findViewById(R.id.tv_cost_group_total)
+            costDetail = itemView.findViewById(R.id.rv_cost_detail)
+        }
+    }
+
+    class CostDetailAdapter : RecyclerView.Adapter<CostDetailAdapter.ChildViewHolder> {
+        private var costData: List<CustomerFeeConfigVO>
+
+        constructor(data: List<CustomerFeeConfigVO>) {
+            costData = data
+        }
+
+        override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ChildViewHolder {
+            val view = LayoutInflater.from(parent?.context).inflate(R.layout.item_cost_detail, parent, false)
+            val viewHolder = ChildViewHolder(view)
+
+            return viewHolder
+        }
+
+        override fun onBindViewHolder(holder: ChildViewHolder?, position: Int) {
+            holder?.costName?.text = costData.get(position).feeName
+            holder?.costValue?.text = "¥" + costData.get(position).feeValue
+            holder?.costId?.text = costData.get(position).keyCode
+            holder?.costUnit?.text = costData.get(position).unit
+        }
+
+        override fun getItemCount(): Int {
+            return costData.size
+        }
+
+        class ChildViewHolder : RecyclerView.ViewHolder {
+            var costName : TextView
+            var costValue : TextView
+            var costId : TextView
+            var costUnit : TextView
+
+            constructor(item : View) : super(item) {
+                costName = item.findViewById(R.id.tv_item_cost_name)
+                costValue = item.findViewById(R.id.tv_item_cost_value)
+                costId = item.findViewById(R.id.tv_item_cost_id)
+                costUnit = item.findViewById(R.id.tv_item_cost_unit)
+            }
+        }
+    }
+}

+ 60 - 0
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/adapter/NurseConfigAdpter.kt

@@ -0,0 +1,60 @@
+package com.wdkl.app.ncs.callingbed.adapter
+
+import android.content.Context
+import android.graphics.Color
+import android.support.v7.widget.RecyclerView
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.ncs.android.middleware.model.dto.NurseConfigDto
+import java.lang.Exception
+
+class NurseConfigAdpter : RecyclerView.Adapter<NurseConfigAdpter.ViewHolder> {
+    private var context: Context
+    private var data: ArrayList<NurseConfigDto>
+
+    constructor(context: Context, data: ArrayList<NurseConfigDto>) {
+        this.context = context
+        this.data = data
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
+        val view = LayoutInflater.from(parent?.context).inflate(R.layout.item_nurse_config, parent, false)
+        val viewHolder = ViewHolder(view)
+
+        return viewHolder
+    }
+
+    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+        try {
+            holder.nurseColor.setBackgroundColor(Color.parseColor("#"+data.get(position).nurseColorRbg))
+            holder.nurseName.setText(data.get(position).nurseConfigName)
+            holder.nurseValue.setText(data.get(position).nurseOptionName)
+        } catch (e: Exception) {
+            e.printStackTrace()
+        }
+    }
+
+    override fun getItemCount(): Int {
+        return data.size
+    }
+
+    fun updateData(data: ArrayList<NurseConfigDto>) {
+        this.data = data
+        notifyDataSetChanged()
+    }
+
+    class ViewHolder: RecyclerView.ViewHolder {
+        var nurseColor : TextView
+        var nurseName : TextView
+        var nurseValue : TextView
+
+        constructor(itemView: View): super(itemView) {
+            nurseColor = itemView.findViewById(R.id.tv_nurse_color)
+            nurseName = itemView.findViewById(R.id.tv_nurse_config_name)
+            nurseValue = itemView.findViewById(R.id.tv_nurse_config_value)
+        }
+    }
+}

+ 9 - 0
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/agreement/CallingbedAgreement.kt

@@ -0,0 +1,9 @@
+package com.wdkl.app.ncs.callingbed2.agreement
+
+import com.wdkl.ncs.android.middleware.model.dto.NurseConfigDto
+
+interface CallingbedAgreement {
+
+    //更新护理数据
+    fun updateNurseConfig(list: List<NurseConfigDto>)
+}

+ 0 - 28
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/common/Constant.java

@@ -1,28 +0,0 @@
-package com.wdkl.app.ncs.callingbed.common;
-
-public class Constant {
-
-    /**
-     * Sip注册状态
-     */
-    public static final int EVENT_SIP_REGISTER_STATUS = 0x01;
-
-    /**
-     * Sip通话状态
-     */
-    public static final int EVENT_SIP_CALL_STATUS = 0x02;
-
-    /**
-     * 以太网ping状态
-     */
-    public static final int EVENT_INTERNETPING = 0x03;
-
-    /**
-     * 返回主fragment
-     */
-    public static final int EVENT_BACK_MAIN = 0x04;
-
-
-    //分机呼叫超时时间,默认30s
-    public static final long CALL_TIMEOUT = 30;
-}

+ 3 - 3
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/CallCareFragment.kt

@@ -3,13 +3,13 @@ package com.wdkl.app.ncs.callingbed.fragment
 import android.os.CountDownTimer
 import com.enation.javashop.net.engine.model.NetState
 import com.wdkl.app.ncs.callingbed.R
-import com.wdkl.app.ncs.callingbed.common.Constant
-import com.wdkl.app.ncs.callingbed.common.MessageEvent
 import com.wdkl.app.ncs.callingbed.databinding.CallCareViewBinding
 import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
 import com.wdkl.ncs.android.lib.base.BaseFragment
 import com.wdkl.ncs.android.lib.utils.debugLog
 import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
 import com.wdkl.ncs.android.middleware.logic.contract.callingbed.CallCareFragmentContract
 import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.CallCareFragmentPresenter
 import kotlinx.android.synthetic.main.call_care_view.*
@@ -66,7 +66,7 @@ class CallCareFragment : BaseFragment<CallCareFragmentPresenter, CallCareViewBin
     }
 
     fun initCountDownTimer() {
-        countDownTimer = object: CountDownTimer(Constant.CALL_TIMEOUT*1000, 1000) {
+        countDownTimer = object: CountDownTimer(Constant.CALL_TIMEOUT*1000L, 1000) {
             override fun onTick(millisUntilFinished: Long) {
                 val time = millisUntilFinished/1000
                 view_call_layout_tv_call_timeout?.setText("" + time + " 秒")

+ 3 - 3
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/CallNurseFragment.kt

@@ -4,12 +4,12 @@ import android.os.CountDownTimer
 import com.enation.javashop.net.engine.model.NetState
 import com.wdkl.app.ncs.callingbed.R
 import com.wdkl.app.ncs.callingbed.activity.CallingbedActivity
-import com.wdkl.app.ncs.callingbed.common.Constant
-import com.wdkl.app.ncs.callingbed.common.MessageEvent
 import com.wdkl.app.ncs.callingbed.databinding.CallNurseViewBinding
 import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
 import com.wdkl.ncs.android.lib.base.BaseFragment
 import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
 import com.wdkl.ncs.android.middleware.logic.contract.callingbed.CallNurseFragmentContract
 import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.CallNurseFragmentPresenter
 import kotlinx.android.synthetic.main.call_nurse_view.*
@@ -92,7 +92,7 @@ class CallNurseFragment : BaseFragment<CallNurseFragmentPresenter, CallNurseView
     }
 
     fun initCountDownTimer() {
-        countDownTimer = object: CountDownTimer(Constant.CALL_TIMEOUT*1000, 1000) {
+        countDownTimer = object: CountDownTimer(Constant.CALL_TIMEOUT*1000L, 1000) {
             override fun onTick(millisUntilFinished: Long) {
                 val time = millisUntilFinished/1000
                 view_nurse_layout_tv_call_timeout?.setText("" + time + " 秒")

+ 20 - 6
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/CostFragment.kt

@@ -1,7 +1,9 @@
 package com.wdkl.app.ncs.callingbed.fragment
 
+import android.support.v7.widget.LinearLayoutManager
 import com.enation.javashop.net.engine.model.NetState
 import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.app.ncs.callingbed.adapter.CostItemAdapter
 import com.wdkl.app.ncs.callingbed.databinding.CostViewBinding
 import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
 import com.wdkl.ncs.android.lib.base.BaseFragment
@@ -9,8 +11,11 @@ import com.wdkl.ncs.android.lib.utils.debugLog
 import com.wdkl.ncs.android.lib.utils.errorLog
 import com.wdkl.ncs.android.lib.utils.showMessage
 import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
 import com.wdkl.ncs.android.middleware.logic.contract.callingbed.CostFragmentContract
 import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.CostFragmentPresenter
+import com.wdkl.ncs.android.middleware.model.vo.CustomerFeeConfigByGroupNameVO
+import kotlinx.android.synthetic.main.cost_view.*
 
 class CostFragment : BaseFragment<CostFragmentPresenter, CostViewBinding>(), CostFragmentContract.View {
     val TAG = "CostFragment"
@@ -24,7 +29,11 @@ class CostFragment : BaseFragment<CostFragmentPresenter, CostViewBinding>(), Cos
     }
 
     override fun init() {
-        //
+        if (Constant.CUSTOM_ID != -1) {
+            presenter.loadCustomCost(Constant.CUSTOM_ID)
+        } else {
+            showMessage("没有custom id")
+        }
     }
 
     override fun bindEvent() {
@@ -35,22 +44,27 @@ class CostFragment : BaseFragment<CostFragmentPresenter, CostViewBinding>(), Cos
         debugLog(TAG,"destory")
     }
 
-    override fun showData(data: ArrayList<Any>) {
-        debugLog(TAG,"showData")
+    override fun showCustomCost(cost: ArrayList<CustomerFeeConfigByGroupNameVO>) {
+        val layoutManager = LinearLayoutManager(activity)
+        rv_cost_main_view.layoutManager = layoutManager
+        rv_cost_main_view.adapter = CostItemAdapter(activity, cost)
     }
 
     override fun onError(message: String, type: Int) {
-        getUtils().dismissDialog()
         errorLog("error",message)
         showMessage(message)
     }
 
     override fun complete(message: String, type: Int) {
-        getUtils().dismissDialog()
+        //
     }
 
     override fun start() {
-        getUtils().showDialog()
+        //
+    }
+
+    override fun onNoNet() {
+        showMessage("没有网络")
     }
 
     override fun networkMonitor(state: NetState) {

+ 63 - 50
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/MainFragment.kt

@@ -1,28 +1,29 @@
 package com.wdkl.app.ncs.callingbed.fragment
 
 import android.content.Intent
+import android.text.TextUtils
 import android.util.Log
+import android.view.View
 import com.enation.javashop.net.engine.model.NetState
 import com.wdkl.app.ncs.callingbed.BuildConfig
 import com.wdkl.app.ncs.callingbed.R
 import com.wdkl.app.ncs.callingbed.activity.CallingbedActivity
-import com.wdkl.app.ncs.callingbed.common.Constant
-import com.wdkl.app.ncs.callingbed.common.MessageEvent
 import com.wdkl.app.ncs.callingbed.databinding.MainViewLayoutBinding
 import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
 import com.wdkl.app.ncs.callingbed.net.NettyClient
 import com.wdkl.app.ncs.callingbed.sip.SipHelper
 //import com.wdkl.app.ncs.sip.activity.VoipAudioActivity
 import com.wdkl.ncs.android.lib.base.BaseFragment
-import com.wdkl.ncs.android.lib.utils.debugLog
-import com.wdkl.ncs.android.lib.utils.errorLog
-import com.wdkl.ncs.android.lib.utils.showMessage
-import com.wdkl.ncs.android.lib.utils.to
+import com.wdkl.ncs.android.lib.utils.*
 import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
 import com.wdkl.ncs.android.middleware.logic.contract.callingbed.MainFragmentContract
 import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.MainFragmentPresenter
+import com.wdkl.ncs.android.middleware.model.vo.CustomerInfoVO
 import kotlinx.android.synthetic.main.main_view.*
 import kotlinx.android.synthetic.main.main_view_layout.*
+import kotlinx.android.synthetic.main.view_bed_name.*
 import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
@@ -39,46 +40,74 @@ class MainFragment: BaseFragment<MainFragmentPresenter, MainViewLayoutBinding>()
     }
 
     override fun init() {
-        activity_calling_bed_layout_tv_version?.setText("V" + BuildConfig.VERSION_NAME)
+        if (!TextUtils.isEmpty(Constant.BED_NAME)) {
+            //床位名称
+            tv_bed_name.text = Constant.BED_NAME
+        }
 
-        //presenter.loadData();
-        //NettyClient.getInstance().connect()
+        updateInfo()
     }
 
     override fun bindEvent() {
         debugLog(TAG,"bindEvent")
     }
 
-    override fun onResume() {
-        //EventBus.getDefault().register(this)
-        super.onResume()
+    override fun onStart() {
+        EventBus.getDefault().register(this)
+        super.onStart()
     }
 
-    override fun onPause() {
-        //EventBus.getDefault().unregister(this)
-        super.onPause()
+    override fun onStop() {
+        EventBus.getDefault().unregister(this)
+        super.onStop()
     }
 
     override fun destory() {
         debugLog(TAG,"destory")
     }
 
-    override fun showData(data: ArrayList<Any>) {
-        debugLog(TAG,"showData")
+    override fun showCustomInfo(customInfo: CustomerInfoVO) {
+        //隐藏空页面并展示入住信息
+        ll_empty.visibility = View.GONE
+        ll_custom_view.visibility = View.VISIBLE
+        //床位名称
+        tv_bed_name.text = Constant.BED_NAME
+
+        //显示入住信息
+        tv_custom_name.text = customInfo.named
+        if (customInfo.sex == 0) {
+            tv_custom_gender.setBackgroundResource(R.mipmap.ic_gender_female)
+        } else if (customInfo.sex == 1) {
+            tv_custom_gender.setBackgroundResource(R.mipmap.ic_gender_male)
+        }
+        tv_custom_age.text = "" + customInfo.age + customInfo.ageUnit
+        if (customInfo.inDate != null) {
+            tv_custom_indate.text = "入院日期: " + TimeHandle.getDateTime(customInfo.inDate * 1000, "yyyy.MM.dd")
+        }
+        if (TextUtils.isEmpty(customInfo.advice)) {
+            tv_order_content.text = "暂无"
+        } else {
+            tv_order_content.text = customInfo.advice
+        }
+
+        tv_doctor_name.text = customInfo.doctorName
+        tv_nurse_name.text = customInfo.nurseName
+
+        //更新护理项
+        (activity as CallingbedActivity).updateNurseConfig(customInfo.list)
     }
 
     override fun onError(message: String, type: Int) {
-        getUtils().dismissDialog()
         errorLog("error",message)
         showMessage(message)
     }
 
     override fun complete(message: String, type: Int) {
-        getUtils().dismissDialog()
+        //
     }
 
     override fun start() {
-        getUtils().showDialog()
+        //
     }
 
     override fun networkMonitor(state: NetState) {
@@ -91,39 +120,23 @@ class MainFragment: BaseFragment<MainFragmentPresenter, MainViewLayoutBinding>()
         })
     }
 
+    override fun onNoNet() {
+        showMessage("没有网络")
+    }
 
-    /*@Subscribe(threadMode = ThreadMode.MAIN)
+    fun updateInfo() {
+        if (Constant.CUSTOM_ID != -1) {
+            ll_empty.visibility = View.GONE
+            presenter.loadCustomInfo(Constant.CUSTOM_ID)
+        }
+    }
+
+    @Subscribe(threadMode = ThreadMode.MAIN)
     fun onMoonEvent(messageEvent: MessageEvent) {
         when (messageEvent.getType()) {
-            Constant.EVENT_SIP_CALL_STATUS -> {
-                if (messageEvent.message is Int) run {
-                    val status = messageEvent.message as Int
-                    Log.d("sip", "sip call status: " + status)
-
-                    when (status) {
-                        0 -> {
-                            //正在呼叫中:子机自动接通 isIncomingCall() = true  mState = 0  //正在通话中:isIncomingCall() = true
-                            //=============================================SIP自动接听===================================//
-                            Log.d("sip", "auto talking...")
-                            //正在通话中:isIncomingCall() = true
-                        }
-                        1 -> {
-                            //???
-                        }
-                        2 -> {
-                            //正在通话中:isIncomingCall() = true  mState = 2
-                            Log.d("sip", "in call...")
-                        }
-                        3 -> {
-                            //无人应答/挂断:isIncomingCall() = true  mState = 3
-                            Log.d("sip", "end call...")
-                        }
-                        else -> {
-                            //none
-                        }
-                    }
-                }
+            Constant.EVENT_UPDATE_CUSTOM -> {
+                updateInfo()
             }
         }
-    }*/
+    }
 }

+ 15 - 3
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/QrCodeFragment.kt

@@ -2,8 +2,10 @@ package com.wdkl.app.ncs.callingbed.fragment
 
 import android.graphics.BitmapFactory
 import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.app.ncs.callingbed.BuildConfig
 import com.wdkl.app.ncs.callingbed.R
 import com.wdkl.app.ncs.callingbed.databinding.QrcodeViewBinding
+import com.wdkl.app.ncs.callingbed.helper.NetHelper
 import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
 import com.wdkl.ncs.android.lib.base.BaseFragment
 import com.wdkl.ncs.android.lib.utils.EcodeHelper
@@ -11,9 +13,11 @@ import com.wdkl.ncs.android.lib.utils.debugLog
 import com.wdkl.ncs.android.lib.utils.errorLog
 import com.wdkl.ncs.android.lib.utils.showMessage
 import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
 import com.wdkl.ncs.android.middleware.logic.contract.callingbed.QrCodeFragmentContract
 import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.QrCodeFragmentPresenter
 import kotlinx.android.synthetic.main.qrcode_view.*
+import kotlinx.android.synthetic.main.view_bed_name.*
 
 class QrCodeFragment : BaseFragment<QrCodeFragmentPresenter, QrcodeViewBinding>(), QrCodeFragmentContract.View {
     val TAG = "QrCodeFragment"
@@ -29,13 +33,21 @@ class QrCodeFragment : BaseFragment<QrCodeFragmentPresenter, QrcodeViewBinding>(
     }
 
     override fun init() {
+        tv_bed_name.text = Constant.BED_NAME
+
         Thread{
-            val logoBitmap = BitmapFactory.decodeResource(resources, R.mipmap.erlogo)
-            val code = EcodeHelper().createQRImage(QR_CODE_PATH + KEY_ID,240,logoBitmap)
+            //val logoBitmap = BitmapFactory.decodeResource(resources, R.mipmap.erlogo)
+            val code = EcodeHelper().createQRImage(QR_CODE_PATH + KEY_ID,200, null)
             activity.runOnUiThread {
-                view_qr_code.setImageBitmap(code)
+                view_qr_code?.setImageBitmap(code)
             }
         }.start()
+        val macAddr = NetHelper.getInstance().macAddress
+        val ipAddr = NetHelper.getInstance().localIP
+        tv_device_id.text = "设备ID: " + Constant.DEVICE_ID
+        tv_local_ip.text = "本机IP: " + ipAddr
+        tv_local_mac.text = "本机MAC: " + macAddr
+        tv_app_version.text = "版本信息: V" + BuildConfig.VERSION_NAME
     }
 
     override fun bindEvent() {

+ 3 - 3
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/SupportFragment.kt

@@ -3,12 +3,12 @@ package com.wdkl.app.ncs.callingbed.fragment
 import android.os.CountDownTimer
 import com.enation.javashop.net.engine.model.NetState
 import com.wdkl.app.ncs.callingbed.R
-import com.wdkl.app.ncs.callingbed.common.Constant
-import com.wdkl.app.ncs.callingbed.common.MessageEvent
 import com.wdkl.app.ncs.callingbed.databinding.SupportViewBinding
 import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
 import com.wdkl.ncs.android.lib.base.BaseFragment
 import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.common.Constant
+import com.wdkl.ncs.android.middleware.common.MessageEvent
 import com.wdkl.ncs.android.middleware.logic.contract.callingbed.SupportFragmentContract
 import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.SupportFragmentPresenter
 import kotlinx.android.synthetic.main.support_view.*
@@ -65,7 +65,7 @@ class SupportFragment : BaseFragment<SupportFragmentPresenter, SupportViewBindin
     }
 
     fun initCountDownTimer() {
-        countDownTimer = object: CountDownTimer(Constant.CALL_TIMEOUT*1000, 1000) {
+        countDownTimer = object: CountDownTimer(Constant.CALL_TIMEOUT*1000L, 1000) {
             override fun onTick(millisUntilFinished: Long) {
                 val time = millisUntilFinished/1000
                 view_support_layout_tv_call_timeout?.setText("" + time + " 秒")

+ 13 - 2
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/helper/NetHelper.java

@@ -1,13 +1,14 @@
 package com.wdkl.app.ncs.callingbed.helper;
 
 import android.annotation.SuppressLint;
+import android.bluetooth.BluetoothAdapter;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.text.TextUtils;
 
-import com.wdkl.app.ncs.callingbed.common.MessageEvent;
+import com.wdkl.ncs.android.middleware.common.MessageEvent;
 
 import org.greenrobot.eventbus.EventBus;
 
@@ -24,7 +25,8 @@ import java.util.List;
 import java.util.Timer;
 import java.util.TimerTask;
 
-import static com.wdkl.app.ncs.callingbed.common.Constant.EVENT_INTERNETPING;
+import static com.wdkl.ncs.android.middleware.common.Constant.EVENT_INTERNETPING;
+
 
 public class NetHelper {
     private Context mContext;
@@ -465,4 +467,13 @@ public class NetHelper {
         }
         return "";
     }
+
+    public static boolean isBTConnected() {
+        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (btAdapter != null) {
+            return btAdapter.getState() == BluetoothAdapter.STATE_ON;
+        }
+
+        return false;
+    }
 }

+ 2 - 2
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/sip/SipHelper.java

@@ -19,8 +19,8 @@ import com.vvsip.ansip.VvsipCall;
 import com.vvsip.ansip.VvsipService;
 import com.vvsip.ansip.VvsipServiceBinder;
 import com.vvsip.ansip.VvsipTask;
-import com.wdkl.app.ncs.callingbed.common.MessageEvent;
 import com.wdkl.app.ncs.callingbed.helper.NetHelper;
+import com.wdkl.ncs.android.middleware.common.MessageEvent;
 
 
 import org.greenrobot.eventbus.EventBus;
@@ -29,11 +29,11 @@ import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.List;
 
-import static com.wdkl.app.ncs.callingbed.common.Constant.EVENT_SIP_REGISTER_STATUS;
 import static com.wdkl.app.ncs.callingbed.sip.SipStatus.REGISTERCOM;
 import static com.wdkl.app.ncs.callingbed.sip.SipStatus.REGISTERFAIL;
 import static com.wdkl.app.ncs.callingbed.sip.SipStatus.REGISTERING;
 import static com.vvsip.ansip.VvsipTask.EXOSIP_CALL_CLOSED;
+import static com.wdkl.ncs.android.middleware.common.Constant.EVENT_SIP_REGISTER_STATUS;
 
 
 public class SipHelper {

+ 5 - 0
callingbed/src/main/res/drawable/selector_bottom_btn_text_color.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@color/yellow_color" android:state_pressed="true"/>
+    <item android:color="@color/white"/>
+</selector>

+ 5 - 0
callingbed/src/main/res/drawable/selector_call_end.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@mipmap/ic_hangup_press" android:state_pressed="true"/>
+    <item android:drawable="@mipmap/ic_hangup_normal"/>
+</selector>

+ 156 - 105
callingbed/src/main/res/layout/callingbed_main_lay.xml

@@ -2,35 +2,102 @@
 <layout>
     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
-
-        <!--<TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="Hello World!"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintLeft_toLeftOf="parent"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintTop_toTopOf="parent" />
-
-        <TextView
-            android:id="@+id/calling_data"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintLeft_toLeftOf="parent"
-            app:layout_constraintRight_toRightOf="parent"
-            app:layout_constraintTop_toTopOf="parent" />-->
+        android:layout_height="match_parent"
+        android:background="#EAF2F9">
 
         <include
             android:id="@+id/activity_calling_bed_layout_title"
             layout="@layout/view_title_layout"/>
 
+        <LinearLayout
+            android:id="@+id/rl_left_view"
+            android:layout_width="220dp"
+            android:layout_height="match_parent"
+            android:layout_below="@id/activity_calling_bed_layout_title"
+            android:layout_marginTop="4dp"
+            android:paddingLeft="10dp"
+            android:paddingRight="10dp">
+
+            <!--左侧护理列表-->
+            <android.support.v7.widget.RecyclerView
+                android:id="@+id/rv_left_list"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
+
+        </LinearLayout>
+
+        <!--右侧fragment区域-->
         <FrameLayout
             android:id="@+id/callingbed_main_frame"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:layout_below="@id/activity_calling_bed_layout_title"/>
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="2dp"
+            android:layout_marginRight="10dp"
+            android:layout_toRightOf="@id/rl_left_view"
+            android:layout_below="@id/activity_calling_bed_layout_title" />
+
+        <!--呼叫状态显示-->
+        <LinearLayout
+            android:id="@+id/ll_call_view"
+            android:layout_width="match_parent"
+            android:layout_height="86dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="10dp"
+            android:layout_marginRight="10dp"
+            android:layout_toRightOf="@id/rl_left_view"
+            android:layout_below="@id/activity_calling_bed_layout_title"
+            android:background="#37C127"
+            android:gravity="center_vertical"
+            android:visibility="gone">
+
+            <com.wdkl.ncs.android.lib.widget.MarqueeTextView
+                android:id="@+id/tv_call_bed_name"
+                android:layout_width="200dp"
+                android:layout_height="match_parent"
+                android:gravity="center"
+                android:ellipsize="marquee"
+                android:focusable="true"
+                android:focusableInTouchMode="true"
+                android:marqueeRepeatLimit="-1"
+                android:singleLine="true"
+                android:textColor="@color/white"
+                android:textSize="48sp"/>
+
+            <com.wdkl.ncs.android.lib.widget.MarqueeTextView
+                android:id="@+id/tv_call_state"
+                android:layout_width="200dp"
+                android:layout_height="match_parent"
+                android:paddingLeft="10dp"
+                android:paddingRight="10dp"
+                android:gravity="center"
+                android:ellipsize="marquee"
+                android:focusable="true"
+                android:focusableInTouchMode="true"
+                android:marqueeRepeatLimit="-1"
+                android:singleLine="true"
+                android:textColor="@color/red_color"
+                android:textSize="32sp" />
+
+            <Chronometer
+                android:id="@+id/voice_call_timer_view"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_marginLeft="20dp"
+                android:gravity="center"
+                android:text="00:00"
+                android:textColor="@color/white"
+                android:textSize="20sp" />
+
+            <ImageView
+                android:id="@+id/iv_call_end"
+                android:layout_width="60dp"
+                android:layout_height="60dp"
+                android:layout_marginLeft="20dp"
+                android:src="@drawable/selector_call_end"
+                android:scaleType="centerInside"/>
+        </LinearLayout>
+
 
         <LinearLayout
             android:id="@+id/right_menu"
@@ -39,132 +106,116 @@
             android:layout_alignParentRight="true"
             android:background="@mipmap/bg_right"
             android:orientation="vertical"
-            android:padding="20dp"
+            android:paddingTop="20dp"
+            android:paddingLeft="6dp"
+            android:paddingRight="6dp"
             android:visibility="gone">
 
             <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:orientation="vertical">
-
-                <TextView
-                    android:id="@+id/activity_calling_bed_layout_tv_doctor"
-                    android:layout_width="60dp"
-                    android:layout_height="60dp"
-                    android:layout_gravity="center"
-                    android:background="@drawable/selector_doctor" />
+                android:layout_height="0dp"
+                android:layout_weight="1">
 
                 <TextView
                     android:id="@+id/activity_calling_bed_layout_tv_doctor_text"
-                    android:layout_width="wrap_content"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:text="医嘱"
-                    android:textColor="@color/white"
-                    android:textSize="16sp"
-                    android:textStyle="bold" />
+                    android:paddingLeft="14dp"
+                    android:paddingTop="10dp"
+                    android:paddingBottom="10dp"
+                    android:background="@mipmap/bg_bottom_btn"
+                    android:drawableLeft="@mipmap/ic_home"
+                    android:drawablePadding="4dp"
+                    android:text="首页"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="24sp"/>
+
             </LinearLayout>
 
             <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:orientation="vertical">
-
-                <TextView
-                    android:id="@+id/activity_calling_bed_layout_tv_cost"
-                    android:layout_width="60dp"
-                    android:layout_height="60dp"
-                    android:layout_below="@+id/activity_calling_bed_layout_tv_doctor"
-                    android:layout_gravity="center"
-                    android:background="@drawable/selector_cost" />
+                android:layout_height="0dp"
+                android:layout_weight="1" >
 
                 <TextView
                     android:id="@+id/activity_calling_bed_layout_tv_cost_text"
-                    android:layout_width="wrap_content"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:text="费用查询"
-                    android:textColor="@color/white"
-                    android:textSize="16sp"
-                    android:textStyle="bold" />
+                    android:paddingLeft="14dp"
+                    android:paddingTop="10dp"
+                    android:paddingBottom="10dp"
+                    android:background="@mipmap/bg_bottom_btn"
+                    android:drawableLeft="@mipmap/ic_cost"
+                    android:drawablePadding="4dp"
+                    android:text="费用"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="24sp"/>
+
             </LinearLayout>
 
             <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:orientation="vertical">
-
-                <TextView
-                    android:id="@+id/activity_calling_bed_layout_tv_qr_code"
-                    android:layout_width="60dp"
-                    android:layout_height="60dp"
-                    android:layout_below="@+id/activity_calling_bed_layout_tv_cost"
-                    android:layout_gravity="center"
-                    android:background="@drawable/selector_qr_code" />
+                android:layout_height="0dp"
+                android:layout_weight="1">
 
                 <TextView
                     android:id="@+id/activity_calling_bed_layout_tv_qr_code_text"
-                    android:layout_width="wrap_content"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:text="二维码"
-                    android:textColor="@color/white"
-                    android:textSize="16sp"
-                    android:textStyle="bold" />
+                    android:paddingLeft="14dp"
+                    android:paddingTop="10dp"
+                    android:paddingBottom="10dp"
+                    android:background="@mipmap/bg_bottom_btn"
+                    android:drawableLeft="@mipmap/ic_more"
+                    android:drawablePadding="4dp"
+                    android:text="更多"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="24sp"/>
+
             </LinearLayout>
 
             <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:orientation="vertical">
-
-                <TextView
-                    android:id="@+id/activity_calling_bed_layout_tv_support"
-                    android:layout_width="60dp"
-                    android:layout_height="60dp"
-                    android:layout_below="@+id/activity_calling_bed_layout_tv_qr_code"
-                    android:layout_gravity="center"
-                    android:background="@drawable/selector_support" />
+                android:layout_height="0dp"
+                android:layout_weight="1">
 
                 <TextView
                     android:id="@+id/activity_calling_bed_layout_tv_support_text"
-                    android:layout_width="wrap_content"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:text="请求增援"
-                    android:textColor="@color/white"
-                    android:textSize="16sp"
-                    android:textStyle="bold" />
+                    android:paddingLeft="14dp"
+                    android:paddingTop="10dp"
+                    android:paddingBottom="10dp"
+                    android:background="@mipmap/bg_bottom_btn"
+                    android:drawableLeft="@mipmap/ic_support"
+                    android:drawablePadding="4dp"
+                    android:text="增援"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="24sp"/>
+
             </LinearLayout>
 
             <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_weight="1"
-                android:orientation="vertical">
-
-                <TextView
-                    android:id="@+id/activity_calling_bed_layout_tv_call"
-                    android:layout_width="60dp"
-                    android:layout_height="60dp"
-                    android:layout_below="@+id/activity_calling_bed_layout_tv_support"
-                    android:layout_gravity="center"
-                    android:background="@drawable/selector_call" />
+                android:layout_height="0dp"
+                android:layout_weight="1">
 
                 <TextView
                     android:id="@+id/activity_calling_bed_layout_tv_call_text"
-                    android:layout_width="wrap_content"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center"
-                    android:text="呼叫护工"
-                    android:textColor="@color/white"
-                    android:textSize="16sp"
-                    android:textStyle="bold" />
+                    android:paddingLeft="14dp"
+                    android:paddingTop="10dp"
+                    android:paddingBottom="10dp"
+                    android:background="@mipmap/bg_bottom_btn"
+                    android:drawableLeft="@mipmap/ic_call"
+                    android:drawablePadding="4dp"
+                    android:text="呼叫"
+                    android:textColor="@drawable/selector_bottom_btn_text_color"
+                    android:textSize="24sp"/>
+
             </LinearLayout>
         </LinearLayout>
+
     </RelativeLayout>
 </layout>

+ 7 - 71
callingbed/src/main/res/layout/cost_view.xml

@@ -1,78 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <layout>
-
-    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    <LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="@mipmap/bg_main"
-        android:orientation="vertical">
+        android:layout_height="match_parent">
 
-        <RelativeLayout
+        <android.support.v7.widget.RecyclerView
+            android:id="@+id/rv_cost_main_view"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:layout_marginLeft="@dimen/font_size_20"
-            android:layout_marginTop="@dimen/font_size_20"
-            android:layout_marginRight="@dimen/font_size_20"
-            android:layout_marginBottom="@dimen/font_size_20"
-            android:background="@drawable/shape_cost_bg">
-
-            <RelativeLayout
-                android:id="@+id/view_cost_layout_rl_title"
-                android:layout_width="match_parent"
-                android:layout_height="50dp"
-                android:background="@drawable/shape_cost_list_title_bg">
-
-                <TextView
-                    android:id="@+id/view_cost_layout_tv_name"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_centerVertical="true"
-                    android:layout_marginLeft="20dp"
-                    android:text="--"
-                    android:textColor="#FF5963"
-                    android:textSize="@dimen/font_size_25"
-                    android:textStyle="bold" />
-
-                <TextView
-                    android:id="@+id/view_cost_layout_tv_inpatient_num"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_alignParentRight="true"
-                    android:layout_centerVertical="true"
-                    android:layout_marginLeft="20dp"
-                    android:layout_marginRight="50dp"
-                    android:text="--"
-                    android:textColor="#FF5963"
-                    android:textSize="@dimen/font_size_25"
-                    android:textStyle="bold" />
-            </RelativeLayout>
-
-            <android.support.v7.widget.RecyclerView
-                android:id="@+id/view_cost_layout_rv_cost"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_above="@+id/view_cost_layout_tv_text"
-                android:layout_below="@+id/view_cost_layout_rl_title"
-                android:paddingLeft="@dimen/font_size_20"
-                android:paddingTop="@dimen/font_size_20"
-                android:paddingRight="@dimen/font_size_20" />
-
-            <TextView
-                android:id="@+id/view_cost_layout_tv_text"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentBottom="true"
-                android:layout_centerHorizontal="true"
-                android:layout_gravity="center"
-                android:layout_marginTop="@dimen/margin_to_side_5"
-                android:layout_marginBottom="@dimen/margin_to_side_5"
-                android:background="@drawable/shape_main_bg_admission"
-                android:padding="@dimen/margin_to_side_5"
-                android:paddingLeft="@dimen/margin_to_side_10"
-                android:paddingRight="@dimen/margin_to_side_10"
-                android:text="               更多信息请按右侧按键扫描二维码               "
-                android:textColor="#FF5963"
-                android:textSize="@dimen/font_size_20" />
-        </RelativeLayout>
-    </RelativeLayout>
+            android:layout_marginBottom="6dp"/>
+    </LinearLayout>
 </layout>

+ 39 - 0
callingbed/src/main/res/layout/item_cost_detail.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginTop="10dp">
+
+    <TextView
+        android:id="@+id/tv_item_cost_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="20sp"
+        android:textColor="@color/black"/>
+    <TextView
+        android:id="@+id/tv_item_cost_value"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:textSize="20sp"
+        android:textColor="@color/black"/>
+    <TextView
+        android:id="@+id/tv_item_cost_id"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/tv_item_cost_name"
+        android:layout_marginTop="8dp"
+        android:textSize="20sp"
+        android:textColor="#A4A4A4"/>
+    <TextView
+        android:id="@+id/tv_item_cost_unit"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_below="@id/tv_item_cost_value"
+        android:layout_marginTop="8dp"
+        android:textSize="20sp"
+        android:textColor="#A4A4A4"/>
+
+</RelativeLayout>

+ 38 - 0
callingbed/src/main/res/layout/item_cost_main_view.xml

@@ -0,0 +1,38 @@
+<?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:padding="16dp"
+    android:layout_marginBottom="10dp"
+    android:orientation="vertical"
+    android:background="@color/white">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <TextView
+            android:id="@+id/tv_cost_group_name"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:text=""
+            android:textColor="@color/main_color"
+            android:textSize="24sp"/>
+        <TextView
+            android:id="@+id/tv_cost_group_total"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:gravity="right"
+            android:text=""
+            android:textColor="@color/main_color"
+            android:textSize="24sp"/>
+    </LinearLayout>
+
+    <android.support.v7.widget.RecyclerView
+        android:id="@+id/rv_cost_detail"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+
+</LinearLayout>

+ 38 - 0
callingbed/src/main/res/layout/item_nurse_config.xml

@@ -0,0 +1,38 @@
+<?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="80dp"
+    android:layout_marginTop="6dp"
+    android:background="@color/white">
+
+    <TextView
+        android:id="@+id/tv_nurse_color"
+        android:layout_width="8dp"
+        android:layout_height="match_parent"
+        android:background="@color/main_color"/>
+
+    <TextView
+        android:id="@+id/tv_nurse_config_name"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:paddingLeft="6dp"
+        android:paddingTop="6dp"
+        android:text="护理"
+        android:textSize="20sp"
+        android:textColor="#B4B4B4"/>
+
+    <TextView
+        android:id="@+id/tv_nurse_config_value"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:paddingRight="6dp"
+        android:paddingBottom="6dp"
+        android:gravity="right|bottom"
+        android:text="暂无"
+        android:textSize="24sp"
+        android:textColor="@color/main_color"/>
+
+</LinearLayout>

+ 150 - 394
callingbed/src/main/res/layout/main_view.xml

@@ -1,442 +1,198 @@
 <?xml version="1.0" encoding="utf-8"?>
 <layout>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <LinearLayout
-        android:id="@+id/activity_calling_bed_layout_ll_left"
-        android:layout_width="150dp"
-        android:layout_height="match_parent"
-        android:background="#FCADB1"
-        android:paddingTop="16dp"
-        android:orientation="vertical">
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="75dp"
-            android:background="#EA4F77"
-            android:gravity="center_vertical"
-            android:orientation="horizontal">
-
-            <TextView
-                android:id="@+id/view_main_layout_left_one_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="@dimen/margin_to_side_5"
-                android:text="--"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_30" />
-
-            <TextView
-                android:id="@+id/view_main_layout_left_one_content"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="@dimen/margin_to_side_10"
-                android:text="--"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_30" />
-
-        </LinearLayout>
-
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:background="#B34A44"
-            android:layout_weight="1"/>
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="75dp"
-            android:background="#EA4F77"
-            android:gravity="center_vertical"
-            android:orientation="horizontal">
-
-            <TextView
-                android:id="@+id/view_main_layout_left_two_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="@dimen/margin_to_side_5"
-                android:text="--"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_30" />
-
-            <TextView
-                android:id="@+id/view_main_layout_left_two_content"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="@dimen/margin_to_side_10"
-                android:text="--"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_30" />
-        </LinearLayout>
-
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:background="#B34A44"
-            android:layout_weight="1"/>
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="75dp"
-            android:background="#EA4F77"
-            android:gravity="center_vertical"
-            android:orientation="horizontal">
-
-            <TextView
-                android:id="@+id/view_main_layout_left_three_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="@dimen/margin_to_side_5"
-                android:text="--"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_30" />
-
-            <TextView
-                android:id="@+id/view_main_layout_left_three_content"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="@dimen/margin_to_side_10"
-                android:text="--"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_30" />
-        </LinearLayout>
-
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:background="#B34A44"
-            android:layout_weight="1"/>
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="75dp"
-            android:background="#EA4F77"
-            android:gravity="center_vertical"
-            android:orientation="horizontal">
-
-            <TextView
-                android:id="@+id/view_main_layout_left_four_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="@dimen/margin_to_side_5"
-                android:text="--"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_30" />
-
-            <TextView
-                android:id="@+id/view_main_layout_left_four_content"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="@dimen/margin_to_side_10"
-                android:text="--"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_30" />
-        </LinearLayout>
-
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:background="#B34A44"
-            android:layout_weight="1"/>
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="75dp"
-            android:background="#EA4F77"
-            android:gravity="center_vertical"
-            android:orientation="horizontal">
-
-            <TextView
-                android:id="@+id/view_main_layout_left_five_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="@dimen/margin_to_side_5"
-                android:text="--"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_30" />
-
-            <TextView
-                android:id="@+id/view_main_layout_left_five_content"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginLeft="@dimen/margin_to_side_10"
-                android:text="--"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_30" />
-        </LinearLayout>
-    </LinearLayout>
-
     <RelativeLayout
-        android:id="@+id/activity_calling_bed_layout_rl_middle"
+        xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_toRightOf="@+id/activity_calling_bed_layout_ll_left"
-        android:background="@mipmap/bg_main">
+        android:layout_height="match_parent">
+
+        <include android:id="@+id/lay_main_bed_name"
+            layout="@layout/view_bed_name"/>
 
         <LinearLayout
-            android:id="@+id/view_main_layout_ll_content"
-            android:layout_width="500dp"
+            android:id="@+id/ll_doctor_nurse_view"
+            android:layout_width="140dp"
             android:layout_height="match_parent"
-            android:layout_above="@+id/view_main_layout_bottom"
-            android:orientation="vertical"
-            android:paddingLeft="@dimen/margin_to_side_15"
-            android:paddingTop="@dimen/margin_to_side_15"
-            android:paddingRight="@dimen/margin_to_side_15">
-
+            android:layout_below="@id/lay_main_bed_name"
+            android:layout_alignParentRight="true"
+            android:layout_marginTop="6dp"
+            android:layout_marginBottom="6dp"
+            android:orientation="vertical">
+            <!--责任医生-->
             <LinearLayout
+                android:id="@+id/ll_doctor_view"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
-                android:layout_weight="1.15"
-                android:background="@drawable/shape_bed_num_bg"
+                android:layout_weight="1"
+                android:gravity="center_horizontal"
                 android:orientation="vertical"
-                android:padding="@dimen/margin_to_side_5">
-
-                <com.wdkl.ncs.android.lib.widget.MarqueeTextView
-                    android:id="@+id/view_main_layout_tv_bed_num"
+                android:background="@color/white">
+                <ImageView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:layout_marginTop="-12dp"
-                    android:layout_gravity="center"
-                    android:ellipsize="marquee"
-                    android:focusable="true"
-                    android:focusableInTouchMode="true"
-                    android:gravity="center"
-                    android:marqueeRepeatLimit="-1"
-                    android:singleLine="true"
-                    android:text="000"
-                    android:textColor="#EA4F77"
-                    android:textSize="110sp"
-                    android:textStyle="bold" />
+                    android:layout_marginTop="12dp"
+                    android:src="@mipmap/ic_doctor_default"/>
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dp"
+                    android:textColor="#B4B4B4"
+                    android:textSize="18sp"
+                    android:text="责任医生"/>
+                <TextView
+                    android:id="@+id/tv_doctor_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="4dp"
+                    android:textColor="@color/black"
+                    android:textSize="18sp"
+                    android:text="暂无"/>
             </LinearLayout>
 
+            <!--责任护士-->
             <LinearLayout
+                android:id="@+id/ll_nurse_view"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
-                android:layout_weight="1.85"
-                android:background="@drawable/shape_bed_name_bg"
-                android:orientation="vertical">
-
-                <RelativeLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent">
-
-                    <TextView
-                        android:id="@+id/view_main_layout_tv_admission"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_centerHorizontal="true"
-                        android:layout_alignParentBottom="true"
-                        android:layout_marginBottom="@dimen/margin_to_side_5"
-                        android:background="#FBD7D9"
-                        android:padding="@dimen/margin_to_side_5"
-                        android:paddingLeft="20dp"
-                        android:paddingRight="20dp"
-                        android:text="入住时间: ----/--/--"
-                        android:textColor="#FF5963"
-                        android:textSize="@dimen/font_size_18" />
-
-                    <View
-                        android:id="@+id/view_center_line"
-                        android:layout_width="2dp"
-                        android:layout_height="match_parent"
-                        android:layout_centerHorizontal="true"
-                        android:layout_above="@id/view_main_layout_tv_admission"
-                        android:layout_marginTop="20dp"
-                        android:layout_marginBottom="20dp"
-                        android:background="#E85E5B"/>
-
-                    <com.wdkl.ncs.android.lib.widget.MarqueeTextView
-                        android:id="@+id/view_main_layout_tv_name"
-                        android:layout_width="match_parent"
-                        android:layout_height="match_parent"
-                        android:layout_above="@id/view_main_layout_tv_admission"
-                        android:layout_toLeftOf="@id/view_center_line"
-                        android:padding="6dp"
-                        android:gravity="center"
-                        android:ellipsize="marquee"
-                        android:focusable="true"
-                        android:focusableInTouchMode="true"
-                        android:marqueeRepeatLimit="-1"
-                        android:singleLine="true"
-                        android:text="---"
-                        android:textColor="#E85E5B"
-                        android:textSize="68sp"
-                        android:textStyle="bold" />
-
-                    <ImageView
-                        android:layout_width="70dp"
-                        android:layout_height="140dp"
-                        android:layout_toRightOf="@id/view_center_line"
-                        android:layout_marginLeft="32dp"
-                        android:layout_marginTop="20dp"
-                        android:src="@mipmap/ic_baby"/>
-
-                    <TextView
-                        android:id="@+id/view_main_layout_tv_illness"
-                        android:layout_width="60dp"
-                        android:layout_height="60dp"
-                        android:layout_above="@+id/view_main_layout_tv_admission"
-                        android:layout_alignParentRight="true"
-                        android:layout_marginRight="20dp"
-                        android:layout_marginBottom="20dp"
-                        android:background="@drawable/shape_circle_bg_age"
-                        android:gravity="center"
-                        android:text="--"
-                        android:textColor="@color/white"
-                        android:textSize="20sp"
-                        android:textStyle="bold" />
-
-                    <TextView
-                        android:id="@+id/view_main_layout_tv_detail"
-                        android:layout_width="60dp"
-                        android:layout_height="60dp"
-                        android:layout_above="@id/view_main_layout_tv_illness"
-                        android:layout_alignParentRight="true"
-                        android:layout_marginRight="20dp"
-                        android:layout_marginBottom="20dp"
-                        android:layout_marginTop="20dp"
-                        android:background="@drawable/shape_circle_bg"
-                        android:gravity="center"
-                        android:text="-"
-                        android:textColor="@color/white"
-                        android:textSize="28sp"
-                        android:textStyle="bold" />
-
-                </RelativeLayout>
+                android:layout_weight="1"
+                android:layout_marginTop="10dp"
+                android:gravity="center_horizontal"
+                android:orientation="vertical"
+                android:background="@color/white">
+                <ImageView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="12dp"
+                    android:src="@mipmap/ic_nurse_default"/>
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dp"
+                    android:textColor="#B4B4B4"
+                    android:textSize="18sp"
+                    android:text="责任护士"/>
+                <TextView
+                    android:id="@+id/tv_nurse_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="4dp"
+                    android:textColor="@color/black"
+                    android:textSize="18sp"
+                    android:text="暂无"/>
             </LinearLayout>
         </LinearLayout>
 
 
-        <LinearLayout
-            android:id="@+id/view_main_layout_ll_content_ll_right"
+        <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:layout_above="@+id/view_main_layout_bottom"
-            android:layout_toRightOf="@+id/view_main_layout_ll_content"
-            android:orientation="vertical"
-            android:paddingTop="@dimen/margin_to_side_15"
-            android:paddingRight="@dimen/margin_to_side_15">
-
-            <TextView
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:background="@drawable/shape_mai_bg_doctor_title"
-                android:gravity="center"
-                android:text="母婴师"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_20" />
-
+            android:layout_below="@id/lay_main_bed_name"
+            android:layout_toLeftOf="@id/ll_doctor_nurse_view"
+            android:layout_marginTop="6dp"
+            android:layout_marginRight="10dp"
+            android:layout_marginBottom="6dp">
+            <!--无人入住时展示-->
             <LinearLayout
+                android:id="@+id/ll_empty"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight="6"
-                android:background="#F28B8C"
-                android:gravity="center"
+                android:layout_height="match_parent"
+                android:padding="12dp"
+                android:background="@mipmap/bg_empty_info"
                 android:orientation="vertical">
-
-                <ImageView
-                    android:id="@+id/view_main_layout_iv_doctor"
-                    android:layout_width="85dp"
-                    android:layout_height="85dp"
-                    android:scaleType="fitXY"
-                    android:src="@mipmap/ic_response_baby_care" />
-
                 <TextView
-                    android:id="@+id/view_main_layout_tv_doctor_name"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:layout_marginTop="@dimen/margin_to_side_5"
-                    android:text="--"
-                    android:textColor="@color/white"
-                    android:textSize="@dimen/font_size_20" />
-            </LinearLayout>
-
-            <TextView
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:background="#D4676A"
-                android:gravity="center"
-                android:text="护士"
-                android:textColor="@color/white"
-                android:textSize="@dimen/font_size_20" />
-
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight="6"
-                android:background="#F28B8C"
-                android:gravity="center"
-                android:orientation="vertical">
-
-                <ImageView
-                    android:id="@+id/view_main_layout_iv_nurse"
-                    android:layout_width="85dp"
-                    android:layout_height="85dp"
-                    android:scaleType="fitXY"
-                    android:src="@mipmap/ic_response_nurse" />
-
+                    android:layout_marginTop="10dp"
+                    android:text="空"
+                    android:textSize="48sp"
+                    android:textColor="@color/main_color"
+                    android:visibility="invisible"/>
                 <TextView
-                    android:id="@+id/view_main_layout_tv_nurse_name"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:layout_marginTop="@dimen/margin_to_side_5"
-                    android:text="--"
-                    android:textColor="@color/white"
-                    android:textSize="@dimen/font_size_20" />
+                    android:layout_marginTop="24dp"
+                    android:text="祝您安康!"
+                    android:textSize="56sp"
+                    android:textColor="@color/black"/>
             </LinearLayout>
 
+            <!--有人入住时展示-->
             <RelativeLayout
+                android:id="@+id/ll_custom_view"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight="2"
-                android:background="@drawable/shape_main_bg_doctor_bottom">
-
-                <com.wdkl.ncs.android.lib.widget.MarqueeTextView
-                    android:id="@+id/view_main_layout_tv_broadcasting"
+                android:layout_height="match_parent"
+                android:padding="16dp"
+                android:background="@color/white"
+                android:orientation="vertical"
+                android:visibility="gone">
+                <TextView
+                    android:id="@+id/tv_custom_name"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
-                    android:layout_centerInParent="true"
-                    android:layout_marginLeft="10dp"
-                    android:layout_marginTop="1dp"
-                    android:layout_marginRight="10dp"
-                    android:layout_marginBottom="1dp"
-                    android:background="@drawable/shape_main_bg_bottom_broadcasting"
+                    android:textSize="60sp"
+                    android:textColor="@color/main_color"
+                    android:text="---"/>
+                <TextView
+                    android:id="@+id/tv_custom_gender"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_toRightOf="@id/tv_custom_name"
+                    android:layout_alignBottom="@id/tv_custom_name"
+                    android:background="@mipmap/ic_gender_male"
+                    android:layout_marginLeft="20dp"
+                    android:layout_marginBottom="10dp"/>
+                <TextView
+                    android:id="@+id/tv_custom_age"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_toRightOf="@id/tv_custom_gender"
+                    android:layout_alignBottom="@id/tv_custom_name"
+                    android:layout_marginLeft="20dp"
+                    android:textSize="40sp"
+                    android:textColor="#B4B4B4"
+                    android:text="--岁"/>
+                <TextView
+                    android:id="@+id/tv_custom_indate"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@id/tv_custom_name"
+                    android:layout_marginTop="20dp"
+                    android:textSize="28sp"
+                    android:textColor="#B4B4B4"
+                    android:text="入院日期: "/>
+                <TextView
+                    android:id="@+id/tv_order_title"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@id/tv_custom_indate"
+                    android:layout_marginTop="20dp"
+                    android:padding="10dp"
+                    android:background="#F3F9FE"
+                    android:drawableLeft="@mipmap/ic_order"
+                    android:drawablePadding="10dp"
+                    android:textSize="24sp"
+                    android:textColor="@color/black"
+                    android:text="医嘱: "/>
+                <com.wdkl.ncs.android.lib.widget.MarqueeTextView
+                    android:id="@+id/tv_order_content"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_below="@id/tv_order_title"
+                    android:padding="10dp"
                     android:ellipsize="marquee"
                     android:focusable="true"
                     android:focusableInTouchMode="true"
-                    android:gravity="center"
                     android:marqueeRepeatLimit="marquee_forever"
-                    android:paddingLeft="10dp"
-                    android:paddingRight="10dp"
+                    android:scrollHorizontally="true"
                     android:singleLine="true"
-                    android:text=""
-                    android:textColor="#FCFF16"
-                    android:textSize="16sp"
-                    android:visibility="invisible" />
-
+                    android:background="#F3F9FE"
+                    android:scrollbars="vertical"
+                    android:fadeScrollbars="true"
+                    android:textSize="24sp"
+                    android:textColor="#131313"
+                    android:text="暂无"
+                    android:lineSpacingExtra="12dp"/>
             </RelativeLayout>
-        </LinearLayout>
+        </FrameLayout>
 
-        <include
-            android:id="@+id/view_main_layout_bottom"
-            layout="@layout/view_message_layout"/>
     </RelativeLayout>
-
-    <TextView
-        android:id="@+id/activity_calling_bed_layout_tv_version"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentRight="true"
-        android:layout_alignParentBottom="true"
-        android:layout_marginRight="10dp"
-        android:layout_marginBottom="16dp"
-        android:text="V0.0"
-        android:textColor="@color/white"
-        android:textSize="@dimen/font_size_18" />
-</RelativeLayout>
 </layout>

+ 86 - 26
callingbed/src/main/res/layout/qrcode_view.xml

@@ -1,36 +1,96 @@
 <?xml version="1.0" encoding="utf-8"?>
 <layout>
-    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    <RelativeLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="#FCADB1"
-        android:orientation="vertical">
-
-        <RelativeLayout
-            android:id="@+id/view_qr_code_layout_re"
-            android:layout_width="240dp"
-            android:layout_height="240dp"
-            android:layout_centerHorizontal="true"
-            android:layout_centerVertical="true"
+        android:layout_height="match_parent">
+
+        <include android:id="@+id/lay_qr_bed_name"
+            layout="@layout/view_bed_name"/>
+
+        <LinearLayout
+            android:id="@+id/ll_qr_code_view"
+            android:layout_width="340dp"
+            android:layout_height="match_parent"
+            android:layout_below="@id/lay_qr_bed_name"
+            android:layout_marginTop="6dp"
+            android:layout_marginBottom="6dp"
             android:background="@color/white"
             android:orientation="vertical">
-
             <ImageView
                 android:id="@+id/view_qr_code"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:layout_centerInParent="true" />
-        </RelativeLayout>
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/view_qr_code_layout_re"
-            android:layout_centerHorizontal="true"
-            android:layout_marginTop="8dp"
-            android:text="扫描二维码,下载APP绑定设备"
-            android:textColor="@color/white"
-            android:textSize="@dimen/font_size_20" />
+                android:layout_width="180dp"
+                android:layout_height="180dp"
+                android:layout_marginTop="10dp"
+                android:layout_gravity="center_horizontal"/>
+
+            <TextView
+                android:id="@+id/tv_device_id"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="40dp"
+                android:text="设备ID:"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+
+            <TextView
+                android:id="@+id/tv_local_ip"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:layout_marginLeft="40dp"
+                android:text="本机IP:"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+
+            <TextView
+                android:id="@+id/tv_local_mac"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:layout_marginLeft="40dp"
+                android:text="本机MAC:"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+
+            <TextView
+                android:id="@+id/tv_app_version"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:layout_marginLeft="40dp"
+                android:text="版本信息:"
+                android:textColor="@color/black"
+                android:textSize="20sp" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="@color/white"
+            android:layout_toRightOf="@id/ll_qr_code_view"
+            android:layout_below="@id/lay_qr_bed_name"
+            android:layout_marginTop="6dp"
+            android:layout_marginBottom="6dp"
+            android:layout_marginLeft="10dp"
+            android:padding="10dp"
+            android:orientation="vertical">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="产品说明:"
+                android:textColor="@color/black"
+                android:textSize="22sp" />
+
+            <TextView
+                android:id="@+id/tv_about_me"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:text="暂无"
+                android:textColor="#949494"
+                android:textSize="20sp" />
+        </LinearLayout>
 
     </RelativeLayout>
 </layout>

+ 17 - 0
callingbed/src/main/res/layout/view_bed_name.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="80dp">
+
+    <TextView
+        android:id="@+id/tv_bed_name"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/white"
+        android:paddingLeft="24dp"
+        android:gravity="center_vertical"
+        android:textColor="@color/main_color"
+        android:textSize="54sp"
+        android:text=""/>
+</LinearLayout>

+ 39 - 22
callingbed/src/main/res/layout/view_title_layout.xml

@@ -2,7 +2,7 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="42dp"
-    android:background="@mipmap/title_bg"
+    android:background="#FFFFFF"
     android:orientation="vertical">
 
     <!--SIP状态图标-->
@@ -11,7 +11,8 @@
         android:layout_width="12dp"
         android:layout_height="12dp"
         android:layout_centerVertical="true"
-        android:layout_marginLeft="20dp" />
+        android:layout_marginLeft="20dp"
+        android:background="@color/red_color"/>
 
     <!--医院名称-->
     <TextView
@@ -19,10 +20,10 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_centerVertical="true"
-        android:layout_marginLeft="10dp"
+        android:layout_marginLeft="20dp"
         android:layout_toRightOf="@+id/view_title_layout_tv_point"
         android:text="----"
-        android:textColor="@color/white"
+        android:textColor="@color/main_color"
         android:textSize="@dimen/font_size_20" />
 
     <!--日期时间-->
@@ -34,7 +35,7 @@
         android:layout_centerVertical="true"
         android:layout_marginRight="5dp"
         android:text="--"
-        android:textColor="@color/white"
+        android:textColor="@color/main_color"
         android:textSize="@dimen/font_size_20" />
 
     <!--设备号-->
@@ -46,40 +47,56 @@
         android:layout_marginRight="10dp"
         android:layout_toLeftOf="@+id/view_title_layout_ll_right"
         android:text=""
-        android:textColor="@color/white"
+        android:textColor="@color/main_color"
         android:textSize="@dimen/font_size_20" />
 
-    <!--网络状态图标-->
+    <!--状态图标-->
     <LinearLayout
         android:id="@+id/view_title_layout_ll_right"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentRight="true"
         android:layout_centerVertical="true"
-        android:layout_marginRight="20dp"
+        android:layout_marginRight="10dp"
         android:orientation="horizontal">
 
         <ImageView
-            android:id="@+id/view_title_layout_iv_current_trust"
-            android:layout_width="15dp"
-            android:layout_height="15dp"
+            android:id="@+id/view_title_layout_iv_bt"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="4dp"
+            android:layout_marginRight="4dp" />
+        <ImageView
+            android:id="@+id/view_title_layout_iv_wifi"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
             android:layout_gravity="center_vertical"
-            android:layout_marginLeft="2dp"
-            android:layout_marginRight="2dp" />
+            android:layout_marginLeft="4dp"
+            android:layout_marginRight="4dp" />
+        <ImageView
+            android:id="@+id/view_title_layout_iv_tcp"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="4dp"
+            android:layout_marginRight="4dp"
+            android:src="@mipmap/ic_tcp_fail"/>
         <ImageView
             android:id="@+id/view_title_layout_iv_ethernet"
-            android:layout_width="15dp"
-            android:layout_height="15dp"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
             android:layout_gravity="center_vertical"
-            android:layout_marginLeft="2dp"
-            android:layout_marginRight="2dp" />
+            android:layout_marginLeft="4dp"
+            android:layout_marginRight="4dp" />
         <ImageView
-            android:id="@+id/view_title_layout_iv_wifi"
-            android:layout_width="15dp"
-            android:layout_height="15dp"
+            android:id="@+id/view_title_layout_iv_day_night"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
             android:layout_gravity="center_vertical"
-            android:layout_marginLeft="2dp"
-            android:layout_marginRight="2dp" />
+            android:layout_marginLeft="4dp"
+            android:layout_marginRight="4dp"
+            android:src="@mipmap/ic_daylight"/>
 
     </LinearLayout>
 </RelativeLayout>

TEMPAT SAMPAH
callingbed/src/main/res/mipmap-hdpi/bg_right.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/bg_bottom_btn.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/bg_empty_info.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/bg_right.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_bt_fail.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_bt_success.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_call.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_cost.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_daylight.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_doctor_default.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_ethernet_fail.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_ethernet_success.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_gender_female.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_gender_male.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_hangup_normal.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_hangup_press.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_home.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_more.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_night.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_nurse_default.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_order.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_support.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_tcp_fail.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_tcp_success.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_wifi_fail.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-mdpi/ic_wifi_success.png


TEMPAT SAMPAH
callingbed/src/main/res/mipmap-xhdpi/bg_right.png


+ 1 - 1
callingbed/src/main/res/values/colors.xml

@@ -13,7 +13,7 @@
     <color name="drawer_item_bg_n">#fffff9</color>
     <color name="green">#00FF00</color>
 
-
+    <color name="main_color">#2F9DF1</color>
     <color name="content_color">#F3F3F3</color>
     <color name="transparent">#00000000</color>
     <!--title颜色-->

+ 18 - 0
common/build.gradle

@@ -151,6 +151,24 @@ dependencies {
      */
     kapt 'com.google.dagger:dagger-compiler:2.7'
 
+    //eventbus
+    compile 'org.greenrobot:eventbus:3.0.0'
+
+    /**
+     * netty
+     */
+    compile 'io.netty:netty-all:4.1.42.Final'
+
+    /**
+     * json
+     */
+    compile 'com.alibaba:fastjson:1.2.23'
+
+    /**
+     * google
+     */
+    compile 'com.google.guava:guava:23.0'
+
     /**
      *  七巧板框架
      */

+ 11 - 0
common/src/main/code/com/wdkl/ncs/android/lib/utils/TimeHandle.kt

@@ -67,4 +67,15 @@ object TimeHandle {
         val sdf = SimpleDateFormat(format)
         return sdf.format(date)
     }
+
+    //按指定格式获取指定日期时间
+    fun getDateTime(timeMillis: Long, format: String): String {
+        if (timeMillis > 0) {
+            val date = Date(timeMillis)
+            val sdf = SimpleDateFormat(format)
+            sdf.timeZone = TimeZone.getTimeZone("GMT+8")
+            return sdf.format(date)
+        }
+        return "null"
+    }
 }

+ 28 - 4
middleware/src/main/code/com/wdkl/ncs/android/middleware/api/CallingbedApi.kt

@@ -3,13 +3,37 @@ package com.wdkl.ncs.android.middleware.api
 import io.reactivex.Observable
 import okhttp3.ResponseBody
 import retrofit2.http.GET
+import retrofit2.http.POST
 import retrofit2.http.Path
+import retrofit2.http.Query
 
 interface CallingbedApi {
 
-    @GET("/ncs/customer/{customer_id}")
-    fun getBedData(@Path("customer_id") customerId :Int): Observable<ResponseBody>
+    //设备信息
+    @GET("/deviceBed/getBedDeviceInfoByEthMac/{ethMac}")
+    fun getDeviceInfo(@Path("ethMac") ethMac :String): Observable<ResponseBody>
 
-    @GET("/ncs/device/{device_mac}")
-    fun getDeviceInfo(@Path("device_mac") deviceMac :String): Observable<ResponseBody>
+    //入住信息
+    @GET("/deviceBed/getCustomerInfo/{customerId}")
+    fun getCustomInfo(@Path("customerId") customerId :Int): Observable<ResponseBody>
+
+    //费用信息
+    @GET("/deviceBed/getCustomerFeeConfigByGroupName/{customerId}")
+    fun getCustomCost(@Path("customerId") customerId :Int): Observable<ResponseBody>
+
+    //事件信息
+    @GET("/deviceBed/getEventList")
+    fun getEventList(): Observable<ResponseBody>
+
+    //呼叫历史
+    @POST("/deviceBed/getInteractionVOByCustomerId")
+    fun getCallRecords(@Query("page_no")page_no:Int, @Query("page_size")page_size:Int, @Query("customer_id")part_id:Int): Observable<ResponseBody>
+
+    //科室设置参数
+    @GET("/deviceBed/getPartSetting/{partId}")
+    fun getPartSettings(@Path("partId") partId : Int): Observable<ResponseBody>
+
+    //tcp服务器地址
+    @GET("/ncs_url/getHostIP")
+    fun getTcpServerHost(): Observable<ResponseBody>
 }

+ 96 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/common/Constant.java

@@ -0,0 +1,96 @@
+package com.wdkl.ncs.android.middleware.common;
+
+public class Constant {
+
+    //TCP服务器地址:
+    public static String TCP_SERVER_URL = "47.106.200.55";
+
+    //数据接口端口:
+    public static int URL_PORT = 8006;
+
+    //TCP服务端口
+    public static int TCP_PORT = 5080;
+
+    //TCP服务连接心跳
+    public static int TCP_HEART_BEAT = 9;
+
+    //TCP连接是否成功
+    public static boolean TCP_CONNECTED = false;
+
+    //语音留言上传地址
+    public static final String UPLOAD_VOICE_MSG_URL = "/ncs/upload/File";
+
+    //分机呼叫超时时间,默认30s
+    public static int CALL_TIMEOUT = 30;
+
+    //待机
+    public final static int CALL_STANDBY = 0;
+
+    //呼叫中
+    public final static int CALL_OUTGOING = 1;
+
+    //来电中
+    public final static int CALL_INCOMING = 2;
+
+    //通话中
+    public final static int CALL_CALLING = 3;
+
+    //通话状态
+    public static int CALL_STATE = CALL_STANDBY;
+
+    //MAC地址
+    public static String LOCAL_MAC = "";
+
+    //设备ID
+    public static Integer DEVICE_ID;
+
+    //客户ID
+    public static Integer CUSTOM_ID = -1;
+
+    //SIP host
+    public static String SIP_HOST = "192.168.101.1";
+
+    //SIP ID
+    public static String SIP_ID = "";
+
+    //科室id
+    public static Integer PART_ID;
+
+    //床位名称
+    public static String BED_NAME = "";
+
+    /**
+     * Sip注册状态
+     */
+    public static final int EVENT_SIP_REGISTER_STATUS = 0x01;
+
+    /**
+     * Sip通话状态
+     */
+    public static final int EVENT_SIP_CALL_STATUS = 0x02;
+
+    /**
+     * 以太网ping状态
+     */
+    public static final int EVENT_INTERNETPING = 0x03;
+
+    /**
+     * 返回主fragment
+     */
+    public static final int EVENT_BACK_MAIN = 0x04;
+
+    /**
+     * TCP消息
+     */
+    public static final int EVENT_TCP_MSG = 0x05;
+
+    /**
+     * TCP连接状态
+     */
+    public static final int EVENT_TCP_STATE = 0x06;
+
+    /**
+     * 刷新客户信息
+     */
+    public static final int EVENT_UPDATE_CUSTOM = 0x07;
+}

+ 1 - 1
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/common/MessageEvent.java

@@ -1,4 +1,4 @@
-package com.wdkl.app.ncs.callingbed.common;
+package com.wdkl.ncs.android.middleware.common;
 
 /**
  * Created by Administrator on 2016/8/15 0015.

+ 20 - 2
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/contract/callingbed/CallingbedActivityContract.kt

@@ -1,16 +1,34 @@
 package com.wdkl.ncs.android.middleware.logic.contract.callingbed
 
 import com.wdkl.ncs.android.lib.base.BaseContract
+import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
+import com.wdkl.ncs.android.middleware.model.dto.TcpSeverDTO
+import com.wdkl.ncs.android.middleware.model.vo.BedDeviceInfoVO
 import com.wdkl.ncs.android.middleware.model.vo.CustomerInfoVO
 
 //定义接口
 interface CallingbedActivityContract {
 
     interface View :BaseContract.BaseView {
-        fun showData(customInfo :CustomerInfoVO)
+
+        fun showDeviceInfo(deviceInfo: BedDeviceInfoVO)
+
+        fun setPartSettings(partSetting : PartSettingDO)
+
+        fun setTcpServerHost(tcpSeverDTO: TcpSeverDTO)
+
+        fun onNoNet()
     }
 
     interface Presenter :BaseContract.BasePresenter {
-        fun loadData(bedId :Int)
+
+        //获取设备信息
+        fun loadDeviceInfo(mac: String)
+
+        //获取设置参数
+        fun loadPartSettings(partId: Int)
+
+        //获取tcp服务器地址
+        fun loadTcpServerHost()
     }
 }

+ 6 - 2
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/contract/callingbed/CostFragmentContract.kt

@@ -1,16 +1,20 @@
 package com.wdkl.ncs.android.middleware.logic.contract.callingbed
 
 import com.wdkl.ncs.android.lib.base.BaseContract
+import com.wdkl.ncs.android.middleware.model.vo.CustomerFeeConfigByGroupNameVO
 
 interface CostFragmentContract {
     interface View : BaseContract.BaseView {
 
-        fun showData(data: ArrayList<Any>)
+        fun showCustomCost(cost: ArrayList<CustomerFeeConfigByGroupNameVO>)
+
+        fun onNoNet()
     }
 
     interface Presenter : BaseContract.BasePresenter {
 
-        fun loadData()
+        //获取客户费用信息
+        fun loadCustomCost(customId: Int)
 
     }
 }

+ 6 - 2
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/contract/callingbed/MainFragmentContract.kt

@@ -1,17 +1,21 @@
 package com.wdkl.ncs.android.middleware.logic.contract.callingbed
 
 import com.wdkl.ncs.android.lib.base.BaseContract
+import com.wdkl.ncs.android.middleware.model.vo.CustomerInfoVO
 
 interface MainFragmentContract {
 
     interface View : BaseContract.BaseView {
 
-        fun showData(data: ArrayList<Any>)
+        fun showCustomInfo(customInfo: CustomerInfoVO)
+
+        fun onNoNet()
     }
 
     interface Presenter : BaseContract.BasePresenter {
 
-        fun loadData()
+        //获取病人信息
+        fun loadCustomInfo(customId: Int)
 
     }
 }

+ 57 - 8
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/callingbed/CallingbedActivityPresenter.kt

@@ -11,6 +11,9 @@ import com.wdkl.ncs.android.lib.utils.getJsonString
 import com.wdkl.ncs.android.middleware.api.CallingbedApi
 import com.wdkl.ncs.android.middleware.di.MiddlewareDaggerComponent
 import com.wdkl.ncs.android.middleware.logic.contract.callingbed.CallingbedActivityContract
+import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
+import com.wdkl.ncs.android.middleware.model.dto.TcpSeverDTO
+import com.wdkl.ncs.android.middleware.model.vo.BedDeviceInfoVO
 import com.wdkl.ncs.android.middleware.model.vo.CustomerInfoVO
 import io.reactivex.disposables.Disposable
 import javax.inject.Inject
@@ -22,7 +25,7 @@ class CallingbedActivityPresenter @Inject constructor() :RxPresenter<CallingbedA
     }
 
     @Inject
-    protected lateinit var callingbedApi: CallingbedApi
+    protected lateinit var bedDeviceApi: CallingbedApi
 
     private val observer = object :ConnectionObserver<Any>() {
         override fun onStartWithConnection() {
@@ -30,8 +33,25 @@ class CallingbedActivityPresenter @Inject constructor() :RxPresenter<CallingbedA
         }
 
         override fun onNextWithConnection(result: Any, connectionQuality: ConnectionQuality) {
-            providerView().complete("")
-            providerView().showData(result as CustomerInfoVO)
+            when (result) {
+                is BedDeviceInfoVO -> {
+                    //设备信息
+                    providerView().complete("")
+                    providerView().showDeviceInfo(result)
+                }
+
+                is PartSettingDO -> {
+                    //设置参数
+                    providerView().complete("")
+                    providerView().setPartSettings(result)
+                }
+
+                is TcpSeverDTO -> {
+                    //tcp服务器地址
+                    providerView().complete("")
+                    providerView().setTcpServerHost(result)
+                }
+            }
         }
 
         override fun onErrorWithConnection(error: ExceptionHandle.ResponeThrowable, connectionQuality: ConnectionQuality) {
@@ -41,15 +61,44 @@ class CallingbedActivityPresenter @Inject constructor() :RxPresenter<CallingbedA
         override fun attachSubscribe(var1: Disposable) {
             addDisposable(var1)
         }
+
+        override fun onNoneNet() {
+            super.onNoneNet()
+            providerView().onNoNet()
+        }
+    }
+
+    override fun loadDeviceInfo(mac: String) {
+        bedDeviceApi.getDeviceInfo(mac)
+                .map {
+                    val gson = GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()
+                    val deviceInfo = gson.fromJson(it.getJsonString(), BedDeviceInfoVO::class.java)
+
+                    return@map deviceInfo
+                }
+                .compose(ThreadFromUtils.defaultSchedulers())
+                .subscribe(observer)
+    }
+
+    override fun loadPartSettings(partId: Int) {
+        bedDeviceApi.getPartSettings(partId)
+                .map {
+                    val gson = GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()
+                    val settings = gson.fromJson(it.getJsonString(), PartSettingDO::class.java)
+
+                    return@map settings
+                }
+                .compose(ThreadFromUtils.defaultSchedulers())
+                .subscribe(observer)
     }
 
-    override fun loadData(bedId: Int) {
-        callingbedApi.getBedData(bedId)
+    override fun loadTcpServerHost() {
+        bedDeviceApi.getTcpServerHost()
                 .map {
-                    var gson = GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()
-                    var customerInfoVO = gson.fromJson(it.getJsonString(), CustomerInfoVO::class.java)
+                    val gson = GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()
+                    val tcpServer = gson.fromJson(it.getJsonString(), TcpSeverDTO::class.java)
 
-                    return@map customerInfoVO
+                    return@map tcpServer
                 }
                 .compose(ThreadFromUtils.defaultSchedulers())
                 .subscribe(observer)

+ 34 - 7
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/callingbed/CostFragmentPresenter.kt

@@ -2,27 +2,38 @@ package com.wdkl.ncs.android.middleware.logic.presenter.callingbed
 
 import com.enation.javashop.net.engine.plugin.connection.ConnectionQuality
 import com.enation.javashop.net.engine.plugin.exception.ExceptionHandle
+import com.enation.javashop.net.engine.utils.ThreadFromUtils
+import com.google.gson.FieldNamingPolicy
+import com.google.gson.GsonBuilder
+import com.google.gson.reflect.TypeToken
 import com.wdkl.ncs.android.lib.base.RxPresenter
 import com.wdkl.ncs.android.lib.utils.ConnectionObserver
+import com.wdkl.ncs.android.lib.utils.getJsonString
+import com.wdkl.ncs.android.middleware.api.CallingbedApi
 import com.wdkl.ncs.android.middleware.di.MiddlewareDaggerComponent
 import com.wdkl.ncs.android.middleware.logic.contract.callingbed.CostFragmentContract
+import com.wdkl.ncs.android.middleware.model.vo.CustomerFeeConfigByGroupNameVO
 import io.reactivex.disposables.Disposable
 import javax.inject.Inject
 
 class CostFragmentPresenter @Inject constructor() : RxPresenter<CostFragmentContract.View>(), CostFragmentContract.Presenter {
+
+    @Inject
+    protected lateinit var bedDeviceApi : CallingbedApi
+
     /**
      * @Name  observer
      * @Type  ConnectionObserver
      * @Note  数据监听者
      */
-    private val observer = object : ConnectionObserver<ArrayList<Any>>() {
+    private val observer = object : ConnectionObserver<Any>() {
         override fun onStartWithConnection() {
-            providerView()
+            providerView().start()
         }
 
-        override fun onNextWithConnection(result: ArrayList<Any>, connectionQuality: ConnectionQuality) {
-            providerView().complete()
-            providerView().showData(result)
+        override fun onNextWithConnection(result: Any, connectionQuality: ConnectionQuality) {
+            providerView().complete("")
+            providerView().showCustomCost(result as ArrayList<CustomerFeeConfigByGroupNameVO>)
         }
 
         override fun onErrorWithConnection(error: ExceptionHandle.ResponeThrowable, connectionQuality: ConnectionQuality) {
@@ -32,6 +43,12 @@ class CostFragmentPresenter @Inject constructor() : RxPresenter<CostFragmentCont
         override fun attachSubscribe(var1: Disposable) {
             addDisposable(var1)
         }
+
+
+        override fun onNoneNet() {
+            super.onNoneNet()
+            providerView().onNoNet()
+        }
     }
 
 
@@ -39,7 +56,17 @@ class CostFragmentPresenter @Inject constructor() : RxPresenter<CostFragmentCont
         MiddlewareDaggerComponent.component.inject(this)
     }
 
-    override fun loadData() {
-        //
+    override fun loadCustomCost(customId: Int) {
+        bedDeviceApi.getCustomCost(customId)
+                .map {
+                    val data = it.getJsonString()
+                    val gson = GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()
+                    val itemType = object : TypeToken<ArrayList<CustomerFeeConfigByGroupNameVO>>(){}.type
+                    val customCostVO = gson.fromJson<ArrayList<CustomerFeeConfigByGroupNameVO>>(data, itemType)
+
+                    return@map customCostVO
+                }
+                .compose(ThreadFromUtils.defaultSchedulers())
+                .subscribe(observer)
     }
 }

+ 29 - 8
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/callingbed/MainFragmentPresenter.kt

@@ -1,15 +1,20 @@
 package com.wdkl.ncs.android.middleware.logic.presenter.callingbed
 
+import android.util.Log
 import com.enation.javashop.net.engine.plugin.connection.ConnectionQuality
 import com.enation.javashop.net.engine.plugin.exception.ExceptionHandle
 import com.enation.javashop.net.engine.utils.ThreadFromUtils
+import com.google.gson.FieldNamingPolicy
+import com.google.gson.GsonBuilder
 import com.wdkl.ncs.android.lib.base.RxPresenter
 import com.wdkl.ncs.android.lib.utils.*
+import com.wdkl.ncs.android.middleware.api.CallingbedApi
 import com.wdkl.ncs.android.middleware.api.ExtraApi
 import com.wdkl.ncs.android.middleware.api.PromotionApi
 import com.wdkl.ncs.android.middleware.di.MiddlewareDaggerComponent
 import com.wdkl.ncs.android.middleware.logic.contract.callingbed.MainFragmentContract
 import com.wdkl.ncs.android.middleware.model.*
+import com.wdkl.ncs.android.middleware.model.vo.CustomerInfoVO
 import io.reactivex.Observable
 import io.reactivex.disposables.Disposable
 import org.json.JSONArray
@@ -18,19 +23,22 @@ import javax.inject.Inject
 
 class MainFragmentPresenter @Inject constructor() : RxPresenter<MainFragmentContract.View>(), MainFragmentContract.Presenter  {
 
+    @Inject
+    protected lateinit var bedDeviceApi : CallingbedApi
+
     /**
      * @Name  observer
      * @Type  ConnectionObserver
      * @Note  数据监听者
      */
-    private val observer = object : ConnectionObserver<ArrayList<Any>>() {
+    private val observer = object : ConnectionObserver<Any>() {
         override fun onStartWithConnection() {
-            providerView()
+            providerView().start()
         }
 
-        override fun onNextWithConnection(result: ArrayList<Any>, connectionQuality: ConnectionQuality) {
-            providerView().complete()
-            providerView().showData(result)
+        override fun onNextWithConnection(result: Any, connectionQuality: ConnectionQuality) {
+            providerView().complete("")
+            providerView().showCustomInfo(result as CustomerInfoVO)
         }
 
         override fun onErrorWithConnection(error: ExceptionHandle.ResponeThrowable, connectionQuality: ConnectionQuality) {
@@ -40,6 +48,12 @@ class MainFragmentPresenter @Inject constructor() : RxPresenter<MainFragmentCont
         override fun attachSubscribe(var1: Disposable) {
             addDisposable(var1)
         }
+
+        override fun onNoneNet() {
+            Log.d("MainFragmentPresenter", "onNoneNet...")
+            super.onNoneNet()
+            providerView().onNoNet()
+        }
     }
 
 
@@ -47,8 +61,15 @@ class MainFragmentPresenter @Inject constructor() : RxPresenter<MainFragmentCont
         MiddlewareDaggerComponent.component.inject(this)
     }
 
-    override fun loadData() {
-        //
-    }
+    override fun loadCustomInfo(customId: Int) {
+        bedDeviceApi.getCustomInfo(customId)
+                .map {
+                    val gson = GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create()
+                    val customerInfoVO = gson.fromJson(it.getJsonString(), CustomerInfoVO::class.java)
 
+                    return@map customerInfoVO
+                }
+                .compose(ThreadFromUtils.defaultSchedulers())
+                .subscribe(observer)
+    }
 }

+ 56 - 20
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dos/DeviceDO.java

@@ -2,8 +2,6 @@ package com.wdkl.ncs.android.middleware.model.dos;
 
 import com.fasterxml.jackson.databind.PropertyNamingStrategy;
 import com.fasterxml.jackson.databind.annotation.JsonNaming;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
 import com.wdkl.ncs.android.middleware.model.annotation.Column;
 import com.wdkl.ncs.android.middleware.model.annotation.Id;
 import com.wdkl.ncs.android.middleware.model.annotation.PrimaryKeyField;
@@ -11,6 +9,9 @@ import com.wdkl.ncs.android.middleware.model.annotation.Table;
 
 import java.io.Serializable;
 
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
 @Table(name = "ncs_device")
 @ApiModel
 @JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)
@@ -107,6 +108,11 @@ public class DeviceDO implements Serializable {
     @ApiModelProperty(value = "该设备的有线以太网卡分配的IP地址", required = false)
     private String ethIp;
     /**
+     *	该设备的有线以太网卡分配的IP地址端口
+     */	@Column(name = "eth_ip_port" )
+    @ApiModelProperty(value="该设备的有线以太网卡分配的IP地址端口",required=false)
+    private String ethIpPort;
+    /**
      * 该设备的WIFI网卡MAC地址
      */
     @Column(name = "wifi_mac")
@@ -135,7 +141,7 @@ public class DeviceDO implements Serializable {
      */
     @Column(name = "status")
     @ApiModelProperty(value = "该设备是否启用状态:false:表示未启用,设备不进入主界面。true:表示已开启正常使用。", required = false)
-    private String status;
+    private Integer status;
     /**
      * SIP服务器IP地址
      */
@@ -159,7 +165,7 @@ public class DeviceDO implements Serializable {
      */
     @Column(name = "sip_status")
     @ApiModelProperty(value = "表示SIP账号状态:true:可以使用   false:暂停使用", required = false)
-    private String sipStatus;
+    private Boolean sipStatus;
     /**
      * null
      */
@@ -170,12 +176,21 @@ public class DeviceDO implements Serializable {
      *	是否为后备,空或否时为并行
      */	@Column(name = "bool_backup" )
     @ApiModelProperty(value="是否为后备,空或否时为并行",required=false)
-    private String boolBackup;
+    private Boolean boolBackup;
     /**
      *	后备哪个设备,设备id
      */	@Column(name = "backup_id" )
     @ApiModelProperty(value="后备哪个设备,设备id",required=false)
     private Integer backupId;
+    /**
+     *	null
+     */	@Column(name = "priority" )
+    @ApiModelProperty(value="null",required=false)
+    private Integer priority;
+
+    @Column(name = "full_name")
+    @ApiModelProperty(value = "病房病床名称", required = false)
+    private String fullName; // 空间结构全名
 
 
     @PrimaryKeyField
@@ -314,6 +329,14 @@ public class DeviceDO implements Serializable {
     }
 
 
+    public String getEthIpPort() {
+        return ethIpPort;
+    }
+
+    public void setEthIpPort(String ethIpPort) {
+        this.ethIpPort = ethIpPort;
+    }
+
     public String getWifiMac() {
         return wifiMac;
     }
@@ -350,15 +373,14 @@ public class DeviceDO implements Serializable {
     }
 
 
-    public String getStatus() {
+    public Integer getStatus() {
         return status;
     }
 
-    public void setStatus(String status) {
+    public void setStatus(Integer status) {
         this.status = status;
     }
 
-
     public String getSipIp() {
         return sipIp;
     }
@@ -386,15 +408,6 @@ public class DeviceDO implements Serializable {
     }
 
 
-    public String getSipStatus() {
-        return sipStatus;
-    }
-
-    public void setSipStatus(String sipStatus) {
-        this.sipStatus = sipStatus;
-    }
-
-
     public Integer getMemberId() {
         return memberId;
     }
@@ -404,15 +417,22 @@ public class DeviceDO implements Serializable {
     }
 
 
-    public String getBoolBackup() {
+    public Boolean getSipStatus() {
+        return sipStatus;
+    }
+
+    public void setSipStatus(Boolean sipStatus) {
+        this.sipStatus = sipStatus;
+    }
+
+    public Boolean getBoolBackup() {
         return boolBackup;
     }
 
-    public void setBoolBackup(String boolBackup) {
+    public void setBoolBackup(Boolean boolBackup) {
         this.boolBackup = boolBackup;
     }
 
-
     public Integer getBackupId() {
         return backupId;
     }
@@ -420,4 +440,20 @@ public class DeviceDO implements Serializable {
     public void setBackupId(Integer backupId) {
         this.backupId = backupId;
     }
+
+    public String getFullName() {
+        return fullName;
+    }
+
+    public void setFullName(String fullName) {
+        this.fullName = fullName;
+    }
+
+    public Integer getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Integer priority) {
+        this.priority = priority;
+    }
 }

+ 364 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dos/InteractionDO.java

@@ -0,0 +1,364 @@
+package com.wdkl.ncs.android.middleware.model.dos;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import com.wdkl.ncs.android.middleware.model.annotation.Column;
+import com.wdkl.ncs.android.middleware.model.annotation.Id;
+import com.wdkl.ncs.android.middleware.model.annotation.PrimaryKeyField;
+import com.wdkl.ncs.android.middleware.model.annotation.Table;
+
+import java.io.Serializable;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@Table(name = "ncs_interaction")
+@ApiModel
+@JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)
+public class InteractionDO implements Serializable {
+
+    /**
+     * id
+     */
+    @Column(name = "id")
+    @ApiModelProperty(value = "id", required = false)
+    @Id(name = "id")
+    private Integer id;
+    /**
+     * union_id,线下线上同步ID
+     */
+    @Column(name = "union_id")
+    @ApiModelProperty(value = "union_id,线下线上同步ID", required = false)
+    private String unionId;
+    /**
+     * 创建时间
+     */
+    @Column(name = "create_date")
+    @ApiModelProperty(value = "创建时间", required = false)
+    private Long createDate;
+    /**
+     * 科室Id
+     */
+    @Column(name = "part_id")
+    @ApiModelProperty(value = "科室Id", required = false)
+    private Integer partId;
+    /**
+     * 交互类型(1:语音通话,2:视频通话,3:卫生间紧急呼叫,4:语音留言,5:文本消息,6:按键事件)
+     */
+    @Column(name = "action_type")
+    @ApiModelProperty(value = "交互类型(1:语音通话,2:视频通话,3:卫生间紧急呼叫,4:语音留言,5:文本消息,6:按键事件)", required = false)
+    private String actionType;
+    /**
+     * SUCCESS、FAILED
+     */
+    @Column(name = "action_result")
+    @ApiModelProperty(value = "0失败,1成功", required = false)
+    private Integer actionResult;
+    /**
+     * 交互发起设备Id
+     */
+    @Column(name = "from_device_id")
+    @ApiModelProperty(value = "交互发起设备Id", required = false)
+    private Integer fromDeviceId;
+    /**
+     * 交互对象设备Id
+     */
+    @Column(name = "to_device_id")
+    @ApiModelProperty(value = "交互对象设备Id", required = false)
+    private Integer toDeviceId;
+    /**
+     * 发起设备所在空间结构
+     */
+    @Column(name = "from_device_frame_id")
+    @ApiModelProperty(value = "发起设备所在空间结构", required = false)
+    private Integer fromDeviceFrameId;
+    /**
+     * 交互对象所在空间结果
+     */
+    @Column(name = "to_device_frame_id")
+    @ApiModelProperty(value = "交互对象所在空间结果", required = false)
+    private Integer toDeviceFrameId;
+    /**
+     * 交互发起设备使用者member_id
+     */
+    @Column(name = "from_device_member_id")
+    @ApiModelProperty(value = "交互发起设备使用者member_id", required = false)
+    private Integer fromDeviceMemberId;
+    /**
+     * 交互对象设备使用者member_id
+     */
+    @Column(name = "to_device_member_id")
+    @ApiModelProperty(value = "交互对象设备使用者member_id", required = false)
+    private Integer toDeviceMemberId;
+    /**
+     * 是否为呼叫系统内部交互(如果是外部电话呼叫为true,否则为false)
+     */
+    @Column(name = "outerior_action")
+    @ApiModelProperty(value = "是否为呼叫系统内部交互(如果是外部电话呼叫为true,否则为false)", required = false)
+    private Boolean outeriorAction;
+    /**
+     * 外部呼叫时的来电号码(根据此号码查询member,并设置from_device信息)
+     */
+    @Column(name = "outerior_action_number")
+    @ApiModelProperty(value = "外部呼叫时的来电号码(根据此号码查询member,并设置from_device信息)", required = false)
+    private String outeriorActionNumber;
+    /**
+     * 外部交互者的用户id
+     */
+    @Column(name = "outerior_action_member_id")
+    @ApiModelProperty(value = "外部交互者的用户id", required = false)
+    private Long outeriorActionMemberId;
+    /**
+     * 备注Id
+     */
+    @Column(name = "remark_id")
+    @ApiModelProperty(value = "备注Id", required = false)
+    private Integer remarkId;
+    /**
+     * 交互开始时间(通话时指通话接通时间,与create_time相同)
+     */
+    @Column(name = "action_start")
+    @ApiModelProperty(value = "交互开始时间(通话时指通话接通时间,与create_time相同)", required = false)
+    private Long actionStart;
+    /**
+     * 应答时间
+     */
+    @Column(name = "action_accept")
+    @ApiModelProperty(value = "应答时间", required = false)
+    private Long actionAccept;
+    /**
+     * 交互结束时间(通话时指通话挂断时间,通话挂断后要更新此字段)。事件响应时间、语音已读时间
+     */
+    @Column(name = "action_end")
+    @ApiModelProperty(value = "交互结束时间(通话时指通话挂断时间,通话挂断后要更新此字段)。事件响应时间、语音已读时间", required = false)
+    private Long actionEnd;
+    /**
+     * 交互数据(类型1,2,3为空)(类型4为音频文件地址)(5为文本内容)(类型6为具体按键类型)
+     */
+    @Column(name = "data")
+    @ApiModelProperty(value = "交互数据(类型1,2,3为空)(类型4为音频文件地址)(5为文本内容)(类型6为具体按键类型)", required = false)
+    private String data;
+    /**
+     * 交互错误代码
+     */
+    @Column(name = "error_code")
+    @ApiModelProperty(value = "交互错误代码", required = false)
+    private String errorCode;
+    /**
+     * 交互错误描述
+     */
+    @Column(name = "error_message")
+    @ApiModelProperty(value = "交互错误描述", required = false)
+    private String errorMessage;
+
+    @Column(name = "action_direction_type")
+    @ApiModelProperty(value = "交互方向类型(1:分机到主机、腕表、医生机,2:主机、腕表、医生机到分机,3主机、腕表、医生机之间互通,4:分机到分机)",required = false)
+    private Integer actionDirectionType;
+
+
+    @PrimaryKeyField
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+
+    public String getUnionId() {
+        return unionId;
+    }
+
+    public void setUnionId(String unionId) {
+        this.unionId = unionId;
+    }
+
+
+    public Long getCreateDate() {
+        return createDate;
+    }
+
+    public void setCreateDate(Long createDate) {
+        this.createDate = createDate;
+    }
+
+
+    public Integer getPartId() {
+        return partId;
+    }
+
+    public void setPartId(Integer partId) {
+        this.partId = partId;
+    }
+
+
+    public String getActionType() {
+        return actionType;
+    }
+
+    public void setActionType(String actionType) {
+        this.actionType = actionType;
+    }
+
+
+    public Integer getActionResult() {
+        return actionResult;
+    }
+
+    public void setActionResult(Integer actionResult) {
+        this.actionResult = actionResult;
+    }
+
+
+    public Integer getFromDeviceId() {
+        return fromDeviceId;
+    }
+
+    public void setFromDeviceId(Integer fromDeviceId) {
+        this.fromDeviceId = fromDeviceId;
+    }
+
+
+    public Integer getToDeviceId() {
+        return toDeviceId;
+    }
+
+    public void setToDeviceId(Integer toDeviceId) {
+        this.toDeviceId = toDeviceId;
+    }
+
+
+    public Integer getFromDeviceFrameId() {
+        return fromDeviceFrameId;
+    }
+
+    public void setFromDeviceFrameId(Integer fromDeviceFrameId) {
+        this.fromDeviceFrameId = fromDeviceFrameId;
+    }
+
+
+    public Integer getToDeviceFrameId() {
+        return toDeviceFrameId;
+    }
+
+    public void setToDeviceFrameId(Integer toDeviceFrameId) {
+        this.toDeviceFrameId = toDeviceFrameId;
+    }
+
+
+    public Integer getFromDeviceMemberId() {
+        return fromDeviceMemberId;
+    }
+
+    public void setFromDeviceMemberId(Integer fromDeviceMemberId) {
+        this.fromDeviceMemberId = fromDeviceMemberId;
+    }
+
+
+    public Integer getToDeviceMemberId() {
+        return toDeviceMemberId;
+    }
+
+    public void setToDeviceMemberId(Integer toDeviceMemberId) {
+        this.toDeviceMemberId = toDeviceMemberId;
+    }
+
+
+    public Boolean getOuteriorAction() {
+        return outeriorAction;
+    }
+
+    public void setOuteriorAction(Boolean outeriorAction) {
+        this.outeriorAction = outeriorAction;
+    }
+
+
+    public String getOuteriorActionNumber() {
+        return outeriorActionNumber;
+    }
+
+    public void setOuteriorActionNumber(String outeriorActionNumber) {
+        this.outeriorActionNumber = outeriorActionNumber;
+    }
+
+
+    public Long getOuteriorActionMemberId() {
+        return outeriorActionMemberId;
+    }
+
+    public void setOuteriorActionMemberId(Long outeriorActionMemberId) {
+        this.outeriorActionMemberId = outeriorActionMemberId;
+    }
+
+
+    public Integer getRemarkId() {
+        return remarkId;
+    }
+
+    public void setRemarkId(Integer remarkId) {
+        this.remarkId = remarkId;
+    }
+
+
+    public Long getActionStart() {
+        return actionStart;
+    }
+
+    public void setActionStart(Long actionStart) {
+        this.actionStart = actionStart;
+    }
+
+
+    public Long getActionAccept() {
+        return actionAccept;
+    }
+
+    public void setActionAccept(Long actionAccept) {
+        this.actionAccept = actionAccept;
+    }
+
+
+    public Long getActionEnd() {
+        return actionEnd;
+    }
+
+    public void setActionEnd(Long actionEnd) {
+        this.actionEnd = actionEnd;
+    }
+
+
+    public String getData() {
+        return data;
+    }
+
+    public void setData(String data) {
+        this.data = data;
+    }
+
+
+    public String getErrorCode() {
+        return errorCode;
+    }
+
+    public void setErrorCode(String errorCode) {
+        this.errorCode = errorCode;
+    }
+
+
+    public String getErrorMessage() {
+        return errorMessage;
+    }
+
+    public void setErrorMessage(String errorMessage) {
+        this.errorMessage = errorMessage;
+    }
+
+    public Integer getActionDirectionType() {
+        return actionDirectionType;
+    }
+
+    public void setActionDirectionType(Integer actionDirectionType) {
+        this.actionDirectionType = actionDirectionType;
+    }
+}

+ 3 - 2
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dos/NurseConfigDO.java

@@ -2,8 +2,6 @@ package com.wdkl.ncs.android.middleware.model.dos;
 
 import com.fasterxml.jackson.databind.PropertyNamingStrategy;
 import com.fasterxml.jackson.databind.annotation.JsonNaming;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
 import com.wdkl.ncs.android.middleware.model.annotation.Column;
 import com.wdkl.ncs.android.middleware.model.annotation.Id;
 import com.wdkl.ncs.android.middleware.model.annotation.PrimaryKeyField;
@@ -11,6 +9,9 @@ import com.wdkl.ncs.android.middleware.model.annotation.Table;
 
 import java.io.Serializable;
 
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
 @Table(name = "ncs_nurse_config")
 @ApiModel
 @JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)

+ 80 - 86
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dos/PartSettingDO.java

@@ -2,8 +2,6 @@ package com.wdkl.ncs.android.middleware.model.dos;
 
 import com.fasterxml.jackson.databind.PropertyNamingStrategy;
 import com.fasterxml.jackson.databind.annotation.JsonNaming;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
 import com.wdkl.ncs.android.middleware.model.annotation.Column;
 import com.wdkl.ncs.android.middleware.model.annotation.Id;
 import com.wdkl.ncs.android.middleware.model.annotation.PrimaryKeyField;
@@ -11,6 +9,9 @@ import com.wdkl.ncs.android.middleware.model.annotation.Table;
 
 import java.io.Serializable;
 
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
 @Table(name = "ncs_part_setting")
 @ApiModel
 @JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)
@@ -58,55 +59,55 @@ public class PartSettingDO implements Serializable {
      */
     @Column(name = "day_light")
     @ApiModelProperty(value = "白天背光亮度", required = false)
-    private Boolean dayLight;
+    private Integer dayLight;
     /**
      * 白天通话音量
      */
     @Column(name = "day_vol")
     @ApiModelProperty(value = "白天通话音量", required = false)
-    private Boolean dayVol;
+    private Integer dayVol;
     /**
      * 白天响铃音量
      */
     @Column(name = "day_ring_vol")
     @ApiModelProperty(value = "白天响铃音量", required = false)
-    private Boolean dayRingVol;
+    private Integer dayRingVol;
     /**
      * 白天响铃次数
      */
     @Column(name = "day_ring_times")
     @ApiModelProperty(value = "白天响铃次数", required = false)
-    private Boolean dayRingTimes;
+    private Integer dayRingTimes;
     /**
      * 白天护理灯亮度
      */
     @Column(name = "day_nurse_led")
     @ApiModelProperty(value = "白天护理灯亮度", required = false)
-    private Boolean dayNurseLed;
+    private Integer dayNurseLed;
     /**
      * 白天门口机通话音量
      */
     @Column(name = "day_door_vol")
     @ApiModelProperty(value = "白天门口机通话音量", required = false)
-    private Boolean dayDoorVol;
+    private Integer dayDoorVol;
     /**
      * 白天床头机通话音量
      */
     @Column(name = "day_bed_vol")
     @ApiModelProperty(value = "白天床头机通话音量", required = false)
-    private Boolean dayBedVol;
+    private Integer dayBedVol;
     /**
      * 白天转换盒通话音量
      */
     @Column(name = "day_transfer_box_vol")
     @ApiModelProperty(value = "白天转换盒通话音量", required = false)
-    private Boolean dayTransferBoxVol;
+    private Integer dayTransferBoxVol;
     /**
      * 白天转换盒系统音量
      */
     @Column(name = "day_transfer_box_system_vol")
     @ApiModelProperty(value = "白天转换盒系统音量", required = false)
-    private Boolean dayTransferBoxSystemVol;
+    private Integer dayTransferBoxSystemVol;
     /**
      * 夜晚开始时间
      */
@@ -118,73 +119,80 @@ public class PartSettingDO implements Serializable {
      */
     @Column(name = "night_light")
     @ApiModelProperty(value = "夜晚背光亮度", required = false)
-    private Boolean nightLight;
+    private Integer nightLight;
     /**
      * 夜晚通话音量
      */
     @Column(name = "night_vol")
     @ApiModelProperty(value = "夜晚通话音量", required = false)
-    private Boolean nightVol;
+    private Integer nightVol;
     /**
      * 夜晚响铃音量
      */
     @Column(name = "night_ring_vol")
     @ApiModelProperty(value = "夜晚响铃音量", required = false)
-    private Boolean nightRingVol;
+    private Integer nightRingVol;
     /**
      * 夜晚响铃次数
      */
     @Column(name = "night_ring_times")
     @ApiModelProperty(value = "夜晚响铃次数", required = false)
-    private Boolean nightRingTimes;
+    private Integer nightRingTimes;
     /**
      * 夜晚护理灯亮度
      */
     @Column(name = "night_nurse_led")
     @ApiModelProperty(value = "夜晚护理灯亮度", required = false)
-    private Boolean nightNurseLed;
+    private Integer nightNurseLed;
     /**
      * 夜晚门口机通话音量
      */
     @Column(name = "night_door_vol")
     @ApiModelProperty(value = "夜晚门口机通话音量", required = false)
-    private Boolean nightDoorVol;
+    private Integer nightDoorVol;
     /**
      * 夜晚床头机通话音量
      */
     @Column(name = "night_bed_vol")
     @ApiModelProperty(value = "夜晚床头机通话音量", required = false)
-    private Boolean nightBedVol;
+    private Integer nightBedVol;
     /**
      * 夜晚转换盒通话音量
      */
     @Column(name = "night_transfer_box_vol")
     @ApiModelProperty(value = "夜晚转换盒通话音量", required = false)
-    private Boolean nightTransferBoxVol;
+    private Integer nightTransferBoxVol;
     /**
      * 夜晚转换盒系统音量
      */
     @Column(name = "night_transfer_box_system_vol")
     @ApiModelProperty(value = "夜晚转换盒系统音量", required = false)
-    private Boolean nightTransferBoxSystemVol;
+    private Integer nightTransferBoxSystemVol;
     /**
      * 护士机熄屏时间,单位:秒
      */
     @Column(name = "sleep_seconds_nurse")
     @ApiModelProperty(value = "护士机熄屏时间,单位:秒", required = false)
-    private Boolean sleepSecondsNurse;
+    private Integer sleepSecondsNurse;
     /**
      * 门口机熄屏时间,单位:秒
      */
     @Column(name = "sleep_seconds_door")
     @ApiModelProperty(value = "门口机熄屏时间,单位:秒", required = false)
-    private Boolean sleepSecondsDoor;
+    private Integer sleepSecondsDoor;
     /**
      * 病床分机熄屏时间,单位:秒
      */
     @Column(name = "sleep_seconds_bed")
     @ApiModelProperty(value = "病床分机熄屏时间,单位:秒", required = false)
-    private Boolean sleepSecondsBed;
+    private Integer sleepSecondsBed;
+
+    /**
+     * 呼叫响应超时,单位:秒
+     */
+    @Column(name = "sip_overtime")
+    @ApiModelProperty(value = "呼叫响应超时,单位:秒", required = false)
+    private Integer sipOvertime;
 
 
     @PrimaryKeyField
@@ -242,87 +250,78 @@ public class PartSettingDO implements Serializable {
     }
 
 
-    public Boolean getDayLight() {
+    public Integer getDayLight() {
         return dayLight;
     }
 
-    public void setDayLight(Boolean dayLight) {
+    public void setDayLight(Integer dayLight) {
         this.dayLight = dayLight;
     }
 
-
-    public Boolean getDayVol() {
+    public Integer getDayVol() {
         return dayVol;
     }
 
-    public void setDayVol(Boolean dayVol) {
+    public void setDayVol(Integer dayVol) {
         this.dayVol = dayVol;
     }
 
-
-    public Boolean getDayRingVol() {
+    public Integer getDayRingVol() {
         return dayRingVol;
     }
 
-    public void setDayRingVol(Boolean dayRingVol) {
+    public void setDayRingVol(Integer dayRingVol) {
         this.dayRingVol = dayRingVol;
     }
 
-
-    public Boolean getDayRingTimes() {
+    public Integer getDayRingTimes() {
         return dayRingTimes;
     }
 
-    public void setDayRingTimes(Boolean dayRingTimes) {
+    public void setDayRingTimes(Integer dayRingTimes) {
         this.dayRingTimes = dayRingTimes;
     }
 
-
-    public Boolean getDayNurseLed() {
+    public Integer getDayNurseLed() {
         return dayNurseLed;
     }
 
-    public void setDayNurseLed(Boolean dayNurseLed) {
+    public void setDayNurseLed(Integer dayNurseLed) {
         this.dayNurseLed = dayNurseLed;
     }
 
-
-    public Boolean getDayDoorVol() {
+    public Integer getDayDoorVol() {
         return dayDoorVol;
     }
 
-    public void setDayDoorVol(Boolean dayDoorVol) {
+    public void setDayDoorVol(Integer dayDoorVol) {
         this.dayDoorVol = dayDoorVol;
     }
 
-
-    public Boolean getDayBedVol() {
+    public Integer getDayBedVol() {
         return dayBedVol;
     }
 
-    public void setDayBedVol(Boolean dayBedVol) {
+    public void setDayBedVol(Integer dayBedVol) {
         this.dayBedVol = dayBedVol;
     }
 
-
-    public Boolean getDayTransferBoxVol() {
+    public Integer getDayTransferBoxVol() {
         return dayTransferBoxVol;
     }
 
-    public void setDayTransferBoxVol(Boolean dayTransferBoxVol) {
+    public void setDayTransferBoxVol(Integer dayTransferBoxVol) {
         this.dayTransferBoxVol = dayTransferBoxVol;
     }
 
-
-    public Boolean getDayTransferBoxSystemVol() {
+    public Integer getDayTransferBoxSystemVol() {
         return dayTransferBoxSystemVol;
     }
 
-    public void setDayTransferBoxSystemVol(Boolean dayTransferBoxSystemVol) {
+    public void setDayTransferBoxSystemVol(Integer dayTransferBoxSystemVol) {
         this.dayTransferBoxSystemVol = dayTransferBoxSystemVol;
     }
 
-
     public String getNightStart() {
         return nightStart;
     }
@@ -331,112 +330,107 @@ public class PartSettingDO implements Serializable {
         this.nightStart = nightStart;
     }
 
-
-    public Boolean getNightLight() {
+    public Integer getNightLight() {
         return nightLight;
     }
 
-    public void setNightLight(Boolean nightLight) {
+    public void setNightLight(Integer nightLight) {
         this.nightLight = nightLight;
     }
 
-
-    public Boolean getNightVol() {
+    public Integer getNightVol() {
         return nightVol;
     }
 
-    public void setNightVol(Boolean nightVol) {
+    public void setNightVol(Integer nightVol) {
         this.nightVol = nightVol;
     }
 
-
-    public Boolean getNightRingVol() {
+    public Integer getNightRingVol() {
         return nightRingVol;
     }
 
-    public void setNightRingVol(Boolean nightRingVol) {
+    public void setNightRingVol(Integer nightRingVol) {
         this.nightRingVol = nightRingVol;
     }
 
-
-    public Boolean getNightRingTimes() {
+    public Integer getNightRingTimes() {
         return nightRingTimes;
     }
 
-    public void setNightRingTimes(Boolean nightRingTimes) {
+    public void setNightRingTimes(Integer nightRingTimes) {
         this.nightRingTimes = nightRingTimes;
     }
 
-
-    public Boolean getNightNurseLed() {
+    public Integer getNightNurseLed() {
         return nightNurseLed;
     }
 
-    public void setNightNurseLed(Boolean nightNurseLed) {
+    public void setNightNurseLed(Integer nightNurseLed) {
         this.nightNurseLed = nightNurseLed;
     }
 
-
-    public Boolean getNightDoorVol() {
+    public Integer getNightDoorVol() {
         return nightDoorVol;
     }
 
-    public void setNightDoorVol(Boolean nightDoorVol) {
+    public void setNightDoorVol(Integer nightDoorVol) {
         this.nightDoorVol = nightDoorVol;
     }
 
-
-    public Boolean getNightBedVol() {
+    public Integer getNightBedVol() {
         return nightBedVol;
     }
 
-    public void setNightBedVol(Boolean nightBedVol) {
+    public void setNightBedVol(Integer nightBedVol) {
         this.nightBedVol = nightBedVol;
     }
 
-
-    public Boolean getNightTransferBoxVol() {
+    public Integer getNightTransferBoxVol() {
         return nightTransferBoxVol;
     }
 
-    public void setNightTransferBoxVol(Boolean nightTransferBoxVol) {
+    public void setNightTransferBoxVol(Integer nightTransferBoxVol) {
         this.nightTransferBoxVol = nightTransferBoxVol;
     }
 
-
-    public Boolean getNightTransferBoxSystemVol() {
+    public Integer getNightTransferBoxSystemVol() {
         return nightTransferBoxSystemVol;
     }
 
-    public void setNightTransferBoxSystemVol(Boolean nightTransferBoxSystemVol) {
+    public void setNightTransferBoxSystemVol(Integer nightTransferBoxSystemVol) {
         this.nightTransferBoxSystemVol = nightTransferBoxSystemVol;
     }
 
-
-    public Boolean getSleepSecondsNurse() {
+    public Integer getSleepSecondsNurse() {
         return sleepSecondsNurse;
     }
 
-    public void setSleepSecondsNurse(Boolean sleepSecondsNurse) {
+    public void setSleepSecondsNurse(Integer sleepSecondsNurse) {
         this.sleepSecondsNurse = sleepSecondsNurse;
     }
 
-
-    public Boolean getSleepSecondsDoor() {
+    public Integer getSleepSecondsDoor() {
         return sleepSecondsDoor;
     }
 
-    public void setSleepSecondsDoor(Boolean sleepSecondsDoor) {
+    public void setSleepSecondsDoor(Integer sleepSecondsDoor) {
         this.sleepSecondsDoor = sleepSecondsDoor;
     }
 
-
-    public Boolean getSleepSecondsBed() {
+    public Integer getSleepSecondsBed() {
         return sleepSecondsBed;
     }
 
-    public void setSleepSecondsBed(Boolean sleepSecondsBed) {
+    public void setSleepSecondsBed(Integer sleepSecondsBed) {
         this.sleepSecondsBed = sleepSecondsBed;
     }
 
+    public Integer getSipOvertime() {
+        return sipOvertime;
+    }
+
+    public void setSipOvertime(Integer sipOvertime) {
+        this.sipOvertime = sipOvertime;
+    }
 }

+ 31 - 1
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dos/NurseConfigDto.java

@@ -1,4 +1,4 @@
-package com.wdkl.ncs.android.middleware.model.dos;
+package com.wdkl.ncs.android.middleware.model.dto;
 
 public class NurseConfigDto {
     private Integer id;
@@ -7,6 +7,12 @@ public class NurseConfigDto {
 
     private Integer nurseConfig;
 
+    private String nurseOptionAndConfigName;
+
+    private String nurseOptionName;
+
+    private String nurseColorRbg;
+
     private String nurseConfigName;
 
     public Integer getId() {
@@ -33,6 +39,30 @@ public class NurseConfigDto {
         this.nurseConfig = nurseConfig;
     }
 
+    public String getNurseOptionAndConfigName() {
+        return nurseOptionAndConfigName;
+    }
+
+    public void setNurseOptionAndConfigName(String nurseOptionAndConfigName) {
+        this.nurseOptionAndConfigName = nurseOptionAndConfigName;
+    }
+
+    public String getNurseOptionName() {
+        return nurseOptionName;
+    }
+
+    public void setNurseOptionName(String nurseOptionName) {
+        this.nurseOptionName = nurseOptionName;
+    }
+
+    public String getNurseColorRbg() {
+        return nurseColorRbg;
+    }
+
+    public void setNurseColorRbg(String nurseColorRbg) {
+        this.nurseColorRbg = nurseColorRbg;
+    }
+
     public String getNurseConfigName() {
         return nurseConfigName;
     }

+ 53 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/dto/TcpSeverDTO.java

@@ -0,0 +1,53 @@
+package com.wdkl.ncs.android.middleware.model.dto;
+
+
+/**
+ * @author
+ * @title: TcpSevserDTO
+ * @projectName nc
+ * @description: TODO
+ * @date 2021/4/1512:21
+ */
+
+public class TcpSeverDTO {
+
+    private String localIp;
+
+    private String publicIp;
+
+    private Integer tcpPort;
+
+    private Integer readerIdleTime;
+
+    public String getLocalIp() {
+        return localIp;
+    }
+
+    public void setLocalIp(String localIp) {
+        this.localIp = localIp;
+    }
+
+    public String getPublicIp() {
+        return publicIp;
+    }
+
+    public void setPublicIp(String publicIp) {
+        this.publicIp = publicIp;
+    }
+
+    public Integer getTcpPort() {
+        return tcpPort;
+    }
+
+    public void setTcpPort(Integer tcpPort) {
+        this.tcpPort = tcpPort;
+    }
+
+    public Integer getReaderIdleTime() {
+        return readerIdleTime;
+    }
+
+    public void setReaderIdleTime(Integer readerIdleTime) {
+        this.readerIdleTime = readerIdleTime;
+    }
+}

+ 64 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/vo/BedDeviceInfoVO.java

@@ -0,0 +1,64 @@
+package com.wdkl.ncs.android.middleware.model.vo;
+
+import com.wdkl.ncs.android.middleware.model.annotation.Column;
+import com.wdkl.ncs.android.middleware.model.dos.DeviceDO;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @program nc
+ * @description:
+ * @author: Vothin
+ * @create: 2021/04/06 11:09
+ */
+
+public class BedDeviceInfoVO extends DeviceDO {
+
+    @Column(name = "hospital_id")
+    @ApiModelProperty(value = "医院id", required = false)
+    private Integer hospitalId;
+
+    @Column(name = "hospital_name")
+    @ApiModelProperty(value = "医院名称", required = false)
+    private String hospitalName;
+
+    @Column(name = "part_name")
+    @ApiModelProperty(value = "科室名称", required = false)
+    private String partName;
+
+    @Column(name = "customer_d")
+    @ApiModelProperty(value = "病人id", required = false)
+    private Integer customerId;
+
+    public Integer getHospitalId() {
+        return hospitalId;
+    }
+
+    public void setHospitalId(Integer hospitalId) {
+        this.hospitalId = hospitalId;
+    }
+
+    public String getHospitalName() {
+        return hospitalName;
+    }
+
+    public void setHospitalName(String hospitalName) {
+        this.hospitalName = hospitalName;
+    }
+
+    public String getPartName() {
+        return partName;
+    }
+
+    public void setPartName(String partName) {
+        this.partName = partName;
+    }
+
+    public Integer getCustomerId() {
+        return customerId;
+    }
+
+    public void setCustomerId(Integer customerId) {
+        this.customerId = customerId;
+    }
+}

+ 70 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/vo/CustomerFeeConfigByGroupNameVO.java

@@ -0,0 +1,70 @@
+package com.wdkl.ncs.android.middleware.model.vo;
+
+import com.wdkl.ncs.android.middleware.model.annotation.Column;
+
+import java.io.Serializable;
+import java.util.List;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author
+ * @title: CustomerFeeConfigByGroupNameVO
+ * @projectName nc
+ * @description: TODO
+ * @date 2021/4/2611:27
+ */
+public class CustomerFeeConfigByGroupNameVO implements Serializable {
+    /**
+     * 费用项组名
+     */
+    @Column(name = "fee_group_name")
+    @ApiModelProperty(value = "费用项组名", required = false)
+    private String feeGroupName;
+    /**
+     * null
+     */
+    @Column(name = "fee_number")
+    @ApiModelProperty(value = "费用批次", required = false)
+    private Integer feeNumber;
+    /**
+     * 费用项组名
+     */
+    @Column(name = "subtotal")
+    @ApiModelProperty(value = "小计", required = false)
+    private Double subtotal;
+
+    private List<CustomerFeeConfigVO> customerFeeConfigList;
+
+    public String getFeeGroupName() {
+        return feeGroupName;
+    }
+
+    public void setFeeGroupName(String feeGroupName) {
+        this.feeGroupName = feeGroupName;
+    }
+
+    public Integer getFeeNumber() {
+        return feeNumber;
+    }
+
+    public void setFeeNumber(Integer feeNumber) {
+        this.feeNumber = feeNumber;
+    }
+
+    public Double getSubtotal() {
+        return subtotal;
+    }
+
+    public void setSubtotal(Double subtotal) {
+        this.subtotal = subtotal;
+    }
+
+    public List<CustomerFeeConfigVO> getCustomerFeeConfigList() {
+        return customerFeeConfigList;
+    }
+
+    public void setCustomerFeeConfigList(List<CustomerFeeConfigVO> customerFeeConfigList) {
+        this.customerFeeConfigList = customerFeeConfigList;
+    }
+}

+ 185 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/vo/CustomerFeeConfigVO.java

@@ -0,0 +1,185 @@
+package com.wdkl.ncs.android.middleware.model.vo;
+
+import com.wdkl.ncs.android.middleware.model.annotation.Column;
+
+import java.io.Serializable;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @author
+ * @title: CustomerFeeConfigVO
+ * @projectName nc
+ * @description: TODO
+ * @date 2021/4/2610:23
+ */
+public class CustomerFeeConfigVO implements Serializable {
+    /**
+     * 病人ID
+     */
+    @Column(name = "customer_id")
+    @ApiModelProperty(value = "病人ID", required = false)
+    private Integer customerId;
+    /**
+     * 关联费用配置项
+     */
+    @Column(name = "fee_config_id")
+    @ApiModelProperty(value = "关联费用配置项", required = false)
+    private Integer feeConfigId;
+    /**
+     * 不使用费用配置表时使用此字段
+     */
+    @Column(name = "fee_name")
+    @ApiModelProperty(value = "费用名称", required = false)
+    private String feeName;
+    /**
+     * null
+     */
+    @Column(name = "fee_value")
+    @ApiModelProperty(value = "具体费用", required = false)
+    private Double feeValue;
+    /**
+     * null
+     */
+    @Column(name = "fee_number")
+    @ApiModelProperty(value = "费用批次", required = false)
+    private Integer feeNumber;
+    /**
+     * null
+     */
+    @Column(name = "fee_time")
+    @ApiModelProperty(value = "费用产生的时间", required = false)
+    private Long feeTime;
+    /**
+     * 费用项组名
+     */
+    @Column(name = "group_name")
+    @ApiModelProperty(value = "费用项组名", required = false)
+    private String groupName;
+    /**
+     * 费用编码
+     */
+    @Column(name = "key_code")
+    @ApiModelProperty(value = "费用编码", required = false)
+    private String keyCode;
+    /**
+     * 单位
+     */
+    @Column(name = "unit")
+    @ApiModelProperty(value = "单位", required = false)
+    private String unit;
+    /**
+     * 描述
+     */
+    @Column(name = "description")
+    @ApiModelProperty(value = "描述", required = false)
+    private String description;
+    /**
+     * 参数类型
+     */
+    @Column(name = "key_type")
+    @ApiModelProperty(value = "参数类型", required = false)
+    private String keyType;
+    /**
+     * null
+     */
+    @Column(name = "index")
+    @ApiModelProperty(value = "null", required = false)
+    private Integer index;
+
+    public Integer getCustomerId() {
+        return customerId;
+    }
+
+    public void setCustomerId(Integer customerId) {
+        this.customerId = customerId;
+    }
+
+    public Integer getFeeConfigId() {
+        return feeConfigId;
+    }
+
+    public void setFeeConfigId(Integer feeConfigId) {
+        this.feeConfigId = feeConfigId;
+    }
+
+    public String getFeeName() {
+        return feeName;
+    }
+
+    public void setFeeName(String feeName) {
+        this.feeName = feeName;
+    }
+
+    public Double getFeeValue() {
+        return feeValue;
+    }
+
+    public void setFeeValue(Double feeValue) {
+        this.feeValue = feeValue;
+    }
+
+    public Integer getFeeNumber() {
+        return feeNumber;
+    }
+
+    public void setFeeNumber(Integer feeNumber) {
+        this.feeNumber = feeNumber;
+    }
+
+    public Long getFeeTime() {
+        return feeTime;
+    }
+
+    public void setFeeTime(Long feeTime) {
+        this.feeTime = feeTime;
+    }
+
+    public String getGroupName() {
+        return groupName;
+    }
+
+    public void setGroupName(String groupName) {
+        this.groupName = groupName;
+    }
+
+    public String getKeyCode() {
+        return keyCode;
+    }
+
+    public void setKeyCode(String keyCode) {
+        this.keyCode = keyCode;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getKeyType() {
+        return keyType;
+    }
+
+    public void setKeyType(String keyType) {
+        this.keyType = keyType;
+    }
+
+    public Integer getIndex() {
+        return index;
+    }
+
+    public void setIndex(Integer index) {
+        this.index = index;
+    }
+}

+ 99 - 25
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/vo/CustomerInfoVO.java

@@ -1,10 +1,14 @@
 package com.wdkl.ncs.android.middleware.model.vo;
 
-import com.wdkl.ncs.android.middleware.model.dos.NurseConfigDto;
+import com.wdkl.ncs.android.middleware.model.annotation.Column;
+import com.wdkl.ncs.android.middleware.model.annotation.Id;
+import com.wdkl.ncs.android.middleware.model.dto.NurseConfigDto;
 
 import java.io.Serializable;
 import java.util.List;
 
+import io.swagger.annotations.ApiModelProperty;
+
 /**
  * @program nc
  * @description: 病人信息集合
@@ -13,34 +17,96 @@ import java.util.List;
  */
 
 public class CustomerInfoVO implements Serializable {
-
+    /**
+     * customerId
+     */
+    @Column(name = "id")
+    @ApiModelProperty(value = "customerId", required = false)
+    @Id(name = "id")
     private Integer id;
-
-    private Integer customerId;
-
+    /**
+     * memberId
+     */
+    @Column(name = "member_id")
+    @ApiModelProperty(name = "memberId")
     private Integer memberId;
-
+    /**
+     * null
+     */
+    @Column(name = "part_id")
+    @ApiModelProperty(value = "null", required = false)
+    private Integer partId;
+    /**
+     * 病人的名字
+     */
+    @Column(name = "named")
+    @ApiModelProperty(name = "病人的名字")
     private String named;
-
+    /**
+     * 病人的年龄
+     */
+    @Column(name = "age")
+    @ApiModelProperty(name = "病人的年龄")
     private Integer age;
-
+    /**
+     * 年龄单位。岁、月、天
+     */
+    @Column(name = "age_unit")
+    @ApiModelProperty(value = "年龄单位。岁、月、天", required = false)
     private String ageUnit;
-
+    /**
+     * 身份证件类型。身份证、护照、军人证
+     */
+    @Column(name = "id_type")
+    @ApiModelProperty(value = "身份证件类型。身份证、护照、军人证", required = false)
     private String idType;
-
+    /**
+     * 身份证号
+     */
+    @Column(name = "id_no")
+    @ApiModelProperty(value = "身份证号", required = false)
     private String idNo;
-
+    /**
+     * 病人编号
+     */
+    @Column(name = "card_no")
+    @ApiModelProperty(value = "病人编号", required = false)
     private String cardNo;
-
+    /**
+     * 状态。
+     */
+    @Column(name = "status")
+    @ApiModelProperty(value = "状态。", required = false)
     private Integer status;
-
+    /**
+     * 入院时间
+     */
+    @Column(name = "in_date")
+    @ApiModelProperty(value = "入院时间", required = false)
     private Long inDate;
-
+    /**
+     * 出院时间
+     */
+    @Column(name = "out_date")
+    @ApiModelProperty(value = "出院时间", required = false)
     private Long outDate;
-
+    /**
+     * 病情描述
+     */
+    @Column(name = "illness_desc")
+    @ApiModelProperty(value = "病情描述", required = false)
     private String illnessDesc;
-
-    private Integer partId;
+    /**
+     * null
+     */
+    @Column(name = "frame_id")
+    @ApiModelProperty(value = "null", required = false)
+    private Integer frameId;
+    /**
+     *	医嘱
+     */	@Column(name = "advice" )
+    @ApiModelProperty(value="医嘱",required=false)
+    private String advice;
 
     private Integer sex;
 
@@ -180,6 +246,22 @@ public class CustomerInfoVO implements Serializable {
         this.sex = sex;
     }
 
+    public Integer getFrameId() {
+        return frameId;
+    }
+
+    public void setFrameId(Integer frameId) {
+        this.frameId = frameId;
+    }
+
+    public String getAdvice() {
+        return advice;
+    }
+
+    public void setAdvice(String advice) {
+        this.advice = advice;
+    }
+
     public String getDoctorName() {
         return doctorName;
     }
@@ -308,14 +390,6 @@ public class CustomerInfoVO implements Serializable {
         this.workerId = workerId;
     }
 
-    public Integer getCustomerId() {
-        return customerId;
-    }
-
-    public void setCustomerId(Integer customerId) {
-        this.customerId = customerId;
-    }
-
     public Integer getMemberId() {
         return memberId;
     }

+ 391 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/model/vo/InteractionVO.java

@@ -0,0 +1,391 @@
+package com.wdkl.ncs.android.middleware.model.vo;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategy;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import com.wdkl.ncs.android.middleware.model.annotation.Column;
+import com.wdkl.ncs.android.middleware.model.dos.InteractionDO;
+
+import java.io.Serializable;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @program nc
+ * @description:
+ * @author: Vothin
+ * @create: 2021/04/02 15:27
+ */
+@JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class)
+public class InteractionVO extends InteractionDO implements Serializable {
+
+    /** 用户 **/
+    @Column(name = "from_customer_id")
+    @ApiModelProperty(value = "发起端用户CustomId", required = false)
+    private Integer fromCustomerId;
+
+    @Column(name = "from_member_name")
+    @ApiModelProperty(value = "发起端用户姓名", required = false)
+    private String fromMemberName;
+
+    @Column(name = "from_member_face")
+    @ApiModelProperty(value = "发起端用户头像", required = false)
+    private String fromMemberFace;
+
+    @Column(name = "from_clerk_id")
+    @ApiModelProperty(value = "发起端用户成员Id,发起端为护士主机,腕表,医生机时才有", required = false)
+    private Integer fromClerkId;
+
+    @Column(name = "from_role_name")
+    @ApiModelProperty(value = "发起端用户角色名(医生、护士、护工)", required = false)
+    private String fromRoleName;
+
+
+    @Column(name = "to_customer_id")
+    @ApiModelProperty(value = "目的端用户CustomId", required = false)
+    private Integer toCustomerId;
+
+    @Column(name = "to_member_name")
+    @ApiModelProperty(value = "目的端用户姓名", required = false)
+    private String toMemberName;
+
+    @Column(name = "to_member_face")
+    @ApiModelProperty(value = "目的端用户头像", required = false)
+    private String toMemberFace;
+
+    @Column(name = "to_clerk_id")
+    @ApiModelProperty(value = "目的端用户成员Id,目的端为护士主机,腕表,医生机时才有", required = false)
+    private Integer toClerkId;
+
+    @Column(name = "to_role_name")
+    @ApiModelProperty(value = "目的端用户角色名(医生、护士、护工)", required = false)
+    private String toRoleName;
+
+
+    /** 设备 **/
+    @Column(name = "from_eth_mac")
+    @ApiModelProperty(value = "发起端设备的有线以太网卡MAC地址", required = false)
+    private String fromEthMac;
+
+    @Column(name = "from_eth_ip")
+    @ApiModelProperty(value = "发起端设备的有线以太网卡分配的IP地址", required = false)
+    private String fromEthIp;
+
+
+    @Column(name = "from_sip_id")
+    @ApiModelProperty(value = "发起端设备的SIP账号", required = false)
+    private String fromSipId;
+
+    @Column(name = "from_device_type")
+    @ApiModelProperty(value = "发起端设备的设备类型", required = false)
+    private Integer fromDeviceType;
+
+
+    @Column(name = "to_eth_mac")
+    @ApiModelProperty(value = "目的端设备的有线以太网卡MAC地址", required = false)
+    private String toEthMac;
+
+    @Column(name = "to_eth_ip")
+    @ApiModelProperty(value = "目的端设备的有线以太网卡分配的IP地址", required = false)
+    private String toEthIp;
+
+
+    @Column(name = "to_sip_id")
+    @ApiModelProperty(value = "目的端设备的SIP账号", required = false)
+    private String toSipId;
+
+    @Column(name = "to_device_type")
+    @ApiModelProperty(value = "目的端设备的设备类型", required = false)
+    private Integer toDeviceType;
+
+    /** 空间结构 **/
+
+    @Column(name = "from_frame_type")
+    @ApiModelProperty(value = "发起端空间结构类型:0楼、1病房、2床位", required = false)
+    private Integer fromFrameType;
+
+
+    @Column(name = "from_frame_name")
+    @ApiModelProperty(value = "发起端空间结构名称", required = false)
+    private String fromFrameName;
+
+    @Column(name = "from_frame_full_name")
+    @ApiModelProperty(value = "发起端空间结构全名", required = false)
+    private String fromFrameFullName;
+
+
+    @Column(name = "to_frame_type")
+    @ApiModelProperty(value = "目的端空间结构类型:0楼、1病房、2床位", required = false)
+    private Integer toFrameType;
+
+
+    @Column(name = "to_frame_name")
+    @ApiModelProperty(value = "目的端空间结构名称", required = false)
+    private String toFrameName;
+
+    @Column(name = "to_frame_full_name")
+    @ApiModelProperty(value = "发起端空间结构全名", required = false)
+    private String toFrameFullName;
+
+
+    @Column(name = "relative_id")
+    @ApiModelProperty(value = "亲属id,外部来电时,from_member亲属的memberId", required = false)
+    private Integer relativeId;
+
+    @Column(name = "relative_name")
+    @ApiModelProperty(value = "外部来电时,from_member亲属关系", required = false)
+    private String relativeName;
+
+    @Column(name = "outerior_action_name")
+    @ApiModelProperty(value = "外部来电时,from_member亲属名字", required = false)
+    private String outeriorActionName;
+
+
+    public Integer getFromCustomerId() {
+        return fromCustomerId;
+    }
+
+    public void setFromCustomerId(Integer fromCustomerId) {
+        this.fromCustomerId = fromCustomerId;
+    }
+
+    public String getFromMemberName() {
+        return fromMemberName;
+    }
+
+    public void setFromMemberName(String fromMemberName) {
+        this.fromMemberName = fromMemberName;
+    }
+
+    public String getFromMemberFace() {
+        return fromMemberFace;
+    }
+
+    public void setFromMemberFace(String fromMemberFace) {
+        this.fromMemberFace = fromMemberFace;
+    }
+
+    public Integer getFromClerkId() {
+        return fromClerkId;
+    }
+
+    public void setFromClerkId(Integer fromClerkId) {
+        this.fromClerkId = fromClerkId;
+    }
+
+    public String getFromRoleName() {
+        return fromRoleName;
+    }
+
+    public void setFromRoleName(String fromRoleName) {
+        this.fromRoleName = fromRoleName;
+    }
+
+    public Integer getToCustomerId() {
+        return toCustomerId;
+    }
+
+    public void setToCustomerId(Integer toCustomerId) {
+        this.toCustomerId = toCustomerId;
+    }
+
+    public String getToMemberName() {
+        return toMemberName;
+    }
+
+    public void setToMemberName(String toMemberName) {
+        this.toMemberName = toMemberName;
+    }
+
+    public String getToMemberFace() {
+        return toMemberFace;
+    }
+
+    public void setToMemberFace(String toMemberFace) {
+        this.toMemberFace = toMemberFace;
+    }
+
+    public Integer getToClerkId() {
+        return toClerkId;
+    }
+
+    public void setToClerkId(Integer toClerkId) {
+        this.toClerkId = toClerkId;
+    }
+
+    public String getToRoleName() {
+        return toRoleName;
+    }
+
+    public void setToRoleName(String toRoleName) {
+        this.toRoleName = toRoleName;
+    }
+
+    public String getFromEthMac() {
+        return fromEthMac;
+    }
+
+    public void setFromEthMac(String fromEthMac) {
+        this.fromEthMac = fromEthMac;
+    }
+
+    public String getFromEthIp() {
+        return fromEthIp;
+    }
+
+    public void setFromEthIp(String fromEthIp) {
+        this.fromEthIp = fromEthIp;
+    }
+
+    public String getFromSipId() {
+        return fromSipId;
+    }
+
+    public void setFromSipId(String fromSipId) {
+        this.fromSipId = fromSipId;
+    }
+
+    public String getToEthMac() {
+        return toEthMac;
+    }
+
+    public void setToEthMac(String toEthMac) {
+        this.toEthMac = toEthMac;
+    }
+
+    public String getToEthIp() {
+        return toEthIp;
+    }
+
+    public void setToEthIp(String toEthIp) {
+        this.toEthIp = toEthIp;
+    }
+
+    public String getToSipId() {
+        return toSipId;
+    }
+
+    public void setToSipId(String toSipId) {
+        this.toSipId = toSipId;
+    }
+
+    public Integer getFromFrameType() {
+        return fromFrameType;
+    }
+
+    public void setFromFrameType(Integer fromFrameType) {
+        this.fromFrameType = fromFrameType;
+    }
+
+    public String getFromFrameName() {
+        return fromFrameName;
+    }
+
+    public void setFromFrameName(String fromFrameName) {
+        this.fromFrameName = fromFrameName;
+    }
+
+    public String getFromFrameFullName() {
+        return fromFrameFullName;
+    }
+
+    public void setFromFrameFullName(String fromFrameFullName) {
+        this.fromFrameFullName = fromFrameFullName;
+    }
+
+    public Integer getToFrameType() {
+        return toFrameType;
+    }
+
+    public void setToFrameType(Integer toFrameType) {
+        this.toFrameType = toFrameType;
+    }
+
+    public String getToFrameName() {
+        return toFrameName;
+    }
+
+    public void setToFrameName(String toFrameName) {
+        this.toFrameName = toFrameName;
+    }
+
+    public String getToFrameFullName() {
+        return toFrameFullName;
+    }
+
+    public void setToFrameFullName(String toFrameFullName) {
+        this.toFrameFullName = toFrameFullName;
+    }
+
+    public Integer getRelativeId() {
+        return relativeId;
+    }
+
+    public void setRelativeId(Integer relativeId) {
+        this.relativeId = relativeId;
+    }
+
+    public String getRelativeName() {
+        return relativeName;
+    }
+
+    public void setRelativeName(String relativeName) {
+        this.relativeName = relativeName;
+    }
+
+    public String getOuteriorActionName() {
+        return outeriorActionName;
+    }
+
+    public void setOuteriorActionName(String outeriorActionName) {
+        this.outeriorActionName = outeriorActionName;
+    }
+
+    public Integer getFromDeviceType() {
+        return fromDeviceType;
+    }
+
+    public void setFromDeviceType(Integer fromDeviceType) {
+        this.fromDeviceType = fromDeviceType;
+    }
+
+    public Integer getToDeviceType() {
+        return toDeviceType;
+    }
+
+    public void setToDeviceType(Integer toDeviceType) {
+        this.toDeviceType = toDeviceType;
+    }
+
+    @Override
+    public String toString() {
+        return "InteractionVO{" +
+                "fromCustomerId=" + fromCustomerId +
+                ", fromMemberName='" + fromMemberName + '\'' +
+                ", fromMemberFace='" + fromMemberFace + '\'' +
+                ", fromClerkId=" + fromClerkId +
+                ", fromRoleName='" + fromRoleName + '\'' +
+                ", toCustomerId=" + toCustomerId +
+                ", toMemberName='" + toMemberName + '\'' +
+                ", toMemberFace='" + toMemberFace + '\'' +
+                ", toClerkId=" + toClerkId +
+                ", toRoleName='" + toRoleName + '\'' +
+                ", fromEthMac='" + fromEthMac + '\'' +
+                ", fromEthIp='" + fromEthIp + '\'' +
+                ", fromSipId='" + fromSipId + '\'' +
+                ", fromDeviceType='" + fromDeviceType + '\'' +
+                ", toEthMac='" + toEthMac + '\'' +
+                ", toEthIp='" + toEthIp + '\'' +
+                ", toSipId='" + toSipId + '\'' +
+                ", toDeviceType='" + toDeviceType + '\'' +
+                ", fromFrameType=" + fromFrameType +
+                ", fromFrameName='" + fromFrameName + '\'' +
+                ", fromFrameFullName='" + fromFrameFullName + '\'' +
+                ", toFrameType=" + toFrameType +
+                ", toFrameName='" + toFrameName + '\'' +
+                ", toFrameFullName='" + toFrameFullName + '\'' +
+                ", relativeId=" + relativeId +
+                ", relativeName='" + relativeName + '\'' +
+                ", outeriorActionName='" + outeriorActionName + '\'' +
+                '}';
+    }
+}

+ 150 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/TcpClient.java

@@ -0,0 +1,150 @@
+package com.wdkl.ncs.android.middleware.tcp;
+
+import java.util.Scanner;
+import java.util.concurrent.TimeUnit;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
+import io.netty.handler.codec.LengthFieldPrepender;
+import io.netty.handler.codec.string.StringDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import io.netty.handler.timeout.IdleStateHandler;
+import io.netty.util.CharsetUtil;
+
+//单例
+public class TcpClient {
+    private NioEventLoopGroup workGroup = new NioEventLoopGroup(2);
+    public Channel channel;
+    private Bootstrap bootstrap;
+
+    //数据处理
+    private TcpClientHandler tcpClientHandler = new TcpClientHandler();
+    //是否运行中
+    public boolean isRunning = false;
+    //重试间隔
+    private Integer retrySeconds = 5;
+    //重试计数
+    private Integer retryTimes = 1;
+
+
+    //单例
+    private static class TcpClientHolder{
+        private static TcpClient instance = new TcpClient();
+    }
+
+    public static TcpClient getInstance(){
+        return TcpClientHolder.instance;
+    }
+
+    //初始化Netty Tcp Client 并连接
+    public void init(String serverIP, Integer serverPort, Integer heartBeatSeconds){
+        final Integer hbSeconds = heartBeatSeconds;
+        bootstrap = new Bootstrap();
+        bootstrap.group(workGroup)
+                .channel(NioSocketChannel.class)
+                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 15*1000)
+                .option(ChannelOption.SO_KEEPALIVE,true)
+                .handler(new ChannelInitializer<SocketChannel>() {
+                    @Override
+                    protected void initChannel(SocketChannel socketChannel) throws Exception {
+                        // 这里将LengthFieldBasedFrameDecoder添加到pipeline的首位,因为其需要对接收到的数据
+                        // 进行长度字段解码,这里也会对数据进行粘包和拆包处理
+                        socketChannel.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 0, 2));
+                        // LengthFieldPrepender是一个编码器,主要是在响应字节数据前面添加字节长度字段
+                        socketChannel.pipeline().addLast(new LengthFieldPrepender(2));
+                        //心跳包应当小于服务器间隔
+                        socketChannel.pipeline().addLast(new IdleStateHandler(0, hbSeconds,0, TimeUnit.SECONDS));
+                        socketChannel.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
+                        socketChannel.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
+                        socketChannel.pipeline().addLast(tcpClientHandler);
+                    }
+                }).remoteAddress(serverIP,serverPort);
+        doConnect();
+        System.out.println("connect server host: " + serverIP + ", port: " + serverPort);
+    }
+
+    //独立连接方法,用于重新连接
+    public synchronized void doConnect(){
+        if (channel != null && channel.isActive()){
+            System.out.println("TcpClient connecting");
+            return;
+        }
+
+        System.out.println("connect start");
+        ChannelFuture future = bootstrap.connect().addListener(new ChannelFutureListener() {
+            @Override
+            public void operationComplete(ChannelFuture channelFuture) throws Exception {
+                if (channelFuture.isSuccess()){
+                    isRunning = true;
+                    retryTimes = 0;
+                    System.out.println("connect success");
+                } else {
+                    //连接失败时的处理
+                    isRunning = false;
+                    System.out.println("connect retry : " + retryTimes);
+                    //EventBus.getDefault().post(new MessageEvent(0, Constant.EVENT_TCP_STATE));
+                    channelFuture.channel().eventLoop().schedule(new Runnable() {
+                        @Override
+                        public void run() {
+                            retryTimes++;
+                            if (retryTimes>30){
+                                System.out.println("重试"+(retryTimes-1)+"次,结束");
+                                workGroup.shutdownGracefully();
+                                //todo: 从API获取新的serverIP和serverPort,全新连接
+                                //TcpClient.getInstance().init();
+                                return;
+                            }
+                            doConnect();
+                        }
+                    },retrySeconds * retryTimes, TimeUnit.SECONDS);
+                }
+            }
+        });
+//        try {
+//            future.sync();
+//            future.channel().closeFuture().sync();
+//        } catch (InterruptedException e) {
+//            e.printStackTrace();
+//        } finally {
+            //重试之前不关
+//            try {
+//                Thread.sleep(retrySeconds * retryTimes*1000 + 1000);
+//            } catch (InterruptedException e) {
+//            }
+//            workGroup.shutdownGracefully();
+//        }
+    }
+
+    //发送消息,线程安全
+    public synchronized void sendMsg(String content){
+        if (tcpClientHandler != null) {
+            tcpClientHandler.sendMsg(content);
+        }
+    }
+
+    //测试
+    public static void main(String[] args) {
+
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                TcpClient.getInstance().init("47.106.200.55",5080, 9);
+            }
+        }).start();
+
+        Scanner scanner = new Scanner(System.in);
+        while (true){
+            System.out.println("please type : ");
+            String line = scanner.nextLine();
+            TcpClient.getInstance().sendMsg(line);
+        }
+    }
+}

+ 144 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/TcpClientHandler.java

@@ -0,0 +1,144 @@
+package com.wdkl.ncs.android.middleware.tcp;
+
+import com.wdkl.ncs.android.middleware.common.Constant;
+import com.wdkl.ncs.android.middleware.common.MessageEvent;
+import com.wdkl.ncs.android.middleware.tcp.channel.DeviceChannel;
+import com.wdkl.ncs.android.middleware.tcp.channel.DeviceUtil;
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.util.concurrent.TimeUnit;
+
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
+import io.netty.util.CharsetUtil;
+import io.netty.util.ReferenceCountUtil;
+
+@ChannelHandler.Sharable
+public class TcpClientHandler extends SimpleChannelInboundHandler<String> {
+    ChannelHandlerContext ctx;
+    //重连间隔
+    private static Integer retrySeconds = 5;
+    //重连计数
+    private static Integer retryTimes = 0;
+    //总共总连接次数,总连接次数过多可能是网络不稳定
+    private static Integer totalRetryTimes = 0;
+    //是否连接成功
+    private static Boolean connected = false;
+
+    //连接成功执行的方法
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        super.channelActive(ctx);
+        System.out.println("连接成功");
+        this.ctx = ctx;
+        connected = true;
+        retryTimes = 0;
+        Constant.TCP_CONNECTED = true;
+        EventBus.getDefault().post(new MessageEvent(1, Constant.EVENT_TCP_STATE));
+        TcpModel tcpModel = DeviceUtil.deviceConnect(Constant.LOCAL_MAC);
+        TcpClient.getInstance().sendMsg(tcpModel.toJson());
+    }
+
+    //断开连接
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        super.channelInactive(ctx);
+        EventBus.getDefault().post(new MessageEvent(0, Constant.EVENT_TCP_STATE));
+        connected = false;
+        Constant.TCP_CONNECTED = false;
+        System.out.println("失去连接");
+        TcpClient.getInstance().doConnect();
+        //reConnect(ctx);
+    }
+
+    //读取String消息
+    @Override
+    protected void channelRead0(ChannelHandlerContext ctx, String source) throws Exception {
+        //System.out.println("channelRead0: read callback from server ===> " + source);
+        TcpModel tcpModel = TcpModel.getModelByJson(source);
+
+        TcpModel responseTcpModel = null;
+        if (tcpModel != null) {
+            responseTcpModel = DeviceChannel.handleTcpReceived(tcpModel);
+        }
+        if (responseTcpModel != null) {
+            ctx.writeAndFlush(responseTcpModel.toJson());
+        } else {
+            ReferenceCountUtil.release(source);
+        }
+
+    }
+
+    //写心跳包。没有消息发送时,每间隔一定时间会由此方法向服务端发送心跳
+    @Override
+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+        if (evt instanceof IdleStateEvent){
+            IdleStateEvent event = (IdleStateEvent)evt;
+            if (event.state()== IdleState.WRITER_IDLE){
+                ctx.writeAndFlush("0");
+            }
+        }
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        cause.printStackTrace();
+        ctx.close();
+        Constant.TCP_CONNECTED = false;
+        EventBus.getDefault().post(new MessageEvent(0, Constant.EVENT_TCP_STATE));
+        connected = false;
+        System.out.println("失去连接,错误引起");
+    }
+
+    //发送消息,不直接调用些方法,调用TcpClient中的发送消息
+    public void sendMsg(String msg){
+        if (ctx==null){
+            System.out.println("ctx is null");
+            /*try {
+                Thread.sleep(1000);
+                sendMsg(msg);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }*/
+            return;
+        }
+        System.out.println("wzlll: tcp msg====" + msg);
+        ctx.writeAndFlush(Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
+    }
+
+    //已经连接上,中途失去连接时的处理
+    private void reConnect(final ChannelHandlerContext ctx){
+        if (totalRetryTimes>100){
+            //todo: 存储数据库,并告警
+        }
+        if (connected && (TcpClient.getInstance().channel != null && TcpClient.getInstance().channel.isActive())){
+            return;
+        }
+        totalRetryTimes++;
+        System.out.println("TcpClientHandler 总计连接次数:"+totalRetryTimes);
+        retryTimes++;
+        if (retryTimes>30){
+            //超时3次,其它处理
+            System.out.println("TcpClientHandler 重新连接"+(retryTimes-1)+"次,结束");
+            retryTimes = 0;
+            //todo: 从API获取新的serverIP和serverPort,全新连接
+            //TcpClient.getInstance().init();
+            return;
+        }
+
+        ctx.channel().eventLoop().schedule(new Runnable() {
+            @Override
+            public void run() {
+                System.out.println("TcpClientHandler 重新连接,第"+retryTimes+"次");
+                TcpClient.getInstance().doConnect();
+                reConnect(ctx);
+            }
+        },retrySeconds*retryTimes, TimeUnit.SECONDS);
+    }
+}

+ 91 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/DeviceChannel.java

@@ -0,0 +1,91 @@
+package com.wdkl.ncs.android.middleware.tcp.channel;
+
+import android.util.Log;
+
+import com.google.gson.Gson;
+import com.wdkl.ncs.android.middleware.common.Constant;
+import com.wdkl.ncs.android.middleware.common.MessageEvent;
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO;
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction;
+
+import org.greenrobot.eventbus.EventBus;
+
+import static com.wdkl.ncs.android.middleware.common.Constant.EVENT_TCP_MSG;
+
+/**
+ * 前提:所有安卓设备可以互相通话。
+ * 在此前提下,所有安卓设备接收TCP信号的逻辑一致
+ */
+public class DeviceChannel {
+
+    public static TcpModel handleTcpReceived(TcpModel tcpModel){
+        TcpModel responseTcpModel = null;
+
+        Log.d("wzlll", "received tcp model: " + tcpModel.toJson());
+        switch (tcpModel.getType()){
+            case VOICE:
+                if (tcpModel.getAction()==TcpAction.VoiceAction.CALL){ //语音呼入
+                    //todo: 判断当前是否通话
+                    // 当前正在通话中或有新的来电或正在呼叫,直接返回该状态给服务器
+                    if (Constant.CALL_STATE != Constant.CALL_STANDBY){
+                        InteractionVO interactionVO = new Gson().fromJson(tcpModel.getData().toString(), InteractionVO.class);
+                        responseTcpModel = VoiceUtil.voiceCalling(tcpModel.getToId(), tcpModel.getFromId(), interactionVO.getId());
+                        return responseTcpModel;
+                    } else {
+                        //todo: 通话界面展现,data中服务器传过来呼入名称;从接口重新获取左侧数据
+                        // 当前待机状态,返回呼叫成功,并切换到呼叫界面
+                        EventBus.getDefault().post(new MessageEvent(tcpModel, EVENT_TCP_MSG));
+                        //responseTcpModel = VoiceUtil.voiceSuccess(tcpModel.getToId(), tcpModel.getFromId());
+                        //return responseTcpModel;
+                    }
+                } else {
+                    //tcpModel.getAction()==TcpAction.VoiceAction.ACCEPT
+                    //todo: 通话中界面更新;建立数据通话
+                    //tcpModel.getAction()==TcpAction.VoiceAction.REJECT
+                    //todo: 清掉呼出的TcpModel,通话中界面更新 --- 显示对方拒绝并停留3秒,结束至正常界面;更新左侧
+                    //tcpModel.getAction()==TcpAction.VoiceAction.CALLING
+                    //todo: 清掉呼出的TcpModel,通话中界面更新 --- 显示对方占线并停留3秒,结束至正常界面;更新左侧
+                    //tcpModel.getAction()==TcpAction.VoiceAction.FAILED
+                    //todo: 清掉呼出的TcpModel,通话中界面更新 --- 显示对方离线并停留3秒,结束至正常界面;更新左侧
+                    //tcpModel.getAction()==TcpAction.VoiceAction.HANDOFF
+                    //todo: 清掉呼出的TcpModel,通话中界面更新 --- 显示对方已挂断并停留3秒,结束至正常界面;更新左侧
+
+                    //交由后续处理
+                    EventBus.getDefault().post(new MessageEvent(tcpModel, EVENT_TCP_MSG));
+                }
+                break;
+            case VIDEO:
+                break;
+            case IM:
+                if (tcpModel.getAction()==TcpAction.IMAction.MSG){
+                    //todo: 从接口重新获取左侧数据;使用通话中界面,显示有语音留言,停留3秒,结束至正常界面
+                } else if (tcpModel.getAction()==TcpAction.IMAction.MSG_READ){ //语音已读取
+                    //todo: 从data得到语音id;更新左侧,注意这里不使用通话中界面提示已读
+                }
+                break;
+            case EVENT:
+                if (tcpModel.getAction()==TcpAction.EventAction.KEY_CLICK){ //有新事件过来
+                    //todo: 服务端通过data给出具体的事件名称放置data。从接口重新获取左侧数据;使用通话中界面,显示事件名称,停留3秒,结束至正常界面
+                } else if (tcpModel.getAction()==TcpAction.EventAction.RESPONSE){ //事件已处理,仅分机用
+                    //todo: 从data得到事件id,使用通话中界面,显示事件名称及已响应字样,停留3秒,结束至正常界面;更新左侧
+                    EventBus.getDefault().post(new MessageEvent(tcpModel, EVENT_TCP_MSG));
+                }
+                break;
+            case DATA:
+                if (tcpModel.getAction()==TcpAction.DataAction.REFRESH){
+                    //todo: 通过data判断刷新何种数据
+                } else if (tcpModel.getAction()==TcpAction.DataAction.INTERACTION) {
+                    EventBus.getDefault().post(new MessageEvent(tcpModel, EVENT_TCP_MSG));
+                }
+                break;
+            case DEVICE:
+                if (tcpModel.getAction()== TcpAction.DeviceAction.RESTART){
+                    //todo:重启设备
+                }
+                break;
+        }
+
+        return responseTcpModel;
+    }
+}

+ 15 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/DeviceUtil.java

@@ -0,0 +1,15 @@
+package com.wdkl.ncs.android.middleware.tcp.channel;
+
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType;
+
+public class DeviceUtil {
+    public static TcpModel deviceConnect(String mac){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.DEVICE);
+        tcpModel.setAction(TcpAction.DeviceAction.CONNECT);
+        tcpModel.setData(mac);
+        return tcpModel;
+    }
+}

+ 33 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/EventUtil.java

@@ -0,0 +1,33 @@
+package com.wdkl.ncs.android.middleware.tcp.channel;
+
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class EventUtil {
+    //分机发送按键事件无需toId
+    public static TcpModel eventKeyClick(Integer fromId, Integer keyId){
+        Map map = new HashMap();
+        map.put("id", keyId);
+
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.EVENT);
+        tcpModel.setAction(TcpAction.EventAction.KEY_CLICK);
+        tcpModel.setFromId(fromId);
+        tcpModel.setData(map);
+        return tcpModel;
+    }
+
+    public static TcpModel eventResponse(Integer fromId, Integer toId, Integer eventId){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.EVENT);
+        tcpModel.setAction(TcpAction.EventAction.RESPONSE);
+        tcpModel.setFromId(fromId);
+        tcpModel.setToId(toId);
+        tcpModel.setData(eventId);
+        return tcpModel;
+    }
+}

+ 26 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/ImUtil.java

@@ -0,0 +1,26 @@
+package com.wdkl.ncs.android.middleware.tcp.channel;
+
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType;
+
+public class ImUtil {
+    public static TcpModel imMsg(Integer fromId, String msg){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.IM);
+        tcpModel.setAction(TcpAction.IMAction.MSG);
+        tcpModel.setFromId(fromId);
+        tcpModel.setData(msg);
+        return tcpModel;
+    }
+
+    public static TcpModel imRead(Integer fromId, Integer toId, Integer msg){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.IM);
+        tcpModel.setAction(TcpAction.IMAction.MSG_READ);
+        tcpModel.setFromId(fromId);
+        tcpModel.setToId(toId);
+        tcpModel.setData(msg);
+        return tcpModel;
+    }
+}

+ 118 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/channel/VoiceUtil.java

@@ -0,0 +1,118 @@
+package com.wdkl.ncs.android.middleware.tcp.channel;
+
+import com.wdkl.ncs.android.middleware.tcp.TcpClient;
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType;
+
+public class VoiceUtil {
+    //分机呼叫,不需要传toId
+    public static TcpModel voiceCall(Integer fromId){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.VOICE);
+        tcpModel.setAction(TcpAction.VoiceAction.CALL);
+        tcpModel.setFromId(fromId);
+        return tcpModel;
+    }
+
+    public static TcpModel voiceAccept(Integer fromId, Integer toId, Integer interactionId){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.VOICE);
+        tcpModel.setAction(TcpAction.VoiceAction.ACCEPT);
+        tcpModel.setFromId(fromId);
+        tcpModel.setToId(toId);
+        if (interactionId != -1) {
+            tcpModel.setData(interactionId);
+        }
+        return tcpModel;
+    }
+
+    public static TcpModel voiceReject(Integer fromId, Integer toId, Integer interactionId){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.VOICE);
+        tcpModel.setAction(TcpAction.VoiceAction.REJECT);
+        tcpModel.setFromId(fromId);
+        tcpModel.setToId(toId);
+        if (interactionId != -1) {
+            tcpModel.setData(interactionId);
+        }
+        return tcpModel;
+    }
+
+    public static TcpModel voiceCalling(Integer fromId, Integer toId, Integer interactionId){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.VOICE);
+        tcpModel.setAction(TcpAction.VoiceAction.CALLING);
+        tcpModel.setFromId(fromId);
+        tcpModel.setToId(toId);
+        if (interactionId != -1) {
+            tcpModel.setData(interactionId);
+        }
+        return tcpModel;
+    }
+
+    //分机自己取消呼叫,没有toId
+    public static TcpModel voiceCancel(Integer fromId){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.VOICE);
+        tcpModel.setAction(TcpAction.VoiceAction.CANCEL);
+        tcpModel.setFromId(fromId);
+        return tcpModel;
+    }
+
+    public static TcpModel voiceHandoff(Integer fromId, Integer toId, Integer interactionId){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.VOICE);
+        tcpModel.setAction(TcpAction.VoiceAction.HANDOFF);
+        tcpModel.setFromId(fromId);
+        if (toId != -1) {
+            tcpModel.setToId(toId);
+        }
+        if (interactionId != -1) {
+            tcpModel.setData(interactionId);
+        }
+        return tcpModel;
+    }
+
+    public static TcpModel voiceSuccess(Integer fromId, Integer toId){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.VOICE);
+        tcpModel.setAction(TcpAction.VoiceAction.SUCCESS);
+        tcpModel.setFromId(fromId);
+        tcpModel.setToId(toId);
+        return tcpModel;
+    }
+
+    /**************************************************************************
+     ************************* 发送呼叫相关TCP *********************************
+    ***************************************************************************/
+    //语音呼叫
+    public static void startAudioCall(Integer fromId) {
+        TcpModel tcpModel = VoiceUtil.voiceCall(fromId);
+        TcpClient.getInstance().sendMsg(tcpModel.toJson());
+    }
+
+    //取消呼叫
+    public static void cancelAudioCall(Integer fromId) {
+        TcpModel tcpModel = VoiceUtil.voiceCancel(fromId);
+        TcpClient.getInstance().sendMsg(tcpModel.toJson());
+    }
+
+    //接受通话
+    public static void acceptAudioCall(Integer fromId, Integer toId, Integer interactionId) {
+        TcpModel tcpModel = VoiceUtil.voiceAccept(fromId, toId, interactionId);
+        TcpClient.getInstance().sendMsg(tcpModel.toJson());
+    }
+
+    //挂断通话
+    public static void handoffAudioCall(Integer fromId, Integer toId, Integer interactionId) {
+        TcpModel tcpModel = VoiceUtil.voiceHandoff(fromId, toId, interactionId);
+        TcpClient.getInstance().sendMsg(tcpModel.toJson());
+    }
+
+    //拒绝通话
+    public static void rejectAudioCall(Integer fromId, Integer toId, Integer interactionId) {
+        TcpModel tcpModel = VoiceUtil.voiceReject(fromId, toId, interactionId);
+        TcpClient.getInstance().sendMsg(tcpModel.toJson());
+    }
+}

+ 210 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/dto/TcpModel.java

@@ -0,0 +1,210 @@
+package com.wdkl.ncs.android.middleware.tcp.dto;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.base.Strings;
+import com.wdkl.ncs.android.middleware.model.dos.DeviceDO;
+import com.wdkl.ncs.android.middleware.model.dos.FrameDO;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction;
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * tcp传输对象
+ *
+ * @author allen
+ * 2021-03-30 11:49
+ */
+public class TcpModel implements Serializable {
+    /**
+     * TCP传输对象的类型
+     */
+    private TcpType type;
+    /**
+     * TCP传输对象类型的动作
+     */
+    private TcpAction action;
+
+    /**
+     * 来源设备id
+     */
+    private Integer fromId;
+    /**
+     * 目标设备id,呼叫分机或其它设备时需要。分机呼叫不需要
+     */
+    private Integer toId;
+
+    /**
+     * TCP传输对象的数据
+     */
+    private Object data;
+
+    public TcpType getType() {
+        return type;
+    }
+
+    public void setType(TcpType type) {
+        this.type = type;
+    }
+
+    public TcpAction getAction() {
+        return action;
+    }
+
+    public void setAction(TcpAction action) {
+        this.action = action;
+    }
+
+    public Integer getFromId() {
+        return fromId;
+    }
+
+    public void setFromId(Integer fromId) {
+        this.fromId = fromId;
+    }
+
+    public Integer getToId() {
+        return toId;
+    }
+
+    public void setToId(Integer toId) {
+        this.toId = toId;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    public String toJson(){
+        return JSON.toJSONString(this);
+    }
+
+    public static TcpModel getModelByJson(String tcpModelJsonString){
+        if (Strings.isNullOrEmpty(tcpModelJsonString)){
+            return null;
+        }
+        TcpModel tcpModel = new TcpModel();
+
+        JSONObject jsonObject = JSON.parseObject(tcpModelJsonString);
+        String type = jsonObject.getString("type");
+        String action = jsonObject.getString("action");
+        Integer fromId = jsonObject.getInteger("fromId");
+        Integer toId = jsonObject.getInteger("toId");
+        String dataString = jsonObject.getString("data");
+
+        TcpType tcpType = TcpType.fromString(type);
+        TcpAction tcpAction = null;
+        switch (tcpType){
+            case CALLBACK:
+                tcpAction = TcpAction.CallbackAction.fromString(action);
+                break;
+            case VOICE:
+                tcpAction = TcpAction.VoiceAction.fromString(action);
+                break;
+            case VIDEO:
+                tcpAction = TcpAction.VideoAction.fromString(action);
+                break;
+            case IM:
+                tcpAction = TcpAction.IMAction.fromString(action);
+                break;
+            case BROADCAST:
+                tcpAction = TcpAction.BroadcastAction.fromString(action);
+                break;
+            case DATA:
+                tcpAction = TcpAction.DataAction.fromString(action);
+                break;
+            case DEVICE:
+                tcpAction = TcpAction.DeviceAction.fromString(action);
+                break;
+            case TIME:
+                tcpAction = TcpAction.TimeAction.fromString(action);
+                break;
+            case EVENT:
+                tcpAction = TcpAction.EventAction.fromString(action);
+                break;
+        }
+
+        tcpModel.setType(tcpType);
+        tcpModel.setAction(tcpAction);
+        tcpModel.setToId(toId);
+        tcpModel.setFromId(fromId);
+        tcpModel.setData(dataString);
+
+        return tcpModel;
+    }
+
+    public static String callbackSuccess(){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.CALLBACK);
+        tcpModel.setAction(TcpAction.CallbackAction.SUCCESS);
+        return tcpModel.toJson();
+    }
+
+    public static String callbackFailed(){
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.CALLBACK);
+        tcpModel.setAction(TcpAction.CallbackAction.FAILED);
+        return tcpModel.toJson();
+    }
+
+    public static String refresh() {
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.DATA);
+        tcpModel.setAction(TcpAction.DataAction.REFRESH);
+        return tcpModel.toJson();
+    }
+
+
+    public static String interaction() {
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.setType(TcpType.DATA);
+        tcpModel.setAction(TcpAction.DataAction.INTERACTION);
+        return tcpModel.toJson();
+    }
+
+    /**
+     * 示例
+     * @param args
+     */
+    public static void main(String[] args) {
+        //创建对象示例
+        TcpModel tcpModel = new TcpModel();
+        tcpModel.type = TcpType.VOICE;
+        tcpModel.action = TcpAction.VoiceAction.CALL;
+
+        Map map = new HashMap();
+
+        DeviceDO deviceDO = new DeviceDO();
+        deviceDO.setCode("123");
+        deviceDO.setEthMac("abcd");
+        map.put("device",deviceDO);
+
+        FrameDO frameDO = new FrameDO();
+        frameDO.setName("ok");
+        map.put("frame",frameDO);
+
+        tcpModel.setData(map);
+
+        System.out.println("enum show === " + tcpModel.action.getDescription() + " -- " + tcpModel.action.getName());
+
+        //要传输的json字符串
+        String jsonStr = tcpModel.toJson();
+        System.out.println("json show === " + jsonStr);
+
+        //获利传输的JSON字符串,转换为对象
+        TcpModel dTcpModel = TcpModel.getModelByJson(jsonStr);
+        //数据反转
+        String dataString = dTcpModel.getData().toString();
+        JSONObject dataJSON = JSON.parseObject(dataString);
+        DeviceDO dDeviceDO = JSON.parseObject(dataJSON.getString("device"), DeviceDO.class);
+
+        System.out.println("json de show === " + dTcpModel.action + " -- " + dDeviceDO.getEthMac());
+    }
+}

+ 271 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/enums/TcpAction.java

@@ -0,0 +1,271 @@
+package com.wdkl.ncs.android.middleware.tcp.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * TCP传输类型的动作
+ *
+ * @author allen
+ * 2021-03-30 15:30
+ */
+public interface TcpAction {
+    String getName();
+    String getDescription();
+
+    enum CallbackAction implements TcpAction {
+        SUCCESS("同步"),
+        FAILED("失败");
+        private String description;
+        CallbackAction(String description){
+            this.description = description;
+        }
+        public String getDescription() {
+            return description;
+        }
+
+        public String getName(){
+            return this.name();
+        }
+
+        private final static Map<String , CallbackAction> ENUM_MAP = new HashMap<String, CallbackAction>();
+        static {
+            for(CallbackAction v : values()) {
+                ENUM_MAP.put(v.toString() , v);
+            }
+        }
+        public static CallbackAction fromString(String v) {
+            CallbackAction userOptionEnum = ENUM_MAP.get(v);
+            return userOptionEnum == null ? SUCCESS :userOptionEnum;
+        }
+    }
+
+    enum VoiceAction implements TcpAction {
+        CALL("呼叫"),
+        ACCEPT("接受呼叫"),
+        CANCEL("取消"),
+        REJECT("拒绝"),
+        CALLING("通话中"),
+        TRANSFER("转接"),
+        HANDOFF("挂断"),
+        SUCCESS("呼叫成功"),
+        FAILED("呼叫失败");
+
+        private String description;
+        VoiceAction(String description){
+            this.description = description;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public String getName(){
+            return this.name();
+        }
+
+        private final static Map<String , VoiceAction> ENUM_MAP = new HashMap<String, VoiceAction>();
+        static {
+            for(VoiceAction v : values()) {
+                ENUM_MAP.put(v.toString() , v);
+            }
+        }
+        public static VoiceAction fromString(String v) {
+            VoiceAction userOptionEnum = ENUM_MAP.get(v);
+            return userOptionEnum == null ? CALL :userOptionEnum;
+        }
+    }
+
+    enum VideoAction implements TcpAction {
+        CALL("呼叫"),
+        CANCEL("取消");
+
+        private String description;
+        VideoAction(String description){
+            this.description = description;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public String getName(){
+            return this.name();
+        }
+
+        private final static Map<String , VideoAction> ENUM_MAP = new HashMap<String, VideoAction>();
+        static {
+            for(VideoAction v : values()) {
+                ENUM_MAP.put(v.toString() , v);
+            }
+        }
+        public static VideoAction fromString(String v) {
+            VideoAction userOptionEnum = ENUM_MAP.get(v);
+            return userOptionEnum == null ? CALL :userOptionEnum;
+        }
+    }
+
+
+    enum IMAction implements TcpAction {
+        MSG("语音留言"),
+        MSG_READ("语音留言已读");
+
+        private String description;
+        IMAction(String description){
+            this.description = description;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public String getName(){
+            return this.name();
+        }
+
+        private final static Map<String , IMAction> ENUM_MAP = new HashMap<String, IMAction>();
+        static {
+            for(IMAction v : values()) {
+                ENUM_MAP.put(v.toString() , v);
+            }
+        }
+        public static IMAction fromString(String v) {
+            IMAction userOptionEnum = ENUM_MAP.get(v);
+            return userOptionEnum == null ? MSG_READ :userOptionEnum;
+        }
+
+    }
+
+    enum DeviceAction implements TcpAction {
+        RESTART("重启"),
+        CONNECT("连接");
+        private String description;
+        DeviceAction(String description){
+            this.description = description;
+        }
+        public String getDescription() {
+            return description;
+        }
+
+        public String getName(){
+            return this.name();
+        }
+
+        private final static Map<String , DeviceAction> ENUM_MAP = new HashMap<String, DeviceAction>();
+        static {
+            for(DeviceAction v : values()) {
+                ENUM_MAP.put(v.toString() , v);
+            }
+        }
+        public static DeviceAction fromString(String v) {
+            DeviceAction userOptionEnum = ENUM_MAP.get(v);
+            return userOptionEnum == null ? RESTART :userOptionEnum;
+        }
+    }
+
+    enum EventAction implements TcpAction {
+        KEY_CLICK("按键事件"),
+        RESPONSE("已响应");
+        private String description;
+        EventAction(String description){
+            this.description = description;
+        }
+        public String getDescription() {
+            return description;
+        }
+
+        public String getName(){
+            return this.name();
+        }
+
+        private final static Map<String , EventAction> ENUM_MAP = new HashMap<String, EventAction>();
+        static {
+            for(EventAction v : values()) {
+                ENUM_MAP.put(v.toString() , v);
+            }
+        }
+        public static EventAction fromString(String v) {
+            EventAction userOptionEnum = ENUM_MAP.get(v);
+            return userOptionEnum == null ? KEY_CLICK :userOptionEnum;
+        }
+    }
+
+    enum DataAction implements TcpAction {
+        REFRESH("刷新数据"),
+        INTERACTION("刷新交互列表");
+        private String description;
+        DataAction(String description){
+            this.description = description;
+        }
+        public String getDescription() {
+            return description;
+        }
+
+        public String getName(){
+            return this.name();
+        }
+
+        private final static Map<String , DataAction> ENUM_MAP = new HashMap<String, DataAction>();
+        static {
+            for(DataAction v : values()) {
+                ENUM_MAP.put(v.toString() , v);
+            }
+        }
+        public static DataAction fromString(String v) {
+            DataAction userOptionEnum = ENUM_MAP.get(v);
+            return userOptionEnum == null ? REFRESH :userOptionEnum;
+        }
+    }
+
+    enum BroadcastAction implements TcpAction {
+        START("开始");
+        private String description;
+        BroadcastAction(String description){
+            this.description = description;
+        }
+        public String getDescription() {
+            return description;
+        }
+
+        public String getName(){
+            return this.name();
+        }
+
+        private final static Map<String , BroadcastAction> ENUM_MAP = new HashMap<String, BroadcastAction>();
+        static {
+            for(BroadcastAction v : values()) {
+                ENUM_MAP.put(v.toString() , v);
+            }
+        }
+        public static BroadcastAction fromString(String v) {
+            BroadcastAction userOptionEnum = ENUM_MAP.get(v);
+            return userOptionEnum == null ? START :userOptionEnum;
+        }
+    }
+
+    enum TimeAction implements TcpAction {
+        SYNC("同步");
+        private String description;
+        TimeAction(String description){
+            this.description = description;
+        }
+        public String getDescription() {
+            return description;
+        }
+
+        public String getName(){
+            return this.name();
+        }
+
+        private final static Map<String , TimeAction> ENUM_MAP = new HashMap<String, TimeAction>();
+        static {
+            for(TimeAction v : values()) {
+                ENUM_MAP.put(v.toString() , v);
+            }
+        }
+        public static TimeAction fromString(String v) {
+            TimeAction userOptionEnum = ENUM_MAP.get(v);
+            return userOptionEnum == null ? SYNC :userOptionEnum;
+        }
+    }
+}

+ 38 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/tcp/enums/TcpType.java

@@ -0,0 +1,38 @@
+package com.wdkl.ncs.android.middleware.tcp.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * TCP传输对象的类型
+ */
+public enum TcpType {
+    CALLBACK("TCP反馈"),
+    VOICE("语音"),
+    VIDEO("视频"),
+    IM("留言"),
+    DEVICE("设备"),
+    DATA("数据"),
+    EVENT("事件"),
+    BROADCAST("广播"),
+    TIME("时间");
+
+    private String description;
+    TcpType(String description){
+        this.description = description;
+    }
+    public String getDescription() {
+        return description;
+    }
+
+    private final static Map<String , TcpType> ENUM_MAP = new HashMap<String, TcpType>();
+    static {
+        for(TcpType v : values()) {
+            ENUM_MAP.put(v.toString() , v);
+        }
+    }
+    public static TcpType fromString(String v) {
+        TcpType userOptionEnum = ENUM_MAP.get(v);
+        return userOptionEnum == null ? CALLBACK :userOptionEnum;
+    }
+}