打开app不再清除本地数据,不再发送数据到结算终端,改为新增人脸采集接口,全量增量接口优化
This commit is contained in:
@@ -34,6 +34,11 @@ class MyApp : App() {
|
|||||||
Log.d("MyApp", "initialize: deviceId=$deviceId")
|
Log.d("MyApp", "initialize: deviceId=$deviceId")
|
||||||
GlobalData.deviceId = deviceId
|
GlobalData.deviceId = deviceId
|
||||||
|
|
||||||
|
// TODO: 临时测试----------------
|
||||||
|
// if ("2987f0c5-5754-33e9-b00a-251db5e2e55f" == deviceId) {
|
||||||
|
// GlobalData.deviceId = "79814f20-f253-397c-9da7-8430ffa5ef00"
|
||||||
|
// }
|
||||||
|
|
||||||
GlobalData.appVersion = AppUtil.getAppVersionCode(this).toString()
|
GlobalData.appVersion = AppUtil.getAppVersionCode(this).toString()
|
||||||
GlobalData.globalEquipmentCode = "202501171634"
|
GlobalData.globalEquipmentCode = "202501171634"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.sw.platecabinet.activity
|
package com.sw.platecabinet.activity
|
||||||
|
|
||||||
import android.app.Dialog
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -15,23 +14,19 @@ import androidx.activity.enableEdgeToEdge
|
|||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.sw.inbound.utils.DateTimeUtils
|
import com.sw.inbound.utils.DateTimeUtils
|
||||||
|
import com.sw.plate.App
|
||||||
import com.sw.plate.utils.Base64
|
import com.sw.plate.utils.Base64
|
||||||
import com.sw.plate.utils.ScanGunKeyEventHelper
|
import com.sw.plate.utils.ScanGunKeyEventHelper
|
||||||
import com.sw.plate.utils.ToastUtils
|
|
||||||
import com.sw.plate.utils.arcface.facedb.FaceDatabase
|
import com.sw.plate.utils.arcface.facedb.FaceDatabase
|
||||||
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
|
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
|
||||||
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
||||||
import com.sw.plate.utils.comn.SerialApi
|
|
||||||
import com.sw.plate.utils.comn.SerialPortManager
|
|
||||||
import com.sw.platecabinet.MyApp
|
import com.sw.platecabinet.MyApp
|
||||||
import com.sw.platecabinet.R
|
import com.sw.platecabinet.R
|
||||||
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
||||||
import com.sw.platecabinet.dialog.BalanceNotEnoughDialog
|
import com.sw.platecabinet.ext.clickWithCoroutines
|
||||||
import com.sw.platecabinet.ext.setClickListeners
|
|
||||||
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
||||||
import com.sw.platecabinet.model.response.UserFaceModel
|
import com.sw.platecabinet.model.response.UserFaceModel
|
||||||
import com.sw.platecabinet.utils.IntervalExecutor
|
import com.sw.platecabinet.utils.IntervalExecutor
|
||||||
@@ -60,10 +55,10 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
|||||||
protected var keyEventHelper: ScanGunKeyEventHelper? = null
|
protected var keyEventHelper: ScanGunKeyEventHelper? = null
|
||||||
|
|
||||||
// 管理员对应的viewmodel
|
// 管理员对应的viewmodel
|
||||||
private val settingViewModel by viewModels<SettingViewModel>()
|
val settingViewModel by viewModels<SettingViewModel>()
|
||||||
|
|
||||||
// 用户对应的viewModel
|
// 用户对应的viewModel
|
||||||
protected val viewModel by viewModels<UserViewModel>()
|
protected val userViewModel by viewModels<UserViewModel>()
|
||||||
|
|
||||||
private var startTime: Long = 0
|
private var startTime: Long = 0
|
||||||
|
|
||||||
@@ -88,8 +83,6 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
|||||||
registerKeyEvent()
|
registerKeyEvent()
|
||||||
val durationTime = System.currentTimeMillis() - startTime
|
val durationTime = System.currentTimeMillis() - startTime
|
||||||
Timber.d("启动时间:$durationTime")
|
Timber.d("启动时间:$durationTime")
|
||||||
|
|
||||||
startFaceTask()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,7 +108,7 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
|||||||
if (scanInfo.length > 6) {
|
if (scanInfo.length > 6) {
|
||||||
plateNumber = scanInfo.take(6)
|
plateNumber = scanInfo.take(6)
|
||||||
}
|
}
|
||||||
Log.d("TAG", "handleScanKeyInfo: "+ Gson().toJson(MyApp.plateList))
|
Log.d("TAG", "handleScanKeyInfo: " + Gson().toJson(MyApp.plateList))
|
||||||
if (MyApp.plateList == null) {
|
if (MyApp.plateList == null) {
|
||||||
initPlateList()
|
initPlateList()
|
||||||
}
|
}
|
||||||
@@ -146,12 +139,12 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
|||||||
|
|
||||||
fun updateTime() {
|
fun updateTime() {
|
||||||
headerBinding?.let {
|
headerBinding?.let {
|
||||||
it.tvLeftDate.setClickListeners(
|
it.tvLeftDate.clickWithCoroutines(
|
||||||
onDoubleClick = {
|
onDoubleClick = {
|
||||||
onLeftDoubleClick()
|
onLeftDoubleClick()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
it.tvRightTime.setClickListeners(
|
it.tvRightTime.clickWithCoroutines(
|
||||||
onDoubleClick = {
|
onDoubleClick = {
|
||||||
onRightDoubleClick()
|
onRightDoubleClick()
|
||||||
}
|
}
|
||||||
@@ -426,7 +419,6 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
|||||||
// private val dealyMillis = 10 * 60 * 1000L
|
// private val dealyMillis = 10 * 60 * 1000L
|
||||||
private val initialDelay = 5 * 60 * 1000L
|
private val initialDelay = 5 * 60 * 1000L
|
||||||
private val dealyMillis = 5 * 60 * 1000L
|
private val dealyMillis = 5 * 60 * 1000L
|
||||||
private var taskPageNo = 1
|
|
||||||
fun startFaceTask() {
|
fun startFaceTask() {
|
||||||
faceTaskJob =
|
faceTaskJob =
|
||||||
intervalExecutor.startIntervalTaskWithInitialDelay(initialDelay, dealyMillis) {
|
intervalExecutor.startIntervalTaskWithInitialDelay(initialDelay, dealyMillis) {
|
||||||
@@ -435,28 +427,28 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var faceTimestamp = 0L
|
private var faceTimestamp = 0L
|
||||||
|
//private var taskPageNo = 1
|
||||||
private fun getFaceIncrementList() {
|
private fun getFaceIncrementList(pageNo: Int = 1) {
|
||||||
val timestamp = SpTool.lastFaceTimestamp
|
val timestamp = SpTool.lastFaceTimestamp
|
||||||
if (timestamp == 0L) {
|
if (timestamp == 0L) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
settingViewModel.getFaceIncrementList(
|
settingViewModel.getFaceIncrementList(
|
||||||
pageNo = taskPageNo,
|
pageNo = pageNo,
|
||||||
timestamp = timestamp
|
timestamp = timestamp
|
||||||
) { list ->
|
) { list ->
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
if (taskPageNo == 1 && list.isEmpty()) {
|
if (pageNo == 1 && list.isEmpty()) {
|
||||||
//未查询到增量数据
|
//未查询到增量数据
|
||||||
return@runOnUiThread
|
return@runOnUiThread
|
||||||
}
|
}
|
||||||
updateFaceData(list)
|
updateFaceData(list)
|
||||||
if (list.size >= settingViewModel.PAGE_SIZE) {
|
//if (list.size >= settingViewModel.PAGE_SIZE) {
|
||||||
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
|
// faceTimestamp = list.last().faceUpdateTimestamp ?: 0
|
||||||
taskPageNo++
|
// taskPageNo++
|
||||||
getFaceIncrementList()
|
// getFaceIncrementList(taskPageNo)
|
||||||
return@runOnUiThread
|
// return@runOnUiThread
|
||||||
}
|
//}
|
||||||
if (list.isNotEmpty()) {
|
if (list.isNotEmpty()) {
|
||||||
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
|
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
|
||||||
}
|
}
|
||||||
@@ -481,7 +473,8 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
|||||||
null,
|
null,
|
||||||
Base64.decode(model.faceFeatureStr)
|
Base64.decode(model.faceFeatureStr)
|
||||||
).also {
|
).also {
|
||||||
it.userType = "1"
|
//1-会员、2-临时用户
|
||||||
|
it.userType = if (model.isMember) "1" else "2"
|
||||||
}
|
}
|
||||||
faceList.add(faceEntity)
|
faceList.add(faceEntity)
|
||||||
}
|
}
|
||||||
@@ -512,4 +505,13 @@ abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {
|
|||||||
MyApp.plateList = list
|
MyApp.plateList = list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clearAllFace(block: () -> Unit) {
|
||||||
|
Thread {
|
||||||
|
val faceDao = FaceDatabase.getInstance(App.getContext()).faceDao()
|
||||||
|
faceDao.deleteAll()
|
||||||
|
faceDao.resetId()
|
||||||
|
runOnUiThread { block() }
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,15 @@
|
|||||||
package com.sw.platecabinet.activity
|
package com.sw.platecabinet.activity
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.util.Log
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.activity.viewModels
|
|
||||||
import com.sw.inbound.utils.DateTimeUtils
|
|
||||||
import com.sw.plate.App
|
|
||||||
import com.sw.plate.utils.AppUtil
|
|
||||||
import com.sw.plate.utils.ToastUtils
|
import com.sw.plate.utils.ToastUtils
|
||||||
import com.sw.plate.utils.arcface.facedb.FaceDatabase
|
import com.sw.plate.utils.arcface.FaceApi
|
||||||
import com.sw.platecabinet.GlobalData
|
import com.sw.platecabinet.GlobalData
|
||||||
import com.sw.platecabinet.MyApp
|
|
||||||
import com.sw.platecabinet.databinding.ActivityDeviceInitBinding
|
import com.sw.platecabinet.databinding.ActivityDeviceInitBinding
|
||||||
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
||||||
import com.sw.platecabinet.ext.gone
|
import kotlinx.coroutines.Dispatchers
|
||||||
import com.sw.platecabinet.ext.invisible
|
import kotlinx.coroutines.launch
|
||||||
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
import kotlinx.coroutines.withContext
|
||||||
import com.sw.platecabinet.utils.SpTool
|
|
||||||
import com.sw.platecabinet.viewmodel.SettingViewModel
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设备初始化界面
|
* 设备初始化界面
|
||||||
@@ -53,37 +46,38 @@ class DeviceInitActivity : BaseActivity<ActivityDeviceInitBinding>() {
|
|||||||
// }, 1000)
|
// }, 1000)
|
||||||
initPlateList()
|
initPlateList()
|
||||||
showWaitingDialog("加载中……")
|
showWaitingDialog("加载中……")
|
||||||
clearAllFace {
|
lifecycleScope.launch {
|
||||||
viewModel.getUserFaceCache()
|
withContext(Dispatchers.Default) {
|
||||||
viewModel.getDeviceConfig { deviceConfig ->
|
val count = FaceApi().queryFaceCount()
|
||||||
runOnUiThread {
|
if (count == 0) {
|
||||||
if (deviceConfig == null) {
|
userViewModel.getUserFaceCache { status, msg ->
|
||||||
hideWaitingDialog()
|
getDeviceConfig()
|
||||||
ToastUtils.showToast("获取设备配置数据失败")
|
|
||||||
hideWaitingDialog()
|
|
||||||
goLoginActivity()
|
|
||||||
return@runOnUiThread
|
|
||||||
}
|
}
|
||||||
GlobalData.appId = deviceConfig.arcsoftAppId ?: ""
|
|
||||||
GlobalData.sdkKey = deviceConfig.arcsoftSdkKey ?: ""
|
|
||||||
GlobalData.activeKey = deviceConfig.arcsoftActiveKey ?: ""
|
|
||||||
binding.root.postDelayed({
|
|
||||||
hideWaitingDialog()
|
|
||||||
goLoginActivity()
|
|
||||||
}, 500)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// goLoginActivity()
|
getDeviceConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clearAllFace(block: () -> Unit) {
|
private fun getDeviceConfig() {
|
||||||
Thread {
|
userViewModel.getDeviceConfig { deviceConfig ->
|
||||||
val faceDao = FaceDatabase.getInstance(App.getContext()).faceDao()
|
runOnUiThread {
|
||||||
faceDao.deleteAll()
|
if (deviceConfig == null) {
|
||||||
faceDao.resetId()
|
hideWaitingDialog()
|
||||||
runOnUiThread { block() }
|
ToastUtils.showToast("获取设备配置数据失败")
|
||||||
}.start()
|
hideWaitingDialog()
|
||||||
|
goLoginActivity()
|
||||||
|
return@runOnUiThread
|
||||||
|
}
|
||||||
|
GlobalData.appId = deviceConfig.arcsoftAppId ?: ""
|
||||||
|
GlobalData.sdkKey = deviceConfig.arcsoftSdkKey ?: ""
|
||||||
|
GlobalData.activeKey = deviceConfig.arcsoftActiveKey ?: ""
|
||||||
|
binding.root.postDelayed({
|
||||||
|
hideWaitingDialog()
|
||||||
|
goLoginActivity()
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun registerDataChange() {
|
override fun registerDataChange() {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.sw.platecabinet.activity
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Point
|
import android.graphics.Point
|
||||||
import android.hardware.Camera
|
import android.hardware.Camera
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@@ -14,7 +15,6 @@ import androidx.annotation.RequiresApi
|
|||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import com.arcsoft.face.ErrorInfo
|
import com.arcsoft.face.ErrorInfo
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.sw.platecabinet.socket.TcpClientListenerImpl
|
|
||||||
import com.sw.inbound.utils.DateTimeUtils
|
import com.sw.inbound.utils.DateTimeUtils
|
||||||
import com.sw.plate.utils.Base64
|
import com.sw.plate.utils.Base64
|
||||||
import com.sw.plate.utils.ToastUtils
|
import com.sw.plate.utils.ToastUtils
|
||||||
@@ -35,17 +35,15 @@ import com.sw.plate.utils.arcface.facedb.entity.FaceEntity
|
|||||||
import com.sw.plate.utils.arcface.model.UserFaceInfo
|
import com.sw.plate.utils.arcface.model.UserFaceInfo
|
||||||
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel
|
||||||
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel.REGISTER_STATUS_READY
|
import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel.REGISTER_STATUS_READY
|
||||||
import com.sw.platecabinet.GlobalData
|
|
||||||
import com.sw.platecabinet.MyApp
|
import com.sw.platecabinet.MyApp
|
||||||
import com.sw.platecabinet.R
|
import com.sw.platecabinet.R
|
||||||
import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
|
import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
|
||||||
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
||||||
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
||||||
import com.sw.platecabinet.socket.LanServer
|
import com.sw.platecabinet.model.response.UserFaceModel
|
||||||
import com.sw.platecabinet.socket.LanServerListenerImpl
|
import com.sw.platecabinet.utils.BitmapSaver
|
||||||
import com.sw.platecabinet.socket.TcpClient
|
|
||||||
import com.sw.platecabinet.utils.Debouncer
|
import com.sw.platecabinet.utils.Debouncer
|
||||||
import com.sw.platecabinet.utils.FileUtil
|
import com.sw.platecabinet.utils.LogFileUtil
|
||||||
import com.sw.platecabinet.utils.PermissionHelper
|
import com.sw.platecabinet.utils.PermissionHelper
|
||||||
import com.sw.platecabinet.utils.PlateUtils
|
import com.sw.platecabinet.utils.PlateUtils
|
||||||
import com.sw.platecabinet.utils.SoundPoolUtil
|
import com.sw.platecabinet.utils.SoundPoolUtil
|
||||||
@@ -53,7 +51,6 @@ import com.sw.platecabinet.utils.SpTool
|
|||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import org.json.JSONObject
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
@@ -98,15 +95,14 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
|
|
||||||
override fun initialize() {
|
override fun initialize() {
|
||||||
instance = this
|
instance = this
|
||||||
viewModel.activeEngine()
|
userViewModel.activeEngine()
|
||||||
addSocketListener()
|
// addSocketListener()
|
||||||
initCountTime()
|
initCountTime()
|
||||||
initArcViewModel()
|
initArcViewModel()
|
||||||
initArcView()
|
initArcView()
|
||||||
openRectInfoDraw = true
|
openRectInfoDraw = true
|
||||||
recognizeViewModel.setDrawRectInfoTextValue(true)
|
recognizeViewModel.setDrawRectInfoTextValue(true)
|
||||||
//viewModel.generateToken()
|
//viewModel.generateToken()
|
||||||
// viewModel.activeEngine()
|
|
||||||
|
|
||||||
// binding.llToPwd.setOnClickListener {
|
// binding.llToPwd.setOnClickListener {
|
||||||
// val intent = Intent(this, LoginByPwdActivity::class.java)
|
// val intent = Intent(this, LoginByPwdActivity::class.java)
|
||||||
@@ -141,6 +137,8 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
//开启人脸增量数据定时任务
|
||||||
|
startFaceTask()
|
||||||
|
|
||||||
val soundMap = hashMapOf<String, Int>()
|
val soundMap = hashMapOf<String, Int>()
|
||||||
soundMap[COLLECT_SUCCESS] = R.raw.collect_success
|
soundMap[COLLECT_SUCCESS] = R.raw.collect_success
|
||||||
@@ -193,11 +191,11 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
if (this.userFaceInfo == null && userFaceInfo != null) {
|
if (this.userFaceInfo == null && userFaceInfo != null) {
|
||||||
recognizeViewModel.updateRegisterStatus(RecognizeViewModel.REGISTER_STATUS_DONE)
|
recognizeViewModel.updateRegisterStatus(RecognizeViewModel.REGISTER_STATUS_DONE)
|
||||||
this.userFaceInfo = userFaceInfo
|
this.userFaceInfo = userFaceInfo
|
||||||
getFaceDataBlock { faceData ->
|
getFaceDataBlock { faceData, headBmp ->
|
||||||
isCollecting.set(false)
|
isCollecting.set(false)
|
||||||
isCollectFace = false
|
isCollectFace = false
|
||||||
Thread {
|
Thread {
|
||||||
saveFaceInfo(faceData)
|
sendFaceData(faceData, headBmp)
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
return@setOnRegisterFinishedCallback
|
return@setOnRegisterFinishedCallback
|
||||||
@@ -476,8 +474,6 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
recognizeViewModel.destroy()
|
recognizeViewModel.destroy()
|
||||||
|
|
||||||
EventBus.getDefault().unregister(this)
|
EventBus.getDefault().unregister(this)
|
||||||
// getFaceScheduler?.shutdown()
|
|
||||||
// checkFaceScheduler?.shutdown()
|
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -705,7 +701,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
collectCount = 0
|
collectCount = 0
|
||||||
tempUserId = "${System.currentTimeMillis()}"
|
tempUserId = "${System.currentTimeMillis()}"
|
||||||
resumeCamera()
|
resumeCamera()
|
||||||
viewModel.resetUserInfo()
|
userViewModel.resetUserInfo()
|
||||||
countDownTimer?.let {
|
countDownTimer?.let {
|
||||||
it.cancel()
|
it.cancel()
|
||||||
it.start()
|
it.start()
|
||||||
@@ -754,6 +750,9 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 采集人脸
|
||||||
|
*/
|
||||||
private fun collectFace() {
|
private fun collectFace() {
|
||||||
loadLogInfo("collectFace: -----------1,开始采集人脸,开始时间:${DateTimeUtils.getDateTimeString()}----------")
|
loadLogInfo("collectFace: -----------1,开始采集人脸,开始时间:${DateTimeUtils.getDateTimeString()}----------")
|
||||||
if (isFirstOpen) return
|
if (isFirstOpen) return
|
||||||
@@ -765,25 +764,43 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
loadLogInfo("collectFace: ----------5,人脸采集中-----------")
|
loadLogInfo("collectFace: ----------5,人脸采集中-----------")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendFaceData(faceData: String) {
|
/**
|
||||||
|
* 改为上传人脸数据,不需要发生人脸数据到收银端
|
||||||
|
*/
|
||||||
|
private fun sendFaceData(faceData: String, headBmp: Bitmap) {
|
||||||
loadLogInfo("collectFace,sendFaceData: ----------11,发送人脸数据-----------")
|
loadLogInfo("collectFace,sendFaceData: ----------11,发送人脸数据-----------")
|
||||||
// 给某个客户端发送
|
|
||||||
val jsonObject = JSONObject().also {
|
val imageFile = BitmapSaver.saveToAppFilesDir(
|
||||||
it.put("type", "faceFeature")
|
headBmp, this, "IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||||
it.put("content", faceData)
|
)
|
||||||
|
loadLogInfo("collectFace,sendFaceData:${imageFile?.absolutePath}")
|
||||||
|
if (imageFile == null) {
|
||||||
|
ToastUtils.showToast("获取人脸照片失败")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
tcpClient?.send(jsonObject)
|
settingViewModel.addUserFace(faceData, imageFile) { status, faceModel ->
|
||||||
|
loadLogInfo("collectFace,saveFaceInfo: ----------12,人脸数据发送完成时间:${DateTimeUtils.getDateTimeString()},结果:$status-----------")
|
||||||
|
if (status.not()) {
|
||||||
|
ToastUtils.showToast("新增数据失败")
|
||||||
|
loadLogInfo("collectFace,sendFaceData: ----------12,发送人脸数据失败,faceData=${faceData}")
|
||||||
|
return@addUserFace
|
||||||
|
}
|
||||||
|
if (faceModel == null) {
|
||||||
|
ToastUtils.showToast("新增数据成功,但未拿到接口数据")
|
||||||
|
loadLogInfo("collectFace,sendFaceData: ----------12,发送人脸数据成功但接口返回为null,faceData=${faceData}")
|
||||||
|
return@addUserFace
|
||||||
|
}
|
||||||
|
saveFaceInfo(faceModel)
|
||||||
|
}
|
||||||
|
// // 给某个客户端发送
|
||||||
|
// val jsonObject = JSONObject().also {
|
||||||
|
// it.put("type", "faceFeature")
|
||||||
|
// it.put("content", faceData)
|
||||||
|
// }
|
||||||
|
// tcpClient?.send(jsonObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
// private var getFaceScheduler: ScheduledExecutorService? = null
|
private fun getFaceDataBlock(block: (String, Bitmap) -> Unit) {
|
||||||
// private var checkFaceScheduler: ScheduledExecutorService? = null
|
|
||||||
//
|
|
||||||
// private fun initFaceScheduler() {
|
|
||||||
//// getFaceScheduler = Executors.newScheduledThreadPool(1)
|
|
||||||
// checkFaceScheduler = Executors.newScheduledThreadPool(1)
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun getFaceDataBlock(block: (String) -> Unit) {
|
|
||||||
if (userFaceInfo == null || userFaceInfo?.faceFeature?.featureData == null) {
|
if (userFaceInfo == null || userFaceInfo?.faceFeature?.featureData == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -792,7 +809,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
loadLogInfo("collectFace,getFaceData: ----------7,拿到人脸提取特征数据时间:${DateTimeUtils.getDateTimeString()}-----------")
|
loadLogInfo("collectFace,getFaceData: ----------7,拿到人脸提取特征数据时间:${DateTimeUtils.getDateTimeString()}-----------")
|
||||||
block(faceData)
|
block(faceData, userFaceInfo!!.headBmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -801,7 +818,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
*/
|
*/
|
||||||
private fun loadLogInfo(msg: String) {
|
private fun loadLogInfo(msg: String) {
|
||||||
Timber.tag(TAG).d(msg)
|
Timber.tag(TAG).d(msg)
|
||||||
FileUtil.saveLog(msg)
|
LogFileUtil.saveLog(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var facePreviewInfoList: MutableList<FacePreviewInfo>? = null
|
private var facePreviewInfoList: MutableList<FacePreviewInfo>? = null
|
||||||
@@ -809,23 +826,17 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
|
|
||||||
private var currentUserId: String? = null
|
private var currentUserId: String? = null
|
||||||
|
|
||||||
private fun saveFaceInfo(faceData: String) {
|
private fun saveFaceInfo(faceModel: UserFaceModel) {
|
||||||
try {
|
try {
|
||||||
sendFaceData(faceData)
|
|
||||||
loadLogInfo("collectFace,saveFaceInfo: ----------12,人脸数据发送完成时间:${DateTimeUtils.getDateTimeString()}-----------")
|
|
||||||
|
|
||||||
// runOnUiThread {
|
|
||||||
// openPlate(tempUserId)
|
|
||||||
// }
|
|
||||||
|
|
||||||
loadLogInfo("collectFace,saveFaceInfo: ----------8,保存人脸取特征数据-----------")
|
loadLogInfo("collectFace,saveFaceInfo: ----------8,保存人脸取特征数据-----------")
|
||||||
val faceDao = FaceDatabase.getInstance(this).faceDao()
|
val faceDao = FaceDatabase.getInstance(this).faceDao()
|
||||||
val faceEntity = FaceEntity(
|
val faceEntity = FaceEntity(
|
||||||
tempUserId,
|
faceModel.userId,
|
||||||
null,
|
null,
|
||||||
Base64.decode(faceData)
|
Base64.decode(faceModel.faceFeatureStr)
|
||||||
).also {
|
).also {
|
||||||
it.userType = "2"
|
//1-会员、2-临时用户
|
||||||
|
it.userType = if (faceModel.isMember) "1" else "2"
|
||||||
}
|
}
|
||||||
faceDao.insert(faceEntity)
|
faceDao.insert(faceEntity)
|
||||||
loadLogInfo("collectFace,saveFaceInfo: ----------10,人脸数据保存完成-----------")
|
loadLogInfo("collectFace,saveFaceInfo: ----------10,人脸数据保存完成-----------")
|
||||||
@@ -843,70 +854,70 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var collectCount = 0;
|
private var collectCount = 0
|
||||||
|
|
||||||
private var tcpClient: TcpClient? = null
|
// private var tcpClient: TcpClient? = null
|
||||||
|
//
|
||||||
private fun addSocketListener() {
|
// private fun addSocketListener() {
|
||||||
// val ipAddress = NetworkUtils.getIPAddress(true)
|
//// val ipAddress = NetworkUtils.getIPAddress(true)
|
||||||
// loadLogInfo( "addSocketListener,ipAddress: $ipAddress");
|
//// loadLogInfo( "addSocketListener,ipAddress: $ipAddress");
|
||||||
tcpClient = TcpClient(
|
// tcpClient = TcpClient(
|
||||||
"192.168.1.95",
|
// "192.168.1.95",
|
||||||
5000,
|
// 5000,
|
||||||
GlobalData.deviceId, // clientId
|
// GlobalData.deviceId, // clientId
|
||||||
5000, // connectTimeoutMs
|
// 5000, // connectTimeoutMs
|
||||||
10 * 1000, // heartbeatIntervalMs
|
// 10 * 1000, // heartbeatIntervalMs
|
||||||
30 * 1000 // heartbeatTimeoutMs
|
// 30 * 1000 // heartbeatTimeoutMs
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
tcpClient?.setListener(object : TcpClientListenerImpl() {
|
// tcpClient?.setListener(object : TcpClientListenerImpl() {
|
||||||
override fun onSendSuccess(json: JSONObject?) {
|
// override fun onSendSuccess(json: JSONObject?) {
|
||||||
super.onSendSuccess(json)
|
// super.onSendSuccess(json)
|
||||||
loadLogInfo("collectFace,TcpClientListener发送成功:$json")
|
// loadLogInfo("collectFace,TcpClientListener发送成功:$json")
|
||||||
// toast("发送成功")
|
//// toast("发送成功")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override fun onSendFailed(json: JSONObject?, e: java.lang.Exception?) {
|
// override fun onSendFailed(json: JSONObject?, e: java.lang.Exception?) {
|
||||||
super.onSendFailed(json, e)
|
// super.onSendFailed(json, e)
|
||||||
ToastUtils.showToast("发送失败${e?.message}")
|
// ToastUtils.showToast("发送失败${e?.message}")
|
||||||
loadLogInfo("collectFace,TcpClientListener人脸数据发送失败:${e?.message}")
|
// loadLogInfo("collectFace,TcpClientListener人脸数据发送失败:${e?.message}")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override fun onMessage(json: JSONObject?) {
|
// override fun onMessage(json: JSONObject?) {
|
||||||
super.onMessage(json)
|
// super.onMessage(json)
|
||||||
loadLogInfo("collectFace,TcpClientListener收到消息:$json")
|
// loadLogInfo("collectFace,TcpClientListener收到消息:$json")
|
||||||
val type = json?.getInt("type")
|
// val type = json?.getInt("type")
|
||||||
// 根据服务端消息类型处理删除新增临时用户人脸数据---------------------
|
// // 根据服务端消息类型处理删除新增临时用户人脸数据---------------------
|
||||||
when (type) {
|
// when (type) {
|
||||||
LanServer.TYPE_ADD_FACE_DATA -> {
|
// LanServer.TYPE_ADD_FACE_DATA -> {
|
||||||
//采集设备id自己生成,不接收服务端的,在本地只判断是否存在同一人脸数据
|
// //采集设备id自己生成,不接收服务端的,在本地只判断是否存在同一人脸数据
|
||||||
loadLogInfo("collectFace,TcpClientListener收到消息,新增用户:采集设备id自己生成,不接收服务端的,在本地只判断是否存在同一人脸数据")
|
// loadLogInfo("collectFace,TcpClientListener收到消息,新增用户:采集设备id自己生成,不接收服务端的,在本地只判断是否存在同一人脸数据")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
LanServer.TYPE_CLEAR_FACE_DATA -> {
|
// LanServer.TYPE_CLEAR_FACE_DATA -> {
|
||||||
clearFaceData()
|
// clearFaceData()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
else -> {}
|
// else -> {}
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
tcpClient?.start()
|
// tcpClient?.start()
|
||||||
|
//
|
||||||
try {
|
// try {
|
||||||
LanServer.getInstance().let {
|
// LanServer.getInstance().let {
|
||||||
it.setListener(object : LanServerListenerImpl() {
|
// it.setListener(object : LanServerListenerImpl() {
|
||||||
override fun onMessageReceived(clientId: String?, message: JSONObject?) {
|
// override fun onMessageReceived(clientId: String?, message: JSONObject?) {
|
||||||
super.onMessageReceived(clientId, message)
|
// super.onMessageReceived(clientId, message)
|
||||||
ToastUtils.showToast("收到消息clientId=$clientId")
|
// ToastUtils.showToast("收到消息clientId=$clientId")
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
it.start()
|
// it.start()
|
||||||
}
|
// }
|
||||||
} catch (e: Exception) {
|
// } catch (e: Exception) {
|
||||||
e.printStackTrace()
|
// e.printStackTrace()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
private fun clearFaceData() {
|
private fun clearFaceData() {
|
||||||
Thread {
|
Thread {
|
||||||
@@ -917,34 +928,6 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
// private val WAITING_TIME = 3 * 1000L
|
|
||||||
// private var checkStartTime = 0L
|
|
||||||
|
|
||||||
private fun checkFaceState() {
|
|
||||||
// checkStartTime = System.currentTimeMillis()
|
|
||||||
//
|
|
||||||
// checkFaceScheduler?.scheduleWithFixedDelay(
|
|
||||||
// {
|
|
||||||
// checkFaceBlock()
|
|
||||||
// }, 5L, 5L, TimeUnit.MILLISECONDS
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
|
|
||||||
private var isCollectFace = false
|
private var isCollectFace = false
|
||||||
// private fun checkFaceBlock() {
|
|
||||||
// loadLogInfo("collectFace,currentUserId=${currentUserId}")
|
|
||||||
// if (currentUserId.isNullOrBlank().not()) {
|
|
||||||
// isCollectFace = false
|
|
||||||
//
|
|
||||||
// checkFaceScheduler?.shutdown()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//// if (System.currentTimeMillis() - checkStartTime >= WAITING_TIME) {
|
|
||||||
//// //超过1秒采集人脸并识别
|
|
||||||
//// checkFaceScheduler?.shutdown()
|
|
||||||
//// isCollectFace = true
|
|
||||||
//// collectFace()
|
|
||||||
//// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,14 +2,14 @@ package com.sw.platecabinet.activity
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import com.sw.platecabinet.MyApp
|
import com.sw.plate.utils.ToastUtils
|
||||||
import com.sw.platecabinet.R
|
import com.sw.platecabinet.R
|
||||||
import com.sw.platecabinet.databinding.ActivityMainBinding
|
import com.sw.platecabinet.databinding.ActivityMainBinding
|
||||||
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
||||||
|
import com.sw.platecabinet.dialog.CustomDialog
|
||||||
import com.sw.platecabinet.fragment.PlateCabinetFullFragment
|
import com.sw.platecabinet.fragment.PlateCabinetFullFragment
|
||||||
import com.sw.platecabinet.fragment.PlateOpenFragment
|
import com.sw.platecabinet.fragment.PlateOpenFragment
|
||||||
import com.sw.platecabinet.fragment.SettingListFragment
|
import com.sw.platecabinet.fragment.SettingListFragment
|
||||||
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
|
||||||
import com.sw.platecabinet.utils.FragmentHelper
|
import com.sw.platecabinet.utils.FragmentHelper
|
||||||
|
|
||||||
typealias Callback = (String) -> Unit
|
typealias Callback = (String) -> Unit
|
||||||
@@ -49,7 +49,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
// context.startActivity(intent)
|
// context.startActivity(intent)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fun start(context: Context,pageType: PageType, isScanCode: Boolean = false) {
|
fun start(context: Context, pageType: PageType, isScanCode: Boolean = false) {
|
||||||
val intent = Intent(context, MainActivity::class.java)
|
val intent = Intent(context, MainActivity::class.java)
|
||||||
intent.putExtra(PARAM_PAGE_TYPE, pageType.name)
|
intent.putExtra(PARAM_PAGE_TYPE, pageType.name)
|
||||||
intent.putExtra(PlateOpenFragment.IS_SCAN_CODE, isScanCode)
|
intent.putExtra(PlateOpenFragment.IS_SCAN_CODE, isScanCode)
|
||||||
@@ -85,7 +85,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onRightDoubleClick() {
|
override fun onRightDoubleClick() {
|
||||||
|
if (pageType == PageType.SETTING_LIST) {
|
||||||
|
loadClearDialog()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleScanKeyInfo(scanInfo: String) {
|
override fun handleScanKeyInfo(scanInfo: String) {
|
||||||
@@ -101,8 +103,27 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||||||
override fun registerDataChange() {
|
override fun registerDataChange() {
|
||||||
super.registerDataChange()
|
super.registerDataChange()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载清除数据弹窗
|
||||||
|
*/
|
||||||
|
private fun loadClearDialog() {
|
||||||
|
CustomDialog(
|
||||||
|
activity = this,
|
||||||
|
content = "请确认是否清除本地所有数据,并重新拉取全量人脸数据?",
|
||||||
|
onConfirm = {
|
||||||
|
showWaitingDialog("加载中……")
|
||||||
|
clearAllFace {
|
||||||
|
userViewModel.getUserFaceCache { status, msg ->
|
||||||
|
hideWaitingDialog()
|
||||||
|
ToastUtils.showToast(
|
||||||
|
if (status) "请求成功,$msg" else "请求失败,$msg"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 界面类型
|
* 界面类型
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.sw.platecabinet.dialog
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.graphics.drawable.ColorDrawable
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.Window
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import com.sw.platecabinet.databinding.DialogCustomBinding
|
||||||
|
import com.sw.platecabinet.databinding.DialogUserBindRemindBinding
|
||||||
|
import com.sw.platecabinet.ext.dp
|
||||||
|
|
||||||
|
open class CustomDialog(
|
||||||
|
var activity: FragmentActivity,
|
||||||
|
var content: String,
|
||||||
|
var onCancel: () -> Unit = {},
|
||||||
|
var onConfirm: () -> Unit = {},
|
||||||
|
) : Dialog(activity) {
|
||||||
|
|
||||||
|
private lateinit var binding: DialogCustomBinding
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||||
|
binding = DialogCustomBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
window?.run {
|
||||||
|
attributes = attributes.apply {
|
||||||
|
width = 480.dp
|
||||||
|
}
|
||||||
|
setBackgroundDrawable(ColorDrawable())
|
||||||
|
setCancelable(false)
|
||||||
|
}
|
||||||
|
binding.tvContent.text = content
|
||||||
|
addClickListener()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addClickListener() {
|
||||||
|
binding.btnCancel.setOnClickListener {
|
||||||
|
onCancel()
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
binding.btnConfirm.setOnClickListener {
|
||||||
|
onConfirm()
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,6 +4,11 @@ import android.os.Handler
|
|||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置 TextView 的双击和单击事件监听器
|
* 设置 TextView 的双击和单击事件监听器
|
||||||
@@ -30,4 +35,38 @@ fun TextView.setClickListeners(
|
|||||||
clickCount = 0 // 重置计数
|
clickCount = 0 // 重置计数
|
||||||
}, doubleClickInterval)
|
}, doubleClickInterval)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun View.clickWithCoroutines(
|
||||||
|
doubleClickInterval: Long = 300,
|
||||||
|
onDoubleClick: (View) -> Unit = {},
|
||||||
|
onSingleClick: (View) -> Unit = {}
|
||||||
|
) {
|
||||||
|
var pendingItem: View? = null
|
||||||
|
var lastClickTime: Long = 0
|
||||||
|
var clickJob: Job? = null
|
||||||
|
|
||||||
|
setOnClickListener { view ->
|
||||||
|
val currentTime = System.currentTimeMillis()
|
||||||
|
|
||||||
|
// 如果是同一控件且在双击间隔内,则判定为双击
|
||||||
|
if (pendingItem === view && currentTime - lastClickTime < doubleClickInterval) {
|
||||||
|
// 取消之前的单击任务
|
||||||
|
clickJob?.cancel()
|
||||||
|
onDoubleClick(view)
|
||||||
|
pendingItem = null
|
||||||
|
} else {
|
||||||
|
// 取消之前的单击任务
|
||||||
|
clickJob?.cancel()
|
||||||
|
|
||||||
|
// 启动新的单击任务
|
||||||
|
clickJob = CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
delay(doubleClickInterval)
|
||||||
|
onSingleClick(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingItem = view
|
||||||
|
lastClickTime = currentTime
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -25,6 +25,18 @@ data class UserFaceModel(
|
|||||||
|
|
||||||
val userId: String? = "",
|
val userId: String? = "",
|
||||||
val faceFeatureStr: String? = "",
|
val faceFeatureStr: String? = "",
|
||||||
val faceUpdateTimestamp:Long?=null,
|
val faceUpdateTimestamp: Long? = null,
|
||||||
val faceDeleted: Boolean?=false
|
/**
|
||||||
|
* 人脸删除标识
|
||||||
|
*/
|
||||||
|
val faceDeleted: Boolean? = false,
|
||||||
|
/**
|
||||||
|
* 会员编号
|
||||||
|
*/
|
||||||
|
val cardNo: String,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否会员
|
||||||
|
*/
|
||||||
|
val isMember: Boolean
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
@@ -16,7 +16,8 @@ object ApiClient {
|
|||||||
// private const val DEVICE_BASE_URL = "http://device.shuziweidao.com:8889/"
|
// private const val DEVICE_BASE_URL = "http://device.shuziweidao.com:8889/"
|
||||||
private var DEVICE_BASE_URL = GlobalData.appBaseUrl
|
private var DEVICE_BASE_URL = GlobalData.appBaseUrl
|
||||||
// private const val BASE_URL = "http://192.168.1.8:9092"
|
// private const val BASE_URL = "http://192.168.1.8:9092"
|
||||||
private const val TIME_OUT = 30L // 超时时间(秒)
|
// private const val TIME_OUT = 30L // 超时时间(秒)
|
||||||
|
private const val TIME_OUT = 60L // 超时时间(秒)
|
||||||
|
|
||||||
val okHttpClient = OkHttpClient.Builder()
|
val okHttpClient = OkHttpClient.Builder()
|
||||||
.connectTimeout(TIME_OUT, TimeUnit.SECONDS)
|
.connectTimeout(TIME_OUT, TimeUnit.SECONDS)
|
||||||
|
|||||||
@@ -11,12 +11,15 @@ import com.sw.platecabinet.model.response.EquipmentInfo
|
|||||||
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
||||||
import com.sw.platecabinet.model.response.SearchResult
|
import com.sw.platecabinet.model.response.SearchResult
|
||||||
import com.sw.platecabinet.model.response.UserFaceModel
|
import com.sw.platecabinet.model.response.UserFaceModel
|
||||||
|
import okhttp3.MultipartBody
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.Field
|
import retrofit2.http.Field
|
||||||
import retrofit2.http.FormUrlEncoded
|
import retrofit2.http.FormUrlEncoded
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.Header
|
import retrofit2.http.Header
|
||||||
|
import retrofit2.http.Multipart
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
|
import retrofit2.http.Part
|
||||||
import retrofit2.http.Query
|
import retrofit2.http.Query
|
||||||
import retrofit2.http.Url
|
import retrofit2.http.Url
|
||||||
|
|
||||||
@@ -75,7 +78,7 @@ interface ApiService {
|
|||||||
// @Body param: LoginParam
|
// @Body param: LoginParam
|
||||||
// ): ApiResponse<EquipmentUserInfo>
|
// ): ApiResponse<EquipmentUserInfo>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 餐盘用户信息获取
|
* 餐盘用户信息获取
|
||||||
*/
|
*/
|
||||||
@POST//("/shuwei-zhct/swEquipmentRelUser/equipmentBoxLogin")
|
@POST//("/shuwei-zhct/swEquipmentRelUser/equipmentBoxLogin")
|
||||||
@@ -145,7 +148,7 @@ interface ApiService {
|
|||||||
// ): ApiResponse<EquipmentUserInfo>
|
// ): ApiResponse<EquipmentUserInfo>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过餐盘号获取信息
|
* 通过餐盘号获取信息
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@@ -155,8 +158,6 @@ interface ApiService {
|
|||||||
): ApiResponse<EquipmentUserInfo>
|
): ApiResponse<EquipmentUserInfo>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取人脸增量数据
|
* 获取人脸增量数据
|
||||||
*
|
*
|
||||||
@@ -173,8 +174,8 @@ interface ApiService {
|
|||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
suspend fun getFaceIncrementList(
|
suspend fun getFaceIncrementList(
|
||||||
@Url url:String = "${GlobalData.appBaseUrl}/terminal/neglect/common/app/faceFeature/increment/list",
|
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/common/app/faceFeature/increment/list",
|
||||||
@Body param:Map<String, Long>
|
@Body param: Map<String, Long>
|
||||||
): ApiResponse<List<UserFaceModel>?>
|
): ApiResponse<List<UserFaceModel>?>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -185,5 +186,22 @@ interface ApiService {
|
|||||||
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/common/app/getYxEquipmentByEquipmentCode"
|
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/common/app/getYxEquipmentByEquipmentCode"
|
||||||
): ApiResponse<DeviceConfig?>
|
): ApiResponse<DeviceConfig?>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加人脸数据
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@FormUrlEncoded
|
||||||
|
suspend fun addUserFace(
|
||||||
|
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/common/app/addUserByFace",
|
||||||
|
@Field("featureChar") faceData:String,
|
||||||
|
@Field("url") imageUr:String
|
||||||
|
): ApiResponse<UserFaceModel?>
|
||||||
|
|
||||||
|
@Multipart
|
||||||
|
@POST
|
||||||
|
suspend fun uploadImage(
|
||||||
|
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/upload",
|
||||||
|
@Part file: MultipartBody.Part,
|
||||||
|
): ApiResponse<String?>
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,14 @@
|
|||||||
package com.sw.platecabinet.repository
|
package com.sw.platecabinet.repository
|
||||||
|
|
||||||
import com.sw.platecabinet.GlobalData
|
|
||||||
import com.sw.platecabinet.model.DeviceConfig
|
import com.sw.platecabinet.model.DeviceConfig
|
||||||
import com.sw.platecabinet.model.request.BindParam
|
|
||||||
import com.sw.platecabinet.model.request.EquipmentParam
|
|
||||||
import com.sw.platecabinet.model.request.LoginParam
|
|
||||||
import com.sw.platecabinet.model.request.SearchParam
|
import com.sw.platecabinet.model.request.SearchParam
|
||||||
import com.sw.platecabinet.model.response.ApiResponse
|
import com.sw.platecabinet.model.response.ApiResponse
|
||||||
import com.sw.platecabinet.model.response.EquipmentInfo
|
|
||||||
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
||||||
import com.sw.platecabinet.model.response.SearchResult
|
import com.sw.platecabinet.model.response.SearchResult
|
||||||
import com.sw.platecabinet.model.response.UserFaceModel
|
import com.sw.platecabinet.model.response.UserFaceModel
|
||||||
import com.sw.platecabinet.network.api.ApiService
|
import com.sw.platecabinet.network.api.ApiService
|
||||||
|
import com.sw.platecabinet.utils.FileUtils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程数据处理
|
* 远程数据处理
|
||||||
@@ -73,19 +70,19 @@ class RemoteRepository constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 登录
|
// * 登录
|
||||||
*/
|
// */
|
||||||
suspend fun equipmentBoxLogin(param: LoginParam): ApiResponse<EquipmentUserInfo> {
|
// suspend fun equipmentBoxLogin(param: LoginParam): ApiResponse<EquipmentUserInfo> {
|
||||||
return safeApiCall { apiService.equipmentBoxLogin(param = param) }
|
// return safeApiCall { apiService.equipmentBoxLogin(param = param) }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 获取设备绑定用户列表
|
// * 获取设备绑定用户列表
|
||||||
*/
|
// */
|
||||||
suspend fun getEquipmentList(): ApiResponse<List<EquipmentUserInfo>> {
|
// suspend fun getEquipmentList(): ApiResponse<List<EquipmentUserInfo>> {
|
||||||
return safeApiCall { apiService.getEquipmentList() }
|
// return safeApiCall { apiService.getEquipmentList() }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * 餐盘用户信息绑定解绑
|
// * 餐盘用户信息绑定解绑
|
||||||
@@ -94,13 +91,13 @@ class RemoteRepository constructor(
|
|||||||
// return safeApiCall { apiService.bindEquipment(param = param) }
|
// return safeApiCall { apiService.bindEquipment(param = param) }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
suspend fun plateBind(param: BindParam): ApiResponse<EquipmentUserInfo?> {
|
// suspend fun plateBind(param: BindParam): ApiResponse<EquipmentUserInfo?> {
|
||||||
return safeApiCall { apiService.plateBind(param = param) }
|
// return safeApiCall { apiService.plateBind(param = param) }
|
||||||
}
|
// }
|
||||||
|
|
||||||
suspend fun plateUnbind(id: Long?): ApiResponse<Any?> {
|
// suspend fun plateUnbind(id: Long?): ApiResponse<Any?> {
|
||||||
return safeApiCall { apiService.plateUnbind(id = id) }
|
// return safeApiCall { apiService.plateUnbind(id = id) }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户信息模糊搜索
|
* 用户信息模糊搜索
|
||||||
@@ -116,11 +113,11 @@ class RemoteRepository constructor(
|
|||||||
return safeApiCall { apiService.findByPlateNumber(plateNumber = plateNumber) }
|
return safeApiCall { apiService.findByPlateNumber(plateNumber = plateNumber) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 获取人脸增量数据
|
// * 获取人脸增量数据
|
||||||
*
|
// *
|
||||||
* @param timeDate 时间戳(毫秒级)
|
// * @param timeDate 时间戳(毫秒级)
|
||||||
*/
|
// */
|
||||||
// suspend fun getHeartbeatInterface(timeDate: Long): ApiResponse<List<UserFaceModel>> {
|
// suspend fun getHeartbeatInterface(timeDate: Long): ApiResponse<List<UserFaceModel>> {
|
||||||
// return safeApiCall { apiService.getHeartbeatInterface(timeDate = timeDate) }
|
// return safeApiCall { apiService.getHeartbeatInterface(timeDate = timeDate) }
|
||||||
// }
|
// }
|
||||||
@@ -144,4 +141,19 @@ class RemoteRepository constructor(
|
|||||||
suspend fun getDeviceConfig(): ApiResponse<DeviceConfig?> {
|
suspend fun getDeviceConfig(): ApiResponse<DeviceConfig?> {
|
||||||
return safeApiCall { apiService.getDeviceConfig() }
|
return safeApiCall { apiService.getDeviceConfig() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun addUserFace(faceData: String, imageUr:String): ApiResponse<UserFaceModel?> {
|
||||||
|
return safeApiCall { apiService.addUserFace(faceData = faceData, imageUr = imageUr) }
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun uploadImage(file: File): ApiResponse<String?> {
|
||||||
|
return safeApiCall {
|
||||||
|
val part = FileUtils.genRequestPart(file)
|
||||||
|
if (part == null) {
|
||||||
|
ApiResponse(code = "-1", msg = "解析图片失败")
|
||||||
|
} else {
|
||||||
|
apiService.uploadImage(file = part)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.sw.platecabinet.utils
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.os.Environment
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import kotlin.io.use
|
||||||
|
|
||||||
|
object BitmapSaver {
|
||||||
|
// 保存到公共目录(需WRITE_EXTERNAL_STORAGE权限)
|
||||||
|
fun saveToPublicDirectory(
|
||||||
|
bitmap: Bitmap,
|
||||||
|
folderName: String = Environment.DIRECTORY_PICTURES,
|
||||||
|
fileName: String,
|
||||||
|
format: Bitmap.CompressFormat = Bitmap.CompressFormat.PNG,
|
||||||
|
quality: Int = 100
|
||||||
|
): File? {
|
||||||
|
val dir = Environment.getExternalStoragePublicDirectory(folderName)
|
||||||
|
if (!dir.exists()) dir.mkdirs()
|
||||||
|
|
||||||
|
return saveBitmap(bitmap, File(dir, fileName), format, quality)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存到应用私有目录(无需权限)
|
||||||
|
fun saveToAppFilesDir(
|
||||||
|
bitmap: Bitmap,
|
||||||
|
context: Context,
|
||||||
|
fileName: String,
|
||||||
|
format: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG,
|
||||||
|
quality: Int = 100
|
||||||
|
): File? {
|
||||||
|
//val dir = context.getExternalFilesDir(null)
|
||||||
|
val dir = context.cacheDir
|
||||||
|
val cropFile = File(dir, "crop")
|
||||||
|
if (cropFile.exists().not()) {
|
||||||
|
cropFile.mkdirs()
|
||||||
|
}
|
||||||
|
return saveBitmap(bitmap, File(cropFile, fileName), format, quality)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveBitmap(
|
||||||
|
bitmap: Bitmap,
|
||||||
|
outputFile: File,
|
||||||
|
format: Bitmap.CompressFormat,
|
||||||
|
quality: Int
|
||||||
|
): File? {
|
||||||
|
return try {
|
||||||
|
FileOutputStream(outputFile).use { fos ->
|
||||||
|
bitmap.compress(format, quality, fos)
|
||||||
|
fos.flush()
|
||||||
|
}
|
||||||
|
outputFile
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package com.sw.platecabinet.utils
|
||||||
|
|
||||||
|
import android.content.ContentUris
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
|
import android.provider.MediaStore
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
|
import okhttp3.MultipartBody
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.io.copyTo
|
||||||
|
import kotlin.io.outputStream
|
||||||
|
import kotlin.io.use
|
||||||
|
import kotlin.text.equals
|
||||||
|
|
||||||
|
object FileUtils {
|
||||||
|
/**
|
||||||
|
* 从Uri获取File
|
||||||
|
* example: file:///data/user/0/com.sw.inbound/cache/IMG_17515262353556856678814444882273.jpg
|
||||||
|
*/
|
||||||
|
private fun getFileFromUri(context: Context, uri: Uri): File? {
|
||||||
|
Timber.d("getFileFromUri uri = ${uri.scheme}")
|
||||||
|
return when (uri.scheme) {
|
||||||
|
"file" -> File(uri.path ?: return null)
|
||||||
|
"content" -> {
|
||||||
|
try {
|
||||||
|
val inputStream = context.contentResolver.openInputStream(uri) ?: return null
|
||||||
|
val cacheDir = context.cacheDir
|
||||||
|
val file = File.createTempFile(
|
||||||
|
"upload_${System.currentTimeMillis()}",
|
||||||
|
".jpg",
|
||||||
|
cacheDir
|
||||||
|
)
|
||||||
|
file.outputStream().use { output ->
|
||||||
|
inputStream.copyTo(output)
|
||||||
|
}
|
||||||
|
file
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过uri生成http请求体
|
||||||
|
*/
|
||||||
|
fun genRequestPart(context: Context, imageUri: Uri): MultipartBody.Part? {
|
||||||
|
Timber.d("genRequestPart imageUri = $imageUri")
|
||||||
|
// 1. 从Uri获取文件
|
||||||
|
val file = getFileFromUri(context, imageUri)
|
||||||
|
return genRequestPart(file)
|
||||||
|
}
|
||||||
|
fun genRequestPart(file: File?): MultipartBody.Part? {
|
||||||
|
if (file == null) {
|
||||||
|
Timber.e("getFileFromUri file is null")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
// 2. 创建请求体
|
||||||
|
val requestFile = file
|
||||||
|
.asRequestBody("application/octet-stream".toMediaTypeOrNull())
|
||||||
|
val imagePart = MultipartBody.Part.createFormData(
|
||||||
|
"file",
|
||||||
|
file.name,
|
||||||
|
requestFile
|
||||||
|
)
|
||||||
|
return imagePart
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过Uri删除文件
|
||||||
|
* @param context 上下文
|
||||||
|
* @param uri 文件Uri
|
||||||
|
* @return Boolean 是否删除成功
|
||||||
|
*/
|
||||||
|
fun deleteFileWithUri(context: Context, uri: Uri): Boolean {
|
||||||
|
Timber.d("deleteFileWithUri uri = ${uri.scheme}")
|
||||||
|
return when {
|
||||||
|
// 1. 处理 content:// 类型的Uri (MediaStore)
|
||||||
|
uri.scheme.equals("content", ignoreCase = true) -> {
|
||||||
|
deleteContentUriFile(context, uri)
|
||||||
|
}
|
||||||
|
// 2. 处理 file:// 类型的Uri
|
||||||
|
uri.scheme.equals("file", ignoreCase = true) -> {
|
||||||
|
deleteFileUriFile(uri)
|
||||||
|
}
|
||||||
|
// 3. 其他情况尝试直接解析路径
|
||||||
|
else -> {
|
||||||
|
deleteFileFromPath(uri.path ?: return false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除Content Uri文件
|
||||||
|
private fun deleteContentUriFile(context: Context, uri: Uri): Boolean {
|
||||||
|
Timber.d("deleteContentUriFile uri = ${uri.scheme}")
|
||||||
|
return try {
|
||||||
|
context.contentResolver.delete(uri, null, null) > 0
|
||||||
|
} catch (e: SecurityException) {
|
||||||
|
// Android 10+需要特殊处理
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
deleteMediaStoreFile(context, uri)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Android 10+删除MediaStore文件
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
private fun deleteMediaStoreFile(context: Context, uri: Uri): Boolean {
|
||||||
|
Timber.d("deleteMediaStoreFile uri = ${uri.scheme}")
|
||||||
|
val contentResolver = context.contentResolver
|
||||||
|
val projection = arrayOf(MediaStore.MediaColumns._ID)
|
||||||
|
|
||||||
|
return try {
|
||||||
|
contentResolver.query(uri, projection, null, null, null)?.use { cursor ->
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
val id =
|
||||||
|
cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
|
||||||
|
val contentUri = ContentUris.withAppendedId(uri, id)
|
||||||
|
contentResolver.delete(contentUri, null, null) > 0
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} ?: false
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除File Uri文件
|
||||||
|
private fun deleteFileUriFile(uri: Uri): Boolean {
|
||||||
|
Timber.d("deleteFileUriFile uri = $uri")
|
||||||
|
return try {
|
||||||
|
File(uri.path ?: return false).delete()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接通过路径删除文件
|
||||||
|
private fun deleteFileFromPath(path: String): Boolean {
|
||||||
|
Timber.d("deleteFileFromPath path = $path")
|
||||||
|
return try {
|
||||||
|
File(path).delete()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -20,7 +20,7 @@ import java.text.DecimalFormat;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class FileUtil {
|
public class LogFileUtil {
|
||||||
private static boolean isSaveLog = true;
|
private static boolean isSaveLog = true;
|
||||||
public static final String FILE_STR_PATH = App.getContext().getExternalCacheDir().getAbsolutePath();
|
public static final String FILE_STR_PATH = App.getContext().getExternalCacheDir().getAbsolutePath();
|
||||||
|
|
||||||
@@ -624,7 +624,7 @@ public class FileUtil {
|
|||||||
.append("\n");
|
.append("\n");
|
||||||
}
|
}
|
||||||
String fileName = "log" + AppUtil.formatDateGetDay(System.currentTimeMillis()) + ".txt";
|
String fileName = "log" + AppUtil.formatDateGetDay(System.currentTimeMillis()) + ".txt";
|
||||||
FileUtil.saveStrFile(sb.toString(), fileName, FILE_STR_PATH, true);
|
LogFileUtil.saveStrFile(sb.toString(), fileName, FILE_STR_PATH, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
@@ -1,22 +1,14 @@
|
|||||||
package com.sw.platecabinet.viewmodel
|
package com.sw.platecabinet.viewmodel
|
||||||
|
|
||||||
import android.text.TextUtils
|
|
||||||
import com.sw.inbound.utils.DateTimeUtils
|
|
||||||
import com.sw.platecabinet.GlobalData
|
|
||||||
import com.sw.platecabinet.GlobalData.globalEquipmentCode
|
import com.sw.platecabinet.GlobalData.globalEquipmentCode
|
||||||
import com.sw.platecabinet.model.ErrorInfo
|
|
||||||
import com.sw.platecabinet.model.request.BindParam
|
|
||||||
import com.sw.platecabinet.model.request.EquipmentParam
|
|
||||||
import com.sw.platecabinet.model.request.SearchParam
|
|
||||||
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
||||||
import com.sw.platecabinet.model.response.SearchResult
|
import com.sw.platecabinet.model.response.SearchResult
|
||||||
import com.sw.platecabinet.model.response.UserFaceModel
|
import com.sw.platecabinet.model.response.UserFaceModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import timber.log.Timber
|
import java.io.File
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理员操作viewmodel
|
* 管理员操作viewmodel
|
||||||
@@ -71,43 +63,43 @@ class SettingViewModel : BaseViewModel() {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* 搜索会员信息列表
|
// * 搜索会员信息列表
|
||||||
*/
|
// */
|
||||||
fun getSearchMemberList(param:String, pageNum: Int = 1, pageSize: Int = 50) {
|
// fun getSearchMemberList(param:String, pageNum: Int = 1, pageSize: Int = 50) {
|
||||||
if (TextUtils.isEmpty(param)) return
|
// if (TextUtils.isEmpty(param)) return
|
||||||
currentPage = pageNum
|
// currentPage = pageNum
|
||||||
var name =""
|
// var name =""
|
||||||
var phone =""
|
// var phone =""
|
||||||
val num = param.toIntOrNull()
|
// val num = param.toIntOrNull()
|
||||||
if (num != null) {
|
// if (num != null) {
|
||||||
phone = param
|
// phone = param
|
||||||
} else {
|
// } else {
|
||||||
name = param
|
// name = param
|
||||||
}
|
// }
|
||||||
launch {
|
// launch {
|
||||||
val searchParam = SearchParam(
|
// val searchParam = SearchParam(
|
||||||
// appVersion = GlobalData.appVersion,
|
//// appVersion = GlobalData.appVersion,
|
||||||
name = name,
|
// name = name,
|
||||||
phone = phone,
|
// phone = phone,
|
||||||
pageNum = pageNum,
|
// pageNum = pageNum,
|
||||||
pageSize = pageSize
|
// pageSize = pageSize
|
||||||
)
|
// )
|
||||||
isLoading = true
|
// isLoading = true
|
||||||
val response = repository.searchUser(searchParam)
|
// val response = repository.searchUser(searchParam)
|
||||||
isLoading = false
|
// isLoading = false
|
||||||
if (parseResponse(response)) {
|
// if (parseResponse(response)) {
|
||||||
response.data?.let { list ->
|
// response.data?.let { list ->
|
||||||
if (pageNum == 1) {
|
// if (pageNum == 1) {
|
||||||
_searchMemberList.value = list
|
// _searchMemberList.value = list
|
||||||
} else {
|
// } else {
|
||||||
_searchMemberList.value = _searchMemberList.value.plus(list)
|
// _searchMemberList.value = _searchMemberList.value.plus(list)
|
||||||
}
|
// }
|
||||||
if (list.size >= pageSize) currentPage++
|
// if (list.size >= pageSize) currentPage++
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// fun bindPlate(
|
// fun bindPlate(
|
||||||
// equipmentBoxCode: String,
|
// equipmentBoxCode: String,
|
||||||
@@ -158,35 +150,35 @@ class SettingViewModel : BaseViewModel() {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fun unbindPlate(id: Long?, block:(Pair<Boolean?, ErrorInfo>)-> Unit) {
|
// fun unbindPlate(id: Long?, block:(Pair<Boolean?, ErrorInfo>)-> Unit) {
|
||||||
block(null to ErrorInfo())
|
// block(null to ErrorInfo())
|
||||||
launchWithLoading {
|
// launchWithLoading {
|
||||||
val response = repository.plateUnbind(id)
|
// val response = repository.plateUnbind(id)
|
||||||
if (parseResponse(response)) {
|
|
||||||
block(false to ErrorInfo())
|
|
||||||
} else {
|
|
||||||
block(false to ErrorInfo(response.code, response.msg.toString()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun bindPlate(bindParam: BindParam, block:(Pair<Boolean?, ErrorInfo>)-> Unit) {
|
|
||||||
launchWithLoading {
|
|
||||||
// val response = repository.plateBind(bindParam)
|
|
||||||
// if (parseResponse(response)) {
|
// if (parseResponse(response)) {
|
||||||
// var userInfo = response.data
|
// block(false to ErrorInfo())
|
||||||
// if (userInfo == null) {
|
|
||||||
// userInfo = EquipmentUserInfo()
|
|
||||||
// userInfo.equipmentBoxCode = bindParam.equipmentBoxCode
|
|
||||||
// userInfo.plateNumber = bindParam.plateNumber
|
|
||||||
// userInfo.equipmentCode = bindParam.equipmentCode
|
|
||||||
// }
|
|
||||||
// block(true to ErrorInfo(equipmentUserInfo = userInfo))
|
|
||||||
// } else {
|
// } else {
|
||||||
// block(true to ErrorInfo(response.code, response.msg.toString()))
|
// block(false to ErrorInfo(response.code, response.msg.toString()))
|
||||||
// }
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
// fun bindPlate(bindParam: BindParam, block:(Pair<Boolean?, ErrorInfo>)-> Unit) {
|
||||||
|
// launchWithLoading {
|
||||||
|
//// val response = repository.plateBind(bindParam)
|
||||||
|
//// if (parseResponse(response)) {
|
||||||
|
//// var userInfo = response.data
|
||||||
|
//// if (userInfo == null) {
|
||||||
|
//// userInfo = EquipmentUserInfo()
|
||||||
|
//// userInfo.equipmentBoxCode = bindParam.equipmentBoxCode
|
||||||
|
//// userInfo.plateNumber = bindParam.plateNumber
|
||||||
|
//// userInfo.equipmentCode = bindParam.equipmentCode
|
||||||
|
//// }
|
||||||
|
//// block(true to ErrorInfo(equipmentUserInfo = userInfo))
|
||||||
|
//// } else {
|
||||||
|
//// block(true to ErrorInfo(response.code, response.msg.toString()))
|
||||||
|
//// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
fun findByPlateNumber(
|
fun findByPlateNumber(
|
||||||
plateNumber: String,
|
plateNumber: String,
|
||||||
@@ -234,4 +226,25 @@ class SettingViewModel : BaseViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加人脸数据
|
||||||
|
*/
|
||||||
|
fun addUserFace(faceData: String, imageFile: File, block: (Boolean, UserFaceModel?) -> Unit) {
|
||||||
|
launch {
|
||||||
|
val imageResp = repository.uploadImage(imageFile)
|
||||||
|
val imageUrl = imageResp.data?:""
|
||||||
|
if (imageUrl.isBlank()) {
|
||||||
|
block(false, null)
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
val faceResp = repository.addUserFace(faceData, imageUrl)
|
||||||
|
val status = parseResponse(faceResp)
|
||||||
|
if (status.not()) {
|
||||||
|
block(false, null)
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
block(true, faceResp.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -58,38 +58,45 @@ class UserViewModel : BaseViewModel() {
|
|||||||
/**
|
/**
|
||||||
* 获取人脸数据
|
* 获取人脸数据
|
||||||
*/
|
*/
|
||||||
fun getUserFaceCache(pageNo: Int = 1, pageSize: Int = PAGE_SIZE, refreshFaceBlock: () -> Unit={}) {
|
fun getUserFaceCache(
|
||||||
|
pageNo: Int = 1,
|
||||||
|
pageSize: Int = PAGE_SIZE,
|
||||||
|
callback: (Boolean, String?) -> Unit = { statue, msg -> }
|
||||||
|
) {
|
||||||
var currentPageNo = pageNo
|
var currentPageNo = pageNo
|
||||||
launchWithLoading {
|
launchWithLoading {
|
||||||
val response = repository.getUserFaceCache(pageNum = pageNo, pageSize = pageSize)
|
val response = repository.getUserFaceCache(pageNum = pageNo, pageSize = pageSize)
|
||||||
if (parseResponse(response)) {
|
val status = parseResponse(response)
|
||||||
// 获取成功一次后缓存状态
|
if (status.not()) {
|
||||||
SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true)
|
callback(false, response.msg)
|
||||||
val list: List<UserFaceModel> = response.data ?: emptyList()
|
return@launchWithLoading
|
||||||
if (pageNo == 1 && list.isEmpty()) {
|
}
|
||||||
return@launchWithLoading
|
// 获取成功一次后缓存状态
|
||||||
|
SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true)
|
||||||
|
val list: List<UserFaceModel> = response.data ?: emptyList()
|
||||||
|
if (pageNo == 1 && list.isEmpty()) {
|
||||||
|
callback(true, "暂无数据")
|
||||||
|
return@launchWithLoading
|
||||||
|
}
|
||||||
|
val faceEntityList = list.map {
|
||||||
|
FaceEntity(it.userId, null, Base64.decode(it.faceFeatureStr))
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Default) {
|
||||||
|
faceApi.updateFaceData(pageNo, faceEntityList)
|
||||||
|
if (list.size >= pageSize) {
|
||||||
|
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
|
||||||
|
currentPageNo++
|
||||||
|
getUserFaceCache(
|
||||||
|
pageNo = currentPageNo,
|
||||||
|
callback = callback
|
||||||
|
)
|
||||||
|
return@withContext
|
||||||
}
|
}
|
||||||
val faceEntityList = list.map {
|
if (list.isNotEmpty()) {
|
||||||
FaceEntity(it.userId, null, Base64.decode(it.faceFeatureStr))
|
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
|
||||||
}
|
|
||||||
withContext(Dispatchers.Default) {
|
|
||||||
faceApi.updateFaceData(pageNo, faceEntityList)
|
|
||||||
refreshFaceBlock()
|
|
||||||
if (list.size >= pageSize) {
|
|
||||||
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
|
|
||||||
currentPageNo++
|
|
||||||
getUserFaceCache(
|
|
||||||
pageNo = currentPageNo,
|
|
||||||
refreshFaceBlock = refreshFaceBlock
|
|
||||||
)
|
|
||||||
return@withContext
|
|
||||||
}
|
|
||||||
if (list.isNotEmpty()) {
|
|
||||||
faceTimestamp = list.last().faceUpdateTimestamp ?: 0
|
|
||||||
}
|
|
||||||
SpTool.lastFaceTimestamp = faceTimestamp
|
|
||||||
//activeEngine()
|
|
||||||
}
|
}
|
||||||
|
SpTool.lastFaceTimestamp = faceTimestamp
|
||||||
|
callback(true, "查询完成")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,35 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:width="600dp"
|
android:width="600dp"
|
||||||
android:height="1024dp">
|
android:height="1024dp">
|
||||||
<bitmap android:src="@drawable/bg"/>
|
<bitmap android:src="@drawable/bg" />
|
||||||
</item>
|
</item>
|
||||||
<item
|
<item
|
||||||
android:width="337dp"
|
android:width="337dp"
|
||||||
android:height="322dp"
|
android:height="322dp"
|
||||||
android:gravity="top|center_horizontal"
|
android:gravity="top|center_horizontal"
|
||||||
android:top="112dp">
|
android:top="112dp">
|
||||||
<bitmap android:src="@drawable/img_init" android:scaleType="fitCenter"/>
|
<bitmap
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/img_init" />
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
|
<!-- TODO 临时测试 -->
|
||||||
|
<!-- <item-->
|
||||||
|
<!-- android:width="828dp"-->
|
||||||
|
<!-- android:height="1768dp">-->
|
||||||
|
<!-- <bitmap android:src="@drawable/bg" />-->
|
||||||
|
<!-- </item>-->
|
||||||
|
|
||||||
|
<!-- <item-->
|
||||||
|
<!-- android:width="337dp"-->
|
||||||
|
<!-- android:height="322dp"-->
|
||||||
|
<!-- android:gravity="top|center_horizontal"-->
|
||||||
|
<!-- android:top="360dp">-->
|
||||||
|
<!-- <bitmap-->
|
||||||
|
<!-- android:scaleType="fitCenter"-->
|
||||||
|
<!-- android:src="@drawable/img_init" />-->
|
||||||
|
<!-- </item>-->
|
||||||
</layer-list>
|
</layer-list>
|
||||||
@@ -6,14 +6,14 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ImageView
|
<!-- <ImageView-->
|
||||||
android:layout_width="337dp"
|
<!-- android:layout_width="337dp"-->
|
||||||
android:layout_height="322dp"
|
<!-- android:layout_height="322dp"-->
|
||||||
android:layout_gravity="center_horizontal"
|
<!-- android:layout_gravity="center_horizontal"-->
|
||||||
android:layout_marginTop="112dp"
|
<!-- android:layout_marginTop="112dp"-->
|
||||||
android:src="@drawable/img_init"
|
<!-- android:src="@drawable/img_init"-->
|
||||||
tools:ignore="ContentDescription"
|
<!-- tools:ignore="ContentDescription"-->
|
||||||
android:visibility="invisible"/>
|
<!-- android:visibility="invisible"/>-->
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/btnInit"
|
android:id="@+id/btnInit"
|
||||||
|
|||||||
@@ -47,15 +47,15 @@
|
|||||||
android:id="@+id/takeButton"
|
android:id="@+id/takeButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="-20dp">
|
android:layout_marginTop="-35dp">
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:text="点击取盘"
|
android:text="点击取盘"
|
||||||
android:textColor="#FFCC99"
|
android:textColor="#FFCC99"
|
||||||
android:textSize="24sp"
|
android:textSize="24sp"
|
||||||
android:layout_marginHorizontal="30dp"
|
android:layout_marginHorizontal="60dp"
|
||||||
android:layout_marginVertical="20dp"
|
android:layout_marginVertical="50dp"
|
||||||
android:paddingHorizontal="45dp"
|
android:paddingHorizontal="45dp"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:background="@drawable/btn_outline"
|
android:background="@drawable/btn_outline"
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_dialog"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_marginTop="30dp"
|
||||||
|
android:src="@drawable/ic_tip_warn_unbind" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="30dp"
|
||||||
|
android:textColor="#ffffffff"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:text="即将解除【曹德磊】的餐盘"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvContent"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="30dp"
|
||||||
|
tools:text="解绑后该用户将无法使用餐盘柜"
|
||||||
|
android:textColor="#ff999999"
|
||||||
|
android:textSize="24sp"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginTop="30dp"
|
||||||
|
android:background="#ff333333" />
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="90dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/btnCancel"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="取消"
|
||||||
|
android:textColor="#ff999999"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#333333" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/btnConfirm"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="确定"
|
||||||
|
android:textColor="#ffffcc99"
|
||||||
|
android:textSize="30sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:spanCount="2"
|
app:spanCount="2"
|
||||||
|
tools:itemCount="22"
|
||||||
android:overScrollMode="never"
|
android:overScrollMode="never"
|
||||||
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
||||||
tools:listitem="@layout/item_bind_view"/>
|
tools:listitem="@layout/item_bind_view"/>
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ public class FaceApi {
|
|||||||
public void updateFaceData(int index, List<FaceEntity> list) {
|
public void updateFaceData(int index, List<FaceEntity> list) {
|
||||||
Log.d(TAG, "updateFaceData: index = " + index + ", listSize = " + list.size());
|
Log.d(TAG, "updateFaceData: index = " + index + ", listSize = " + list.size());
|
||||||
FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao();
|
FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao();
|
||||||
if (index == 1) {
|
//if (index == 1) {
|
||||||
faceDao.deleteAll();
|
// faceDao.deleteAll();
|
||||||
faceDao.resetId();
|
// faceDao.resetId();
|
||||||
}
|
//}
|
||||||
faceDao.insert(list);
|
faceDao.insert(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,4 +102,9 @@ public class FaceApi {
|
|||||||
return faceDao.queryByUserName(userName);
|
return faceDao.queryByUserName(userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int queryFaceCount() {
|
||||||
|
FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao();
|
||||||
|
return faceDao.getFaceCount();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,10 +45,15 @@ public class FaceEntity implements Parcelable {
|
|||||||
@ColumnInfo(name = "register_time")
|
@ColumnInfo(name = "register_time")
|
||||||
private long registerTime;
|
private long registerTime;
|
||||||
/**
|
/**
|
||||||
* 用户类型:1-普通会员、2-临时用户、3-内部员工、或者其它待定类型
|
* 用户类型:1-普通会员、2-临时用户、或者其它待定类型
|
||||||
*/
|
*/
|
||||||
@ColumnInfo(name = "user_type")
|
@ColumnInfo(name = "user_type")
|
||||||
private String userType;
|
private String userType;
|
||||||
|
/**
|
||||||
|
* 会员编号
|
||||||
|
*/
|
||||||
|
@ColumnInfo(name = "cardNo")
|
||||||
|
private String cardNo;
|
||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
private int trackId;//人脸追踪ID
|
private int trackId;//人脸追踪ID
|
||||||
@@ -66,6 +71,8 @@ public class FaceEntity implements Parcelable {
|
|||||||
this.imagePath = faceEntity.imagePath;
|
this.imagePath = faceEntity.imagePath;
|
||||||
this.featureData = faceEntity.featureData;
|
this.featureData = faceEntity.featureData;
|
||||||
this.registerTime = faceEntity.registerTime;
|
this.registerTime = faceEntity.registerTime;
|
||||||
|
this.userType = faceEntity.getUserType();
|
||||||
|
this.cardNo = faceEntity.getCardNo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -75,6 +82,8 @@ public class FaceEntity implements Parcelable {
|
|||||||
userName = in.readString();
|
userName = in.readString();
|
||||||
imagePath = in.readString();
|
imagePath = in.readString();
|
||||||
featureData = in.createByteArray();
|
featureData = in.createByteArray();
|
||||||
|
userType = in.readString();
|
||||||
|
cardNo = in.readString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<FaceEntity> CREATOR = new Creator<FaceEntity>() {
|
public static final Creator<FaceEntity> CREATOR = new Creator<FaceEntity>() {
|
||||||
@@ -145,6 +154,16 @@ public class FaceEntity implements Parcelable {
|
|||||||
this.userType = userType;
|
this.userType = userType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCardNo() {
|
||||||
|
return cardNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCardNo(String cardNo) {
|
||||||
|
this.cardNo = cardNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int describeContents() {
|
public int describeContents() {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -158,10 +177,9 @@ public class FaceEntity implements Parcelable {
|
|||||||
dest.writeString(imagePath);
|
dest.writeString(imagePath);
|
||||||
dest.writeByteArray(featureData);
|
dest.writeByteArray(featureData);
|
||||||
dest.writeString(userType);
|
dest.writeString(userType);
|
||||||
|
dest.writeString(cardNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
@@ -176,12 +194,13 @@ public class FaceEntity implements Parcelable {
|
|||||||
TextUtils.equals(this.userName, that.userName) &&
|
TextUtils.equals(this.userName, that.userName) &&
|
||||||
TextUtils.equals(this.imagePath, that.imagePath) &&
|
TextUtils.equals(this.imagePath, that.imagePath) &&
|
||||||
Arrays.equals(featureData, that.featureData) &&
|
Arrays.equals(featureData, that.featureData) &&
|
||||||
TextUtils.equals(this.userType, that.userType);
|
TextUtils.equals(this.userType, that.userType) &&
|
||||||
|
TextUtils.equals(this.cardNo, that.cardNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = Objects.hash(faceId, registerTime, userName, imagePath, userType);
|
int result = Objects.hash(faceId, registerTime, userName, imagePath, userType, cardNo);
|
||||||
result = 31 * result + Arrays.hashCode(featureData);
|
result = 31 * result + Arrays.hashCode(featureData);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user