HomeActivity.kt 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861
  1. package com.dlc.eboard.ui
  2. import android.app.AlertDialog
  3. import android.content.ComponentName
  4. import android.content.Intent
  5. import android.content.ServiceConnection
  6. import android.os.Bundle
  7. import android.os.Handler
  8. import android.os.IBinder
  9. import android.os.Looper
  10. import android.view.KeyEvent
  11. import android.view.LayoutInflater
  12. import android.view.View
  13. import android.view.ViewGroup
  14. import android.widget.BaseAdapter
  15. import android.widget.ImageView
  16. import android.widget.TextView
  17. import androidx.core.content.ContextCompat
  18. import androidx.recyclerview.widget.DividerItemDecoration
  19. import androidx.recyclerview.widget.RecyclerView
  20. import com.blankj.utilcode.util.AppUtils
  21. import com.bumptech.glide.Glide
  22. import com.chad.library.adapter.base.BaseQuickAdapter
  23. import com.chad.library.adapter.base.viewholder.BaseViewHolder
  24. import com.dlc.eboard.BuildConfig
  25. import com.dlc.eboard.LabApp
  26. import com.dlc.eboard.R
  27. import com.dlc.eboard.common.AuthTypeConfig
  28. import com.dlc.eboard.common.CommonUtils
  29. import com.dlc.eboard.common.SensorEnum
  30. import com.dlc.eboard.databinding.ActivityHomeBinding
  31. import com.dlc.eboard.databinding.ItemHomePersonFlipperBinding
  32. import com.dlc.eboard.event.OnlineUserEvent
  33. import com.dlc.eboard.finger.FingerHelper
  34. import com.dlc.eboard.finger.OnFingerListener
  35. import com.dlc.eboard.mqtt.AudioService
  36. import com.dlc.eboard.mqtt.MqttService
  37. import com.dlc.eboard.mqtt.entity.BulletinBoardEntity
  38. import com.dlc.eboard.mqtt.event.*
  39. import com.dlc.eboard.serial.OnSerialScanListener
  40. import com.dlc.eboard.serial.SerialPortHelper
  41. import com.dlc.eboard.ui.auth.*
  42. import com.dlc.eboard.ui.common.BaseCountDownActivity
  43. import com.dlc.eboard.ui.dialog.WaringDialog
  44. import com.dlc.eboard.ui.home.AccessPersonFragment
  45. import com.dlc.eboard.ui.home.DutyPersonFragment
  46. import com.dlc.eboard.ui.home.HomeFragmentCallback
  47. import com.dlc.eboard.ui.home.LabBasicFragment
  48. import com.dlc.eboard.ui.lib.LabDescActivity
  49. import com.dlc.eboard.ui.settings.PasswordDialog
  50. import com.dlc.eboard.ui.settings.SettingsActivity
  51. import com.dlc.eboard.ui.widget.LooperLayoutManager
  52. import com.dlc.eboard.ui.widget.ItemBoardView
  53. import com.dlc.eboard.ui.widget.NavViewCompat
  54. import com.dlc.eboard.ui.widget.ITitleBar
  55. import com.rc.core.log.RcLog
  56. import com.rc.core.ui.widget.decoration.NoLastLineItemDecoration
  57. import com.rc.core.util.ApkUpdater
  58. import com.rc.core.util.DeviceUtils
  59. import com.rc.core.util.FastClickDelegate
  60. import com.rc.httpcore.client.ApiRepository
  61. import com.rc.httpcore.vo.response.*
  62. import org.greenrobot.eventbus.Subscribe
  63. import org.greenrobot.eventbus.ThreadMode
  64. import org.json.JSONObject
  65. /**
  66. * 主页
  67. *
  68. * @author ReiChin_
  69. */
  70. class HomeActivity :
  71. BaseCountDownActivity<ActivityHomeBinding>(),
  72. HomeFragmentCallback {
  73. companion object {
  74. private const val SENSOR_SPLASH_TIME = 3000L // 传感器面板1.5s自动滚动
  75. }
  76. override val mTitleBar: ITitleBar by lazy { viewBinding.titleBar }
  77. override val mNavView: NavViewCompat? = null
  78. private val mBulletinBoardAdapter = HomeBoardAdapter()
  79. private var handler: Handler = Handler(Looper.getMainLooper())
  80. private lateinit var runnable: Runnable
  81. override fun onCreate(savedInstanceState: Bundle?) {
  82. super.onCreate(savedInstanceState)
  83. bindService(Intent(this, MqttService::class.java), mConnection, BIND_AUTO_CREATE)
  84. // startService(Intent(this, HeartService::class.java))
  85. bindService(Intent(this, AudioService::class.java), mAudioConnection, BIND_AUTO_CREATE)
  86. mSerialPortHelper.bindService()
  87. mFingerHelper = generateFingerHelper()
  88. lifecycle.addObserver(mFingerHelper)
  89. // 创建定时任务
  90. runnable = object : Runnable {
  91. override fun run() {
  92. // 每隔一个小时执行一次操作
  93. // 这里可以添加你需要执行的代码
  94. listenIn()
  95. // 重新启动定时任务
  96. handler.postDelayed(this, 30000) // 30000 毫秒为一小时
  97. }
  98. }
  99. // 第一次启动定时任务
  100. handler.post(runnable)
  101. // queryLabConfig()
  102. }
  103. private fun queryLabConfig() {
  104. RcLog.info("============CommonUtils.getAndroidId()" + CommonUtils.getAndroidId())
  105. val disposable = ApiRepository.queryLabConfig(CommonUtils.getAndroidId())
  106. .subscribe({ data ->
  107. RcLog.info("===========" + data.authType)
  108. LabApp.sLabConfig = data
  109. }, { throwable ->
  110. // dismissLoading()
  111. throwable.printStackTrace()
  112. showNetError(throwable)
  113. })
  114. addDisposable(disposable)
  115. }
  116. fun listenIn() {
  117. val disposable = ApiRepository.heartbeat(CommonUtils.getAndroidId())
  118. .subscribe({
  119. }, {
  120. })
  121. addDisposable(disposable)
  122. }
  123. override fun onDestroy() {
  124. unbindService(mConnection)
  125. // stopService(Intent(this, HeartService::class.java))
  126. unbindService(mAudioConnection)
  127. mSerialPortHelper.unbindService()
  128. lifecycle.removeObserver(mFingerHelper)
  129. viewBinding.bulletinBoardView.stopAuto()
  130. handler.removeCallbacks(runnable)
  131. handler.removeCallbacksAndMessages(null)
  132. super.onDestroy()
  133. AppUtils.exitApp()
  134. }
  135. private val mConnection: ServiceConnection = object : ServiceConnection {
  136. override fun onServiceConnected(name: ComponentName, service: IBinder) {
  137. LabApp.sLabConfig?.let { config ->
  138. service as MqttService.MqttBinder
  139. service.initMqtt(config.labId)
  140. }
  141. }
  142. override fun onServiceDisconnected(name: ComponentName) {
  143. }
  144. }
  145. private var mAudioBinder: AudioService.AudioBinder? = null
  146. private val mAudioConnection: ServiceConnection = object : ServiceConnection {
  147. override fun onServiceConnected(name: ComponentName, service: IBinder) {
  148. mAudioBinder = service as AudioService.AudioBinder
  149. }
  150. override fun onServiceDisconnected(name: ComponentName) {
  151. }
  152. }
  153. override fun createViewBinding() = ActivityHomeBinding.inflate(layoutInflater)
  154. override fun initViews(savedInstanceState: Bundle?) {
  155. val transaction = supportFragmentManager.beginTransaction()
  156. transaction.add(
  157. R.id.container,
  158. LabBasicFragment.newInstance(),
  159. LabBasicFragment.TAG
  160. )
  161. transaction.commitAllowingStateLoss()
  162. viewBinding.bulletinBoardView.layoutManager = LooperLayoutManager(RecyclerView.HORIZONTAL)
  163. val decor = NoLastLineItemDecoration(this, DividerItemDecoration.HORIZONTAL)
  164. decor.setDrawable(ContextCompat.getDrawable(this, R.drawable.shape_item_divider_middle)!!)
  165. viewBinding.bulletinBoardView.addItemDecoration(decor)
  166. viewBinding.bulletinBoardView.adapter = mBulletinBoardAdapter
  167. }
  168. override fun initListener() {
  169. viewBinding.titleBar.setTitleListener(this)
  170. viewBinding.titleBar.setOnLongClickListener {
  171. PasswordDialog(this) {
  172. val intent = Intent(this, SettingsActivity::class.java)
  173. startActivity(intent)
  174. }.show()
  175. true
  176. }
  177. // 值班人员
  178. viewBinding.dutyExpand.setOnClickListener(FastClickDelegate {
  179. if (null == LabApp.sLabConfig) return@FastClickDelegate
  180. val fragment = supportFragmentManager.findFragmentByTag(DutyPersonFragment.TAG)
  181. as? DutyPersonFragment ?: DutyPersonFragment()
  182. fragment.arguments = Bundle().apply {
  183. putString("labId", LabApp.sLabConfig!!.labId)
  184. }
  185. supportFragmentManager.beginTransaction().apply {
  186. // setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
  187. setCustomAnimations(R.anim.from_right, 0, 0, R.anim.out_right)
  188. replace(R.id.container, fragment, DutyPersonFragment.TAG)
  189. addToBackStack(null)
  190. commit()
  191. }
  192. switchPersonPanel(View.GONE)
  193. })
  194. // 实验人员
  195. viewBinding.experimentExpand.setOnClickListener(FastClickDelegate {
  196. if (null == LabApp.sLabConfig) return@FastClickDelegate
  197. val fragment =
  198. supportFragmentManager.findFragmentByTag(AccessPersonFragment.TAG_EXPERIMENT)
  199. as? AccessPersonFragment ?: AccessPersonFragment()
  200. fragment.arguments = Bundle().apply {
  201. putInt("type", AccessPersonFragment.TYPE_EXPERIMENT)
  202. putString("labId", LabApp.sLabConfig!!.labId)
  203. }
  204. supportFragmentManager.beginTransaction().apply {
  205. // setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
  206. setCustomAnimations(R.anim.from_right, 0, 0, R.anim.out_right)
  207. replace(R.id.container, fragment, AccessPersonFragment.TAG_EXPERIMENT)
  208. addToBackStack(null)
  209. commit()
  210. }
  211. switchPersonPanel(View.GONE)
  212. })
  213. // 准入人员
  214. viewBinding.accessExpand.setOnClickListener(FastClickDelegate {
  215. if (null == LabApp.sLabConfig) return@FastClickDelegate
  216. val fragment = supportFragmentManager.findFragmentByTag(AccessPersonFragment.TAG_ACCESS)
  217. as? AccessPersonFragment ?: AccessPersonFragment()
  218. fragment.arguments = Bundle().apply {
  219. putInt("type", AccessPersonFragment.TYPE_ACCESS)
  220. putString("labId", LabApp.sLabConfig!!.labId)
  221. }
  222. supportFragmentManager.beginTransaction().apply {
  223. // setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
  224. setCustomAnimations(R.anim.from_right, 0, 0, R.anim.out_right)
  225. // setCustomAnimations(R.anim.from_right, R.anim.out_right)
  226. replace(R.id.container, fragment, AccessPersonFragment.TAG_ACCESS)
  227. addToBackStack(null)
  228. commit()
  229. }
  230. switchPersonPanel(View.GONE)
  231. })
  232. // 实验室简介
  233. viewBinding.labDesc.setOnClickListener(FastClickDelegate {
  234. startActivity(Intent(this, LabDescActivity::class.java))
  235. })
  236. RcLog.info("==================LabApp.sLabConfig?.authType:" + LabApp.sLabConfig?.authType)
  237. // 身份验证
  238. viewBinding.accessVerify.setOnClickListener(FastClickDelegate {
  239. RcLog.info("==================LabApp.sLabConfig?.authType:" + LabApp.sLabConfig?.authType)
  240. val authType = LabApp.sLabConfig?.authType ?: return@FastClickDelegate
  241. RcLog.info("==================authType:$authType")
  242. when (authType) {
  243. "1" -> {
  244. Intent(this, FingerAuthActivity::class.java)
  245. }
  246. "2" -> {
  247. Intent(this, FourChoiceAuthActivity::class.java)
  248. }
  249. "3" -> {
  250. Intent(this, TwoChoiceAuthActivity::class.java)
  251. }
  252. "4",
  253. "5",
  254. "6" -> {
  255. Intent(this, DualAuthActivity::class.java)
  256. }
  257. else -> {
  258. null
  259. }
  260. }?.let {
  261. startActivity(it)
  262. }
  263. })
  264. }
  265. override fun initData() {
  266. if (null == LabApp.sLabConfig) {
  267. showToast("暂无实验室信息,即将重新获取")
  268. CommonUtils.restartApp(this)
  269. return
  270. }
  271. viewBinding.titleBar.setTitleInfoFromSp()
  272. queryBulletinBoard()
  273. queryPerson()
  274. queryNoticeMsgList()
  275. }
  276. private fun queryNoticeMsgList() {
  277. val disposable = ApiRepository.newMsgGroup(LabApp.sLabConfig!!.labId)
  278. .subscribe({ response ->
  279. LabApp.sNoticeList = response
  280. viewBinding.titleBar.updateNotice(response)
  281. }, { throwable ->
  282. throwable.printStackTrace()
  283. showNetError(throwable)
  284. })
  285. addDisposable(disposable)
  286. }
  287. private var mHomeRightResp: HomeRightResp? = null
  288. private fun queryPerson() {
  289. val disposable = ApiRepository.homeRightInfo(LabApp.sLabConfig!!.labId)
  290. .subscribe({ response ->
  291. dismissLoading()
  292. mHomeRightResp = response
  293. dispatchLabPerson(response)
  294. }, { throwable ->
  295. dismissLoading()
  296. mHomeRightResp = null
  297. showNetError(throwable)
  298. throwable.printStackTrace()
  299. })
  300. addDisposable(disposable)
  301. }
  302. private fun dispatchLabPerson(data: HomeRightResp) {
  303. // 值班人员
  304. val dutyAdapter = PersonFlipperAdapter(1, data.dutyUser)
  305. viewBinding.dutyPerson.adapter = dutyAdapter
  306. viewBinding.dutyPerson.flipInterval = 3000
  307. viewBinding.dutyPerson.setInAnimation(this, R.animator.anim_in)
  308. viewBinding.dutyPerson.setOutAnimation(this, R.animator.anim_out)
  309. if (!data.dutyUser.isNullOrEmpty()) {
  310. viewBinding.dutyPerson.startFlipping()
  311. }
  312. // 实验人员
  313. val experimentAdapter = ExperimentPersonAdapter()
  314. viewBinding.experimentPerson.layoutManager = LooperLayoutManager(RecyclerView.VERTICAL)
  315. viewBinding.experimentPerson.adapter = experimentAdapter
  316. experimentAdapter.setNewInstance(data.tentativeUser)
  317. if (!data.tentativeUser.isNullOrEmpty()) {
  318. viewBinding.experimentPerson.initTimer(4, data.tentativeUser.size)
  319. viewBinding.experimentPerson.startAuto(SENSOR_SPLASH_TIME)
  320. } else {
  321. experimentAdapter.setEmptyView(R.layout.view_list_empty)
  322. }
  323. // 准入人员
  324. val accessAdapter = PersonFlipperAdapter(2, data.securityUser)
  325. viewBinding.accessPerson.adapter = accessAdapter
  326. viewBinding.accessPerson.flipInterval = 3000
  327. viewBinding.accessPerson.setInAnimation(this, R.animator.anim_in)
  328. viewBinding.accessPerson.setOutAnimation(this, R.animator.anim_out)
  329. if (!data.securityUser.isNullOrEmpty()) {
  330. viewBinding.accessPerson.startFlipping()
  331. }
  332. }
  333. private fun queryBulletinBoard() {
  334. showLoading("加载中...")
  335. val disposable = ApiRepository.functionList(LabApp.sLabConfig!!.labId)
  336. .subscribe({ data ->
  337. dismissLoading()
  338. if (data.isNotEmpty()) {
  339. mBulletinBoardAdapter.setNewInstance(data.toMutableList())
  340. viewBinding.bulletinBoardView.initTimer(4, data.size)
  341. viewBinding.bulletinBoardView.startAuto(SENSOR_SPLASH_TIME)
  342. if (data.isNullOrEmpty()) {
  343. mBulletinBoardAdapter.setEmptyView(R.layout.view_list_empty)
  344. }
  345. queryWarning()
  346. }
  347. }, { throwable ->
  348. dismissLoading()
  349. throwable.printStackTrace()
  350. showNetError(throwable)
  351. mBulletinBoardAdapter.setEmptyView(R.layout.view_list_empty)
  352. })
  353. addDisposable(disposable)
  354. }
  355. private fun queryWarning() {
  356. val disposable = ApiRepository.warnList(LabApp.sLabConfig!!.labId)
  357. .subscribe({ data ->
  358. mBulletinBoardAdapter.updateWaringValue(data)
  359. }, { throwable ->
  360. throwable.printStackTrace()
  361. showNetError(throwable)
  362. })
  363. addDisposable(disposable)
  364. }
  365. private fun switchPersonPanel(visibility: Int) {
  366. viewBinding.dutyExpandGroup.visibility = visibility
  367. viewBinding.experimentExpandGroup.visibility = visibility
  368. viewBinding.accessExpandGroup.visibility = visibility
  369. }
  370. override fun closePersonPanel() {
  371. switchPersonPanel(View.VISIBLE)
  372. }
  373. override fun onBackPressed() {
  374. if (supportFragmentManager.backStackEntryCount >= 1) {
  375. supportFragmentManager.popBackStack()
  376. closePersonPanel()
  377. } else {
  378. super.onBackPressed()
  379. }
  380. }
  381. override fun onStop() {
  382. backCountDownFinish()
  383. super.onStop()
  384. }
  385. override fun enabledBackCountDown() = true
  386. override fun backCountDownFinish() {
  387. // 显示LabBasicFragment
  388. if (supportFragmentManager.backStackEntryCount >= 1) {
  389. supportFragmentManager.popBackStack()
  390. closePersonPanel()
  391. }
  392. }
  393. private fun generateFingerHelper(): FingerHelper {
  394. return FingerHelper(object : OnFingerListener {
  395. override fun showToast(message: String) {
  396. if (isFinishing || !mFingerEnabled) return
  397. if ("设备忙" == message) {
  398. viewBinding.titleBar.postDelayed({
  399. if (!isFinishing && mFingerEnabled) mFingerHelper.verify()
  400. }, 1000)
  401. } else {
  402. this.showToast(message)
  403. }
  404. }
  405. override fun onMatchSuccess(userVo: UserFingerVo): Boolean {
  406. if (isFinishing || !mFingerEnabled) return false
  407. onAuthSuccess(AuthType.FINGER, userVo)
  408. return true
  409. }
  410. override fun onMatchFailure(message: String) {
  411. if (isFinishing || !mFingerEnabled) return
  412. showMatchErrDialog(message)
  413. }
  414. override fun loopMatch() {
  415. if (isFinishing || !mFingerEnabled) return
  416. mFingerHelper.verify()
  417. }
  418. })
  419. }
  420. private lateinit var mFingerHelper: FingerHelper
  421. private var mFingerEnabled = false
  422. private fun showMatchErrDialog(message: String) {
  423. AlertDialog.Builder(this)
  424. .setTitle("提示")
  425. .setMessage(message)
  426. .setCancelable(false)
  427. .setPositiveButton("重新验证") { _, _ ->
  428. mFingerHelper.verify()
  429. }.show()
  430. }
  431. override fun onResume() {
  432. // 刷卡+门禁
  433. mSerialPortHelper.onResume()
  434. // 5s后开始验证指纹
  435. viewBinding.titleBar.postDelayed({
  436. mFingerHelper.lazyVerify()
  437. }, 1000)
  438. mFingerEnabled = true
  439. super.onResume()
  440. }
  441. override fun onPause() {
  442. // 刷卡+门禁
  443. mSerialPortHelper.onPause()
  444. // 指纹
  445. mFingerEnabled = false
  446. super.onPause()
  447. }
  448. override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
  449. mSerialPortHelper.dispatchKeyEvent(event)
  450. return super.dispatchKeyEvent(event)
  451. }
  452. private val mSerialPortHelper by lazy {
  453. SerialPortHelper(this, object : OnSerialScanListener {
  454. override fun dispatchScanEvent(type: OnSerialScanListener.ScanType, content: String) {
  455. // 刷卡开门
  456. dispatchReadCardResult(content)
  457. }
  458. })
  459. }
  460. private fun dispatchReadCardResult(username: String) {
  461. showLoading()
  462. val disposable = ApiRepository.getCardIsOpen(LabApp.sLabConfig!!.labId, username)
  463. .subscribe({ userVo ->
  464. dismissLoading()
  465. onAuthSuccess(AuthType.CARD, userVo)
  466. }, { throwable ->
  467. dismissLoading()
  468. showNetError(throwable)
  469. throwable.printStackTrace()
  470. })
  471. addDisposable(disposable)
  472. }
  473. private fun onAuthSuccess(authType: AuthType, userVo: UserVo) {
  474. // 在未登录首页验证成功后,判断用户是否有开门权限,登录+开门
  475. val configAuthType = LabApp.sLabConfig?.authType ?: return
  476. // showToast("当前类型${LabApp.sLabConfig?.authType} 取值参数${AuthTypeConfig.FOUR_CHOICE.type}")
  477. RcLog.info("当前类型${LabApp.sLabConfig?.authType} 取值参数${AuthTypeConfig.FOUR_CHOICE.type}")
  478. // when (configAuthType) {
  479. // "1","2","3"->{
  480. // openDoor(userVo)
  481. // }
  482. // "4"->{
  483. // // 进入密码验证
  484. // val intent = Intent(this, DualAuthActivity::class.java)
  485. // intent.putExtra("card_auth", true)
  486. // intent.putExtra("user", userVo)
  487. // startActivity(intent)
  488. // }
  489. // }
  490. when (configAuthType) {
  491. AuthTypeConfig.FINGER.type,
  492. AuthTypeConfig.FACE_OR_FINGER.type -> {
  493. if (AuthType.FINGER == authType) {
  494. openDoor(userVo)
  495. }
  496. }
  497. AuthTypeConfig.FOUR_CHOICE.type -> {
  498. openDoor(userVo)
  499. }
  500. AuthTypeConfig.CARD_PASSWORD.type -> {
  501. if (AuthType.CARD == authType) {
  502. // 进入密码验证
  503. val intent = Intent(this, DualAuthActivity::class.java)
  504. intent.putExtra("card_auth", true)
  505. intent.putExtra("user", userVo)
  506. startActivity(intent)
  507. }
  508. }
  509. }
  510. }
  511. private fun openDoor(userVo: UserVo) {
  512. LabApp.sUserVo = userVo
  513. val intent = Intent(this, MainActivity::class.java)
  514. startActivity(intent)
  515. }
  516. @Subscribe(threadMode = ThreadMode.MAIN)
  517. fun onUpdateEventEvent(event: UpdateEvent) {
  518. if (CommonUtils.stringParseInt(event.data.version) > DeviceUtils.getVersionCode(this)) {
  519. // 显示版本更新
  520. downloadApk(event.data.apkUploadFile)
  521. }
  522. }
  523. private var apkDownloading = false
  524. private fun downloadApk(downloadUrl: String) {
  525. if (apkDownloading) return
  526. apkDownloading = true
  527. callApkUpdateApi("2")
  528. ApkUpdater(this, BuildConfig.APPLICATION_ID, callback = object :
  529. ApkUpdater.DownloadCallback {
  530. override fun onProgress(progress: Int) {
  531. }
  532. override fun onFailed(errMsg: String?) {
  533. apkDownloading = false
  534. callApkUpdateApi("0")
  535. }
  536. override fun onSuccess(apkFile: String) {
  537. apkDownloading = false
  538. callApkUpdateApi("1")
  539. }
  540. }).downloadApk(downloadUrl)
  541. }
  542. /*
  543. * state 0:升级失败; 1:升级成功; 2:升级中
  544. */
  545. private fun callApkUpdateApi(state: String) {
  546. val disposable = ApiRepository.onepcApkUpdate(CommonUtils.getAndroidId(), state)
  547. .subscribe({ }, { })
  548. addDisposable(disposable)
  549. }
  550. @Subscribe(threadMode = ThreadMode.MAIN)
  551. fun onBulletinBoardEvent(event: BulletinBoardEvent) {
  552. mBulletinBoardAdapter.updateSensorValue(event.data)
  553. }
  554. private var mWaringDialog: WaringDialog? = null
  555. @Subscribe(threadMode = ThreadMode.MAIN)
  556. fun onWarningEvent(event: WarningEvent) {
  557. if (null == mWaringDialog) {
  558. if (!event.data.isNullOrEmpty()) {
  559. mWaringDialog = WaringDialog(this, event.data).apply {
  560. setOnDismissListener {
  561. mWaringDialog = null
  562. }
  563. }
  564. mWaringDialog!!.show()
  565. }
  566. } else {
  567. if (event.data.isNullOrEmpty()) {
  568. mWaringDialog!!.dismiss()
  569. } else {
  570. mWaringDialog!!.updateWaringValue(event.data)
  571. }
  572. }
  573. mBulletinBoardAdapter.updateWaringValue(event.data)
  574. }
  575. @Subscribe(threadMode = ThreadMode.MAIN)
  576. fun onEmergencyEvent(event: EmergencyEvent) {
  577. when (event.type) {
  578. 1 -> textParseVideo(event.data)
  579. 2 -> mAudioBinder?.startPlayer(event.data)
  580. }
  581. }
  582. private fun textParseVideo(text: String?) {
  583. if (text.isNullOrEmpty()) return
  584. showLoading()
  585. val disposable = ApiRepository.textParseVideo(text)
  586. .subscribe({ data ->
  587. dismissLoading()
  588. mAudioBinder?.startPlayer(data.url)
  589. }, { throwable ->
  590. dismissLoading()
  591. throwable.printStackTrace()
  592. showNetError(throwable)
  593. })
  594. addDisposable(disposable)
  595. }
  596. @Subscribe(threadMode = ThreadMode.MAIN)
  597. fun onLabInfoEvent(event: LabInfoEvent) {
  598. // {"msg":"5","sendDate":"2023-04-13 13:17:39"}
  599. if (event.message.isEmpty()) return
  600. LabApp.sLabConfig?.let { labConfig ->
  601. val authType = JSONObject(event.message).optString("msg", labConfig.authType)
  602. labConfig.authType = authType
  603. }
  604. }
  605. @Subscribe(threadMode = ThreadMode.MAIN)
  606. fun onOnlineUserEvent(event: OnlineUserEvent) {
  607. queryPerson()
  608. }
  609. }
  610. private class HomeBoardAdapter :
  611. BaseQuickAdapter<LabBulletinBoardVo, BaseViewHolder>(R.layout.item_home_board) {
  612. private val mValueMap = HashMap<String, BoardValue>()
  613. private val mWarningSet = HashSet<String>()
  614. private val mSensorMap = HashMap<String, SensorEnum>().apply {
  615. SensorEnum.values().forEach {
  616. put(it.funNum, it)
  617. }
  618. }
  619. private fun goneSensor(funNum: String?): Boolean {
  620. return SensorEnum.FIRE.funNum == funNum
  621. }
  622. override fun setNewInstance(list: MutableList<LabBulletinBoardVo>?) {
  623. val newlyList = list?.filter { !goneSensor(it.funNum) }
  624. if (null != newlyList) {
  625. mValueMap.clear()
  626. newlyList.forEach {
  627. mValueMap[it.funNum] = BoardValue(it.`val`, it.unit, it.formatVal)
  628. }
  629. }
  630. super.setNewInstance(newlyList?.toMutableList())
  631. }
  632. fun updateSensorValue(data: BulletinBoardEntity.Data?) {
  633. val newlyList = data?.functionStatuses?.filter { !goneSensor(it.funNum) }
  634. var valueChanged = mValueMap.size != newlyList?.size
  635. newlyList?.forEach { item ->
  636. val oldValue = mValueMap[item.funNum]
  637. if (!valueChanged) {
  638. valueChanged = oldValue?.value != item.`val` || oldValue?.unit != item.unit
  639. }
  640. mValueMap[item.funNum] = BoardValue(item.`val`, item.unit, item.formatVal)
  641. }
  642. if (valueChanged) {
  643. notifyDataSetChanged()
  644. }
  645. }
  646. fun updateWaringValue(data: List<LabBulletinBoardVo>?) {
  647. val newlyList = data?.filter { !goneSensor(it.funNum) }
  648. var valueChanged = mWarningSet.size != newlyList?.size
  649. if (!valueChanged) {
  650. val changedItem = newlyList?.find { !mWarningSet.contains(it.funNum) }
  651. valueChanged = null != changedItem
  652. }
  653. mWarningSet.clear()
  654. newlyList?.forEach { item ->
  655. mWarningSet.add(item.funNum)
  656. }
  657. if (valueChanged) {
  658. notifyDataSetChanged()
  659. }
  660. }
  661. override fun convert(holder: BaseViewHolder, item: LabBulletinBoardVo) {
  662. val itemView = holder.itemView as ItemBoardView
  663. itemView.setSensorInfo(
  664. item.describe,
  665. mSensorMap[item.funNum]?.icon ?: R.mipmap.icon_sy_wzcgq
  666. )
  667. val itemVal = mValueMap[item.funNum]
  668. itemView.setSensorValue(itemVal?.value, itemVal?.unit, mWarningSet.contains(item.funNum))
  669. }
  670. private data class BoardValue(val value: String?, val unit: String?, val formatVal: String?)
  671. }
  672. // type 1-值班人员 2-准入人员
  673. private class PersonFlipperAdapter(
  674. private val type: Int,
  675. private val data: List<LabPersonVo>?
  676. ) :
  677. BaseAdapter() {
  678. override fun getCount() = data?.size ?: 0
  679. override fun getItem(position: Int): LabPersonVo? {
  680. return data?.get(position)
  681. }
  682. override fun getItemId(position: Int) = position.toLong()
  683. override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
  684. val rootView: View
  685. val viewHolder: ViewHolder
  686. if (convertView == null) {
  687. val viewBinding =
  688. ItemHomePersonFlipperBinding.inflate(LayoutInflater.from(parent!!.context))
  689. rootView = viewBinding.root
  690. viewHolder = ViewHolder(viewBinding.pPhoto, viewBinding.pName, viewBinding.pCardNumber)
  691. rootView.tag = viewHolder
  692. } else {
  693. rootView = convertView
  694. viewHolder = convertView.tag as ViewHolder
  695. }
  696. getItem(position)?.let {
  697. Glide.with(rootView.context)
  698. .load(it.avatar)
  699. .placeholder(R.mipmap.icon_sign_in_avatar)
  700. .error(R.mipmap.icon_sign_in_avatar)
  701. // .transform(RoundedCorners(DeviceUtils.dip2px(context, 6f)))
  702. .into(viewHolder.imageView)
  703. viewHolder.name.text = it.userName
  704. if (1 == type) {
  705. viewHolder.number.text = it.userPhone // 值班人员
  706. } else {
  707. viewHolder.number.text = "准入期限:${formatValidTime(it.validEndTime)}" // 准入人员
  708. }
  709. }
  710. return rootView
  711. }
  712. private fun formatValidTime(input: String?): String {
  713. // 2023-10-10 => 23-10-10
  714. return if (input.isNullOrEmpty()) "" else input.substring(2, input.length)
  715. }
  716. class ViewHolder(
  717. val imageView: ImageView,
  718. val name: TextView,
  719. val number: TextView
  720. )
  721. }
  722. // 实验人员Adapter
  723. private class ExperimentPersonAdapter :
  724. BaseQuickAdapter<LabPersonVo, BaseViewHolder>(R.layout.item_home_person_flipper) {
  725. override fun convert(holder: BaseViewHolder, item: LabPersonVo) {
  726. Glide.with(context)
  727. .load(item.avatar)
  728. .placeholder(R.mipmap.icon_sign_in_avatar)
  729. .error(R.mipmap.icon_sign_in_avatar)
  730. // .transform(RoundedCorners(DeviceUtils.dip2px(context, 6f)))
  731. .into(holder.getView(R.id.pPhoto))
  732. // 签到时间:11-08 14:35
  733. holder.setText(R.id.pName, item.userName)
  734. .setText(R.id.pCardNumber, "签到时间:${formatSignTime(item.signTime)}")
  735. .setVisible(R.id.bottom_line, true)
  736. }
  737. private fun formatSignTime(time: String?): CharSequence {
  738. // 2023-03-30 15:45:25 => 03-30 15:45
  739. return if (time.isNullOrEmpty()) "" else time.subSequence(5, 16)
  740. }
  741. }