This commit is contained in:
2026-02-10 19:02:21 +08:00
parent 3d29e17225
commit 655e9cd56e
12 changed files with 333 additions and 46 deletions
@@ -45,6 +45,7 @@ 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.invisible import com.sw.inbound.utils.ext.invisible
import com.sw.inbound.utils.ext.startActivity import com.sw.inbound.utils.ext.startActivity
import com.sw.inbound.utils.ext.toJsonString
import com.sw.inbound.utils.ext.toObject import com.sw.inbound.utils.ext.toObject
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.utils.ext.visible
@@ -86,6 +87,13 @@ class FoodCollectionActivity : ComponentActivity() {
} }
private val collectionAdapter: FoodCollectionAdapter by lazy { private val collectionAdapter: FoodCollectionAdapter by lazy {
FoodCollectionAdapter(collectList).apply { FoodCollectionAdapter(collectList).apply {
setOnItemClickListener { adapter, view, position ->
val file = collectList[position].imageFile ?: return@setOnItemClickListener
ImageUtil.decodeFromFile(file)?.let { bitmap ->
val imageVector = FoodModule.bitmap2FloatArray(bitmap, false)
Timber.tag(TAG).d("向量:${imageVector.toJsonString()}")
}
}
addOnItemChildClickListener(R.id.ivDelete) { _, _, position -> addOnItemChildClickListener(R.id.ivDelete) { _, _, position ->
collectList[position].let { collectList[position].let {
it.imageFile = null it.imageFile = null
@@ -177,7 +185,7 @@ class FoodCollectionActivity : ComponentActivity() {
upload() upload()
} }
binding.btnTakePhoto.clickWithDebounce { binding.btnTakePhoto.clickWithDebounce(800) {
takePhoto() takePhoto()
} }
binding.btnCollectedGoods.setOnClickListener { binding.btnCollectedGoods.setOnClickListener {
@@ -319,6 +327,7 @@ class FoodCollectionActivity : ComponentActivity() {
toast("操作失败") toast("操作失败")
return@let return@let
} }
Timber.tag(TAG).d("向量:${imageVector.toJsonString()}")
val foodList = try { val foodList = try {
FoodModule.queryFoodNameScore(imageVector) FoodModule.queryFoodNameScore(imageVector)
} catch (e: DbException) { } catch (e: DbException) {
@@ -37,7 +37,11 @@ import com.sw.inbound.model.request.UploadInfo
import com.sw.inbound.model.response.DictType import com.sw.inbound.model.response.DictType
import com.sw.inbound.model.response.GoodsInfo import com.sw.inbound.model.response.GoodsInfo
import com.sw.inbound.model.response.SearchGoodsInfo import com.sw.inbound.model.response.SearchGoodsInfo
import com.sw.inbound.objbox.Food
import com.sw.inbound.objbox.FoodModule import com.sw.inbound.objbox.FoodModule
import com.sw.inbound.objbox.FoodModule.IdNameScore
import com.sw.inbound.objbox.Food_
import com.sw.inbound.objbox.ObjectBox
import com.sw.inbound.sdk.SensorScaleUtils import com.sw.inbound.sdk.SensorScaleUtils
import com.sw.inbound.utils.BitmapCropper import com.sw.inbound.utils.BitmapCropper
import com.sw.inbound.utils.CameraUtils import com.sw.inbound.utils.CameraUtils
@@ -53,6 +57,7 @@ import com.sw.inbound.utils.ext.toast
import com.sw.inbound.viewmodel.ReceiptViewModel import com.sw.inbound.viewmodel.ReceiptViewModel
import com.sw.inbound.viewmodel.UserViewModel import com.sw.inbound.viewmodel.UserViewModel
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import io.objectbox.query.Query
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import okhttp3.RequestBody import okhttp3.RequestBody
@@ -179,6 +184,42 @@ abstract class GoodsListActivity : ComponentActivity() {
//Timber.tag(TAG).d("测试:${array[2].toInt()}") //Timber.tag(TAG).d("测试:${array[2].toInt()}")
userViewModel.getInitInfo() userViewModel.getInitInfo()
// lifecycleScope.launch {
// ObjectBox.put(
// Food(
// name = "测试",
// foodIdx = -100,
// foodVector = floatArrayOf(
// 0.015068196f,0.0f,0.0f,0.0f,0.0037743463f,0.0f,0.0f,0.07893528f,0.0f,0.0f,0.0f,0.0f,0.052832354f,0.0f,0.045785826f,0.0f,6.156802E-4f,0.04242764f,0.0f,0.0f,0.0f,0.0f,0.11469748f,0.13930011f,0.005731758f,0.03159248f,0.018799406f,0.028927676f,0.03472497f,0.01896616f,0.078822434f,0.0f,0.015187703f,0.0f,0.033177234f,0.07078301f,0.0f,0.0f,0.012238876f,0.0f,0.0f,0.0f,0.0f,0.0f,0.10691055f,0.008628067f,0.0f,0.0f,0.0f,0.0f,0.0f,0.06886323f,0.0f,0.0f,0.10460233f,0.0f,0.0f,0.0f,0.0f,0.0f,0.012850592f,0.0f,0.0f,0.103946045f,0.0f,0.018065454f,0.046292588f,0.063853905f,0.0f,0.10074362f,0.110680245f,0.10660499f,0.0f,0.06775707f,0.0f,0.0f,0.0f,0.0f,0.01639176f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.024850294f,0.0f,0.05308442f,0.0f,0.0f,0.0f,0.028708044f,0.02787582f,0.0f,0.0f,0.0f,0.0f,0.0f,0.027483912f,0.11719905f,0.04781422f,0.09033941f,0.09655397f,0.0032244714f,0.0f,0.0f,0.09580024f,0.07075415f,0.0876085f,0.0f,0.08756652f,2.2919098E-4f,0.019845076f,0.0f,0.0f,0.0f,0.04727701f,0.007276267f,0.0f,0.12660357f,0.03222255f,0.00182945f,0.0f,0.0f,0.0f,0.0f,0.0f,0.09080463f,0.0043369643f,0.0f,0.0f,0.0f,0.0f,0.0f,0.073994264f,0.0f,0.030294247f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.04890032f,0.0f,0.05318369f,0.0f,0.0f,0.0510094f,0.0f,0.0f,0.0f,0.12696978f,0.0f,0.21870367f,0.0f,0.0f,0.0f,0.0f,0.022256335f,0.13343737f,0.0f,0.0f,0.0f,0.0f,0.025192281f,0.1621841f,0.031685397f,0.0f,0.0f,0.03057069f,0.011333849f,0.0f,0.0f,0.11482361f,0.10645431f,0.0f,0.0f,0.0f,0.039949007f,0.0f,0.018850718f,0.0f,0.0f,0.0f,0.026081126f,0.0f,0.07934742f,0.0f,0.0f,0.0f,0.0f,0.0f,0.007998445f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.098366655f,0.0f,0.01606297f,0.16557153f,0.0f,0.0f,0.0f,0.0f,0.042638786f,0.024310581f,0.0f,0.027677892f,5.940642E-4f,0.0f,0.0f,0.0f,0.0f,0.05605889f,0.0f,0.0f,0.05216231f,0.080610394f,0.0f,0.0f,0.0f,0.0f,0.0f,0.07294793f,0.0f,0.02029506f,0.0f,0.0f,0.0f,0.12797904f,0.16668096f,0.083295606f,0.07768397f,0.07725612f,0.0f,0.0f,0.07259326f,0.110221304f,0.0f,0.0f,0.0f,0.0f,0.0f,0.027140126f,0.0f,0.053474665f,0.0f,0.018286237f,0.0f,0.0f,0.12152021f,0.0f,0.0f,0.0822232f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.04146023f,0.0f,0.034810524f,0.0f,0.00393797f,0.0f,0.032150663f,0.0f,0.0f,0.0f,0.0f,0.097777024f,0.0f,0.0f,0.0f,0.078797914f,0.0f,0.1292709f,0.0f,0.010623558f,0.0f,0.08360209f,0.0f,0.0f,0.122683614f,0.0f,0.0f,0.0f,0.0f,0.10111214f,0.10537941f,0.0f,0.0f,0.0f,0.0f,0.06272928f,0.0f,0.029668529f,0.049171254f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.032665383f,0.0f,0.0f,0.044802308f,0.0f,0.0f,0.05388319f,0.0f,0.0f,0.079517856f,0.012373011f,0.0f,0.01629987f,0.014890053f,0.0f,0.027798127f,0.0f,0.051028676f,0.15331483f,0.024111472f,0.0f,0.0f,0.0f,0.0f,0.0f,0.013699274f,0.0f,0.0f,0.07011116f,0.03022409f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.10939847f,0.0f,0.0f,0.0f,0.030306451f,0.0f,0.0f,0.12335773f,0.0f,0.0f,0.09099765f,0.0f,0.0f,0.0073862355f,0.0f,0.027847463f,0.0840776f,0.04207977f,0.046206567f,0.06679146f,0.0f,0.0f,0.01625976f,0.022998374f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.059722353f,0.0f,0.012246756f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.04984296f,0.0f,0.1435546f,0.0f,0.14667304f,0.079418436f,0.1305641f,0.014777453f,0.0f,0.020115053f,0.05619832f,0.011520876f,0.0f,0.11993748f,0.009492612f,0.019984039f,0.0f,0.0f,0.0f,0.0f,0.043548502f,0.0f,0.0f,0.0f,0.0f,0.15310751f,0.0f,0.0f,0.0f,0.0f,0.0f,0.018038996f,0.0021733972f,0.0f,0.0f,0.0f,0.0f,0.060995787f,0.06326715f,0.0f,0.06896745f,0.013745607f,5.018817E-4f,0.0f,0.0f,0.14184067f,0.019447664f,0.047488734f,0.13301876f,0.0f,0.0f,0.06715185f,0.0f,0.0f,0.0025059544f,0.0013816518f,0.0f,0.00415278f,0.17231767f,0.0073697185f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0017814273f,0.040113796f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.016738398f,0.0f,0.10465313f,0.0f,0.057283692f,0.0f,0.05406501f,0.0f,0.012632326f,0.0f,0.0f,0.0f,0.10440692f,0.0f,0.0047152108f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.11544036f
// )
// )
// )
// ObjectBox.remove("测试")
// ObjectBox.safeDbOp {
// val vector2 = floatArrayOf(
// 0.029274145f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.04849013f,0.0f,0.0f,0.0030461443f,0.0f,0.04333778f,0.0f,0.036458552f,0.0f,0.0f,0.032146808f,0.0f,0.0f,0.0f,0.0f,0.12563168f,0.16337962f,0.0086008925f,0.028651662f,0.05676712f,0.038951095f,0.035215054f,0.023515426f,0.09426005f,0.0f,0.0f,0.0f,0.019520408f,0.09774056f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.12273409f,0.03317896f,0.0f,0.0f,0.0f,0.0f,0.0f,0.056036845f,0.0f,0.005601604f,0.09232295f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.10639726f,0.017117623f,0.0f,0.04106111f,0.06582154f,0.0f,0.10570599f,0.10395363f,0.11154216f,0.0f,0.09019618f,0.0f,0.0f,0.0f,0.0f,0.008780864f,0.0f,0.0f,0.01997713f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.016066022f,0.020096382f,0.0f,0.05578338f,0.0f,0.0f,0.0f,0.048834037f,0.031760734f,0.0f,0.0f,0.0f,0.0f,0.0f,0.02459963f,0.11993096f,0.047805987f,0.070974134f,0.10536186f,0.0f,0.0f,0.0f,0.111894555f,0.08973926f,0.071053386f,0.0f,0.071883f,0.005135076f,0.0f,0.0f,0.0f,0.0f,0.023139987f,0.027882056f,0.0f,0.12620124f,0.05076331f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.06944067f,0.0146693f,0.0f,0.0f,0.0f,0.0f,0.00978479f,0.04965295f,0.0f,0.03953311f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.05496083f,0.0f,0.05957852f,0.0f,0.0f,0.05285405f,0.0f,0.0f,0.0f,0.10977843f,0.0f,0.21329264f,0.0f,0.0f,0.0f,0.0f,0.022029493f,0.12511873f,0.0f,0.0f,0.0f,0.0f,0.015391711f,0.1697028f,0.035269253f,0.0f,0.0f,0.0070471396f,0.0f,0.0f,0.0f,0.123943165f,0.10272677f,0.0f,0.0f,0.0f,0.06351426f,0.0f,0.009808158f,0.0f,0.0f,0.0f,0.02582221f,0.0f,0.0745801f,0.0f,0.0f,0.023285847f,0.0f,0.0f,0.017162288f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.09181752f,0.0f,0.007880242f,0.15574618f,0.0f,0.0f,0.0f,0.0f,0.02478441f,0.039601766f,0.0f,0.049401764f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0793202f,0.0f,0.0f,0.071133174f,0.09675928f,0.0f,0.015621623f,0.0f,0.0f,0.0f,0.08347399f,0.009147923f,0.0f,0.0f,0.0f,0.0f,0.14187747f,0.15219086f,0.12055488f,0.07175866f,0.07192898f,0.0f,0.0f,0.04634941f,0.12534219f,0.0f,0.0f,0.0f,0.008665879f,0.0f,0.040081337f,0.0f,0.06729515f,0.0f,0.058273762f,0.0020215393f,0.0f,0.10878004f,0.0f,0.0f,0.09762441f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.03849448f,0.0f,0.03300536f,0.0f,0.0f,0.013231625f,0.018584426f,0.0f,0.0f,0.0f,0.0f,0.08124468f,0.0f,0.0f,0.0f,0.060708806f,0.0f,0.11115098f,0.0f,0.0f,0.0f,0.0803424f,0.0f,0.0f,0.115781434f,0.0f,0.00764197f,0.0f,0.0f,0.121340856f,0.0869794f,0.0f,0.0f,0.0f,0.0f,0.045324527f,0.0f,0.015057986f,0.048937548f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.030864827f,0.0f,0.0029875587f,0.03196471f,0.0f,0.0f,0.054534424f,0.0f,0.0f,0.07863297f,0.019617077f,0.0f,0.026181744f,0.0f,0.0f,0.021914937f,0.0f,0.063720085f,0.16607703f,0.006567324f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0017898319f,0.0f,0.0f,0.04841979f,0.0044351136f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.15329078f,0.0f,0.0f,0.0f,0.030429695f,0.0f,0.0f,0.11840538f,0.0f,0.0f,0.107368395f,0.014730752f,0.0f,0.0f,0.0f,0.030180579f,0.039591953f,0.03209204f,0.048180148f,0.0676186f,0.0f,0.0f,0.03614289f,0.030257396f,1.5626202E-4f,0.018185573f,0.0f,0.0f,0.0f,0.0f,0.055325508f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.051894154f,0.0f,0.12869093f,0.0f,0.122797504f,0.083724305f,0.12840301f,0.0f,0.0f,0.0f,0.05686797f,0.0f,0.0f,0.11015593f,0.018203156f,0.020094728f,0.0f,0.0f,0.0f,0.0f,0.058597155f,0.0f,0.0f,0.0f,0.0f,0.12797132f,0.0f,0.006606713f,0.0f,0.0f,0.0f,0.028628595f,0.0f,0.0f,0.0f,0.0f,0.0f,0.050383586f,0.07132696f,0.0f,0.092209496f,0.0f,0.0f,0.0f,0.0f,0.14604862f,0.01660271f,0.057229653f,0.13104743f,0.0f,0.0f,0.06136706f,0.0f,0.0f,0.0f,0.0011910667f,0.0f,0.0f,0.15921566f,0.0f,0.0f,0.0f,0.0f,0.007558685f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.007532647f,0.05110198f,0.00667856f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0016389234f,0.0f,0.0f,0.0f,0.0f,0.018518167f,0.0f,0.08580791f,0.0f,0.06099585f,0.0f,0.0366169f,0.0f,0.0f,0.0f,0.0f,0.0f,0.073218584f,0.0f,0.0f,0.0f,0.008933658f,0.0f,0.0f,0.0f,0.0f,0.0f,0.116691895f
// )
// ObjectBox.getBox<Food>()?.let {
// val query: Query<Food>? = it.query(
// Food_.foodVector
// .nearestNeighbors(vector2, 5)
// )?.build()
// try {
// val list = query?.findIdsWithScores()
// val resultList = mutableListOf<String>()
// list?.forEach { idWithScore ->
// val food = it.get(idWithScore.id)
// resultList.add("${food.name}|${food.id}|${idWithScore.score}")
// }
// Timber.tag(TAG).d("比较结果:${resultList.joinToString(separator = ",")}")
// } finally {
// // 先关闭Query,释放Cursor
// query?.close()
// }
// }
// }
// }
} }
private var weightCallback: ((weight: Int) -> Unit)? = null private var weightCallback: ((weight: Int) -> Unit)? = null
@@ -336,10 +377,23 @@ abstract class GoodsListActivity : ComponentActivity() {
if (newBmp.isRecycled.not()) { if (newBmp.isRecycled.not()) {
newBmp.recycle() newBmp.recycle()
} }
if (foodList.isEmpty()) { val count = foodList.count { it.score < 0.15 }
recognizeFoodError() if (count == 0) {
//未识别到满足相似度>=0.85的,显示识别率最高的
var tempList = foodList.filter { it.name.contains("黑袋子").not() }
if (tempList.isEmpty()) {
recognizeFoodError()
return@let
}
tempList = tempList.subList(0, 1)
tempList.forEach { it.name = it.name.split("WP")[0] }
recognizeGoodsList(tempList)
return@let return@let
} }
//if (foodList.isEmpty()) {
// recognizeFoodError()
// return@let
//}
foodList.forEach { foodList.forEach {
it.name = it.name.split("WP")[0] it.name = it.name.split("WP")[0]
} }
@@ -358,23 +412,27 @@ abstract class GoodsListActivity : ComponentActivity() {
} }
return@let return@let
} }
receiptViewModel.recognizeGoodsList( recognizeGoodsList(foodList)
//nameList = foodList, }
scoreList = foodList, }
) { goodsList ->
runOnUiThread { private fun recognizeGoodsList(foodList: List<IdNameScore>) {
if (isAgainRecognize) { receiptViewModel.recognizeGoodsList(
Loading.dismiss() //nameList = foodList,
recognizeCallback?.invoke(goodsList) scoreList = foodList,
isAgainRecognize = false ) { goodsList ->
return@runOnUiThread runOnUiThread {
} if (isAgainRecognize) {
handleGoodsResult( Loading.dismiss()
goodsList = if (goodsList.size == foodList.size) goodsList else mutableListOf(), recognizeCallback?.invoke(goodsList)
isAgainRecognize = false
return@runOnUiThread
}
handleGoodsResult(
goodsList = if (goodsList.size == foodList.size) goodsList else mutableListOf(),
// file = null, // file = null,
// name = foodList.joinToString(",") // name = foodList.joinToString(",")
) )
}
} }
} }
} }
@@ -4,6 +4,7 @@ import android.content.Context
import android.net.Uri import android.net.Uri
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.EditText
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
@@ -120,7 +121,28 @@ class AddGoodsDialog(
arrowImage = binding.ivProcurementArrow, arrowImage = binding.ivProcurementArrow,
list = GlobalData.unitTypeList, list = GlobalData.unitTypeList,
height = 2 * 71.dp height = 2 * 71.dp
) ) {
val warehouseUnit = binding.tvWarehouseUnit.text.toString().trim()
if (warehouseUnit.isBlank()) return@showDropDownList
when (it.value) {
"千克", "公斤" -> {
setGoodsCount(warehouseUnit, "1", "2", "1000")
}
"" -> {
setGoodsCount(warehouseUnit, "0.5", "1", "500")
}
"" -> {
setGoodsCount(warehouseUnit, "0.001", "0.002", "1")
}
else -> {
val procurementUnit = binding.tvProcurementUnit.text.toString().trim()
val warehouseUnit = binding.tvWarehouseUnit.text.toString().trim()
binding.etGoodsCount.setText(
if (procurementUnit == warehouseUnit) "1" else ""
)
}
}
}
// showDropDownList( // showDropDownList(
// binding.flGoodsType, // binding.flGoodsType,
// textView = binding.tvGoodsType, // textView = binding.tvGoodsType,
@@ -141,6 +163,51 @@ class AddGoodsDialog(
) { ) {
binding.tvSelectUseUnit.text = it.value binding.tvSelectUseUnit.text = it.value
binding.tvSelectProcurementUnit.text = it.value binding.tvSelectProcurementUnit.text = it.value
val procurementUnit = binding.tvProcurementUnit.text.toString().trim()
when (it.value) {
"千克", "公斤" -> {
binding.etUseUnit.setText("1000")
setGoodsCount(procurementUnit, "1", "0.5", "0.001")
}
"" -> {
binding.etUseUnit.setText("500")
setGoodsCount(procurementUnit, "2", "1", "0.002")
}
"" -> {
binding.etUseUnit.setText("1")
setGoodsCount(procurementUnit, "1000", "500", "1")
}
else -> {
binding.etUseUnit.setText("")
val procurementUnit = binding.tvProcurementUnit.text.toString().trim()
val warehouseUnit = binding.tvWarehouseUnit.text.toString().trim()
binding.etGoodsCount.setText(
if (procurementUnit == warehouseUnit) "1" else ""
)
}
}
}
}
private fun setGoodsCount(unit:String, kgCount:String, jinCount:String, gCount:String) {
when (unit) {
"千克", "公斤" -> {
binding.etGoodsCount.setText(kgCount)
}
"" -> {
binding.etGoodsCount.setText(jinCount)
}
"" -> {
binding.etGoodsCount.setText(gCount)
}
else -> {
val procurementUnit = binding.tvProcurementUnit.text.toString().trim()
val warehouseUnit = binding.tvWarehouseUnit.text.toString().trim()
binding.etGoodsCount.setText(
if (procurementUnit == warehouseUnit) "1" else ""
)
}
} }
} }
@@ -227,7 +294,7 @@ class AddGoodsDialog(
return return
} }
val goodsCount = binding.etGoodsCount.text.trim().toString() val goodsCount = binding.etGoodsCount.text.trim().toString()
if (costValue.isBlank()) { if (goodsCount.isBlank()) {
context.toast("请输入采购数量") context.toast("请输入采购数量")
return return
} }
@@ -7,6 +7,7 @@ import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import com.sw.inbound.GlobalData
import com.sw.inbound.R import com.sw.inbound.R
import com.sw.inbound.activity.FoodCollectionActivity import com.sw.inbound.activity.FoodCollectionActivity
import com.sw.inbound.activity.GoodsListActivity import com.sw.inbound.activity.GoodsListActivity
@@ -17,7 +18,7 @@ abstract class BaseDialog(
context: Context, context: Context,
var defWidth: Int = 1500.dp, var defWidth: Int = 1500.dp,
// var defHeight: Int = 900.dp // var defHeight: Int = 900.dp
var defHeight: Int = 750.dp var defHeight: Int = if ("f0bcabbb-0d58-3b14-8bed-9863b7ec61ef" == GlobalData.deviceId) 750.dp else 900.dp
) : Dialog(context, R.style.DialogTheme) { ) : Dialog(context, R.style.DialogTheme) {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@@ -17,8 +17,8 @@ class RequestInterceptor : Interceptor {
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.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-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()}")
@@ -137,12 +137,14 @@ object FoodModule {
} }
suspend fun getFoodScoreList(bitmap: Bitmap, queryCount: Int = 15): List<IdNameScore> { suspend fun getFoodScoreList(bitmap: Bitmap, queryCount: Int = 15): List<IdNameScore> {
val floatArray = bitmap2FloatArray(bitmap, false) ?: return emptyList() val floatArray = bitmap2FloatArray(bitmap, false) ?: return emptyList()
Timber.tag("FoodModule").d("向量:${floatArray.toJsonString()}")
val nameScoreList = queryFoodNameScore(floatArray, queryCount) val nameScoreList = queryFoodNameScore(floatArray, queryCount)
if (nameScoreList.isEmpty()) { if (nameScoreList.isEmpty()) {
return emptyList() return emptyList()
} }
//暂时不过滤
val maxScoreList = nameScoreList val maxScoreList = nameScoreList
.filter { it.score < 0.15 } //.filter { it.score < 0.15 }
.groupBy { it.name } .groupBy { it.name }
.map { (_, value) -> value.minByOrNull { it.score }!! } .map { (_, value) -> value.minByOrNull { it.score }!! }
.toMutableList() .toMutableList()
@@ -177,11 +177,12 @@ object ObjectBox {
} }
suspend fun filter(name:String?) = safeDbOp { suspend fun filter(name:String?) = safeDbOp {
var list = getBox<Food>()?.all?.distinctBy { it.name } val list = getBox<Food>()?.all?.distinctBy { it.name }
if (name.isNullOrBlank().not()) { if (name.isNullOrBlank().not()) {
list?.filter { it.name?.contains(name!!) == true } list?.filter { it.name?.contains(name) == true }
} } else {
list?:emptyList() list
}?:emptyList()
} }
suspend fun remove(name:String) = safeDbOp { suspend fun remove(name:String) = safeDbOp {
@@ -4,6 +4,7 @@ import android.content.Context
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.net.Uri import android.net.Uri
import java.io.File
object ImageUtil { object ImageUtil {
fun uriToBitmap(context: Context, uri: Uri): Bitmap? { fun uriToBitmap(context: Context, uri: Uri): Bitmap? {
@@ -23,4 +24,13 @@ object ImageUtil {
} }
} }
// 直接解码文件路径
fun decodeFromFile(file: File): Bitmap? {
return if (file.exists()) {
BitmapFactory.decodeFile(file.absolutePath)
} else {
null
}
}
} }
@@ -154,13 +154,36 @@ fun EditText.addOnActionSearchListener(searchCallback: () -> Unit) {
} }
//fun View.clickWithDebounce(delay: Long = 300, action: () -> Unit) {
// var job: Job? = null
// setOnClickListener {
// job?.cancel()
// job = CoroutineScope(Dispatchers.Main).launch {
// delay(delay)
// action()
// }
// }
//}
/**
* 极简版防重复点击扩展函数
* @param delay 防抖时间(默认300ms
* @param action 点击执行逻辑
*/
fun View.clickWithDebounce(delay: Long = 300, action: () -> Unit) { fun View.clickWithDebounce(delay: Long = 300, action: () -> Unit) {
var job: Job? = null var job: Job? = null
setOnClickListener { setOnClickListener {
job?.cancel() job?.cancel()
job = CoroutineScope(Dispatchers.Main).launch { // 用View的tag存储是否可点击的状态(默认可点击)
delay(delay) if (tag as? Boolean ?: true) {
action() tag = false // 标记为不可点击
action() // 立即执行点击逻辑
// 启动协程,延迟后恢复可点击状态
CoroutineScope(Dispatchers.Main).launch {
delay(delay)
tag = true // 恢复可点击
}
} }
} }
} }
+39 -13
View File
@@ -160,7 +160,10 @@
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/flImageCollect"> app:layout_constraintStart_toEndOf="@id/flImageCollect">
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="2"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
@@ -183,10 +186,13 @@
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout> </LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1.0"/>
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -239,10 +245,13 @@
</FrameLayout> </FrameLayout>
</LinearLayout> </LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1.1"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_marginTop="25dp">
<TextView <TextView
android:layout_width="432dp" android:layout_width="432dp"
@@ -262,10 +271,13 @@
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout> </LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1.0"/>
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -333,10 +345,13 @@
</FrameLayout> </FrameLayout>
</LinearLayout> </LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1.1"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_marginTop="25dp">
<TextView <TextView
android:layout_width="432dp" android:layout_width="432dp"
@@ -356,10 +371,13 @@
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout> </LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1.0"/>
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -448,20 +466,25 @@
tools:text="瓶" /> tools:text="瓶" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1.0"/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:text="采购单位" android:text="采购单位"
android:textColor="#ff141428" android:textColor="#ff141428"
android:textSize="24sp" android:textSize="24sp"
android:textStyle="bold" /> android:textStyle="bold" />
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1.0"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="92dp" android:layout_height="92dp"
android:layout_marginTop="20dp"
android:background="@drawable/bg_white_radius10_stroke2_dash" android:background="@drawable/bg_white_radius10_stroke2_dash"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -521,7 +544,7 @@
android:background="@drawable/bg_white_radius10_stroke2" android:background="@drawable/bg_white_radius10_stroke2"
android:gravity="center" android:gravity="center"
android:hint="请录入" android:hint="请录入"
android:inputType="number" android:inputType="numberDecimal"
android:maxLines="1" android:maxLines="1"
android:paddingStart="25dp" android:paddingStart="25dp"
android:paddingEnd="25dp" android:paddingEnd="25dp"
@@ -578,7 +601,10 @@
android:textStyle="bold" android:textStyle="bold"
android:text="元" /> android:text="元" />
</LinearLayout> </LinearLayout>
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="2"/>
</LinearLayout> </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
@@ -9,7 +9,7 @@ import org.junit.Test
*/ */
class ExampleUnitTest { class ExampleUnitTest {
@Test // @Test
fun addition_isCorrect() { fun addition_isCorrect() {
// println(4, 2 + 2) // println(4, 2 + 2)
val decimalPlaces = 2 val decimalPlaces = 2
@@ -29,7 +29,7 @@ class ExampleUnitTest {
println("$tag, result = $msg") println("$tag, result = $msg")
} }
@Test // @Test
fun testFloat() { fun testFloat() {
log("0.00", "0.00".isValidFloat()) log("0.00", "0.00".isValidFloat())
log("0.01", "0.01".isValidFloat()) log("0.01", "0.01".isValidFloat())
@@ -67,4 +67,29 @@ class ExampleUnitTest {
return matches(decimalRegex) return matches(decimalRegex)
} }
@Test
fun vectorSimilarity() {
// val vector = floatArrayOf(
// 0.044965353f,0.0f,0.0f,0.0f,0.0f,8.377289E-4f,0.0f,0.08697582f,0.0f,0.0f,0.0f,0.0f,0.056673132f,0.0048905406f,0.057954628f,0.0f,0.017238954f,0.03816336f,0.0f,0.0f,4.9872044E-5f,0.0f,0.103112906f,0.12678225f,0.028405422f,0.039923374f,0.0045142793f,0.030780189f,0.0f,0.050326712f,0.03636783f,0.0f,0.020746801f,0.0f,0.02912772f,0.07644723f,0.0f,0.0f,0.012707499f,0.0f,0.0f,0.0f,0.0f,0.0f,0.05465086f,0.019942753f,0.0f,0.0f,0.0f,0.0f,0.0f,0.09032286f,0.0f,0.025173543f,0.09341076f,0.002681128f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.032784935f,0.09999022f,0.0f,0.056982663f,0.036085635f,0.076223254f,0.0f,0.078823626f,0.09971455f,0.101214215f,0.0f,0.062269375f,0.0f,0.0f,0.0f,0.0f,0.043811474f,0.016228097f,0.0f,0.005065734f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.02193476f,0.0f,0.05240194f,0.0f,0.0f,0.0f,0.0f,0.013821804f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.13496852f,0.046263166f,0.084122986f,0.09910474f,0.026525209f,0.0f,0.0f,0.100664f,0.052160427f,0.074085265f,0.0124217225f,0.062484015f,0.0f,0.03609839f,0.0f,0.0f,0.0f,0.043177273f,0.0f,0.0f,0.11422996f,0.033960324f,0.014480866f,0.0f,0.0f,0.0f,0.0f,0.0f,0.09051817f,0.012583549f,0.0f,0.013904583f,0.0f,0.0f,0.0f,0.09033129f,0.0f,0.0f,0.00943393f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.021974336f,0.0f,0.07020068f,0.0f,0.0f,0.028822942f,0.0f,0.0f,0.0f,0.100173116f,0.0f,0.20344076f,0.0f,0.0f,0.0f,0.0f,0.014526786f,0.16405603f,0.0f,0.0f,0.0f,0.0f,0.010118703f,0.20771901f,0.021986803f,0.017206948f,0.0f,0.035743967f,0.0233565f,0.0f,0.0f,0.08678867f,0.1028636f,0.0f,0.0f,0.0f,0.013465163f,0.0f,0.01907301f,0.02529738f,0.0f,0.0f,0.0035515137f,0.0f,0.071397446f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0051259883f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.121495984f,0.0f,0.023764635f,0.16825739f,0.0f,0.0f,0.0f,0.0f,0.046005785f,0.03436156f,0.0f,0.021297242f,0.014054135f,0.0f,0.0f,0.0f,0.0f,0.047426794f,0.0f,0.0f,0.053715404f,0.08112736f,0.0f,0.0f,0.0f,0.0f,0.0f,0.044106703f,0.0f,0.04367752f,0.0f,0.0f,0.0f,0.15173462f,0.16032499f,0.06236599f,0.08927157f,0.054597132f,0.0f,0.0f,0.109912835f,0.11166212f,0.0f,0.0f,0.0f,0.0f,0.0f,0.013451309f,0.0f,0.04017654f,0.0f,0.006972992f,0.011281665f,0.0f,0.1272958f,0.0f,0.0f,0.07654262f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.022481557f,0.0f,0.041888714f,0.0f,0.008270643f,0.0055315774f,0.037642997f,0.0f,0.011266245f,0.0f,0.0f,0.11921886f,0.0f,0.0f,0.0f,0.09897007f,0.0f,0.11849627f,0.0f,0.003410538f,0.0f,0.09413481f,0.0f,0.0f,0.15098546f,0.0f,0.0f,0.0f,0.021952175f,0.11610187f,0.10997474f,0.0f,0.0f,0.0f,0.0f,0.0730338f,0.0f,0.008537221f,0.08227911f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.010958639f,0.0f,0.009177053f,0.03729424f,0.0f,0.0024872338f,0.054441202f,0.0f,0.0f,0.08428903f,0.0f,0.0f,0.022766057f,0.0021686116f,0.0f,0.001098188f,0.014538243f,0.05301009f,0.12891653f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.060878154f,0.018891823f,0.0f,0.10552897f,0.06017957f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.112172805f,0.0f,0.0f,0.0f,0.05110971f,0.0f,0.0f,0.08507675f,0.0f,0.0f,0.06618395f,0.011874482f,0.0f,0.008187234f,0.0f,0.029391974f,0.104699776f,0.041166715f,0.057819895f,0.041235283f,0.0f,0.0f,0.00257591f,7.3478563E-4f,0.0f,0.0f,0.0f,0.0f,0.0f,0.005514997f,0.067062065f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.054157283f,0.0f,0.12115284f,0.0f,0.12101457f,0.075238846f,0.121489145f,0.028768577f,0.0f,0.02615311f,0.019434305f,0.0142671075f,0.0f,0.12127015f,0.0f,0.031494588f,0.0f,0.0f,0.0f,0.0f,0.030308783f,0.0f,0.0f,0.0f,0.0f,0.15617357f,0.0f,0.0f,0.0f,0.0f,0.0f,0.01530996f,0.008721488f,0.0f,0.0f,0.0f,0.0f,0.055147484f,0.043269463f,0.0f,0.07176485f,0.0f,0.0f,0.0f,0.0f,0.14983608f,0.008038647f,0.04870005f,0.1245386f,0.0f,0.0f,0.08583651f,0.0f,0.0f,0.0f,0.016693637f,0.0f,0.0060664704f,0.17301567f,8.5748E-4f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.002572342f,0.023325972f,0.021881843f,0.0f,0.0f,0.0f,0.0f,0.01587723f,0.022998065f,0.0f,0.0f,0.0f,0.0f,0.0f,0.011861979f,0.09544845f,0.0f,0.055203125f,0.0f,0.0629969f,0.0f,0.0035823747f,0.0f,0.0f,0.007002083f,0.10776374f,0.0f,0.017752303f,0.0f,0.0061969324f,0.0f,0.0f,0.009520484f,0.0f,0.0f,0.102450386f
// )
// val vector2 = floatArrayOf(
// 0.04888371f,0.0f,0.0f,0.0f,0.0029784122f,0.002596595f,0.0f,0.09006795f,0.0f,0.0f,0.0f,0.0f,0.055271827f,0.0f,0.05845978f,0.0f,0.019993817f,0.041442946f,0.0f,0.0f,0.0f,0.0f,0.110088825f,0.12857845f,0.027423449f,0.042506482f,0.0062566767f,0.02848646f,0.0f,0.053226694f,0.0363839f,0.0f,0.024389764f,0.0f,0.024480496f,0.07460136f,0.0f,0.0f,0.0095814075f,0.0f,0.0f,0.0f,0.0f,0.0f,0.054666847f,0.016595673f,0.0f,0.0f,0.0f,0.0f,0.0f,0.090781584f,0.0f,0.029958958f,0.08923955f,0.0035447674f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.030632209f,0.098676704f,0.0f,0.05408989f,0.037333414f,0.07468324f,0.0f,0.077006094f,0.10075786f,0.10385432f,0.0f,0.068913125f,0.0f,0.0f,0.0f,0.0f,0.05182277f,0.015297369f,0.0f,0.0057702474f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.022514984f,0.0f,0.04740151f,0.0f,0.0f,0.0f,0.0f,0.011726161f,0.0f,0.0f,0.0f,0.0f,0.0f,0.001217202f,0.13705015f,0.05138347f,0.0816593f,0.096534394f,0.033242907f,0.0f,0.0f,0.09895034f,0.052346945f,0.07408804f,0.009087045f,0.06717835f,0.0f,0.037536476f,0.0f,0.0f,0.0f,0.045073338f,0.0f,0.0f,0.109948605f,0.033441752f,0.0144465f,0.0f,0.0f,0.0f,0.0f,0.0f,0.09093299f,0.01587698f,0.0f,0.016737117f,0.0f,0.0f,0.0f,0.09095665f,0.0f,0.0f,0.007922342f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.028204395f,0.0f,0.06497759f,0.0f,0.0f,0.03524986f,0.0f,0.0f,0.0f,0.098453656f,0.0f,0.20563814f,0.0f,0.0f,0.0f,0.0f,0.018535f,0.16479786f,0.0f,0.0f,0.0f,0.0f,0.014758027f,0.20929694f,0.017117912f,0.010678992f,0.0f,0.034372084f,0.020094762f,0.0f,0.0f,0.08637927f,0.10176056f,0.0f,0.0f,0.0f,0.011331189f,0.0f,0.018886581f,0.026822357f,0.0f,0.0f,0.0070237503f,0.0f,0.07202005f,0.0f,0.0f,0.0f,0.0f,0.0f,0.013319949f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.11933144f,0.0f,0.021441849f,0.1652874f,0.0f,0.0f,0.0f,0.0f,0.04828791f,0.029381368f,0.0f,0.023457773f,0.015665215f,0.0f,0.0f,0.0f,0.0f,0.041535854f,0.0f,0.0f,0.048669547f,0.08775835f,0.0f,0.0f,0.0f,0.0f,0.0f,0.041737933f,0.0f,0.042860966f,0.0f,0.0f,0.0f,0.15421067f,0.15791793f,0.055794608f,0.09275912f,0.0545075f,0.0f,0.0f,0.10848742f,0.11504846f,0.0f,0.0f,0.0f,0.0f,0.0f,0.011648767f,0.0f,0.036499906f,0.0f,0.0054769856f,0.0141694015f,0.0f,0.1272967f,0.0f,0.0f,0.08008197f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0037580582f,0.0f,0.0f,0.02007829f,0.0f,0.042384353f,0.0f,0.0066040033f,0.0018169946f,0.03661767f,0.0f,0.01246191f,0.0f,0.0f,0.120526984f,0.0f,0.0f,0.0f,0.098151006f,0.0f,0.12102959f,0.0f,0.008543933f,0.0f,0.09429267f,0.0f,0.0f,0.14950682f,0.0f,0.0f,0.0f,0.023073947f,0.11525905f,0.106162556f,0.0f,0.0f,0.0f,0.0f,0.071997344f,0.0f,0.004406387f,0.089178264f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.012335265f,0.0f,0.012351429f,0.03485895f,0.0f,0.0036322998f,0.05192084f,0.0f,0.0f,0.09007514f,0.0f,0.0f,0.025151148f,7.919698E-6f,0.0f,0.0018313112f,0.0145436f,0.054450806f,0.12797984f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.059141297f,0.020892957f,0.0f,0.098279655f,0.05828297f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.11039665f,0.0f,0.0f,0.0f,0.053336646f,0.0f,0.0f,0.08507843f,0.0f,0.0f,0.06554685f,0.009452949f,0.0f,0.007629284f,0.0f,0.028765898f,0.10263872f,0.041752808f,0.062005337f,0.044478178f,0.0f,0.0f,0.005904024f,8.8682055E-4f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0069284006f,0.066498056f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.05035396f,0.0f,0.12217615f,0.0f,0.119913526f,0.07956571f,0.12207263f,0.03218483f,0.0f,0.02710066f,0.022636268f,0.015647167f,0.0f,0.11522004f,0.0f,0.02771379f,0.0f,0.0f,0.0f,0.0f,0.029701354f,0.0f,0.0f,0.0f,0.0f,0.15132177f,0.0f,0.0f,0.0f,0.0f,0.0f,0.016040573f,0.0123390155f,0.0f,0.0f,0.0f,0.0f,0.05401499f,0.04475604f,0.0f,0.064246304f,0.0f,0.0f,0.0f,0.0f,0.1514622f,0.0037367684f,0.05236134f,0.12125185f,0.0f,0.0f,0.08529345f,0.0f,0.0f,0.0f,0.021191478f,0.0f,0.00896594f,0.1678437f,0.00846115f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.006917588f,0.022895483f,0.02009568f,0.0f,0.0f,0.0f,0.0f,0.02269956f,0.020049047f,0.0f,0.0f,0.0f,0.0f,0.0f,0.01585178f,0.098444566f,0.0f,0.052533984f,0.0f,0.05852503f,0.0f,0.0018540459f,0.0f,0.0f,0.012348213f,0.11396586f,0.0f,0.014174749f,0.0f,0.010799807f,0.0f,0.0f,0.012921698f,0.0f,0.0f,0.10583927f
// )
val vector =
floatArrayOf(
0.015068196f,0.0f,0.0f,0.0f,0.0037743463f,0.0f,0.0f,0.07893528f,0.0f,0.0f,0.0f,0.0f,0.052832354f,0.0f,0.045785826f,0.0f,6.156802E-4f,0.04242764f,0.0f,0.0f,0.0f,0.0f,0.11469748f,0.13930011f,0.005731758f,0.03159248f,0.018799406f,0.028927676f,0.03472497f,0.01896616f,0.078822434f,0.0f,0.015187703f,0.0f,0.033177234f,0.07078301f,0.0f,0.0f,0.012238876f,0.0f,0.0f,0.0f,0.0f,0.0f,0.10691055f,0.008628067f,0.0f,0.0f,0.0f,0.0f,0.0f,0.06886323f,0.0f,0.0f,0.10460233f,0.0f,0.0f,0.0f,0.0f,0.0f,0.012850592f,0.0f,0.0f,0.103946045f,0.0f,0.018065454f,0.046292588f,0.063853905f,0.0f,0.10074362f,0.110680245f,0.10660499f,0.0f,0.06775707f,0.0f,0.0f,0.0f,0.0f,0.01639176f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.024850294f,0.0f,0.05308442f,0.0f,0.0f,0.0f,0.028708044f,0.02787582f,0.0f,0.0f,0.0f,0.0f,0.0f,0.027483912f,0.11719905f,0.04781422f,0.09033941f,0.09655397f,0.0032244714f,0.0f,0.0f,0.09580024f,0.07075415f,0.0876085f,0.0f,0.08756652f,2.2919098E-4f,0.019845076f,0.0f,0.0f,0.0f,0.04727701f,0.007276267f,0.0f,0.12660357f,0.03222255f,0.00182945f,0.0f,0.0f,0.0f,0.0f,0.0f,0.09080463f,0.0043369643f,0.0f,0.0f,0.0f,0.0f,0.0f,0.073994264f,0.0f,0.030294247f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.04890032f,0.0f,0.05318369f,0.0f,0.0f,0.0510094f,0.0f,0.0f,0.0f,0.12696978f,0.0f,0.21870367f,0.0f,0.0f,0.0f,0.0f,0.022256335f,0.13343737f,0.0f,0.0f,0.0f,0.0f,0.025192281f,0.1621841f,0.031685397f,0.0f,0.0f,0.03057069f,0.011333849f,0.0f,0.0f,0.11482361f,0.10645431f,0.0f,0.0f,0.0f,0.039949007f,0.0f,0.018850718f,0.0f,0.0f,0.0f,0.026081126f,0.0f,0.07934742f,0.0f,0.0f,0.0f,0.0f,0.0f,0.007998445f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.098366655f,0.0f,0.01606297f,0.16557153f,0.0f,0.0f,0.0f,0.0f,0.042638786f,0.024310581f,0.0f,0.027677892f,5.940642E-4f,0.0f,0.0f,0.0f,0.0f,0.05605889f,0.0f,0.0f,0.05216231f,0.080610394f,0.0f,0.0f,0.0f,0.0f,0.0f,0.07294793f,0.0f,0.02029506f,0.0f,0.0f,0.0f,0.12797904f,0.16668096f,0.083295606f,0.07768397f,0.07725612f,0.0f,0.0f,0.07259326f,0.110221304f,0.0f,0.0f,0.0f,0.0f,0.0f,0.027140126f,0.0f,0.053474665f,0.0f,0.018286237f,0.0f,0.0f,0.12152021f,0.0f,0.0f,0.0822232f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.04146023f,0.0f,0.034810524f,0.0f,0.00393797f,0.0f,0.032150663f,0.0f,0.0f,0.0f,0.0f,0.097777024f,0.0f,0.0f,0.0f,0.078797914f,0.0f,0.1292709f,0.0f,0.010623558f,0.0f,0.08360209f,0.0f,0.0f,0.122683614f,0.0f,0.0f,0.0f,0.0f,0.10111214f,0.10537941f,0.0f,0.0f,0.0f,0.0f,0.06272928f,0.0f,0.029668529f,0.049171254f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.032665383f,0.0f,0.0f,0.044802308f,0.0f,0.0f,0.05388319f,0.0f,0.0f,0.079517856f,0.012373011f,0.0f,0.01629987f,0.014890053f,0.0f,0.027798127f,0.0f,0.051028676f,0.15331483f,0.024111472f,0.0f,0.0f,0.0f,0.0f,0.0f,0.013699274f,0.0f,0.0f,0.07011116f,0.03022409f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.10939847f,0.0f,0.0f,0.0f,0.030306451f,0.0f,0.0f,0.12335773f,0.0f,0.0f,0.09099765f,0.0f,0.0f,0.0073862355f,0.0f,0.027847463f,0.0840776f,0.04207977f,0.046206567f,0.06679146f,0.0f,0.0f,0.01625976f,0.022998374f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.059722353f,0.0f,0.012246756f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.04984296f,0.0f,0.1435546f,0.0f,0.14667304f,0.079418436f,0.1305641f,0.014777453f,0.0f,0.020115053f,0.05619832f,0.011520876f,0.0f,0.11993748f,0.009492612f,0.019984039f,0.0f,0.0f,0.0f,0.0f,0.043548502f,0.0f,0.0f,0.0f,0.0f,0.15310751f,0.0f,0.0f,0.0f,0.0f,0.0f,0.018038996f,0.0021733972f,0.0f,0.0f,0.0f,0.0f,0.060995787f,0.06326715f,0.0f,0.06896745f,0.013745607f,5.018817E-4f,0.0f,0.0f,0.14184067f,0.019447664f,0.047488734f,0.13301876f,0.0f,0.0f,0.06715185f,0.0f,0.0f,0.0025059544f,0.0013816518f,0.0f,0.00415278f,0.17231767f,0.0073697185f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0017814273f,0.040113796f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.016738398f,0.0f,0.10465313f,0.0f,0.057283692f,0.0f,0.05406501f,0.0f,0.012632326f,0.0f,0.0f,0.0f,0.10440692f,0.0f,0.0047152108f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.11544036f
)
val vector2 = floatArrayOf(
0.029274145f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.04849013f,0.0f,0.0f,0.0030461443f,0.0f,0.04333778f,0.0f,0.036458552f,0.0f,0.0f,0.032146808f,0.0f,0.0f,0.0f,0.0f,0.12563168f,0.16337962f,0.0086008925f,0.028651662f,0.05676712f,0.038951095f,0.035215054f,0.023515426f,0.09426005f,0.0f,0.0f,0.0f,0.019520408f,0.09774056f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.12273409f,0.03317896f,0.0f,0.0f,0.0f,0.0f,0.0f,0.056036845f,0.0f,0.005601604f,0.09232295f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.10639726f,0.017117623f,0.0f,0.04106111f,0.06582154f,0.0f,0.10570599f,0.10395363f,0.11154216f,0.0f,0.09019618f,0.0f,0.0f,0.0f,0.0f,0.008780864f,0.0f,0.0f,0.01997713f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.016066022f,0.020096382f,0.0f,0.05578338f,0.0f,0.0f,0.0f,0.048834037f,0.031760734f,0.0f,0.0f,0.0f,0.0f,0.0f,0.02459963f,0.11993096f,0.047805987f,0.070974134f,0.10536186f,0.0f,0.0f,0.0f,0.111894555f,0.08973926f,0.071053386f,0.0f,0.071883f,0.005135076f,0.0f,0.0f,0.0f,0.0f,0.023139987f,0.027882056f,0.0f,0.12620124f,0.05076331f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.06944067f,0.0146693f,0.0f,0.0f,0.0f,0.0f,0.00978479f,0.04965295f,0.0f,0.03953311f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.05496083f,0.0f,0.05957852f,0.0f,0.0f,0.05285405f,0.0f,0.0f,0.0f,0.10977843f,0.0f,0.21329264f,0.0f,0.0f,0.0f,0.0f,0.022029493f,0.12511873f,0.0f,0.0f,0.0f,0.0f,0.015391711f,0.1697028f,0.035269253f,0.0f,0.0f,0.0070471396f,0.0f,0.0f,0.0f,0.123943165f,0.10272677f,0.0f,0.0f,0.0f,0.06351426f,0.0f,0.009808158f,0.0f,0.0f,0.0f,0.02582221f,0.0f,0.0745801f,0.0f,0.0f,0.023285847f,0.0f,0.0f,0.017162288f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.09181752f,0.0f,0.007880242f,0.15574618f,0.0f,0.0f,0.0f,0.0f,0.02478441f,0.039601766f,0.0f,0.049401764f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0793202f,0.0f,0.0f,0.071133174f,0.09675928f,0.0f,0.015621623f,0.0f,0.0f,0.0f,0.08347399f,0.009147923f,0.0f,0.0f,0.0f,0.0f,0.14187747f,0.15219086f,0.12055488f,0.07175866f,0.07192898f,0.0f,0.0f,0.04634941f,0.12534219f,0.0f,0.0f,0.0f,0.008665879f,0.0f,0.040081337f,0.0f,0.06729515f,0.0f,0.058273762f,0.0020215393f,0.0f,0.10878004f,0.0f,0.0f,0.09762441f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.03849448f,0.0f,0.03300536f,0.0f,0.0f,0.013231625f,0.018584426f,0.0f,0.0f,0.0f,0.0f,0.08124468f,0.0f,0.0f,0.0f,0.060708806f,0.0f,0.11115098f,0.0f,0.0f,0.0f,0.0803424f,0.0f,0.0f,0.115781434f,0.0f,0.00764197f,0.0f,0.0f,0.121340856f,0.0869794f,0.0f,0.0f,0.0f,0.0f,0.045324527f,0.0f,0.015057986f,0.048937548f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.030864827f,0.0f,0.0029875587f,0.03196471f,0.0f,0.0f,0.054534424f,0.0f,0.0f,0.07863297f,0.019617077f,0.0f,0.026181744f,0.0f,0.0f,0.021914937f,0.0f,0.063720085f,0.16607703f,0.006567324f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0017898319f,0.0f,0.0f,0.04841979f,0.0044351136f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.15329078f,0.0f,0.0f,0.0f,0.030429695f,0.0f,0.0f,0.11840538f,0.0f,0.0f,0.107368395f,0.014730752f,0.0f,0.0f,0.0f,0.030180579f,0.039591953f,0.03209204f,0.048180148f,0.0676186f,0.0f,0.0f,0.03614289f,0.030257396f,1.5626202E-4f,0.018185573f,0.0f,0.0f,0.0f,0.0f,0.055325508f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.051894154f,0.0f,0.12869093f,0.0f,0.122797504f,0.083724305f,0.12840301f,0.0f,0.0f,0.0f,0.05686797f,0.0f,0.0f,0.11015593f,0.018203156f,0.020094728f,0.0f,0.0f,0.0f,0.0f,0.058597155f,0.0f,0.0f,0.0f,0.0f,0.12797132f,0.0f,0.006606713f,0.0f,0.0f,0.0f,0.028628595f,0.0f,0.0f,0.0f,0.0f,0.0f,0.050383586f,0.07132696f,0.0f,0.092209496f,0.0f,0.0f,0.0f,0.0f,0.14604862f,0.01660271f,0.057229653f,0.13104743f,0.0f,0.0f,0.06136706f,0.0f,0.0f,0.0f,0.0011910667f,0.0f,0.0f,0.15921566f,0.0f,0.0f,0.0f,0.0f,0.007558685f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.007532647f,0.05110198f,0.00667856f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0016389234f,0.0f,0.0f,0.0f,0.0f,0.018518167f,0.0f,0.08580791f,0.0f,0.06099585f,0.0f,0.0366169f,0.0f,0.0f,0.0f,0.0f,0.0f,0.073218584f,0.0f,0.0f,0.0f,0.008933658f,0.0f,0.0f,0.0f,0.0f,0.0f,0.116691895f
)
val similarity = VectorSimilarityCalculator.cosineSimilarity(vector, vector2)
println("vectorSimilarity-余弦相似度:$similarity")
val similarity2 = VectorSimilarityCalculator.euclideanDistance(vector, vector2)
println("vectorSimilarity-欧氏距离:$similarity2")
val similarity3 = VectorSimilarityCalculator.normalizedEuclideanDistance(vector, vector2)
println("vectorSimilarity-归一化欧氏距离:$similarity3")
}
} }
@@ -0,0 +1,65 @@
package com.sw.inbound
import kotlin.math.abs
import kotlin.math.sqrt
object VectorSimilarityCalculator {
/**
* 计算两个向量的余弦相似度
* @param vec1 向量1
* @param vec2 向量2
* @return 相似度值(-1~1),向量长度不一致返回0
*/
fun cosineSimilarity(vec1: FloatArray, vec2: FloatArray): Float {
if (vec1.size != vec2.size) return 0f
var dotProduct = 0f // 点积
var norm1 = 0f // 向量1的模长
var norm2 = 0f // 向量2的模长
for (i in vec1.indices) {
dotProduct += vec1[i] * vec2[i]
norm1 += vec1[i] * vec1[i]
norm2 += vec2[i] * vec2[i]
}
// 避免除以0
if (norm1 == 0f || norm2 == 0f) return 0f
return dotProduct / (sqrt(norm1.toDouble()) * sqrt(norm2.toDouble())).toFloat()
}
/**
* 计算两个向量的欧氏距离(值越小越相似)
* @param vec1 向量1
* @param vec2 向量2
* @return 欧氏距离,向量长度不一致返回Float.MAX_VALUE
*/
fun euclideanDistance(vec1: FloatArray, vec2: FloatArray): Float {
if (vec1.size != vec2.size) return Float.MAX_VALUE
var sum = 0f
for (i in vec1.indices) {
val diff = vec1[i] - vec2[i]
sum += diff * diff
}
return sqrt(sum.toDouble()).toFloat()
}
/**
* 归一化欧氏距离(0~1,值越小越相似)
*/
fun normalizedEuclideanDistance(vec1: FloatArray, vec2: FloatArray): Float {
val distance = euclideanDistance(vec1, vec2)
if (distance == Float.MAX_VALUE) return 1f
// 计算向量最大值差(归一化分母)
var maxDiff = 0f
for (i in vec1.indices) {
val diff = abs(vec1[i] - vec2[i])
if (diff > maxDiff) maxDiff = diff
}
return if (maxDiff == 0f) 0f else distance / (maxDiff * vec1.size)
}
}