From c5a72e938fc18ad22498dc55f89a929be0d0e47c Mon Sep 17 00:00:00 2001 From: BBIT-Kai <2911862937@qq.com> Date: Fri, 29 May 2026 09:57:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=85=E7=90=86=E4=BA=BA=E8=84=B8=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E4=BB=A3=E7=A0=81=EF=BC=9B=E6=B8=85=E7=90=86=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=BC=96=E8=AF=91=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 1 - .../f8/pad/base/CustomMaterialComponents.kt | 54 +++-- .../net/response/FaceRecognizeResponse.kt | 4 +- .../f8/pad/receiver/SystemInfoReceiver.kt | 195 ++++++++++++------ .../java/com/bbitcn/f8/pad/ui/MainActivity.kt | 46 +++-- .../bbitcn/f8/pad/ui/screen/LoginScreen.kt | 17 +- .../f8/pad/ui/screen/dialog/ChatDialog.kt | 38 ++-- .../f8/pad/ui/screen/dialog/FaceDialog.kt | 30 ++- .../ui/screen/dialog/FaceDialogViewModel.kt | 117 +++++------ .../ui/screen/dialog/OCRDialogViewModel.kt | 13 +- .../f8/pad/ui/screen/mainFunc/FundsScreen.kt | 4 +- .../pad/ui/screen/mainFunc/PurchaseScreen.kt | 15 +- .../ui/screen/secondFunc/AddUserViewModel.kt | 1 - .../ui/screen/secondFunc/MyCameraViewModel.kt | 13 +- .../f8/pad/ui/screen/secondFunc/PayScreen.kt | 7 +- .../pad/ui/screen/secondFunc/WeightScreen.kt | 7 +- .../bbitcn/f8/pad/ui/screen/view/Toasty.kt | 4 +- .../view/drawer/TicketForDryStoreCocoon.kt | 12 +- .../com/bbitcn/f8/pad/utils/AudioPlayer.kt | 2 +- .../java/com/bbitcn/f8/pad/utils/MyUtil.kt | 22 +- .../devices/printer/JTPrinterUSB.kt | 6 +- .../devices/printer/PrinterBT.kt | 6 +- .../devices/reader/face/FaceRecognize.kt | 11 +- .../devices/reader/face/OssUtils.kt | 3 +- .../manager/DeviceController.kt | 5 +- .../manager/bluetooth/MyBlueTooth.kt | 2 +- .../f8/pad/utils/log/CrashHandlerUtil.kt | 4 +- .../f8/pad/utils/network/RetrofitClient.kt | 5 +- .../pager/DryCocoonAirDetailPagingSource.kt | 4 +- .../utils/pager/DryCocoonAirPagingSource.kt | 4 +- .../pager/DryCocoonInDetailPagingSource.kt | 4 +- .../pager/DryCocoonOutDetailPagingSource.kt | 4 +- .../pager/DryCocoonStoreDetailPagingSource.kt | 4 +- 33 files changed, 382 insertions(+), 282 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2881c43..93a51df 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -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") diff --git a/app/src/main/java/com/bbitcn/f8/pad/base/CustomMaterialComponents.kt b/app/src/main/java/com/bbitcn/f8/pad/base/CustomMaterialComponents.kt index 30809df..dbab22c 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/base/CustomMaterialComponents.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/base/CustomMaterialComponents.kt @@ -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, 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, ) } diff --git a/app/src/main/java/com/bbitcn/f8/pad/model/net/response/FaceRecognizeResponse.kt b/app/src/main/java/com/bbitcn/f8/pad/model/net/response/FaceRecognizeResponse.kt index b04edbd..fca8b75 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/model/net/response/FaceRecognizeResponse.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/model/net/response/FaceRecognizeResponse.kt @@ -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 ) { @@ -33,4 +33,4 @@ data class FaceRecognizeResponse( val userInfo: String = "" ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/bbitcn/f8/pad/receiver/SystemInfoReceiver.kt b/app/src/main/java/com/bbitcn/f8/pad/receiver/SystemInfoReceiver.kt index e73bb65..52ad9a8 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/receiver/SystemInfoReceiver.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/receiver/SystemInfoReceiver.kt @@ -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}") } } diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/MainActivity.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/MainActivity.kt index 13fab9b..3da2183 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/MainActivity.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/MainActivity.kt @@ -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 + } + } + } + ) } } diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/LoginScreen.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/LoginScreen.kt index 81c424e..afcae97 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/LoginScreen.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/LoginScreen.kt @@ -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() ) } diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/ChatDialog.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/ChatDialog.kt index ff5645e..28b58ad 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/ChatDialog.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/ChatDialog.kt @@ -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(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 } ) } diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/FaceDialog.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/FaceDialog.kt index 29d9e82..fc08f59 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/FaceDialog.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/FaceDialog.kt @@ -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 + ) + } + } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/FaceDialogViewModel.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/FaceDialogViewModel.kt index 9901c31..9b8b72e 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/FaceDialogViewModel.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/FaceDialogViewModel.kt @@ -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(null) val surfaceRequests: StateFlow 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) } } @@ -375,4 +358,4 @@ class FaceDialogViewModel : BaseViewModel() { return "$prefix-$timestamp-$randomNum." } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/OCRDialogViewModel.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/OCRDialogViewModel.kt index 12e877e..3601ee3 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/OCRDialogViewModel.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/dialog/OCRDialogViewModel.kt @@ -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) } }) } @@ -213,4 +212,4 @@ data class CameraInfo( val cameraId: String, val lensFacing: Int, val cameraName: String -) \ No newline at end of file +) diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/mainFunc/FundsScreen.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/mainFunc/FundsScreen.kt index 316ca23..ade5378 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/mainFunc/FundsScreen.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/mainFunc/FundsScreen.kt @@ -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) { diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/mainFunc/PurchaseScreen.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/mainFunc/PurchaseScreen.kt index fa8b1e1..a6a9dde 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/mainFunc/PurchaseScreen.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/mainFunc/PurchaseScreen.kt @@ -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, ) } diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/AddUserViewModel.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/AddUserViewModel.kt index 7f9fa4e..d3174df 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/AddUserViewModel.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/AddUserViewModel.kt @@ -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 diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/MyCameraViewModel.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/MyCameraViewModel.kt index 04d2ab4..cb021c3 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/MyCameraViewModel.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/MyCameraViewModel.kt @@ -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) } }) } @@ -227,4 +226,4 @@ data class CameraInfo( val cameraId: String, val lensFacing: Int, val cameraName: String -) \ No newline at end of file +) diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/PayScreen.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/PayScreen.kt index 1248d35..8b582ca 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/PayScreen.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/PayScreen.kt @@ -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, ) } diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/WeightScreen.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/WeightScreen.kt index 9026454..571c0ab 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/WeightScreen.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/secondFunc/WeightScreen.kt @@ -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, ) } diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/view/Toasty.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/view/Toasty.kt index be1598b..16636f6 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/view/Toasty.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/view/Toasty.kt @@ -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, onClick: (String) -> Unit) { - GlobalScope.launch { + CoroutineScope(Dispatchers.Main).launch { withContext(Dispatchers.IO) { if (options.isEmpty()) { Toasty.showToast("暂无选项") diff --git a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/view/drawer/TicketForDryStoreCocoon.kt b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/view/drawer/TicketForDryStoreCocoon.kt index 2a9e0c2..a55931b 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/ui/screen/view/drawer/TicketForDryStoreCocoon.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/ui/screen/view/drawer/TicketForDryStoreCocoon.kt @@ -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 ) diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/AudioPlayer.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/AudioPlayer.kt index 12fa811..beea973 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/AudioPlayer.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/AudioPlayer.kt @@ -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 diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/MyUtil.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/MyUtil.kt index 4f87c6b..32c7bac 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/MyUtil.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/MyUtil.kt @@ -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 diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/printer/JTPrinterUSB.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/printer/JTPrinterUSB.kt index ad39f99..2d27056 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/printer/JTPrinterUSB.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/printer/JTPrinterUSB.kt @@ -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)) { @@ -237,4 +237,4 @@ object JTPrinterUSB : UsbDeviceConnector(), PrinterInterface { // usbManager.requestPermission(usbDevice, pendingIntent) // return false // } -// } \ No newline at end of file +// } diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/printer/PrinterBT.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/printer/PrinterBT.kt index 15a25cd..0097804 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/printer/PrinterBT.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/printer/PrinterBT.kt @@ -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 @@ -437,4 +437,4 @@ object PrinterBT : MyBlueTooth(), PrinterInterface { return Base64.encodeToString(byteArray, Base64.DEFAULT) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/reader/face/FaceRecognize.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/reader/face/FaceRecognize.kt index 3e2c16c..839bf29 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/reader/face/FaceRecognize.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/reader/face/FaceRecognize.kt @@ -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 "图片有误" @@ -116,4 +121,4 @@ object FaceRecognize { inputStream?.close() } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/reader/face/OssUtils.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/reader/face/OssUtils.kt index 444e0df..ac6eed6 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/reader/face/OssUtils.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/devices/reader/face/OssUtils.kt @@ -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 @@ -28,4 +27,4 @@ object OssUtils { // 创建OSSClient实例 return OSSClient(MyApp.appContext, config.endPoint, credentialProvider) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/manager/DeviceController.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/manager/DeviceController.kt index 467559c..9591699 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/manager/DeviceController.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/manager/DeviceController.kt @@ -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) { @@ -151,4 +150,4 @@ abstract class DeviceController { abstract fun getDeviceName(): String -} \ No newline at end of file +} diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/manager/bluetooth/MyBlueTooth.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/manager/bluetooth/MyBlueTooth.kt index 62fddf3..8cd64fd 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/manager/bluetooth/MyBlueTooth.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/externalModules/manager/bluetooth/MyBlueTooth.kt @@ -46,7 +46,7 @@ abstract class MyBlueTooth : BluetoothDeviceConnector() { var devicesFound: MutableList = 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) { diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/log/CrashHandlerUtil.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/log/CrashHandlerUtil.kt index 3292f4e..b2b66f4 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/log/CrashHandlerUtil.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/log/CrashHandlerUtil.kt @@ -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)) { @@ -44,4 +44,4 @@ object CrashHandlerUtil : Thread.UncaughtExceptionHandler { return stringBuilder.toString() } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/network/RetrofitClient.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/network/RetrofitClient.kt index cacfc31..bf9f4ae 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/network/RetrofitClient.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/network/RetrofitClient.kt @@ -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() diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonAirDetailPagingSource.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonAirDetailPagingSource.kt index f923b25..3a34b44 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonAirDetailPagingSource.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonAirDetailPagingSource.kt @@ -9,9 +9,9 @@ class DryCocoonAirDetailPagingSource(tlsysid: String) : override suspend fun fetchData( pageInfoJsonStr: String, - tlsysid: String + requestData: String ): List { - return apiService.getDryCocoonAirDetailList(pageInfoJsonStr, DryCocoonAirDetailListRequest(tlsysid)).data // 返回数据列表 + return apiService.getDryCocoonAirDetailList(pageInfoJsonStr, DryCocoonAirDetailListRequest(requestData)).data // 返回数据列表 } } diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonAirPagingSource.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonAirPagingSource.kt index 8595abe..d0754d5 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonAirPagingSource.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonAirPagingSource.kt @@ -9,9 +9,9 @@ class DryCocoonAirPagingSource(request: DryCocoonAirListRequest) : override suspend fun fetchData( pageInfoJsonStr: String, - request: DryCocoonAirListRequest + requestData: DryCocoonAirListRequest ): List { - return apiService.getDryCocoonAirList(pageInfoJsonStr, request).data + return apiService.getDryCocoonAirList(pageInfoJsonStr, requestData).data } } diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonInDetailPagingSource.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonInDetailPagingSource.kt index 0361cf9..8f8e29e 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonInDetailPagingSource.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonInDetailPagingSource.kt @@ -9,9 +9,9 @@ class DryCocoonInDetailPagingSource(rksysid: String) : override suspend fun fetchData( pageInfoJsonStr: String, - rksysid: String + requestData: String ): List { - return apiService.getDryCocoonInDetailList(pageInfoJsonStr, rksysid).data // 返回数据列表 + return apiService.getDryCocoonInDetailList(pageInfoJsonStr, requestData).data // 返回数据列表 } } diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonOutDetailPagingSource.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonOutDetailPagingSource.kt index 1998f27..d479a1c 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonOutDetailPagingSource.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonOutDetailPagingSource.kt @@ -10,9 +10,9 @@ class DryCocoonOutDetailPagingSource(rksysid: String) : override suspend fun fetchData( pageInfoJsonStr: String, - rksysid: String + requestData: String ): List { - return apiService.getDryCocoonOutDetailList(pageInfoJsonStr, rksysid).data // 返回数据列表 + return apiService.getDryCocoonOutDetailList(pageInfoJsonStr, requestData).data // 返回数据列表 } } diff --git a/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonStoreDetailPagingSource.kt b/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonStoreDetailPagingSource.kt index 290ae9c..03bbe3b 100644 --- a/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonStoreDetailPagingSource.kt +++ b/app/src/main/java/com/bbitcn/f8/pad/utils/pager/DryCocoonStoreDetailPagingSource.kt @@ -9,9 +9,9 @@ class DryCocoonStoreDetailPagingSource(data: DryCocoonStoreDetailListRequest) : override suspend fun fetchData( pageInfoJsonStr: String, - data: DryCocoonStoreDetailListRequest, + requestData: DryCocoonStoreDetailListRequest, ): List { - return apiService.getDryCocoonStoreDetailList(pageInfoJsonStr, data.tlsysid,data.like).data // 返回数据列表 + return apiService.getDryCocoonStoreDetailList(pageInfoJsonStr, requestData.tlsysid,requestData.like).data // 返回数据列表 } }