1.物品采集页面增加查看已采集物品信息,可以与搜索进行切换显示;2.收货已确认未确认显示优化;3.debug和release依赖切换使用问题解决;4其它优化;

This commit is contained in:
2025-11-03 17:45:24 +08:00
parent cb96a3db01
commit bd4e95158f
15 changed files with 188 additions and 40 deletions
+15 -4
View File
@@ -1,3 +1,5 @@
import com.android.tools.r8.internal.fA
plugins { plugins {
// alias(libs.plugins.android.application) // alias(libs.plugins.android.application)
// alias(libs.plugins.kotlin.android) // alias(libs.plugins.kotlin.android)
@@ -11,7 +13,6 @@ plugins {
kotlin("kapt") kotlin("kapt")
alias(libs.plugins.kotlin.compose) alias(libs.plugins.kotlin.compose)
} }
android { android {
signingConfigs { signingConfigs {
getByName("debug") { getByName("debug") {
@@ -42,7 +43,11 @@ android {
} }
buildTypes { buildTypes {
//debug {
// buildConfigField( "boolean", "DEBUG", "true")
//}
release { release {
//buildConfigField( "boolean", "DEBUG", "false")
isMinifyEnabled = false isMinifyEnabled = false
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
@@ -60,6 +65,7 @@ android {
buildFeatures { buildFeatures {
compose = true compose = true
viewBinding = true viewBinding = true
buildConfig = true
} }
// composeOptions { // composeOptions {
// kotlinCompilerExtensionVersion = "1.5.4" // kotlinCompilerExtensionVersion = "1.5.4"
@@ -70,7 +76,9 @@ android {
} }
} }
} }
val isDebug = gradle.startParameter.taskNames.any {
it.contains("debug", ignoreCase = true)
}
dependencies { dependencies {
implementation(libs.androidx.core.ktx) implementation(libs.androidx.core.ktx)
@@ -140,8 +148,11 @@ dependencies {
implementation("io.github.scwang90:refresh-layout-kernel:3.0.0-alpha") implementation("io.github.scwang90:refresh-layout-kernel:3.0.0-alpha")
implementation("io.github.scwang90:refresh-header-classics:3.0.0-alpha") implementation("io.github.scwang90:refresh-header-classics:3.0.0-alpha")
val objectboxVersion = "5.0.1" val objectboxVersion = "5.0.1"
debugImplementation("io.objectbox:objectbox-android-objectbrowser:$objectboxVersion") if (isDebug) {
// releaseImplementation("io.objectbox:objectbox-android:$objectboxVersion") debugImplementation("io.objectbox:objectbox-android-objectbrowser:$objectboxVersion")
} else {
releaseImplementation("io.objectbox:objectbox-android:$objectboxVersion")
}
} }
apply(plugin = "io.objectbox") apply(plugin = "io.objectbox")
@@ -22,6 +22,7 @@ import com.sw.inbound.model.response.SearchGoodsInfo
import com.sw.inbound.objbox.Food import com.sw.inbound.objbox.Food
import com.sw.inbound.objbox.FoodCollectionBean import com.sw.inbound.objbox.FoodCollectionBean
import com.sw.inbound.objbox.FoodModule import com.sw.inbound.objbox.FoodModule
import com.sw.inbound.objbox.Food_
import com.sw.inbound.objbox.ObjectBox import com.sw.inbound.objbox.ObjectBox
import com.sw.inbound.utils.BitmapCropper import com.sw.inbound.utils.BitmapCropper
import com.sw.inbound.utils.BitmapSaver import com.sw.inbound.utils.BitmapSaver
@@ -30,8 +31,10 @@ import com.sw.inbound.utils.ImageUtil
import com.sw.inbound.utils.ext.addOnActionSearchListener import com.sw.inbound.utils.ext.addOnActionSearchListener
import com.sw.inbound.utils.ext.clickWithDebounce import com.sw.inbound.utils.ext.clickWithDebounce
import com.sw.inbound.utils.ext.dp import com.sw.inbound.utils.ext.dp
import com.sw.inbound.utils.ext.gone
import com.sw.inbound.utils.ext.hideKeyboard import com.sw.inbound.utils.ext.hideKeyboard
import com.sw.inbound.utils.ext.toast import com.sw.inbound.utils.ext.toast
import com.sw.inbound.utils.ext.visible
import com.sw.inbound.viewmodel.ReceiptViewModel import com.sw.inbound.viewmodel.ReceiptViewModel
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import io.objectbox.Box import io.objectbox.Box
@@ -39,11 +42,11 @@ import io.objectbox.kotlin.boxFor
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import timber.log.Timber import timber.log.Timber
@SuppressLint("NotifyDataSetChanged")
@AndroidEntryPoint @AndroidEntryPoint
class FoodCollectionActivity : ComponentActivity() { class FoodCollectionActivity : ComponentActivity() {
private val TAG = "FoodCollectionActivity" private val TAG = "FoodCollectionActivity"
private var selectedFoodName: String = ""
private var box: Box<Food>? = null private var box: Box<Food>? = null
private val collectList: MutableList<FoodCollectionBean> = mutableListOf( private val collectList: MutableList<FoodCollectionBean> = mutableListOf(
@@ -97,11 +100,13 @@ class FoodCollectionActivity : ComponentActivity() {
cameraUtils.unbind() cameraUtils.unbind()
} }
@SuppressLint("NotifyDataSetChanged")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityFoodCollectionBinding.inflate(layoutInflater) binding = ActivityFoodCollectionBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
cameraUtils.initCamera() cameraUtils.initCamera()
binding.root.hideKeyboard()
val previewBinding = val previewBinding =
LayoutCameraPreviewBinding.inflate(layoutInflater, binding.flCameraPreview) LayoutCameraPreviewBinding.inflate(layoutInflater, binding.flCameraPreview)
previewView = previewBinding.previewView.also { previewView = previewBinding.previewView.also {
@@ -149,15 +154,13 @@ class FoodCollectionActivity : ComponentActivity() {
}.start() }.start()
} }
binding.btnRemoveDefault.clickWithDebounce { binding.btnRemoveDefault.clickWithDebounce {
if (box == null) { initBox()
box = ObjectBox.boxStore.boxFor(Food::class)
}
val list = box?.all?.filter { it.foodIdx == FoodModule.DEFAULT_FOOD_INDEX } val list = box?.all?.filter { it.foodIdx == FoodModule.DEFAULT_FOOD_INDEX }
if (list.isNullOrEmpty()) { if (list.isNullOrEmpty()) {
toast("不存在默认数据") toast("不存在默认数据")
return@clickWithDebounce return@clickWithDebounce
} }
box?.removeByIds(list!!.map { it.id }) box?.removeByIds(list.map { it.id })
toast("移除完成") toast("移除完成")
} }
binding.btnClearData.setOnClickListener { clearData() } binding.btnClearData.setOnClickListener { clearData() }
@@ -176,7 +179,45 @@ class FoodCollectionActivity : ComponentActivity() {
searchGoods() searchGoods()
} }
} }
loadEmptyView() binding.radioGroup.setOnCheckedChangeListener { group, checkedId ->
if (checkedId == R.id.rbCollected) {
binding.llSearchInput.gone()
binding.refreshLayout.let {
it.setEnableRefresh(false)
it.setEnableLoadMore(false)
}
getCollectedGoods()
return@setOnCheckedChangeListener
}
if (checkedId == R.id.rbSearch) {
binding.llSearchInput.visible()
pageNo = 1
clickIndex = -1
searchGoodsList.clear()
searchAdapter.notifyDataSetChanged()
binding.refreshLayout.let {
it.setEnableRefresh(true)
it.setEnableLoadMore(false)
}
loadEmptyView()
return@setOnCheckedChangeListener
}
}
binding.radioGroup.check(R.id.rbCollected)
}
@SuppressLint("NotifyDataSetChanged")
private fun getCollectedGoods() {
searchGoodsList.clear()
initBox()
box?.all?.distinctBy { it.name }?.forEach {
searchGoodsList.add((SearchGoodsInfo.Record(goodsName = it.name)))
}
binding.rvSearch.layoutManager = GridLayoutManager(this, 2, LinearLayoutManager.VERTICAL, false)
searchAdapter.notifyDataSetChanged()
if (searchGoodsList.isEmpty()) {
loadEmptyView()
}
} }
private var pageNo = 1 private var pageNo = 1
@@ -284,9 +325,7 @@ class FoodCollectionActivity : ComponentActivity() {
} }
private fun image2VectorTask(bitmap: Bitmap, position: Int) { private fun image2VectorTask(bitmap: Bitmap, position: Int) {
if (box == null) { initBox()
box = ObjectBox.boxStore.boxFor(Food::class)
}
val imageVector = FoodModule.bitmap2FloatArray(bitmap) val imageVector = FoodModule.bitmap2FloatArray(bitmap)
box?.put(Food(name = searchGoodsList[clickIndex].goodsName, foodIdx = 0, foodVector = imageVector)) box?.put(Food(name = searchGoodsList[clickIndex].goodsName, foodIdx = 0, foodVector = imageVector))
collectList[position].let { collectList[position].let {
@@ -361,4 +400,10 @@ class FoodCollectionActivity : ComponentActivity() {
} }
} }
private fun initBox() {
if (box == null) {
box = ObjectBox.boxStore.boxFor(Food::class)
}
}
} }
@@ -321,6 +321,9 @@ abstract class GoodsListActivity : ComponentActivity() {
goodsWeight = goods.goodsWeight goodsWeight = goods.goodsWeight
} }
binding.rvGoodsList.adapter?.notifyItemChanged(goodsList.indexOf(item)) binding.rvGoodsList.adapter?.notifyItemChanged(goodsList.indexOf(item))
if (this is ReceiptActivity) {
this.setConfirmNum()
}
} }
fun searchGoods( fun searchGoods(
@@ -55,12 +55,7 @@ class ReceiptActivity : GoodsListActivity() {
} }
goodsList.addAll(list) goodsList.addAll(list)
adapter.notifyDataSetChanged() adapter.notifyDataSetChanged()
val confirmOrderCount = list.count { it.isAdjusted } setConfirmNum()
binding.tvConfirmNum.text =
getSpannable("已确认 ", num = confirmOrderCount, color = "#FF009632")
val notConfirmOrderCount = goodsList.size - confirmOrderCount
binding.tvNotConfirmNum.text =
getSpannable("未确认 ", num = notConfirmOrderCount, color = "#FFFF0000")
} }
} }
} else { } else {
@@ -91,4 +86,13 @@ class ReceiptActivity : GoodsListActivity() {
} }
} }
fun setConfirmNum() {
val confirmOrderCount = goodsList.count { it.isAdjusted }
binding.tvConfirmNum.text =
getSpannable("已确认 ", num = confirmOrderCount, color = "#FF009632")
val notConfirmOrderCount = goodsList.size - confirmOrderCount
binding.tvNotConfirmNum.text =
getSpannable("未确认 ", num = notConfirmOrderCount, color = "#FFFF0000")
}
} }
@@ -18,6 +18,7 @@ class RequestInterceptor : Interceptor {
.header("Accept", "application/json") .header("Accept", "application/json")
.header("deviceId", GlobalData.deviceId) .header("deviceId", GlobalData.deviceId)
.header("X-DEVICE-CODE", GlobalData.deviceId) .header("X-DEVICE-CODE", GlobalData.deviceId)
// .header("X-DEVICE-CODE", "bcf396ed-78f6-3864-9837-7c37c5b2ec41")
.header("x-access-token", GlobalData.appToken) .header("x-access-token", GlobalData.appToken)
.header("authorization", "57ee87183f2a4fa59683ec9ef41c8f5d") .header("authorization", "57ee87183f2a4fa59683ec9ef41c8f5d")
// .header("Authorization", "Bearer ${getToken()}") // .header("Authorization", "Bearer ${getToken()}")
@@ -102,9 +102,10 @@ object FoodModule {
fun initDefFoodData(context: Context, action:()-> Unit={}) { fun initDefFoodData(context: Context, action:()-> Unit={}) {
//if (box.all.isNotEmpty()) { val count = box.all.count { it.foodIdx == DEFAULT_FOOD_INDEX }
// return if (count > 0) {
//} return
}
val embeddingsJson = AssetsTool.readAssetsFile(context, "data/embeddings.json") val embeddingsJson = AssetsTool.readAssetsFile(context, "data/embeddings.json")
val labelsJson = AssetsTool.readAssetsFile(context, "data/labels.json") val labelsJson = AssetsTool.readAssetsFile(context, "data/labels.json")
val classInfoJson = AssetsTool.readAssetsFile(context, "data/class_info.json") val classInfoJson = AssetsTool.readAssetsFile(context, "data/class_info.json")
@@ -20,7 +20,6 @@ import android.content.Context
import android.util.Log import android.util.Log
import io.objectbox.BoxStore import io.objectbox.BoxStore
import io.objectbox.BoxStoreBuilder import io.objectbox.BoxStoreBuilder
import io.objectbox.android.Admin
import io.objectbox.exception.DbException import io.objectbox.exception.DbException
import io.objectbox.exception.FileCorruptException import io.objectbox.exception.FileCorruptException
import io.objectbox.sync.Sync import io.objectbox.sync.Sync
@@ -73,13 +72,13 @@ object ObjectBox {
} }
} }
// if (BuildConfig.DEBUG) { if (com.sw.inbound.BuildConfig.DEBUG) {
var syncAvailable = if (Sync.isAvailable()) "available" else "unavailable" var syncAvailable = if (Sync.isAvailable()) "available" else "unavailable"
Log.d(TAG,"Using ObjectBox ${BoxStore.getVersion()} (${BoxStore.getVersionNative()}, sync $syncAvailable)") Log.d(TAG,"Using ObjectBox ${BoxStore.getVersion()} (${BoxStore.getVersionNative()}, sync $syncAvailable)")
// Enable ObjectBox Admin on debug builds. // Enable ObjectBox Admin on debug builds.
// https://docs.objectbox.io/data-browser // https://docs.objectbox.io/data-browser
Admin(boxStore).start(context.applicationContext) io.objectbox.android.Admin(boxStore).start(context.applicationContext)
// } }
} }
@@ -3,6 +3,8 @@ package com.sw.inbound.ui
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@@ -16,6 +18,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.paint import androidx.compose.ui.draw.paint
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.NavType import androidx.navigation.NavType
@@ -70,8 +73,8 @@ fun AppScreen(
Scaffold( Scaffold(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.paint(painter = painterResource(R.mipmap.bg)), //.paint(painter = painterResource(R.mipmap.bg)),
containerColor = Color.Transparent, ,containerColor = Color.Transparent,
content = { padding -> content = { padding ->
Box { Box {
// Image( // Image(
@@ -80,9 +83,13 @@ fun AppScreen(
// modifier = Modifier.fillMaxSize(), // modifier = Modifier.fillMaxSize(),
// contentScale = ContentScale.Crop // contentScale = ContentScale.Crop
// ) // )
Image(
painter = painterResource(id = R.mipmap.bg),
contentDescription = "背景图片",
modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.Crop
)
NavHost(padding, navController, onBackRequest) NavHost(padding, navController, onBackRequest)
} }
} }
) )
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#FF8B8B8B" android:state_checked="false"/>
<item android:color="#FF00BC71" android:state_checked="true"/>
</selector>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:drawable="@mipmap/ic_radio_normal"/>
<item android:state_checked="true" android:drawable="@mipmap/ic_radio_checked"/>
</selector>
@@ -54,23 +54,23 @@
android:id="@+id/btnAddDefault" android:id="@+id/btnAddDefault"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="60dp" android:layout_height="60dp"
android:gravity="center_vertical"
android:text="加载默认数据"
android:paddingHorizontal="10dp"
android:textColor="#FF0032C8"
android:background="@drawable/bg_white_stroke_blue_ripple" android:background="@drawable/bg_white_stroke_blue_ripple"
android:gravity="center_vertical"
android:paddingHorizontal="10dp"
android:text="加载默认数据"
android:textColor="#FF0032C8"
android:textSize="18sp" /> android:textSize="18sp" />
<TextView <TextView
android:id="@+id/btnRemoveDefault" android:id="@+id/btnRemoveDefault"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="60dp" android:layout_height="60dp"
android:gravity="center_vertical"
android:text="移除默认数据"
android:layout_marginStart="20dp" android:layout_marginStart="20dp"
android:layout_marginEnd="20dp" android:layout_marginEnd="20dp"
android:paddingHorizontal="10dp"
android:background="@drawable/bg_white_stroke_blue_ripple" android:background="@drawable/bg_white_stroke_blue_ripple"
android:gravity="center_vertical"
android:paddingHorizontal="10dp"
android:text="移除默认数据"
android:textColor="#FF0032C8" android:textColor="#FF0032C8"
android:textSize="18sp" /> android:textSize="18sp" />
</LinearLayout> </LinearLayout>
@@ -127,6 +127,70 @@
tools:itemCount="6" tools:itemCount="6"
tools:listitem="@layout/list_item_food_collection" /> tools:listitem="@layout/list_item_food_collection" />
<LinearLayout
android:id="@+id/layoutTab"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_marginHorizontal="20dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/rvFoodCollection"
app:layout_constraintTop_toTopOf="@id/flCameraPreview">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="物品筛选:"
android:textColor="#ff333333"
android:textSize="24sp"
android:textStyle="bold" />
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginHorizontal="20dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/rvFoodCollection"
app:layout_constraintTop_toTopOf="@id/flCameraPreview">
<RadioButton
android:id="@+id/rbCollected"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:button="@null"
android:drawableStart="@drawable/radio_check"
android:drawablePadding="20dp"
android:paddingStart="20dp"
android:paddingEnd="0dp"
android:text="已采集物品"
android:textColor="@color/radio_filter"
android:textSize="24sp" />
<RadioButton
android:id="@+id/rbSearch"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:button="@null"
android:drawableStart="@drawable/radio_check"
android:drawablePadding="20dp"
android:paddingStart="20dp"
android:paddingEnd="0dp"
android:text="搜索物品"
android:textColor="@color/radio_filter"
android:textSize="24sp" />
</RadioGroup>
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/llSearchInput" android:id="@+id/llSearchInput"
android:layout_width="0dp" android:layout_width="0dp"
@@ -137,7 +201,8 @@
android:orientation="horizontal" android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/rvFoodCollection" app:layout_constraintStart_toEndOf="@id/rvFoodCollection"
app:layout_constraintTop_toTopOf="@id/flCameraPreview"> app:layout_constraintTop_toBottomOf="@id/layoutTab"
android:visibility="gone">
<EditText <EditText
android:id="@+id/etGoodsInput" android:id="@+id/etGoodsInput"
@@ -183,7 +248,7 @@
android:overScrollMode="never" android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2" app:spanCount="2"
tools:itemCount="8" tools:itemCount="10"
tools:listitem="@layout/list_item_goods_search" /> tools:listitem="@layout/list_item_goods_search" />
<com.scwang.smart.refresh.footer.ClassicsFooter <com.scwang.smart.refresh.footer.ClassicsFooter
+2 -1
View File
@@ -147,7 +147,8 @@
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintEnd_toEndOf="@id/btnTakePhoto" app:layout_constraintEnd_toEndOf="@id/btnTakePhoto"
app:layout_constraintStart_toStartOf="@id/btnStartPreview" app:layout_constraintStart_toStartOf="@id/btnStartPreview"
app:layout_constraintTop_toBottomOf="@id/btnTakePhoto" /> app:layout_constraintTop_toBottomOf="@id/btnTakePhoto"
android:visibility="gone"/>
<LinearLayout <LinearLayout
android:id="@+id/llGoodsInfo" android:id="@+id/llGoodsInfo"
@@ -28,5 +28,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="请检查物品名称,或点击“添加物品”按钮新增物品信息" android:text="请检查物品名称,或点击“添加物品”按钮新增物品信息"
android:textColor="#ff999999" android:textColor="#ff999999"
android:gravity="center"
android:textSize="30sp" /> android:textSize="30sp" />
</LinearLayout> </LinearLayout>
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB