Compare commits

...
4 Commits
Author SHA1 Message Date
kevin 081884b723 Signed-off-by: 无闻风 <wuwenfengmi@gmail.com> 2026-06-26 20:47:09 +08:00
kevin b7dab20751 feat: 搜索页支持JSON扫码直达,去掉前缀提示
- 搜索输入框内容若是JSON则解码,type为ops_sys时根据module跳转(workorder→工单详情,item→物品详情)
- JSON解码后无论type是否为ops_sys都清空输入框
- 非JSON内容走原有关键字搜索逻辑
- 去掉前缀快捷搜索提示文本
2026-06-26 20:46:58 +08:00
kevin a7d81d42ea Signed-off-by: 无闻风 <wuwenfengmi@gmail.com> 2026-06-26 20:32:49 +08:00
kevin 85bcdfccaa Signed-off-by: 无闻风 <wuwenfengmi@gmail.com>
修改图标与应用名字
2026-06-26 20:20:52 +08:00
29 changed files with 60 additions and 44 deletions
@@ -80,6 +80,21 @@ fun HomeScreen(
}
}
// ── 快捷入口 ──────────────────────────
item {
Text("快捷入口", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
}
item {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
QuickLinkCard(Icons.Default.Search, "搜索", Color(0xFF4CAF50), Modifier.weight(1f), onSearchClick)
QuickLinkCard(Icons.Default.Event, "日程", Color(0xFF9C27B0), Modifier.weight(1f), onScheduleClick)
}
}
// ── 今日日程 ──────────────────────────
item {
Text("今日日程", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
@@ -172,21 +187,6 @@ fun HomeScreen(
}
}
}
// ── 快捷入口 ──────────────────────────
item {
Text("快捷入口", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
}
item {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
QuickLinkCard(Icons.Default.Search, "搜索", Color(0xFF4CAF50), Modifier.weight(1f), onSearchClick)
QuickLinkCard(Icons.Default.Event, "日程", Color(0xFF9C27B0), Modifier.weight(1f), onScheduleClick)
}
}
}
}
}
@@ -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) {
@@ -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(
@@ -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<Item> = emptyList(),
val containers: List<Container> = 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<SearchCategory, String> {
val prefixes = mapOf(
"po:" to SearchCategory.ORDER,
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

+1 -1
View File
@@ -1,3 +1,3 @@
<resources>
<string name="app_name">ops_android</string>
<string name="app_name">Operations 2</string>
</resources>
+2 -2
View File
@@ -1,3 +1,3 @@
#Fri Jun 26 19:56:42 CST 2026
VERSION_CODE=117
#Fri Jun 26 20:46:06 CST 2026
VERSION_CODE=121
VERSION_NAME=1.2
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB