清理人脸识别代码;清理所有编译警告
This commit is contained in:
@@ -131,7 +131,6 @@ dependencies {
|
||||
implementation("androidx.camera:camera-view:$cameraXVersion")
|
||||
|
||||
implementation("com.google.zxing:core:3.5.4")
|
||||
implementation("com.google.mlkit:face-detection:16.1.7")
|
||||
implementation("com.aliyun.dpa:oss-android-sdk:2.9.21")
|
||||
implementation("com.aliyun:ocr_api20210707:3.1.3") {
|
||||
exclude(group = "pull-parser", module = "pull-parser")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.bbitcn.f8.pad.base
|
||||
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.AnimatedVisibilityScope
|
||||
@@ -25,6 +26,7 @@ import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
@@ -54,11 +56,10 @@ import androidx.compose.material3.InputChipDefaults
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.ScrollableTabRow
|
||||
import androidx.compose.material3.PrimaryTabRow
|
||||
import androidx.compose.material3.SecondaryScrollableTabRow
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.TabRow
|
||||
import androidx.compose.material3.TabRowDefaults
|
||||
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.VerticalDivider
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -71,6 +72,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
@@ -95,6 +97,7 @@ import androidx.compose.ui.unit.sp
|
||||
import coil3.compose.AsyncImage
|
||||
import coil3.request.ImageRequest
|
||||
import com.bbitcn.f8.pad.M
|
||||
import com.bbitcn.f8.pad.MyApp
|
||||
import com.bbitcn.f8.pad.R
|
||||
import com.bbitcn.f8.pad.ui.screen.view.Toasty
|
||||
import com.bbitcn.f8.pad.ui.screen.view.drawer.IconInfo
|
||||
@@ -355,24 +358,18 @@ fun VipBadgePreview() {
|
||||
@Composable
|
||||
fun VipBadge(modifier: Modifier = Modifier, content: @Composable () -> Unit) {
|
||||
Box(modifier = modifier) {
|
||||
// 内容显示区域
|
||||
content()
|
||||
|
||||
// 显示 Badge
|
||||
Box(
|
||||
modifier = M
|
||||
.align(Alignment.TopEnd) // 控制Badge的位置
|
||||
.padding(2.5.dp) // 适当的内边距,避免和内容重叠
|
||||
) {
|
||||
// Badge(containerColor = MyColors.Transparent) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.vip),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
// }
|
||||
}
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.vip),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.Fit,
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopEnd)
|
||||
.offset(x = 7.dp, y = (-7).dp)
|
||||
.size(18.dp)
|
||||
.alpha(0.82f)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,7 +779,8 @@ fun isLandscape(): Boolean {
|
||||
}
|
||||
|
||||
fun isBluetoothEnabled(): Boolean {
|
||||
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
|
||||
val bluetoothManager = MyApp.appContext.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||
val bluetoothAdapter = bluetoothManager.adapter
|
||||
return bluetoothAdapter?.isEnabled == true
|
||||
}
|
||||
|
||||
@@ -809,11 +807,11 @@ fun MyTabRowHorizontal(
|
||||
) {
|
||||
var curPage by rememberSaveable { mutableStateOf(0) }
|
||||
Column {
|
||||
TabRow(
|
||||
PrimaryTabRow(
|
||||
selectedTabIndex = curPage,
|
||||
indicator = { tabPositions ->
|
||||
TabRowDefaults.Indicator(
|
||||
M.tabIndicatorOffset(tabPositions[curPage]),
|
||||
indicator = {
|
||||
TabRowDefaults.PrimaryIndicator(
|
||||
M.tabIndicatorOffset(curPage),
|
||||
color = MyColors.BlueGreen
|
||||
)
|
||||
}
|
||||
@@ -880,14 +878,14 @@ fun MyScrollableTabRow(
|
||||
tabs: List<String>,
|
||||
onValueChange: (Int) -> Unit = {}
|
||||
) {
|
||||
ScrollableTabRow(
|
||||
SecondaryScrollableTabRow(
|
||||
selectedTabIndex = position,
|
||||
containerColor = MyColors.Transparent,
|
||||
edgePadding = 5.dp,
|
||||
modifier = moidifer,
|
||||
indicator = { tabPositions ->
|
||||
indicator = {
|
||||
TabRowDefaults.SecondaryIndicator(
|
||||
M.tabIndicatorOffset(tabPositions[position]),
|
||||
M.tabIndicatorOffset(position),
|
||||
color = MyColors.BlueGreen,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ data class FaceRecognizeResponse(
|
||||
@SerializedName("log_id")
|
||||
val logId: Long = 0,
|
||||
@SerializedName("result")
|
||||
val result: Result = Result(),
|
||||
val result: Result? = Result(),
|
||||
@SerializedName("timestamp")
|
||||
val timestamp: Long = 0
|
||||
) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package com.bbitcn.f8.pad.receiver
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
@@ -5,14 +7,17 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.wifi.WifiInfo
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.BatteryManager
|
||||
import android.os.Build
|
||||
import android.telephony.PhoneStateListener
|
||||
import android.telephony.SignalStrength
|
||||
import android.telephony.TelephonyCallback
|
||||
import android.telephony.TelephonyManager
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.bbitcn.f8.pad.utils.PollingTask
|
||||
import com.bbitcn.f8.pad.utils.log.MyLog
|
||||
import com.bbitcn.f8.pad.utils.registerReceiverCompat
|
||||
@@ -29,16 +34,43 @@ class SystemInfoReceiver(private val context: Context) {
|
||||
|
||||
private val _signalStrength = MutableStateFlow(0)
|
||||
val signalStrength = _signalStrength.asStateFlow()
|
||||
|
||||
private val connectivityManager =
|
||||
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
private val telephonyManager =
|
||||
context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||
|
||||
/**
|
||||
* 信号强度监听器
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
private val networkStateListener = object : PhoneStateListener() {
|
||||
@Deprecated("Only used for Android 11 compatibility.")
|
||||
override fun onSignalStrengthsChanged(signalStrengths: SignalStrength) {
|
||||
super.onSignalStrengthsChanged(signalStrengths)
|
||||
_signalStrength.value = signalStrengths.level
|
||||
}
|
||||
}
|
||||
|
||||
private var telephonyCallback: TelephonyCallback? = null
|
||||
|
||||
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
refreshNetworkStatus()
|
||||
}
|
||||
|
||||
override fun onCapabilitiesChanged(
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities
|
||||
) {
|
||||
updateNetworkStatus(networkCapabilities)
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
refreshNetworkStatus()
|
||||
}
|
||||
}
|
||||
|
||||
private val batteryReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(ctx: Context?, intent: Intent?) {
|
||||
val level = intent?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1
|
||||
@@ -46,54 +78,17 @@ class SystemInfoReceiver(private val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
private val connectivityReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(ctx: Context?, intent: Intent?) {
|
||||
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val activeNetwork = connectivityManager.activeNetwork
|
||||
val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
|
||||
|
||||
networkCapabilities?.let {
|
||||
when {
|
||||
it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
|
||||
_networkType.value = "WIFI"
|
||||
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
val wifiInfo = wifiManager.connectionInfo
|
||||
_signalStrength.value = WifiManager.calculateSignalLevel(wifiInfo.rssi, 5)
|
||||
}
|
||||
it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
|
||||
_networkType.value = "Cellular"
|
||||
val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||
telephonyManager.listen(networkStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)
|
||||
}
|
||||
it.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> {
|
||||
_networkType.value = "Ethernet"
|
||||
_signalStrength.value = 4 // Ethernet typically has a strong connection
|
||||
}
|
||||
else -> {
|
||||
_networkType.value = "Unknown"
|
||||
_signalStrength.value = 0
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
_networkType.value = "No Connection"
|
||||
_signalStrength.value = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun register() {
|
||||
val batteryIntentFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
|
||||
val connectivityIntentFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
|
||||
|
||||
context.registerReceiverCompat(
|
||||
batteryReceiver,
|
||||
batteryIntentFilter
|
||||
)
|
||||
|
||||
context.registerReceiverCompat(
|
||||
connectivityReceiver,
|
||||
connectivityIntentFilter
|
||||
)
|
||||
connectivityManager.registerDefaultNetworkCallback(networkCallback)
|
||||
registerSignalStrengthListener()
|
||||
refreshNetworkStatus()
|
||||
// 开始轮询网络状态 防止状态假死
|
||||
PollingTask.getInstance("SystemInfoReceiver").startPollingTaskOnIOThread("NetworkStatusPolling",30_000) {
|
||||
refreshNetworkStatus()
|
||||
@@ -102,42 +97,106 @@ class SystemInfoReceiver(private val context: Context) {
|
||||
|
||||
fun unregister() {
|
||||
context.unregisterReceiver(batteryReceiver)
|
||||
context.unregisterReceiver(connectivityReceiver)
|
||||
runCatching {
|
||||
connectivityManager.unregisterNetworkCallback(networkCallback)
|
||||
}.onFailure {
|
||||
MyLog.appError("取消网络监听失败:${it.message}")
|
||||
}
|
||||
unregisterSignalStrengthListener()
|
||||
PollingTask.getInstance("SystemInfoReceiver").stopTask("NetworkStatusPolling")
|
||||
}
|
||||
|
||||
private fun refreshNetworkStatus() {
|
||||
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val activeNetwork = connectivityManager.activeNetwork
|
||||
val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
|
||||
|
||||
networkCapabilities?.let {
|
||||
when {
|
||||
it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
|
||||
_networkType.value = "WIFI"
|
||||
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
val wifiInfo = wifiManager.connectionInfo
|
||||
val rssi = wifiInfo.rssi
|
||||
if (rssi != -127) { // -127 通常是无效值
|
||||
_signalStrength.value = WifiManager.calculateSignalLevel(rssi, 5)
|
||||
}
|
||||
}
|
||||
it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
|
||||
_networkType.value = "Cellular"
|
||||
// 通常需要 TelephonyManager.getSignalStrength,但这里只能靠原来 listener 补充
|
||||
}
|
||||
it.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> {
|
||||
_networkType.value = "Ethernet"
|
||||
_signalStrength.value = 4
|
||||
}
|
||||
else -> {
|
||||
_networkType.value = "Unknown"
|
||||
_signalStrength.value = 0
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
if (networkCapabilities == null) {
|
||||
_networkType.value = "No Connection"
|
||||
_signalStrength.value = 0
|
||||
} else {
|
||||
updateNetworkStatus(networkCapabilities)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateNetworkStatus(networkCapabilities: NetworkCapabilities) {
|
||||
when {
|
||||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
|
||||
_networkType.value = "WIFI"
|
||||
updateWifiSignalStrength(networkCapabilities)
|
||||
}
|
||||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
|
||||
_networkType.value = "Cellular"
|
||||
}
|
||||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> {
|
||||
_networkType.value = "Ethernet"
|
||||
_signalStrength.value = 4
|
||||
}
|
||||
else -> {
|
||||
_networkType.value = "Unknown"
|
||||
_signalStrength.value = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateWifiSignalStrength(networkCapabilities: NetworkCapabilities) {
|
||||
val rssi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
(networkCapabilities.transportInfo as? WifiInfo)?.rssi
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
wifiManager.connectionInfo?.rssi
|
||||
}
|
||||
if (rssi != null && rssi != -127) {
|
||||
_signalStrength.value = calculateSignalLevel(rssi)
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateSignalLevel(rssi: Int): Int {
|
||||
return when {
|
||||
rssi <= -100 -> 0
|
||||
rssi >= -55 -> 4
|
||||
else -> ((rssi + 100) * 4 / 45).coerceIn(0, 4)
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerSignalStrengthListener() {
|
||||
runCatching {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
val callback = object : TelephonyCallback(), TelephonyCallback.SignalStrengthsListener {
|
||||
override fun onSignalStrengthsChanged(signalStrength: SignalStrength) {
|
||||
_signalStrength.value = signalStrength.level
|
||||
}
|
||||
}
|
||||
telephonyCallback = callback
|
||||
telephonyManager.registerTelephonyCallback(
|
||||
ContextCompat.getMainExecutor(context),
|
||||
callback
|
||||
)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
telephonyManager.listen(
|
||||
networkStateListener,
|
||||
PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
|
||||
)
|
||||
}
|
||||
}.onFailure {
|
||||
MyLog.appError("注册信号强度监听失败:${it.message}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun unregisterSignalStrengthListener() {
|
||||
runCatching {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
telephonyCallback?.let {
|
||||
telephonyManager.unregisterTelephonyCallback(it)
|
||||
}
|
||||
telephonyCallback = null
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
telephonyManager.listen(networkStateListener, PhoneStateListener.LISTEN_NONE)
|
||||
}
|
||||
}.onFailure {
|
||||
MyLog.appError("取消信号强度监听失败:${it.message}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.bbitcn.f8.pad.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.animation.EnterTransition
|
||||
@@ -26,6 +25,9 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.compose.NavHost
|
||||
@@ -71,6 +73,7 @@ class MainActivity : ComponentActivity() {
|
||||
installSplashScreen()
|
||||
super.onCreate(savedInstanceState)
|
||||
setFullScreen(true)
|
||||
registerBackPressedCallback()
|
||||
// 初始化NfcAdapter
|
||||
PrinterBT.init()
|
||||
WaterCutMeterBT.init()
|
||||
@@ -243,30 +246,35 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
|
||||
fun setFullScreen(isFullScreen: Boolean) {
|
||||
val controller = WindowCompat.getInsetsController(window, window.decorView)
|
||||
if (isFullScreen) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN)
|
||||
val decorView = window.decorView
|
||||
val uiOptions = (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN)
|
||||
decorView.systemUiVisibility = uiOptions
|
||||
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
controller.systemBarsBehavior =
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
controller.hide(WindowInsetsCompat.Type.systemBars())
|
||||
} else {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN)
|
||||
WindowCompat.setDecorFitsSystemWindows(window, true)
|
||||
controller.show(WindowInsetsCompat.Type.systemBars())
|
||||
}
|
||||
}
|
||||
|
||||
private var lastBackPressedTime: Long = 0
|
||||
|
||||
override fun onBackPressed() {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (currentTime - lastBackPressedTime < 2000) { // 如果两次点击时间间隔小于2秒
|
||||
super.onBackPressed() // 调用系统默认的退出行为
|
||||
} else {
|
||||
Toasty.showToast("再按一次退出")
|
||||
lastBackPressedTime = currentTime
|
||||
}
|
||||
private fun registerBackPressedCallback() {
|
||||
onBackPressedDispatcher.addCallback(
|
||||
this,
|
||||
object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (currentTime - lastBackPressedTime < 2000) {
|
||||
finish()
|
||||
} else {
|
||||
Toasty.showToast("再按一次退出")
|
||||
lastBackPressedTime = currentTime
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,9 +25,8 @@ import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.TabRow
|
||||
import androidx.compose.material3.PrimaryTabRow
|
||||
import androidx.compose.material3.TabRowDefaults
|
||||
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
@@ -140,11 +139,11 @@ fun TabPagerScreen(
|
||||
val pagerState = rememberPagerState(pageCount = { tabs.size })
|
||||
val scope = rememberCoroutineScope()
|
||||
Column {
|
||||
TabRow(
|
||||
PrimaryTabRow(
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
indicator = { tabPositions ->
|
||||
TabRowDefaults.Indicator(
|
||||
M.tabIndicatorOffset(tabPositions[pagerState.currentPage]),
|
||||
indicator = {
|
||||
TabRowDefaults.PrimaryIndicator(
|
||||
M.tabIndicatorOffset(pagerState.currentPage),
|
||||
color = MyColors.BlueGreen,
|
||||
)
|
||||
}
|
||||
@@ -375,7 +374,7 @@ fun PhoneLogin(loginViewModel: LoginViewModel) {
|
||||
},
|
||||
modifier = Modifier
|
||||
.padding(top = 20.dp)
|
||||
.fillMaxWidth()
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -398,7 +397,7 @@ fun FaceLogin(loginViewModel: LoginViewModel) {
|
||||
Text(
|
||||
text = "请保持光线充足,人脸无遮挡",
|
||||
color = MyColors.Gray,
|
||||
modifier = M.padding(vertical = 10.dp)
|
||||
modifier = M.padding(vertical = 2.5.dp)
|
||||
)
|
||||
MyButton(
|
||||
text = "开始识别登录",
|
||||
@@ -406,7 +405,7 @@ fun FaceLogin(loginViewModel: LoginViewModel) {
|
||||
loginViewModel.faceRecognize()
|
||||
},
|
||||
modifier = Modifier
|
||||
.padding(top = 5.dp)
|
||||
.padding(top = 20.dp)
|
||||
.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -27,12 +28,11 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.ClickableText
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBackIosNew
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -54,10 +54,12 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.layout.LastBaseline
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.TextLayoutResult
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -324,7 +326,7 @@ private fun AuthorNameTimestamp(msg: Message, isUserMe: Boolean) {
|
||||
|
||||
@Composable
|
||||
private fun RowScope.DayHeaderLine() {
|
||||
Divider(
|
||||
HorizontalDivider(
|
||||
modifier = M
|
||||
.weight(1f)
|
||||
.align(Alignment.CenterVertically),
|
||||
@@ -360,20 +362,28 @@ fun ChatItemBubble(
|
||||
text = chatRecord.content,
|
||||
primary = isUserMe
|
||||
)
|
||||
ClickableText(
|
||||
var textLayoutResult by remember { mutableStateOf<TextLayoutResult?>(null) }
|
||||
Text(
|
||||
text = styledMessage,
|
||||
style = MaterialTheme.typography.bodyLarge.copy(color = textColor),
|
||||
modifier = M.padding(16.dp),
|
||||
onClick = {
|
||||
styledMessage
|
||||
.getStringAnnotations(start = it, end = it)
|
||||
.firstOrNull()
|
||||
?.let { annotation ->
|
||||
when (annotation.tag) {
|
||||
SymbolAnnotationType.LINK.name -> uriHandler.openUri(annotation.item)
|
||||
else -> Unit
|
||||
}
|
||||
modifier = M
|
||||
.padding(16.dp)
|
||||
.pointerInput(styledMessage) {
|
||||
detectTapGestures { position ->
|
||||
val offset = textLayoutResult?.getOffsetForPosition(position) ?: return@detectTapGestures
|
||||
styledMessage
|
||||
.getStringAnnotations(start = offset, end = offset)
|
||||
.firstOrNull()
|
||||
?.let { annotation ->
|
||||
when (annotation.tag) {
|
||||
SymbolAnnotationType.LINK.name -> uriHandler.openUri(annotation.item)
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onTextLayout = {
|
||||
textLayoutResult = it
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@ import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
@@ -51,6 +54,7 @@ fun FaceDialog(
|
||||
viewModel: FaceDialogViewModel = viewModel()
|
||||
) {
|
||||
val tips by viewModel.tips.collectAsState()
|
||||
val countdownSeconds by viewModel.countdownSeconds.collectAsState()
|
||||
MyDialog("人脸识别-${tips}",
|
||||
info.showDialog,
|
||||
onDismissRequest = { info.onDismiss() },
|
||||
@@ -65,7 +69,11 @@ fun FaceDialog(
|
||||
) {
|
||||
LaunchedEffect(info.showDialog) {
|
||||
if (info.showDialog){
|
||||
viewModel.initializeCamera(info.isRegister,info.isSystemUser){ userId,faceToken->
|
||||
viewModel.initializeCamera(
|
||||
isRegister = info.isRegister,
|
||||
isSystemUser = info.isSystemUser,
|
||||
onAutoCapture = info.onDismiss
|
||||
) { userId,faceToken->
|
||||
// 识别成功的方法
|
||||
info.onDismiss()
|
||||
info.onRecognizeFace(userId, faceToken)
|
||||
@@ -113,6 +121,24 @@ fun FaceDialog(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (countdownSeconds > 0) {
|
||||
Surface(
|
||||
modifier = M
|
||||
.align(Alignment.TopCenter)
|
||||
.padding(top = 16.dp),
|
||||
shape = MaterialTheme.shapes.large,
|
||||
color = MaterialTheme.colorScheme.primary.copy(alpha = 0.88f),
|
||||
tonalElevation = 6.dp,
|
||||
shadowElevation = 8.dp
|
||||
) {
|
||||
Text(
|
||||
text = "${countdownSeconds}秒后开始识别",
|
||||
modifier = M.padding(horizontal = 24.dp, vertical = 12.dp),
|
||||
color = MaterialTheme.colorScheme.onPrimary,
|
||||
style = MaterialTheme.typography.titleLarge
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,11 @@ import android.hardware.camera2.CameraCharacteristics
|
||||
import android.hardware.camera2.CameraManager
|
||||
import android.net.Uri
|
||||
import android.util.Size
|
||||
import android.view.WindowManager
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.camera.camera2.interop.Camera2CameraInfo
|
||||
import androidx.camera.camera2.interop.ExperimentalCamera2Interop
|
||||
import androidx.camera.core.Camera
|
||||
import androidx.camera.core.CameraSelector
|
||||
import androidx.camera.core.ImageAnalysis
|
||||
import androidx.camera.core.ImageCapture
|
||||
import androidx.camera.core.ImageCaptureException
|
||||
import androidx.camera.core.Preview
|
||||
@@ -19,6 +17,7 @@ import androidx.camera.core.SurfaceRequest
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.alibaba.sdk.android.oss.ClientException
|
||||
import com.alibaba.sdk.android.oss.ServiceException
|
||||
import com.alibaba.sdk.android.oss.model.ObjectMetadata
|
||||
@@ -31,16 +30,17 @@ import com.bbitcn.f8.pad.model.net.response.FarmerDetailResponse
|
||||
import com.bbitcn.f8.pad.ui.screen.view.Toasty
|
||||
import com.bbitcn.f8.pad.ui.screen.view.Toasty.showTipsDialog
|
||||
import com.bbitcn.f8.pad.utils.MMKVUtil
|
||||
import com.bbitcn.f8.pad.utils.MyUtil
|
||||
import com.bbitcn.f8.pad.utils.externalModules.devices.reader.face.FaceRecognize
|
||||
import com.bbitcn.f8.pad.utils.externalModules.devices.reader.face.OssUtils
|
||||
import com.bbitcn.f8.pad.utils.global.RxTag
|
||||
import com.bbitcn.f8.pad.utils.log.MyLog
|
||||
import com.google.mlkit.vision.common.InputImage
|
||||
import com.google.mlkit.vision.face.FaceDetection
|
||||
import com.google.mlkit.vision.face.FaceDetectorOptions
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.util.Random
|
||||
|
||||
@@ -49,6 +49,8 @@ class FaceDialogViewModel : BaseViewModel() {
|
||||
|
||||
private val _tips = MutableStateFlow("")
|
||||
val tips = _tips.asStateFlow()
|
||||
private val _countdownSeconds = MutableStateFlow(0)
|
||||
val countdownSeconds = _countdownSeconds.asStateFlow()
|
||||
private val _surfaceRequests = MutableStateFlow<SurfaceRequest?>(null)
|
||||
val surfaceRequests: StateFlow<SurfaceRequest?> get() = _surfaceRequests.asStateFlow()
|
||||
|
||||
@@ -66,14 +68,14 @@ class FaceDialogViewModel : BaseViewModel() {
|
||||
lateinit var curCameraInfo: CameraInfo
|
||||
|
||||
var myCamera: Camera? = null
|
||||
private var autoRecognizeJob: Job? = null
|
||||
|
||||
|
||||
init {
|
||||
context = MyApp.appContext
|
||||
lifecycleOwner = context as LifecycleOwner
|
||||
// 获取当前设备的旋转角度
|
||||
val rotation = (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager)
|
||||
.defaultDisplay.rotation
|
||||
val rotation = MyUtil.getDisplayRotation(context)
|
||||
imageCapture = ImageCapture.Builder()
|
||||
.setTargetRotation(rotation)
|
||||
.build()
|
||||
@@ -82,15 +84,20 @@ class FaceDialogViewModel : BaseViewModel() {
|
||||
private var _isRegister = false
|
||||
private var _isSystemUser = false
|
||||
private var _onRecognizeFace: ((userId: String, faceToken: String) -> Unit) = { _, _ -> }
|
||||
private var _onAutoCapture: () -> Unit = {}
|
||||
|
||||
fun initializeCamera(
|
||||
isRegister: Boolean,
|
||||
isSystemUser: Boolean,
|
||||
onAutoCapture: () -> Unit = {},
|
||||
onRecognizeFace: (userId: String, faceToken: String) -> Unit
|
||||
) {
|
||||
_isSystemUser = isSystemUser
|
||||
_isRegister = isRegister
|
||||
_onAutoCapture = onAutoCapture
|
||||
_onRecognizeFace = onRecognizeFace
|
||||
_tips.value = ""
|
||||
_countdownSeconds.value = 0
|
||||
val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||
val cameraIdList = cameraManager.cameraIdList
|
||||
|
||||
@@ -132,9 +139,10 @@ class FaceDialogViewModel : BaseViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(androidx.camera.core.ExperimentalGetImage::class)
|
||||
fun setCameraSelector(cameraInfo: CameraInfo) {
|
||||
MyLog.test("setCameraSelector: ${cameraInfo.cameraId}, ${cameraInfo.lensFacing}")
|
||||
autoRecognizeJob?.cancel()
|
||||
_showPreview.value = true
|
||||
// 创建新的 CameraSelector
|
||||
cameraSelector = CameraSelector.Builder()
|
||||
.requireLensFacing(cameraInfo.lensFacing)
|
||||
@@ -159,74 +167,43 @@ class FaceDialogViewModel : BaseViewModel() {
|
||||
}
|
||||
// 解绑所有之前的用例
|
||||
cameraProvider?.unbindAll()
|
||||
|
||||
val imageAnalysis = ImageAnalysis.Builder()
|
||||
// 默认情况下,ImageAnalysis 的输出图像格式是 YUV,适合用于高效的图像处理和计算,但如果你需要以 RGBA 格式输出图像(通常用于处理图像像素颜色、UI 渲染等),就可以启用这一行代码。
|
||||
// .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
|
||||
// .setTargetResolution(Size(1280, 720))
|
||||
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
|
||||
.build()
|
||||
|
||||
// 高精度人脸检测
|
||||
val highAccuracyOpts = FaceDetectorOptions.Builder()
|
||||
.setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE)
|
||||
.setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_ALL)
|
||||
.setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_ALL)
|
||||
.build()
|
||||
// 实时人脸检测
|
||||
val realTimeOpts = FaceDetectorOptions.Builder()
|
||||
.setContourMode(FaceDetectorOptions.CONTOUR_MODE_ALL)
|
||||
.build()
|
||||
val detector = FaceDetection.getClient(realTimeOpts)
|
||||
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(context)) { imageProxy ->
|
||||
val mediaImage = imageProxy.image
|
||||
if (mediaImage != null) {
|
||||
val image =
|
||||
InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
|
||||
val result = detector.process(image)
|
||||
.addOnSuccessListener { faces ->
|
||||
// MyLog.face("检测到人脸数量: ${faces.size}")
|
||||
if (faces.size == 1) {
|
||||
_showPreview.value = false
|
||||
if (!_isRegister) {
|
||||
// 识别:自动
|
||||
faceRecognize()
|
||||
// 停止分析
|
||||
imageAnalysis.clearAnalyzer()
|
||||
}
|
||||
} else if (faces.size > 1) {
|
||||
_tips.value = "识别到多个人,请重试"
|
||||
} else {
|
||||
_tips.value = "未识别到人脸"
|
||||
}
|
||||
}
|
||||
.addOnFailureListener { e ->
|
||||
MyLog.face("没有人脸,${e.message}")
|
||||
}
|
||||
.addOnCompleteListener {
|
||||
mediaImage.close()
|
||||
imageProxy.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
// 绑定选择的摄像头和预览用例
|
||||
myCamera = cameraProvider?.bindToLifecycle(
|
||||
lifecycleOwner,
|
||||
cameraSelector!!,
|
||||
imageCapture,
|
||||
imageAnalysis,
|
||||
previewUseCase!!
|
||||
)
|
||||
scheduleAutoRecognize()
|
||||
}, ContextCompat.getMainExecutor(context))
|
||||
}
|
||||
|
||||
private fun scheduleAutoRecognize() {
|
||||
autoRecognizeJob?.cancel()
|
||||
if (_isRegister) {
|
||||
_countdownSeconds.value = 0
|
||||
_tips.value = "请调整画面后点击确定注册"
|
||||
return
|
||||
}
|
||||
autoRecognizeJob = viewModelScope.launch {
|
||||
for (second in 3 downTo 1) {
|
||||
_countdownSeconds.value = second
|
||||
_tips.value = "${second}秒后自动识别,请保持光线充足,人脸无遮挡"
|
||||
delay(1000L)
|
||||
}
|
||||
_countdownSeconds.value = 0
|
||||
_tips.value = "正在拍照识别"
|
||||
faceRecognize(onPhotoTaken = _onAutoCapture)
|
||||
}
|
||||
}
|
||||
|
||||
fun focusOnPoint(surfaceBounds: Size, x: Float, y: Float) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun takePicture(onFinish: (Uri) -> Unit = {}) {
|
||||
val file = File(context.externalMediaDirs.first(), "${System.currentTimeMillis()}.jpg")
|
||||
val file = MyUtil.createPictureFile(context)
|
||||
val outputFileOptions = ImageCapture.OutputFileOptions.Builder(file).build()
|
||||
val cameraExecutor = ContextCompat.getMainExecutor(context)
|
||||
imageCapture.takePicture(outputFileOptions, cameraExecutor,
|
||||
@@ -238,9 +215,9 @@ class FaceDialogViewModel : BaseViewModel() {
|
||||
|
||||
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
|
||||
// Toasty.success("拍照成功")
|
||||
val savedUri = outputFileResults.savedUri
|
||||
val savedUri = outputFileResults.savedUri ?: Uri.fromFile(file)
|
||||
// _savedUri.value = savedUri
|
||||
onFinish(savedUri!!)
|
||||
onFinish(savedUri)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -307,7 +284,7 @@ class FaceDialogViewModel : BaseViewModel() {
|
||||
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++3.上传信息到服务器
|
||||
val result3 = apiService.registerFaceForF8(
|
||||
data = FaceRegisterF8Request(
|
||||
baiduFaceToken = success1!!.result.faceToken,
|
||||
baiduFaceToken = success1.result.faceToken,
|
||||
ossBucketname = config.bucketName,
|
||||
ossObjectname = objectName,
|
||||
userid = userId,
|
||||
@@ -333,8 +310,12 @@ class FaceDialogViewModel : BaseViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
fun faceRecognize() {
|
||||
fun faceRecognize(onPhotoTaken: () -> Unit = {}) {
|
||||
autoRecognizeJob?.cancel()
|
||||
_countdownSeconds.value = 0
|
||||
_showPreview.value = false
|
||||
takePicture {
|
||||
onPhotoTaken()
|
||||
doInIoThreadThenUI("正在识别人脸", onIO = {
|
||||
val accessToken = apiService.getFaceAccessToken()
|
||||
val result = FaceRecognize.faceRecognize(
|
||||
@@ -345,9 +326,11 @@ class FaceDialogViewModel : BaseViewModel() {
|
||||
return@doInIoThreadThenUI result
|
||||
}) { result ->
|
||||
if (result.first == "false") {
|
||||
// 重新启动摄像头
|
||||
setCameraSelector(curCameraInfo)
|
||||
_tips.value = result.second
|
||||
_showPreview.value = true
|
||||
Toasty.error("人脸识别失败:${result.second}")
|
||||
} else {
|
||||
_tips.value = ""
|
||||
_onRecognizeFace(result.first, result.second)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.hardware.camera2.CameraCharacteristics
|
||||
import android.hardware.camera2.CameraManager
|
||||
import android.net.Uri
|
||||
import android.util.Size
|
||||
import android.view.WindowManager
|
||||
import androidx.camera.camera2.interop.Camera2CameraInfo
|
||||
import androidx.camera.camera2.interop.ExperimentalCamera2Interop
|
||||
import androidx.camera.core.Camera
|
||||
@@ -21,6 +20,7 @@ import com.bbitcn.f8.pad.MyApp
|
||||
import com.bbitcn.f8.pad.base.BaseViewModel
|
||||
import com.bbitcn.f8.pad.ui.screen.secondFunc.CameraInfo
|
||||
import com.bbitcn.f8.pad.ui.screen.view.Toasty
|
||||
import com.bbitcn.f8.pad.utils.MyUtil
|
||||
import com.bbitcn.f8.pad.utils.log.MyLog
|
||||
import com.bbitcn.f8.pad.utils.externalModules.ocr.ALiApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -57,8 +57,7 @@ class OCRDialogViewModel : BaseViewModel() {
|
||||
doInIoThreadThenUI("初始化相机", onIO = {
|
||||
lifecycleOwner = context as LifecycleOwner
|
||||
// 获取当前设备的旋转角度
|
||||
val rotation = (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager)
|
||||
.defaultDisplay.rotation
|
||||
val rotation = MyUtil.getDisplayRotation(context)
|
||||
imageCapture = ImageCapture.Builder()
|
||||
.setTargetRotation(rotation)
|
||||
.build()
|
||||
@@ -142,7 +141,7 @@ class OCRDialogViewModel : BaseViewModel() {
|
||||
}
|
||||
|
||||
fun takePicture(onFinish: (Uri) -> Unit = {}) {
|
||||
val file = File(context.externalMediaDirs.first(), "${System.currentTimeMillis()}.jpg")
|
||||
val file = MyUtil.createPictureFile(context)
|
||||
val outputFileOptions = ImageCapture.OutputFileOptions.Builder(file).build()
|
||||
val cameraExecutor = ContextCompat.getMainExecutor(context)
|
||||
imageCapture.takePicture(outputFileOptions, cameraExecutor,
|
||||
@@ -153,10 +152,10 @@ class OCRDialogViewModel : BaseViewModel() {
|
||||
}
|
||||
|
||||
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
|
||||
val savedUri = outputFileResults.savedUri
|
||||
val savedUri = outputFileResults.savedUri ?: Uri.fromFile(file)
|
||||
// 拍照成功后关闭相机
|
||||
cameraProvider?.unbindAll()
|
||||
onFinish(savedUri!!)
|
||||
onFinish(savedUri)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -122,7 +122,9 @@ fun FundsScreen(
|
||||
val dateStart =
|
||||
SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).parse(start)
|
||||
val dateEnd = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).parse(end)
|
||||
fundsViewModel.updateDateRange(dateStart to dateEnd)
|
||||
if (dateStart != null && dateEnd != null) {
|
||||
fundsViewModel.updateDateRange(dateStart to dateEnd)
|
||||
}
|
||||
onFilterLikeChanged(queryInput)
|
||||
}
|
||||
DateRangePickTextFiled(M.fillMaxWidth(), dateRange = queryDateRange) {
|
||||
|
||||
@@ -22,10 +22,9 @@ import androidx.compose.material3.DatePickerDialog
|
||||
import androidx.compose.material3.DateRangePicker
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ScrollableTabRow
|
||||
import androidx.compose.material3.SecondaryScrollableTabRow
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.TabRowDefaults
|
||||
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.rememberDateRangePickerState
|
||||
@@ -147,15 +146,15 @@ fun PurchaseScreen(
|
||||
purchaseViewModel.openAddTicketDialog(navController)
|
||||
})
|
||||
if (isLandscape()) {
|
||||
ScrollableTabRow(
|
||||
SecondaryScrollableTabRow(
|
||||
modifier = M
|
||||
.weight(1f),
|
||||
selectedTabIndex = queryType,
|
||||
containerColor = MyColors.Transparent,
|
||||
edgePadding = 10.dp,
|
||||
indicator = { tabPositions ->
|
||||
indicator = {
|
||||
TabRowDefaults.SecondaryIndicator(
|
||||
M.tabIndicatorOffset(tabPositions[queryType]),
|
||||
M.tabIndicatorOffset(queryType),
|
||||
color = MyColors.BlueGreen,
|
||||
)
|
||||
}
|
||||
@@ -202,14 +201,14 @@ fun PurchaseScreen(
|
||||
}
|
||||
}
|
||||
if (!isLandscape()) {
|
||||
ScrollableTabRow(
|
||||
SecondaryScrollableTabRow(
|
||||
selectedTabIndex = queryType,
|
||||
containerColor = MyColors.Transparent,
|
||||
edgePadding = 0.dp,
|
||||
modifier = M,
|
||||
indicator = { tabPositions ->
|
||||
indicator = {
|
||||
TabRowDefaults.SecondaryIndicator(
|
||||
M.tabIndicatorOffset(tabPositions[queryType]),
|
||||
M.tabIndicatorOffset(queryType),
|
||||
color = MyColors.BlueGreen,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import androidx.compose.runtime.setValue
|
||||
import com.alibaba.sdk.android.oss.OSS
|
||||
import com.alibaba.sdk.android.oss.OSSClient
|
||||
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider
|
||||
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider
|
||||
import com.alibaba.sdk.android.oss.model.GeneratePresignedUrlRequest
|
||||
import com.bbitcn.f8.pad.MyApp
|
||||
import com.bbitcn.f8.pad.base.BaseViewModel
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.hardware.camera2.CameraCharacteristics
|
||||
import android.hardware.camera2.CameraManager
|
||||
import android.net.Uri
|
||||
import android.util.Size
|
||||
import android.view.WindowManager
|
||||
import androidx.camera.camera2.interop.Camera2CameraInfo
|
||||
import androidx.camera.camera2.interop.ExperimentalCamera2Interop
|
||||
import androidx.camera.core.Camera
|
||||
@@ -23,6 +22,7 @@ import com.bbitcn.f8.pad.base.BaseViewModel
|
||||
import com.bbitcn.f8.pad.ui.screen.dialog.CameraInfo
|
||||
import com.bbitcn.f8.pad.ui.screen.view.Toasty
|
||||
import com.bbitcn.f8.pad.utils.MMKVUtil
|
||||
import com.bbitcn.f8.pad.utils.MyUtil
|
||||
import com.bbitcn.f8.pad.utils.externalModules.devices.reader.face.FaceRecognize
|
||||
import com.bbitcn.f8.pad.utils.log.MyLog
|
||||
import com.bbitcn.f8.pad.utils.externalModules.ocr.ALiApi
|
||||
@@ -60,8 +60,7 @@ class MyCameraViewModel : BaseViewModel() {
|
||||
context = MyApp.appContext
|
||||
lifecycleOwner = context as LifecycleOwner
|
||||
// 获取当前设备的旋转角度
|
||||
val rotation = (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager)
|
||||
.defaultDisplay.rotation
|
||||
val rotation = MyUtil.getDisplayRotation(context)
|
||||
imageCapture = ImageCapture.Builder()
|
||||
.setTargetRotation(rotation)
|
||||
.build()
|
||||
@@ -151,7 +150,7 @@ class MyCameraViewModel : BaseViewModel() {
|
||||
}
|
||||
|
||||
fun takePicture(onFinish: (Uri) -> Unit = {}) {
|
||||
val file = File(context.externalMediaDirs.first(), "${System.currentTimeMillis()}.jpg")
|
||||
val file = MyUtil.createPictureFile(context)
|
||||
val outputFileOptions = ImageCapture.OutputFileOptions.Builder(file).build()
|
||||
val cameraExecutor = ContextCompat.getMainExecutor(context)
|
||||
imageCapture.takePicture(outputFileOptions, cameraExecutor,
|
||||
@@ -163,9 +162,9 @@ class MyCameraViewModel : BaseViewModel() {
|
||||
|
||||
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
|
||||
Toasty.success("拍照成功")
|
||||
val savedUri = outputFileResults.savedUri
|
||||
val savedUri = outputFileResults.savedUri ?: Uri.fromFile(file)
|
||||
_savedUri.value = savedUri
|
||||
onFinish(savedUri!!)
|
||||
onFinish(savedUri)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -89,14 +88,14 @@ fun PayOperate(modifier: Modifier, payViewModel: PayViewModel) {
|
||||
}
|
||||
MyCard(border = BorderStroke(1.dp, MyColors.Gray), elevation = 0.dp) {
|
||||
Column {
|
||||
ScrollableTabRow(
|
||||
SecondaryScrollableTabRow(
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
containerColor = MyColors.Transparent,
|
||||
edgePadding = 10.dp,
|
||||
modifier = M.wrapContentHeight(),
|
||||
indicator = { tabPositions ->
|
||||
indicator = {
|
||||
TabRowDefaults.SecondaryIndicator(
|
||||
M.tabIndicatorOffset(tabPositions[pagerState.currentPage]),
|
||||
M.tabIndicatorOffset(pagerState.currentPage),
|
||||
color = MyColors.BlueGreen,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -191,14 +190,14 @@ fun WeightList(weightViewModel: WeightViewModel) {
|
||||
val detailList by weightViewModel.detailList.collectAsState()
|
||||
Column(modifier = M.padding(horizontal = 10.dp)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
ScrollableTabRow(
|
||||
SecondaryScrollableTabRow(
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
containerColor = MyColors.Transparent,
|
||||
modifier = M
|
||||
.weight(1f),
|
||||
indicator = { tabPositions ->
|
||||
indicator = {
|
||||
TabRowDefaults.SecondaryIndicator(
|
||||
M.tabIndicatorOffset(tabPositions[pagerState.currentPage]),
|
||||
M.tabIndicatorOffset(pagerState.currentPage),
|
||||
color = MyColors.BlueGreen,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.commandiron.wheel_picker_compose.WheelDateTimePicker
|
||||
import com.commandiron.wheel_picker_compose.core.TimeFormat
|
||||
import com.commandiron.wheel_picker_compose.core.WheelPickerDefaults
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
@@ -63,7 +63,7 @@ object Toasty : BaseViewModel() {
|
||||
val drawerContent: StateFlow<@Composable () -> Unit> = _drawerContent.asStateFlow()
|
||||
|
||||
fun showOptionDrawer(title: String, options: List<String>, onClick: (String) -> Unit) {
|
||||
GlobalScope.launch {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
if (options.isEmpty()) {
|
||||
Toasty.showToast("暂无选项")
|
||||
|
||||
+6
-6
@@ -215,7 +215,7 @@ fun TicketForDryStoreCocoon(
|
||||
"芯片",
|
||||
3,
|
||||
{ if (it.rfid.length >= 6) ".." + it.rfid.takeLast(4) else it.rfid }),
|
||||
MyTableData("状态", 2, { it.status.toString() }),
|
||||
MyTableData("状态", 2, { it.status }),
|
||||
MyTableData("毛重", 2, { it.maozhong.toString() }),
|
||||
MyTableData("皮重", 2, { it.pizhong.toString() }),
|
||||
MyTableData("净重", 2, { it.jingzhong.toString() }),
|
||||
@@ -231,13 +231,13 @@ fun TicketForDryStoreCocoon(
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
InfoText(
|
||||
"乡镇",
|
||||
it.xiangzhen.toString(),
|
||||
it.xiangzhen,
|
||||
M.weight(2f),
|
||||
true
|
||||
)
|
||||
InfoText(
|
||||
"芯片",
|
||||
it.rfid.toString(),
|
||||
it.rfid,
|
||||
M.weight(3f),
|
||||
true
|
||||
)
|
||||
@@ -251,13 +251,13 @@ fun TicketForDryStoreCocoon(
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
InfoText(
|
||||
"类型",
|
||||
ex.type.toString(),
|
||||
ex.type,
|
||||
M.weight(2f),
|
||||
true
|
||||
)
|
||||
InfoText(
|
||||
"时间",
|
||||
ex.time.toString(),
|
||||
ex.time,
|
||||
M.weight(3f),
|
||||
true
|
||||
)
|
||||
@@ -265,7 +265,7 @@ fun TicketForDryStoreCocoon(
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
InfoText(
|
||||
"备注",
|
||||
ex.memo.toString(),
|
||||
ex.memo,
|
||||
M.weight(3f),
|
||||
true
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@ object AudioPlayer {
|
||||
return
|
||||
}
|
||||
|
||||
val nextResId = audioQueue.poll()
|
||||
val nextResId = audioQueue.removeFirst()
|
||||
val player = MediaPlayer.create(MyApp.appContext, nextResId)
|
||||
mediaPlayer = player
|
||||
isPlaying = true
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.bbitcn.f8.pad.utils
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.text.format.DateUtils
|
||||
import com.bbitcn.f8.pad.MyApp.Companion.appContext
|
||||
import com.bbitcn.f8.pad.utils.global.Global
|
||||
@@ -12,6 +14,7 @@ import com.blankj.utilcode.util.EncryptUtils
|
||||
import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.EncodeHintType
|
||||
import com.google.zxing.MultiFormatWriter
|
||||
import java.io.File
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
@@ -50,13 +53,30 @@ object MyUtil {
|
||||
val packageManager = appContext.packageManager
|
||||
val packageInfo =
|
||||
packageManager.getPackageInfo(appContext.packageName, 0)
|
||||
return packageInfo.versionCode
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
packageInfo.longVersionCode.toInt()
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
packageInfo.versionCode
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
fun getDisplayRotation(context: Context = appContext): Int {
|
||||
return context.display.rotation
|
||||
}
|
||||
|
||||
fun createPictureFile(context: Context = appContext): File {
|
||||
val dir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) ?: context.filesDir
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs()
|
||||
}
|
||||
return File(dir, "${System.currentTimeMillis()}.jpg")
|
||||
}
|
||||
|
||||
fun getVersionName(): String {
|
||||
try {
|
||||
val packageManager = appContext.packageManager
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ object JTPrinterUSB : UsbDeviceConnector(), PrinterInterface {
|
||||
val listUsbPort = AutoReplyPrint.CP_Port_EnumUsb_Helper.EnumUsb()
|
||||
if (listUsbPort != null) {
|
||||
for (usbPort in listUsbPort) {
|
||||
if (usbPort.contains(vId.toString()) && usbPort.contains(pId.toString())) {
|
||||
if (usbPort.contains(vId) && usbPort.contains(pId)) {
|
||||
// 检测到巨天打印机,视为连接成功
|
||||
setVId(vId)
|
||||
setPId(pId)
|
||||
@@ -74,7 +74,7 @@ object JTPrinterUSB : UsbDeviceConnector(), PrinterInterface {
|
||||
if (listUsbPort != null) {
|
||||
for (usbPort in listUsbPort) {
|
||||
// usbPort 格式为 "VID:0x4B43,PID:0x0FE6"
|
||||
if (usbPort.contains(getVId().toString()) && usbPort.contains(getPId().toString())) {
|
||||
if (usbPort.contains(getVId()) && usbPort.contains(getPId())) {
|
||||
h = AutoReplyPrint.INSTANCE.CP_Port_OpenUsb(usbPort, 1)
|
||||
AutoReplyPrint.INSTANCE.CP_Printer_AddOnPrinterStatusEvent({ handle: Pointer, printerErrorStatus: Long, printerInfoStatus: Long, privateData: Pointer ->
|
||||
if (CP_RTSTATUS_Helper.CP_RTSTATUS_NOPAPER(printerErrorStatus)) {
|
||||
|
||||
+2
-2
@@ -10,8 +10,8 @@ import com.bbitcn.f8.pad.utils.externalModules.devices.printer.JTPrinterUSB.resi
|
||||
import com.bbitcn.f8.pad.utils.externalModules.manager.bluetooth.MyBlueTooth
|
||||
import com.blankj.utilcode.util.TimeUtils
|
||||
import cpcl.PrinterHelper
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.ByteArrayOutputStream
|
||||
@@ -344,7 +344,7 @@ object PrinterBT : MyBlueTooth(), PrinterInterface {
|
||||
}
|
||||
try {
|
||||
setState(0)
|
||||
GlobalScope.launch {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
setState(withContext(Dispatchers.IO) {
|
||||
val result =
|
||||
if (PrinterHelper.portOpenBT(MyApp.appContext, mac) == 0) 1 else -1
|
||||
|
||||
+7
-2
@@ -70,7 +70,12 @@ object FaceRecognize {
|
||||
image = base64,
|
||||
)
|
||||
)
|
||||
val userList = result.result.userList
|
||||
if (result.errorCode != 0) {
|
||||
return "false" to result.errorMsg.ifBlank { "人脸识别失败" }
|
||||
}
|
||||
val faceResult = result.result
|
||||
?: return "false" to result.errorMsg.ifBlank { "未识别到人脸" }
|
||||
val userList = faceResult.userList
|
||||
if (userList.size > 1) {
|
||||
return "false" to "识别到多个人,请重新识别"
|
||||
} else if (userList.isEmpty()) {
|
||||
@@ -80,7 +85,7 @@ object FaceRecognize {
|
||||
} else {
|
||||
val user = userList[0]
|
||||
MyLog.network("faceRecognize result: ${user.userId}")
|
||||
return user.userId.replace("_", "-") to result.result.faceToken
|
||||
return user.userId.replace("_", "-") to faceResult.faceToken
|
||||
}
|
||||
}
|
||||
return "false" to "图片有误"
|
||||
|
||||
-1
@@ -3,7 +3,6 @@ package com.bbitcn.f8.pad.utils.externalModules.devices.reader.face
|
||||
import com.alibaba.sdk.android.oss.OSS
|
||||
import com.alibaba.sdk.android.oss.OSSClient
|
||||
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider
|
||||
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider
|
||||
import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider
|
||||
import com.bbitcn.f8.pad.MyApp
|
||||
import com.bbitcn.f8.pad.ui.screen.view.Toasty.showTipsDialog
|
||||
|
||||
+1
-2
@@ -7,7 +7,6 @@ import com.bbitcn.f8.pad.utils.MMKVUtil
|
||||
import com.bbitcn.f8.pad.utils.log.MyLog
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
@@ -111,7 +110,7 @@ abstract class DeviceController {
|
||||
onIO: suspend () -> T,
|
||||
onUI: (T) -> Unit,
|
||||
) {
|
||||
GlobalScope.launch {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
val result = runCatching {
|
||||
withContext(Dispatchers.IO) {
|
||||
if (showDialog) {
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ abstract class MyBlueTooth : BluetoothDeviceConnector() {
|
||||
|
||||
var devicesFound: MutableList<BluetoothDevice> = mutableStateListOf()
|
||||
val mClient: BluetoothClient? by lazy {
|
||||
MyApp.appContext?.let { BluetoothClient(MyApp.appContext) }
|
||||
BluetoothClient(MyApp.appContext)
|
||||
}
|
||||
val mBleConnectStatusListener: BleConnectStatusListener = object : BleConnectStatusListener() {
|
||||
override fun onConnectStatusChanged(mac: String, status: Int) {
|
||||
|
||||
@@ -14,7 +14,7 @@ object CrashHandlerUtil : Thread.UncaughtExceptionHandler {
|
||||
Thread.setDefaultUncaughtExceptionHandler(this)
|
||||
}
|
||||
|
||||
override fun uncaughtException(thread: Thread?, ex: Throwable) {
|
||||
override fun uncaughtException(thread: Thread, ex: Throwable) {
|
||||
ex.printStackTrace()
|
||||
MyLog.appError("软件已崩溃:" + getFormattedException(ex))
|
||||
Toasty.showConfirmDialog("软件已崩溃,请重启\n" + getFormattedException(ex)) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Protocol
|
||||
import okhttp3.Response
|
||||
import okhttp3.ResponseBody
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
@@ -70,8 +70,7 @@ object RetrofitClient {
|
||||
e.printStackTrace()
|
||||
MyLog.networkError("请求网络时发生异常:${e.message}")
|
||||
MyLog.networkError("错误类型:${e.javaClass.simpleName},错误信息:${e.message}")
|
||||
val responseBody =
|
||||
ResponseBody.create("application/json".toMediaTypeOrNull(), "{}")
|
||||
val responseBody = "{}".toResponseBody("application/json".toMediaTypeOrNull())
|
||||
val fakeResponse: Response =
|
||||
if (e is UnknownHostException || e is SocketTimeoutException || e is ConnectException) {
|
||||
Response.Builder()
|
||||
|
||||
@@ -9,9 +9,9 @@ class DryCocoonAirDetailPagingSource(tlsysid: String) :
|
||||
|
||||
override suspend fun fetchData(
|
||||
pageInfoJsonStr: String,
|
||||
tlsysid: String
|
||||
requestData: String
|
||||
): List<DryCocoonAirDetailListResponse.Data> {
|
||||
return apiService.getDryCocoonAirDetailList(pageInfoJsonStr, DryCocoonAirDetailListRequest(tlsysid)).data // 返回数据列表
|
||||
return apiService.getDryCocoonAirDetailList(pageInfoJsonStr, DryCocoonAirDetailListRequest(requestData)).data // 返回数据列表
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ class DryCocoonAirPagingSource(request: DryCocoonAirListRequest) :
|
||||
|
||||
override suspend fun fetchData(
|
||||
pageInfoJsonStr: String,
|
||||
request: DryCocoonAirListRequest
|
||||
requestData: DryCocoonAirListRequest
|
||||
): List<DryCocoonAirListResponse.Data> {
|
||||
return apiService.getDryCocoonAirList(pageInfoJsonStr, request).data
|
||||
return apiService.getDryCocoonAirList(pageInfoJsonStr, requestData).data
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ class DryCocoonInDetailPagingSource(rksysid: String) :
|
||||
|
||||
override suspend fun fetchData(
|
||||
pageInfoJsonStr: String,
|
||||
rksysid: String
|
||||
requestData: String
|
||||
): List<DryCocoonInDetailResponse.Data> {
|
||||
return apiService.getDryCocoonInDetailList(pageInfoJsonStr, rksysid).data // 返回数据列表
|
||||
return apiService.getDryCocoonInDetailList(pageInfoJsonStr, requestData).data // 返回数据列表
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ class DryCocoonOutDetailPagingSource(rksysid: String) :
|
||||
|
||||
override suspend fun fetchData(
|
||||
pageInfoJsonStr: String,
|
||||
rksysid: String
|
||||
requestData: String
|
||||
): List<DryCocoonOutDetailResponse.Data> {
|
||||
return apiService.getDryCocoonOutDetailList(pageInfoJsonStr, rksysid).data // 返回数据列表
|
||||
return apiService.getDryCocoonOutDetailList(pageInfoJsonStr, requestData).data // 返回数据列表
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ class DryCocoonStoreDetailPagingSource(data: DryCocoonStoreDetailListRequest) :
|
||||
|
||||
override suspend fun fetchData(
|
||||
pageInfoJsonStr: String,
|
||||
data: DryCocoonStoreDetailListRequest,
|
||||
requestData: DryCocoonStoreDetailListRequest,
|
||||
): List<DryCocoonStoreDetailListResponse.Data> {
|
||||
return apiService.getDryCocoonStoreDetailList(pageInfoJsonStr, data.tlsysid,data.like).data // 返回数据列表
|
||||
return apiService.getDryCocoonStoreDetailList(pageInfoJsonStr, requestData.tlsysid,requestData.like).data // 返回数据列表
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user