From b7dab20751fcac519975397ee1a68fa5fedfff4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E9=97=BB=E9=A3=8E?= Date: Fri, 26 Jun 2026 20:46:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=90=9C=E7=B4=A2=E9=A1=B5=E6=94=AF?= =?UTF-8?q?=E6=8C=81JSON=E6=89=AB=E7=A0=81=E7=9B=B4=E8=BE=BE=EF=BC=8C?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=89=8D=E7=BC=80=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 搜索输入框内容若是JSON则解码,type为ops_sys时根据module跳转(workorder→工单详情,item→物品详情) - JSON解码后无论type是否为ops_sys都清空输入框 - 非JSON内容走原有关键字搜索逻辑 - 去掉前缀快捷搜索提示文本 --- .../ops_android/ui/navigation/OPSNavGraph.kt | 8 +++++- .../ops_android/ui/search/SearchScreen.kt | 20 ++++++------- .../ops_android/ui/search/SearchViewModel.kt | 28 +++++++++++++++++-- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/example/ops_android/ui/navigation/OPSNavGraph.kt b/app/src/main/java/com/example/ops_android/ui/navigation/OPSNavGraph.kt index 36455fd..675d3f7 100644 --- a/app/src/main/java/com/example/ops_android/ui/navigation/OPSNavGraph.kt +++ b/app/src/main/java/com/example/ops_android/ui/navigation/OPSNavGraph.kt @@ -111,7 +111,13 @@ fun OPSNavGraph(isLoggedIn: Boolean) { onWorkOrderClick = { id -> rootNavController.navigate(Routes.workOrderDetail(id)) }, onItemClick = { id -> rootNavController.navigate(Routes.itemDetail(id)) }, onContainerClick = { id -> rootNavController.navigate(Routes.MAIN) }, - onBack = { rootNavController.popBackStack() } + onBack = { rootNavController.popBackStack() }, + onOpsSysNavigate = { module, id -> + when (module) { + "workorder" -> rootNavController.navigate(Routes.workOrderDetail(id)) + "item" -> rootNavController.navigate(Routes.itemDetail(id)) + } + } ) } composable(Routes.SCHEDULE) { diff --git a/app/src/main/java/com/example/ops_android/ui/search/SearchScreen.kt b/app/src/main/java/com/example/ops_android/ui/search/SearchScreen.kt index 664ad63..fe9abf3 100644 --- a/app/src/main/java/com/example/ops_android/ui/search/SearchScreen.kt +++ b/app/src/main/java/com/example/ops_android/ui/search/SearchScreen.kt @@ -28,7 +28,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign + import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.viewinterop.AndroidView @@ -51,7 +51,8 @@ fun SearchScreen( onWorkOrderClick: (Int) -> Unit, onItemClick: (Int) -> Unit, onContainerClick: (Int) -> Unit, - onBack: () -> Unit + onBack: () -> Unit, + onOpsSysNavigate: (module: String, id: Int) -> Unit ) { val appContainer = LocalAppContainer.current val viewModel: SearchViewModel = viewModel( @@ -67,6 +68,13 @@ fun SearchScreen( if (granted) showScanner = true } + LaunchedEffect(uiState.opsSysNavigation) { + uiState.opsSysNavigation?.let { navInfo -> + onOpsSysNavigate(navInfo.module, navInfo.id) + viewModel.clearOpsSysNavigation() + } + } + fun checkCameraAndScan() { if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { hasCameraPermission = true @@ -128,14 +136,6 @@ fun SearchScreen( } } - // Prefix hints - Text( - "前缀快捷搜索: po:采购单 wo:工单 item:物品 warehouse:容器", - fontSize = 11.sp, - color = Color.Gray, - modifier = Modifier.padding(horizontal = 16.dp), - textAlign = TextAlign.Center - ) // Category tabs PrimaryScrollableTabRow( diff --git a/app/src/main/java/com/example/ops_android/ui/search/SearchViewModel.kt b/app/src/main/java/com/example/ops_android/ui/search/SearchViewModel.kt index b9af03d..37a1bb5 100644 --- a/app/src/main/java/com/example/ops_android/ui/search/SearchViewModel.kt +++ b/app/src/main/java/com/example/ops_android/ui/search/SearchViewModel.kt @@ -7,7 +7,6 @@ import com.example.ops_android.data.model.Container import com.example.ops_android.data.model.Item import com.example.ops_android.data.model.PurchaseOrder import com.example.ops_android.data.model.WorkOrder -import com.example.ops_android.data.repository.CustomerRepository import com.example.ops_android.data.repository.OrderRepository import com.example.ops_android.data.repository.WarehouseRepository import com.example.ops_android.data.repository.WorkOrderRepository @@ -15,6 +14,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +import org.json.JSONObject enum class SearchCategory(val label: String) { ALL("全部"), @@ -24,6 +24,11 @@ enum class SearchCategory(val label: String) { CONTAINER("容器") } +data class OpsSysNavInfo( + val module: String, + val id: Int +) + data class SearchUiState( val query: String = "", val category: SearchCategory = SearchCategory.ALL, @@ -32,7 +37,8 @@ data class SearchUiState( val items: List = emptyList(), val containers: List = emptyList(), val isSearching: Boolean = false, - val errorMessage: String? = null + val errorMessage: String? = null, + val opsSysNavigation: OpsSysNavInfo? = null ) class SearchViewModel( @@ -61,7 +67,19 @@ class SearchViewModel( val query = _uiState.value.query.trim() if (query.isEmpty()) return - // Parse prefix shortcuts + val jsonObj = try { JSONObject(query) } catch (e: Exception) { null } + if (jsonObj != null) { + _uiState.value = _uiState.value.copy(query = "") + if (jsonObj.optString("type") == "ops_sys") { + val module = jsonObj.optString("module") + val id = jsonObj.optInt("id") + if (module.isNotBlank() && id > 0) { + _uiState.value = _uiState.value.copy(opsSysNavigation = OpsSysNavInfo(module, id)) + } + } + return + } + val (actualCategory, actualQuery) = parsePrefix(query) _uiState.value = _uiState.value.copy(category = actualCategory) @@ -125,6 +143,10 @@ class SearchViewModel( _uiState.value = SearchUiState(query = _uiState.value.query, category = _uiState.value.category) } + fun clearOpsSysNavigation() { + _uiState.value = _uiState.value.copy(opsSysNavigation = null) + } + private fun parsePrefix(query: String): Pair { val prefixes = mapOf( "po:" to SearchCategory.ORDER,