自采入库、新增物品、上传图片、全部收货接口调试,其它逻辑优化
This commit is contained in:
@@ -5,15 +5,22 @@ import android.view.WindowManager
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.viewModels
|
||||
import com.sw.inbound.objbox.FoodModule
|
||||
import com.sw.inbound.sdk.SensorScaleUtils
|
||||
import com.sw.inbound.ui.AppScreen
|
||||
import com.sw.inbound.utils.ContextUtils
|
||||
import com.sw.inbound.utils.SPUtil
|
||||
import com.sw.inbound.utils.ThreadUtils
|
||||
import com.sw.inbound.viewmodel.ReceiptViewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlin.getValue
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
val viewModel: ReceiptViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
@@ -27,6 +34,8 @@ class MainActivity : ComponentActivity() {
|
||||
finish()
|
||||
})
|
||||
}
|
||||
SensorScaleUtils.startScale(autoScale = true){}
|
||||
FoodModule.init(this)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
||||
@@ -8,26 +8,32 @@ import androidx.activity.ComponentActivity
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.viewModels
|
||||
import androidx.camera.core.CameraSelector
|
||||
import androidx.camera.core.Preview
|
||||
import androidx.camera.view.CameraController
|
||||
import androidx.camera.view.LifecycleCameraController
|
||||
import androidx.camera.view.PreviewView
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.view.postDelayed
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import com.shuwei.intelligent.shelves.utils.ext.appendText
|
||||
import com.shuwei.intelligent.shelves.utils.ext.buildSpannableString
|
||||
import com.sw.inbound.GlobalData
|
||||
import com.sw.inbound.databinding.ActivityGoodsListBinding
|
||||
import com.sw.inbound.databinding.LayoutCameraPreviewBinding
|
||||
import com.sw.inbound.databinding.ListItemReceiptGoodsBinding
|
||||
import com.sw.inbound.databinding.ListItemSelfProcurementBinding
|
||||
import com.sw.inbound.dialog.DropdownPopup
|
||||
import com.sw.inbound.dialog.GoodsRecognizeDialog
|
||||
import com.sw.inbound.dialog.GoodsSearchDialog
|
||||
import com.sw.inbound.dialog.NotReceiptWarnDialog
|
||||
import com.sw.inbound.model.request.GoodsAddParam
|
||||
import com.sw.inbound.model.request.PurchaseWarehouseParam
|
||||
import com.sw.inbound.model.request.UploadInfo
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.model.response.GoodsInfo
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.objbox.FoodModule
|
||||
import com.sw.inbound.sdk.SensorScaleUtils
|
||||
import com.sw.inbound.utils.BitmapCropper
|
||||
import com.sw.inbound.utils.BitmapSaver
|
||||
import com.sw.inbound.utils.ImageUtil
|
||||
@@ -67,6 +73,8 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
abstract fun initView()
|
||||
abstract fun getWarehouseList(): List<DictType>
|
||||
private lateinit var backPressedCallback: OnBackPressedCallback
|
||||
private lateinit var previewView: PreviewView
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityGoodsListBinding.inflate(layoutInflater)
|
||||
@@ -76,7 +84,6 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
isNewReceipt = intent.getBooleanExtra(IS_NEW_RECEIPT, false)
|
||||
id = intent.getStringExtra(ID) ?: ""
|
||||
supplierId = intent.getStringExtra(SUPPLIER_ID) ?: ""
|
||||
FoodModule.init(this)
|
||||
initCamera()
|
||||
replaceIncludeContent()
|
||||
initRecyclerView()
|
||||
@@ -105,18 +112,34 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
}
|
||||
dropdownPopup?.showAsDropDown(v)
|
||||
}
|
||||
binding.tvPurchaseNo.setOnClickListener {
|
||||
GoodsRecognizeDialog(
|
||||
context = this,
|
||||
list = mutableListOf()
|
||||
) {
|
||||
GoodsSearchDialog(this).show()
|
||||
}.show()
|
||||
}
|
||||
binding.tvUserName.text = GlobalData.deviceId
|
||||
binding.tvUserName.gone()
|
||||
binding.ivLogout.gone()
|
||||
val previewBinding =
|
||||
LayoutCameraPreviewBinding.inflate(layoutInflater, binding.flCameraPreview)
|
||||
previewView = previewBinding.previewView.also {
|
||||
it.updateLayoutParams {
|
||||
width = 1
|
||||
height = 1
|
||||
}
|
||||
}
|
||||
setPreviewController(previewView)
|
||||
|
||||
setPreviewController(binding.previewView)
|
||||
|
||||
viewModel.startSensorScale()
|
||||
//viewModel.startSensorScale()
|
||||
binding.root.postDelayed({
|
||||
viewModel.readWeight {
|
||||
SensorScaleUtils.addWeightListener {
|
||||
weightCallback?.invoke(it)
|
||||
recognizeWeight(weight = it)
|
||||
}
|
||||
}, 5 * 1000)
|
||||
}, 3 * 1000)
|
||||
}
|
||||
|
||||
private var weightCallback: ((weight: Int) -> Unit)? = null
|
||||
@@ -128,21 +151,23 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
if (weight < 200) {
|
||||
return
|
||||
}
|
||||
if (searchFoodEnable.not()) {
|
||||
if (isShowRecognizeDialog.not()) {
|
||||
return
|
||||
}
|
||||
isShowRecognizeDialog = false
|
||||
runOnUiThread {
|
||||
recognizeFood()
|
||||
}
|
||||
}
|
||||
|
||||
private val takePhotoSuccessCallback: (Uri) -> Unit = { uri ->
|
||||
Thread {
|
||||
searchFood(uri)
|
||||
}.start()
|
||||
}
|
||||
|
||||
fun recognizeFood() {
|
||||
searchFoodEnable = false
|
||||
takePhoto { uri ->
|
||||
Thread {
|
||||
searchFood(uri)
|
||||
}.start()
|
||||
}
|
||||
takePhoto(takePhotoSuccessCallback)
|
||||
}
|
||||
|
||||
private var dropdownPopup: DropdownPopup? = null
|
||||
@@ -156,7 +181,7 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private var searchFoodEnable = true
|
||||
private var isShowRecognizeDialog = true
|
||||
private fun searchFood(uri: Uri) {
|
||||
ImageUtil.uriToBitmap(this, uri)?.let { bitmap ->
|
||||
val newBmp = BitmapCropper.cropCenter(
|
||||
@@ -174,7 +199,6 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
searchMultipleGoods(foodNameList) { goodsList ->
|
||||
//if (goodsList.size != foodNameList.size) {
|
||||
// toast("系统异常,请稍后重试!!!")
|
||||
// searchFoodEnable = true
|
||||
// return@searchMultipleGoods
|
||||
//}
|
||||
handleGoodsResult(
|
||||
@@ -188,19 +212,25 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
private fun handleGoodsResult(goodsList: MutableList<SearchGoodsInfo.Record>) {
|
||||
runOnUiThread {
|
||||
if (goodsRecognizeDialog?.isShowing == true) {
|
||||
searchFoodEnable = true
|
||||
isShowRecognizeDialog = false
|
||||
return@runOnUiThread
|
||||
}
|
||||
goodsRecognizeDialog = GoodsRecognizeDialog(this, goodsList, {
|
||||
goodsRecognizeDialog = null
|
||||
searchFoodEnable = true
|
||||
}) {
|
||||
goodsRecognizeDialog = GoodsRecognizeDialog(
|
||||
context = this,
|
||||
list = goodsList
|
||||
) {
|
||||
GoodsSearchDialog(this).show()
|
||||
}.apply {
|
||||
if (isFinishing || isDestroyed) {
|
||||
return@apply
|
||||
setOnDismissListener {
|
||||
goodsRecognizeDialog = null
|
||||
isShowRecognizeDialog = true
|
||||
}
|
||||
setOnShowListener {
|
||||
isShowRecognizeDialog = false
|
||||
}
|
||||
if (isFinishing.not() && isDestroyed.not()) {
|
||||
show()
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,20 +240,27 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
private var cameraController: LifecycleCameraController? = null
|
||||
private var photoCaptureHelper: PhotoCaptureHelper? = null
|
||||
private var isCameraReady = false
|
||||
fun takePhoto(cameraCallback: (Uri) -> Unit) {
|
||||
fun takePhoto(callback: (Uri) -> Unit) {
|
||||
cameraController?.let {
|
||||
if (photoCaptureHelper == null) {
|
||||
photoCaptureHelper = PhotoCaptureHelper(
|
||||
context = this,
|
||||
cameraController = cameraController!!,
|
||||
onSuccess = cameraCallback,
|
||||
onError = { msg ->
|
||||
//toast(msg)
|
||||
}
|
||||
)
|
||||
initCaptureHelper()
|
||||
}
|
||||
}
|
||||
photoCaptureHelper?.takePhoto()
|
||||
photoCaptureHelper?.let {
|
||||
it.addSuccessCallback(callback)
|
||||
it.takePhoto()
|
||||
}
|
||||
}
|
||||
|
||||
fun initCaptureHelper() {
|
||||
photoCaptureHelper = PhotoCaptureHelper(
|
||||
context = this,
|
||||
cameraController = cameraController!!,
|
||||
onSuccess = {},
|
||||
onError = { msg ->
|
||||
//toast(msg)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun setPreviewController(previewView: PreviewView?) {
|
||||
@@ -271,7 +308,6 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
cameraController?.unbind()
|
||||
viewModel.stopSensorScale()
|
||||
isCameraReady = false
|
||||
}
|
||||
|
||||
@@ -407,4 +443,27 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
fun uploadImage(imageUri: Uri, callback: (String?) -> Unit) {
|
||||
viewModel.uploadImage(imageUri) { imgUrl ->
|
||||
if (imgUrl.isNullOrBlank()) {
|
||||
callback(null)
|
||||
return@uploadImage
|
||||
}
|
||||
callback(imgUrl)
|
||||
}
|
||||
}
|
||||
|
||||
fun createNewGoods(imageUri: Uri, param: GoodsAddParam, callback: (Boolean) -> Unit) {
|
||||
viewModel.uploadImage(imageUri) { imgUrl ->
|
||||
if (imgUrl.isNullOrBlank()) {
|
||||
toast("图片上传失败")
|
||||
return@uploadImage
|
||||
}
|
||||
param.relativeUrl = imgUrl
|
||||
viewModel.createNewGoods(param = param, callback = callback)
|
||||
}
|
||||
}
|
||||
|
||||
private var preview: Preview? = null
|
||||
|
||||
}
|
||||
@@ -34,14 +34,15 @@ class RecognizeAdapter(var list: MutableList<SearchGoodsInfo.Record>) :
|
||||
)
|
||||
}
|
||||
it.ivRecImage.load(item!!.relativeUrl)
|
||||
it.root.run {
|
||||
setShapeDrawable(
|
||||
strokeColor = if (item.isSelected) "#FF0033CC" else "#FFDCDCF0",
|
||||
strokeWidth = 2.dp,
|
||||
radius = 12.dp
|
||||
)
|
||||
//setPadding(if (item.isSelected) 2.dp else 0)
|
||||
}
|
||||
//it.root.run {
|
||||
// setShapeDrawable(
|
||||
// //strokeColor = if (item.isSelected) "#FF0033CC" else "#FFDCDCF0",
|
||||
// strokeColor = "#FFDCDCF0",
|
||||
// strokeWidth = 2.dp,
|
||||
// radius = 12.dp
|
||||
// )
|
||||
// //setPadding(if (item.isSelected) 2.dp else 0)
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,146 +1,249 @@
|
||||
//package com.sw.inbound.dialog
|
||||
//
|
||||
//import android.content.Context
|
||||
//import android.graphics.SurfaceTexture
|
||||
//import android.view.LayoutInflater
|
||||
//import android.view.TextureView
|
||||
//import android.view.View
|
||||
//import android.widget.FrameLayout
|
||||
//import android.widget.TextView
|
||||
//import androidx.compose.ui.text.style.LineHeightStyle
|
||||
//import com.sw.inbound.GlobalData
|
||||
//import com.sw.inbound.activity.GoodsListActivity
|
||||
//import com.sw.inbound.databinding.DialogAddGoodsBinding
|
||||
//import com.sw.inbound.model.response.DictType
|
||||
//import com.sw.inbound.utils.ext.dp
|
||||
//import com.sw.inbound.utils.ext.gone
|
||||
//import com.sw.inbound.utils.ext.toast
|
||||
//import com.sw.inbound.utils.ext.visible
|
||||
//import kotlin.math.min
|
||||
//
|
||||
//class AddGoodsDialog(
|
||||
// context: Context,
|
||||
// var cancelBlock: () -> Unit = {},
|
||||
// var confirmBlock: () -> Unit = {},
|
||||
//) : BaseDialog(context) {
|
||||
//
|
||||
// private lateinit var binding: DialogAddGoodsBinding
|
||||
// override fun getRootView(): View {
|
||||
// val inflater = LayoutInflater.from(context)
|
||||
// binding = DialogAddGoodsBinding.inflate(inflater)
|
||||
// return binding.root
|
||||
// }
|
||||
//
|
||||
// private var dropdownPopup: DropdownPopup? = null
|
||||
//
|
||||
// private val dropdownList: MutableList<DictType> = mutableListOf()
|
||||
// private var activity: GoodsListActivity? = null
|
||||
// override fun initView() {
|
||||
// activity = getReceiptActivity()
|
||||
// binding.previewView.let {
|
||||
// it.visible()
|
||||
// activity?.setPreviewController(it)
|
||||
// activity?.setPreviewController(it)
|
||||
//// val textureView = it.getChildAt(0) as? TextureView
|
||||
//// textureView?.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
|
||||
//// override fun onSurfaceTextureAvailable(
|
||||
//// surface: SurfaceTexture,
|
||||
//// width: Int,
|
||||
//// height: Int
|
||||
//// ) {
|
||||
//// it.visible()
|
||||
//// activity?.setPreviewController(it)
|
||||
//// }
|
||||
////
|
||||
//// override fun onSurfaceTextureSizeChanged(
|
||||
//// surface: SurfaceTexture,
|
||||
//// width: Int,
|
||||
//// height: Int
|
||||
//// ) {
|
||||
//// }
|
||||
////
|
||||
//// override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
|
||||
//// return true
|
||||
//// }
|
||||
////
|
||||
//// override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
|
||||
//// }
|
||||
//// }
|
||||
// }
|
||||
// binding.ivGoodsImage.gone()
|
||||
// binding.btnClose.setOnClickListener {
|
||||
// cancelBlock()
|
||||
// dismiss()
|
||||
// }
|
||||
// binding.btnConfirm.setOnClickListener {
|
||||
// confirmBlock()
|
||||
// dismiss()
|
||||
// }
|
||||
// binding.btnStartPreview.setOnClickListener {
|
||||
// binding.ivGoodsImage.gone()
|
||||
// }
|
||||
// binding.btnTakePhoto.setOnClickListener {
|
||||
// activity?.takePhoto { uri ->
|
||||
// binding.ivGoodsImage.setImageURI(uri)
|
||||
// binding.ivGoodsImage.visible()
|
||||
// }
|
||||
// }
|
||||
// showDropDownList(
|
||||
// binding.flProcurementUnit,
|
||||
// textView = binding.tvProcurementUnit,
|
||||
// list = GlobalData.unitTypeList,
|
||||
// height = 213.dp
|
||||
// )
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.camera.view.PreviewView
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import coil.load
|
||||
import com.sw.inbound.GlobalData
|
||||
import com.sw.inbound.activity.GoodsListActivity
|
||||
import com.sw.inbound.databinding.DialogAddGoodsBinding
|
||||
import com.sw.inbound.databinding.LayoutCameraPreviewBinding
|
||||
import com.sw.inbound.ext.toSafeBigDecimal
|
||||
import com.sw.inbound.ext.toSafeFloat
|
||||
import com.sw.inbound.model.request.GoodsAddParam
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
import com.sw.inbound.utils.ext.gone
|
||||
import com.sw.inbound.utils.ext.toast
|
||||
import com.sw.inbound.utils.ext.visible
|
||||
import kotlin.math.min
|
||||
|
||||
class AddGoodsDialog(
|
||||
context: Context,
|
||||
var cancelBlock: () -> Unit = {},
|
||||
var confirmBlock: (String) -> Unit = {},
|
||||
) : BaseDialog(context) {
|
||||
|
||||
private lateinit var binding: DialogAddGoodsBinding
|
||||
override fun getRootView(): View {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
binding = DialogAddGoodsBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private var dropdownPopup: DropdownPopup? = null
|
||||
|
||||
private val dropdownList: MutableList<DictType> = mutableListOf()
|
||||
private var activity: GoodsListActivity? = null
|
||||
|
||||
override fun show() {
|
||||
super.show()
|
||||
|
||||
window?.decorView?.postDelayed({
|
||||
activity?.setPreviewController(previewView)
|
||||
}, 600)
|
||||
}
|
||||
|
||||
private val takePhotoCallback: (Uri) -> Unit = { uri ->
|
||||
binding.flCameraPreview.gone()
|
||||
imageUri = uri
|
||||
binding.cvImageBg.visible()
|
||||
binding.ivGoodsImage.load(uri)
|
||||
}
|
||||
|
||||
private lateinit var previewView: PreviewView
|
||||
override fun initView() {
|
||||
activity = getReceiptActivity()
|
||||
val previewBinding =
|
||||
LayoutCameraPreviewBinding.inflate(LayoutInflater.from(context), binding.flCameraPreview)
|
||||
previewBinding.previewView.let {
|
||||
it.updateLayoutParams {
|
||||
width = 428.dp
|
||||
height = 320.dp
|
||||
}
|
||||
previewView = it
|
||||
}
|
||||
// binding.flCameraPreview.removeAllViews()
|
||||
// binding.flCameraPreview.addView(previewView)
|
||||
binding.flCameraPreview.visible()
|
||||
binding.cvImageBg.gone()
|
||||
binding.btnClose.setOnClickListener {
|
||||
cancelBlock()
|
||||
dismiss()
|
||||
}
|
||||
binding.btnConfirm.setOnClickListener {
|
||||
submit()
|
||||
}
|
||||
binding.btnStartPreview.setOnClickListener {
|
||||
binding.cvImageBg.gone()
|
||||
binding.flCameraPreview.visible()
|
||||
}
|
||||
binding.btnTakePhoto.setOnClickListener {
|
||||
activity?.takePhoto(takePhotoCallback)
|
||||
}
|
||||
binding.btnUploadImg.gone()
|
||||
binding.btnUploadImg.setOnClickListener {
|
||||
uploadImage()
|
||||
}
|
||||
binding.tvGoodsType.let { tv ->
|
||||
tv.text = "原材料"
|
||||
tv.tag = GlobalData.goodsTypeList.firstOrNull { it.value == "原材料" }?.id
|
||||
?: "1980098911276191746"
|
||||
}
|
||||
showDropDownList(
|
||||
binding.flProcurementUnit,
|
||||
textView = binding.tvProcurementUnit,
|
||||
list = GlobalData.unitTypeList,
|
||||
height = 213.dp
|
||||
)
|
||||
// showDropDownList(
|
||||
// binding.flGoodsType,
|
||||
// textView = binding.tvGoodsType,
|
||||
// list = GlobalData.goodsTypeList,
|
||||
// )
|
||||
// showDropDownList(
|
||||
// binding.flStorageType,
|
||||
// textView = binding.tvStorageType,
|
||||
// list = GlobalData.storageTypeList,
|
||||
// )
|
||||
// showDropDownList(
|
||||
// dropdownView = binding.flWarehouseUnit,
|
||||
// textView = binding.tvWarehouseUnit,
|
||||
// list = GlobalData.unitTypeList
|
||||
// ) {
|
||||
// binding.tvSelectUseUnit.text = it.value
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun showDropDownList(
|
||||
// dropdownView: FrameLayout,
|
||||
// textView: TextView,
|
||||
// list: List<DictType>,
|
||||
// height: Int = 355.dp,
|
||||
// block:(DictType)-> Unit= {}
|
||||
// ) {
|
||||
// dropdownView.setOnClickListener {
|
||||
// dropdownList.clear()
|
||||
// val tempList =
|
||||
// list.filter { it.id.isNullOrBlank().not() && it.value.isNullOrBlank().not() }
|
||||
// if (tempList.isEmpty()) {
|
||||
// context.toast("暂无下拉数据")
|
||||
// return@setOnClickListener
|
||||
// }
|
||||
// dropdownList.addAll(tempList)
|
||||
// val realHeight = min(height, dropdownList.size * 71.dp)
|
||||
// dropdownPopup = DropdownPopup(
|
||||
// context = context,
|
||||
// list = dropdownList,
|
||||
// popWidth = dropdownView.width,
|
||||
// popHeight = realHeight
|
||||
// ) {
|
||||
// textView.text = it.value
|
||||
// block(it)
|
||||
// }
|
||||
// dropdownPopup?.showAsDropDown(dropdownView)
|
||||
// dropdownPopup?.setOnDismissListener {
|
||||
// dropdownPopup = null
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
showDropDownList(
|
||||
binding.flStorageType,
|
||||
textView = binding.tvStorageType,
|
||||
list = GlobalData.storageTypeList,
|
||||
)
|
||||
showDropDownList(
|
||||
dropdownView = binding.flWarehouseUnit,
|
||||
textView = binding.tvWarehouseUnit,
|
||||
list = GlobalData.unitTypeList
|
||||
) {
|
||||
binding.tvSelectUseUnit.text = it.value
|
||||
binding.tvSelectProcurementUnit.text = it.value
|
||||
}
|
||||
}
|
||||
|
||||
private fun showDropDownList(
|
||||
dropdownView: FrameLayout,
|
||||
textView: TextView,
|
||||
list: List<DictType>,
|
||||
height: Int = 355.dp,
|
||||
block: (DictType) -> Unit = {}
|
||||
) {
|
||||
dropdownView.setOnClickListener {
|
||||
dropdownList.clear()
|
||||
val tempList =
|
||||
list.filter { it.id.isNullOrBlank().not() && it.value.isNullOrBlank().not() }
|
||||
if (tempList.isEmpty()) {
|
||||
context.toast("暂无下拉数据")
|
||||
return@setOnClickListener
|
||||
}
|
||||
dropdownList.addAll(tempList)
|
||||
val realHeight = min(height, dropdownList.size * 71.dp)
|
||||
dropdownPopup = DropdownPopup(
|
||||
context = context,
|
||||
list = dropdownList,
|
||||
popWidth = dropdownView.width,
|
||||
popHeight = realHeight
|
||||
) {
|
||||
textView.run {
|
||||
text = it.value
|
||||
tag = it.id
|
||||
}
|
||||
block(it)
|
||||
}
|
||||
dropdownPopup?.showAsDropDown(dropdownView)
|
||||
dropdownPopup?.setOnDismissListener {
|
||||
dropdownPopup = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun submit() {
|
||||
if (imageUri == null) {
|
||||
context.toast("请采集图片")
|
||||
return
|
||||
}
|
||||
val goodsName = binding.etGoodsName.text.trim().toString()
|
||||
if (goodsName.isBlank()) {
|
||||
context.toast("请输入物品名称")
|
||||
return
|
||||
}
|
||||
val netRateText = binding.etNetMaterialRate.text.trim().toString()
|
||||
if (netRateText.isBlank()) {
|
||||
context.toast("请输入净材率")
|
||||
return
|
||||
}
|
||||
val netRate = (netRateText.toFloatOrNull() ?: 0f) / 100f
|
||||
val goodsType = binding.tvGoodsType.tag.toString()
|
||||
if (goodsType.isBlank()) {
|
||||
context.toast("请录入物品类型")
|
||||
return
|
||||
}
|
||||
val storageType = binding.tvStorageType.tag.toString()
|
||||
if (storageType.isBlank()) {
|
||||
context.toast("请录入存储方式")
|
||||
return
|
||||
}
|
||||
val warehouseUnit = binding.tvWarehouseUnit.tag.toString()
|
||||
if (warehouseUnit.isBlank()) {
|
||||
context.toast("请录入库存单位")
|
||||
return
|
||||
}
|
||||
val purchaseUnit = binding.tvProcurementUnit.tag.toString()
|
||||
if (purchaseUnit.isBlank()) {
|
||||
context.toast("请录采购单位")
|
||||
return
|
||||
}
|
||||
val costValue = binding.etUseUnit.text.trim().toString()
|
||||
if (costValue.isBlank()) {
|
||||
context.toast("请输入物品名称")
|
||||
return
|
||||
}
|
||||
val goodsCount = binding.etGoodsCount.text.trim().toString()
|
||||
if (costValue.isBlank()) {
|
||||
context.toast("请输入采购数量")
|
||||
return
|
||||
}
|
||||
val goodsPrice = binding.etGoodsPrice.text.trim().toString()
|
||||
if (goodsPrice.isBlank()) {
|
||||
context.toast("请输入采购单价")
|
||||
return
|
||||
}
|
||||
val param = GoodsAddParam(
|
||||
goodName = goodsName,
|
||||
netRate = netRate,
|
||||
goodType = goodsType,
|
||||
storageType = storageType,
|
||||
unitId = warehouseUnit,
|
||||
consumeValue = costValue,
|
||||
purchaseUnit = purchaseUnit,
|
||||
purchaseValue = goodsCount.toSafeFloat(),
|
||||
purchasePrice = goodsPrice.toSafeBigDecimal(),
|
||||
)
|
||||
activity?.createNewGoods(imageUri!!, param) {
|
||||
if (it.not()) {
|
||||
context.toast("新增物品失败")
|
||||
return@createNewGoods
|
||||
}
|
||||
context.toast("新增物品成功")
|
||||
confirmBlock(goodsName)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private var imageUri: Uri? = null
|
||||
|
||||
private fun uploadImage() {
|
||||
if (imageUri == null) {
|
||||
context.toast("请采集图片")
|
||||
return
|
||||
}
|
||||
activity?.uploadImage(imageUri!!) { imgUrl ->
|
||||
if (imgUrl.isNullOrBlank()) {
|
||||
context.toast("图片上传失败")
|
||||
return@uploadImage
|
||||
}
|
||||
context.toast(imgUrl)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,6 @@ import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
class GoodsRecognizeDialog(
|
||||
context: Context,
|
||||
var list: MutableList<SearchGoodsInfo.Record>,
|
||||
var dismissDialog: () -> Unit,
|
||||
var findGoods: () -> Unit
|
||||
) : BaseDialog(context) {
|
||||
|
||||
@@ -27,11 +26,6 @@ class GoodsRecognizeDialog(
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
dismissDialog()
|
||||
super.dismiss()
|
||||
}
|
||||
|
||||
private val recognizeAdapter by lazy {
|
||||
RecognizeAdapter(list).apply {
|
||||
isStateViewEnable = true
|
||||
|
||||
@@ -38,9 +38,17 @@ class GoodsSearchDialog(
|
||||
searchGoods()
|
||||
}
|
||||
}
|
||||
// binding.btnAddGoods.setOnClickListener {
|
||||
// AddGoodsDialog(context).show()
|
||||
// }
|
||||
binding.btnAddGoods.setOnClickListener {
|
||||
AddGoodsDialog(
|
||||
context = context,
|
||||
cancelBlock = {},
|
||||
confirmBlock = { goodsName->
|
||||
pageNo = 1
|
||||
binding.etInputGoods.setText(goodsName)
|
||||
searchGoods()
|
||||
}
|
||||
).show()
|
||||
}
|
||||
binding.btnConfirm.setOnClickListener {
|
||||
if (list.isEmpty()) {
|
||||
context.toast("请搜索物品")
|
||||
|
||||
@@ -80,6 +80,7 @@ class GoodsStoreDialog(
|
||||
text = it.value
|
||||
tag = it.id
|
||||
}
|
||||
binding.tvCountUnit.text = it.value
|
||||
}
|
||||
}
|
||||
dropdownPopup?.showAsDropDown(v)
|
||||
@@ -166,22 +167,22 @@ class GoodsStoreDialog(
|
||||
private fun confirmInputData() {
|
||||
val unit = binding.tvProcurementUnit.text.trim().toString()
|
||||
if (unit.isBlank()) {
|
||||
context.toast("请选择单位")
|
||||
context.toast("请选择入库单位")
|
||||
return
|
||||
}
|
||||
val countText = binding.etProcurementCount.text.trim().toString()
|
||||
if (countText.isBlank()) {
|
||||
context.toast("请录入数量")
|
||||
return
|
||||
}
|
||||
val priceText = binding.tvProcurementPrice.text.trim().toString()
|
||||
if (priceText.isBlank()) {
|
||||
context.toast("请录入单价")
|
||||
context.toast("请录入入库数量")
|
||||
return
|
||||
}
|
||||
val amountText = binding.etProcurementAmount.text.trim().toString()
|
||||
if (amountText.isBlank()) {
|
||||
context.toast("请录入金额")
|
||||
context.toast("请录入入库金额")
|
||||
return
|
||||
}
|
||||
val priceText = binding.tvProcurementPrice.text.trim().toString()
|
||||
if (priceText.isBlank()) {
|
||||
context.toast("请录入入库单价")
|
||||
return
|
||||
}
|
||||
confirmBlock(
|
||||
|
||||
@@ -27,7 +27,7 @@ data class GoodsAddParam(
|
||||
/**
|
||||
* 存储方式
|
||||
*/
|
||||
var storageType: Int? = null,
|
||||
var storageType: String? = null,
|
||||
|
||||
/**
|
||||
* 净材率
|
||||
@@ -37,18 +37,18 @@ data class GoodsAddParam(
|
||||
/**
|
||||
* 库存单位id
|
||||
*/
|
||||
var unitId: Int? = null,
|
||||
var unitId: String? = null,
|
||||
|
||||
/**
|
||||
* 采购单位
|
||||
*/
|
||||
var purchaseUnit: Int = 0,
|
||||
var purchaseUnit: String? = null,
|
||||
|
||||
/**
|
||||
* 单位转换值
|
||||
*/
|
||||
var purchaseValue: Float = 0F,
|
||||
var purchaseValueStr: String = "",
|
||||
//var purchaseValueStr: String = "",
|
||||
|
||||
/**
|
||||
* 采购单价
|
||||
@@ -119,7 +119,7 @@ data class GoodsAddParam(
|
||||
|
||||
val purchaseUnitStr: String
|
||||
get() {
|
||||
if (purchaseUnit == 0) {
|
||||
if (purchaseUnit == null) {
|
||||
return ""
|
||||
}
|
||||
return GlobalData.unitTypeList.find { it.id == purchaseUnit.toString() }?.value ?: ""
|
||||
@@ -131,16 +131,16 @@ data class GoodsAddParam(
|
||||
if (goodType.isNullOrBlank() || goodType == "0") {
|
||||
return "请选择物品类型"
|
||||
}
|
||||
if (storageType == null || storageType == 0) {
|
||||
if (storageType.isNullOrBlank()) {
|
||||
return "请选择存储方式"
|
||||
}
|
||||
if (netRate == null || netRate == 0f) {
|
||||
return "请录入净材率"
|
||||
}
|
||||
if (unitId == null || unitId == 0) {
|
||||
if (unitId.isNullOrBlank()) {
|
||||
return "请选择库存单位"
|
||||
}
|
||||
if (purchaseUnit == null || purchaseUnit == 0) {
|
||||
if (purchaseUnit.isNullOrBlank()) {
|
||||
return "请选择采购单位"
|
||||
}
|
||||
if (purchaseValue == null || purchaseValue == 0f) {
|
||||
|
||||
@@ -15,7 +15,7 @@ data class ApiResponse<T>(
|
||||
val msg: String? = "",
|
||||
val data: T? = null
|
||||
) {
|
||||
fun isSuccess(): Boolean = code == "00000"
|
||||
fun isSuccess(): Boolean = ("00000" == code)
|
||||
|
||||
val result: T?
|
||||
get() = data
|
||||
|
||||
@@ -139,11 +139,19 @@ interface ApiService {
|
||||
/**
|
||||
* 上传图片
|
||||
*/
|
||||
// @Multipart
|
||||
// @POST//("sys/common/upload")
|
||||
// suspend fun uploadImage(
|
||||
// @Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/sys/common/upload",
|
||||
// @Part("code") code: RequestBody,
|
||||
// @Part file: MultipartBody.Part,
|
||||
// ): ApiResponse<String>
|
||||
|
||||
@Multipart
|
||||
@POST//("sys/common/upload")
|
||||
suspend fun uploadImage(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/sys/common/upload",
|
||||
@Part("code") code: RequestBody,
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/upload",
|
||||
//@Part("code") code: RequestBody,
|
||||
@Part file: MultipartBody.Part,
|
||||
): ApiResponse<String>
|
||||
|
||||
@@ -166,7 +174,7 @@ interface ApiService {
|
||||
suspend fun selfPurchaseGoodsAdd(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/goodsAdd",
|
||||
@Body goodsAddParam: GoodsAddParam,
|
||||
): ApiResponse<SearchGoodsInfo>
|
||||
): ApiResponse<String>
|
||||
|
||||
/**
|
||||
* 添加物品采购单位
|
||||
|
||||
@@ -30,7 +30,7 @@ object FoodModule {
|
||||
val NO_STD_RGB = floatArrayOf(1.0f, 1.0f, 1.0f)
|
||||
|
||||
fun init(context: Context) {
|
||||
Thread{
|
||||
Thread {
|
||||
module_mobile = Module.load(copyAssetToCache(context, "best_embedding_model_mobile.pt"))
|
||||
box = ObjectBox.boxStore.boxFor(Food::class)
|
||||
// if (box.all.isNotEmpty()) {
|
||||
@@ -60,24 +60,30 @@ object FoodModule {
|
||||
return outputTensor.dataAsFloatArray
|
||||
}
|
||||
|
||||
fun queryFood(uri: Uri, queryCount:Int = 15): List<String>? {
|
||||
fun queryFood(uri: Uri, queryCount: Int = 15): List<String>? {
|
||||
return uri2FloatArray(uri)?.let {
|
||||
queryFood(it, queryCount)
|
||||
}
|
||||
}
|
||||
fun queryFood(bitmap: Bitmap, queryCount:Int = 15): List<String> {
|
||||
val inputTensor = TensorImageUtils.bitmapToFloat32Tensor(
|
||||
bitmap,
|
||||
NO_MEAN_RGB, // [0.485, 0.456, 0.406] TORCHVISION_NORM_MEAN_RGB
|
||||
NO_STD_RGB // [0.229, 0.224, 0.225] TORCHVISION_NORM_STD_RGB
|
||||
)
|
||||
|
||||
fun queryFood(bitmap: Bitmap, queryCount: Int = 15): List<String> {
|
||||
val inputTensor =
|
||||
TensorImageUtils.bitmapToFloat32Tensor(
|
||||
bitmap,
|
||||
NO_MEAN_RGB, // [0.485, 0.456, 0.406] TORCHVISION_NORM_MEAN_RGB
|
||||
NO_STD_RGB // [0.229, 0.224, 0.225] TORCHVISION_NORM_STD_RGB
|
||||
)
|
||||
val outputTensor = module_mobile.forward(IValue.from(inputTensor)).toTensor()
|
||||
val floatArray = outputTensor.dataAsFloatArray
|
||||
return queryFood(floatArray,queryCount)
|
||||
if (bitmap.isRecycled.not()) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
return queryFood(floatArray, queryCount)
|
||||
}
|
||||
|
||||
fun queryFood(floatArray: FloatArray, queryCount:Int = 15): List<String> {
|
||||
val query: Query<Food> = box.query(Food_.foodVector.nearestNeighbors(floatArray, queryCount)).build()
|
||||
fun queryFood(floatArray: FloatArray, queryCount: Int = 15): List<String> {
|
||||
val query: Query<Food> =
|
||||
box.query(Food_.foodVector.nearestNeighbors(floatArray, queryCount)).build()
|
||||
//查询比较分数
|
||||
// val tempList = query.findWithScores().sortedBy { it.score }.map { "${it.get().name}|${it.get().foodIdx}|${it.score}" }
|
||||
val map = mutableMapOf<String, Int>()
|
||||
|
||||
@@ -113,17 +113,18 @@ class RemoteRepository @Inject constructor(
|
||||
suspend fun uploadImage(uri: Uri): ApiResponse<String> {
|
||||
Timber.d("uploadImage uri = $uri")
|
||||
return safeApiCall {
|
||||
val codeRequestBody = RequestBody.create(
|
||||
MultipartBody.FORM,
|
||||
"4"
|
||||
)
|
||||
//val codeRequestBody = RequestBody.create(
|
||||
// MultipartBody.FORM,
|
||||
// "4"
|
||||
//)
|
||||
|
||||
val part =
|
||||
FileUtils.genRequestPart(context = ContextUtils.getAppContext(), imageUri = uri)
|
||||
if (part == null) {
|
||||
ApiResponse(code = "-1", msg = "解析图片失败")
|
||||
} else {
|
||||
apiService.uploadImage(code = codeRequestBody, file = part)
|
||||
//apiService.uploadImage(code = codeRequestBody, file = part)
|
||||
apiService.uploadImage(file = part)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,7 +165,7 @@ class RemoteRepository @Inject constructor(
|
||||
/**
|
||||
* 自采购-添加商品
|
||||
*/
|
||||
suspend fun selfPurchaseGoodsAdd(goodsAddParam: GoodsAddParam): ApiResponse<SearchGoodsInfo> {
|
||||
suspend fun selfPurchaseGoodsAdd(goodsAddParam: GoodsAddParam): ApiResponse<String> {
|
||||
return safeApiCall {
|
||||
apiService.selfPurchaseGoodsAdd(goodsAddParam = goodsAddParam)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ object SensorScaleUtils {
|
||||
SensorScale.STATE_OVER_WEIGHT -> "量程溢出"
|
||||
else -> "未知"
|
||||
}
|
||||
|
||||
weightCallback?.invoke((value * 1000).toInt())
|
||||
//Timber.d("readWeight state = ${stateStr}, weight = $value")
|
||||
// 只使用稳定值
|
||||
// if (state == SensorScale.STATE_STABLE) {
|
||||
@@ -52,6 +54,11 @@ object SensorScaleUtils {
|
||||
})
|
||||
}
|
||||
|
||||
private var weightCallback: ((Int) -> Unit)? = null
|
||||
fun addWeightListener(callback: (Int) -> Unit) {
|
||||
weightCallback = callback
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启称重
|
||||
* @param autoScale 是否开启自动读取
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.sw.inbound.utils
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.SystemClock
|
||||
import android.view.View
|
||||
import java.util.Arrays
|
||||
|
||||
class MultiClickDetector(private val targetCount: Int = 10,
|
||||
private val intervalMs: Long = 50) {
|
||||
private var clickCount = 0
|
||||
private val clickTimestamps = LongArray(targetCount)
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private lateinit var callback: () -> Unit
|
||||
|
||||
fun setOnMultiClickListener(view: View, action: () -> Unit) {
|
||||
callback = action
|
||||
view.setOnClickListener {
|
||||
System.arraycopy(clickTimestamps, 1, clickTimestamps, 0, targetCount - 1)
|
||||
clickTimestamps[targetCount - 1] = SystemClock.uptimeMillis()
|
||||
|
||||
if (clickTimestamps[0] >= SystemClock.uptimeMillis() - intervalMs) {
|
||||
callback.invoke()
|
||||
resetCount()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 使用Handler的延迟检测方案
|
||||
fun setOnDelayedMultiClickListener(view: View, action: () -> Unit) {
|
||||
callback = action
|
||||
view.setOnClickListener {
|
||||
clickCount++
|
||||
handler.removeCallbacks(resetTask)
|
||||
handler.postDelayed(resetTask, intervalMs)
|
||||
|
||||
if (clickCount >= targetCount) {
|
||||
callback.invoke()
|
||||
resetCount()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val resetTask = Runnable { resetCount() }
|
||||
private fun resetCount() {
|
||||
clickCount = 0
|
||||
Arrays.fill(clickTimestamps, 0L)
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,12 @@ class PhotoCaptureHelper(
|
||||
private val onSuccess: (Uri) -> Unit = {},
|
||||
private val onError: (String) -> Unit = {}
|
||||
) {
|
||||
private val callbackList: MutableList<(Uri) -> Unit> = mutableListOf()
|
||||
fun addSuccessCallback(callback:(Uri) -> Unit) {
|
||||
if (callbackList.contains(callback).not()) {
|
||||
callbackList.add(callback)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拍照方法
|
||||
@@ -56,6 +62,9 @@ class PhotoCaptureHelper(
|
||||
val photoUri = outputFileResults.savedUri ?: Uri.fromFile(photoFile)
|
||||
Timber.d("照片保存成功: $photoUri")
|
||||
onSuccess(photoUri)
|
||||
callbackList.forEach {
|
||||
it(photoUri)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(exception: ImageCaptureException) {
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.sw.inbound.model.response.GoodsInfo
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.network.LoadingState
|
||||
import com.sw.inbound.repository.RemoteRepository
|
||||
import com.sw.inbound.sdk.SensorScaleUtils
|
||||
import com.sw.inbound.utils.ToastUtils
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
@@ -110,18 +109,18 @@ abstract class BaseViewModel(
|
||||
ToastUtils.showToast(message)
|
||||
}
|
||||
|
||||
fun startSensorScale() {
|
||||
Timber.d("开始称重")
|
||||
SensorScaleUtils.startScale(callback = { weight ->
|
||||
_weightInfo.value = weight
|
||||
handleSensorScale(weight)
|
||||
})
|
||||
}
|
||||
|
||||
fun stopSensorScale() {
|
||||
Timber.d("关闭称重")
|
||||
SensorScaleUtils.stopContinuousRead()
|
||||
}
|
||||
// fun startSensorScale() {
|
||||
// Timber.d("开始称重")
|
||||
// SensorScaleUtils.startScale(callback = { weight ->
|
||||
// _weightInfo.value = weight
|
||||
// handleSensorScale(weight)
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// fun stopSensorScale() {
|
||||
// Timber.d("关闭称重")
|
||||
// SensorScaleUtils.stopContinuousRead()
|
||||
// }
|
||||
|
||||
abstract fun handleSensorScale(weight: Double)
|
||||
|
||||
@@ -239,7 +238,7 @@ abstract class BaseViewModel(
|
||||
response.result
|
||||
?.filter { it.id.isNullOrBlank().not() && it.title.isNullOrBlank().not() }
|
||||
?.forEach {
|
||||
list.add(DictType(id = it.id, value = it.title))
|
||||
list.add(DictType(id = it.value, value = it.title))
|
||||
}
|
||||
GlobalData.storageTypeList = list
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.sw.inbound.viewmodel
|
||||
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.sw.inbound.ext.toFormattedString
|
||||
import com.sw.inbound.ext.toSafeBigDecimal
|
||||
import com.sw.inbound.ext.toSafeDouble
|
||||
import com.sw.inbound.ext.toSafeFloat
|
||||
import com.sw.inbound.model.request.GoodsAddParam
|
||||
import com.sw.inbound.model.request.PurchaseWarehouseParam
|
||||
import com.sw.inbound.model.request.UploadInfo
|
||||
import com.sw.inbound.model.response.DictType
|
||||
@@ -13,6 +16,7 @@ import com.sw.inbound.model.response.PurchaseInfo
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.repository.RemoteRepository
|
||||
import com.sw.inbound.utils.ToastUtils
|
||||
import com.sw.inbound.utils.ext.toJsonString
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
@@ -150,7 +154,7 @@ class ReceiptViewModel @Inject constructor(
|
||||
// _selectedItem.value = purchaseOrder
|
||||
// }
|
||||
|
||||
fun getReceiveDetail(id: String, action:(PurchaseInfo?)->Unit = {}) {
|
||||
fun getReceiveDetail(id: String, action: (PurchaseInfo?) -> Unit = {}) {
|
||||
launchWithLoading {
|
||||
val response = repository.getReceiveDetail(id)
|
||||
if (parseResponse(response)) {
|
||||
@@ -245,12 +249,13 @@ class ReceiptViewModel @Inject constructor(
|
||||
_amountUserInput.value = boolean
|
||||
}
|
||||
|
||||
private var weightCallback:((Int)->Unit)?=null
|
||||
fun readWeight(callback:(Int)->Unit) {
|
||||
weightCallback = callback
|
||||
}
|
||||
//private var weightCallback: ((Int) -> Unit)? = null
|
||||
//fun readWeight(callback: (Int) -> Unit) {
|
||||
// weightCallback = callback
|
||||
//}
|
||||
|
||||
override fun handleSensorScale(weight: Double) {
|
||||
weightCallback?.invoke((weight*1000).toInt())
|
||||
// weightCallback?.invoke((weight * 1000).toInt())
|
||||
// val currentItem = _selectedItem.value
|
||||
//
|
||||
// currentItem?.let { info ->
|
||||
@@ -346,4 +351,35 @@ class ReceiptViewModel @Inject constructor(
|
||||
callback(resp.data == true)
|
||||
}
|
||||
}
|
||||
|
||||
fun uploadImage(imageUri: Uri, callback: (String?) -> Unit) {
|
||||
launchWithLoading {
|
||||
val resp = repository.uploadImage(imageUri)
|
||||
if (!parseResponse(resp)) {
|
||||
callback(null)
|
||||
return@launchWithLoading
|
||||
}
|
||||
callback(resp.data)
|
||||
}
|
||||
}
|
||||
|
||||
fun createNewGoods(imageUri: Uri? = null, param: GoodsAddParam, callback: (Boolean) -> Unit) {
|
||||
launchWithLoading {
|
||||
if (imageUri != null) {
|
||||
val resp = repository.uploadImage(imageUri)
|
||||
if (!parseResponse(resp)) {
|
||||
callback(false)
|
||||
return@launchWithLoading
|
||||
}
|
||||
param.relativeUrl = resp.data
|
||||
}
|
||||
Timber.tag("ReceiptViewModel").d("createNewGoods入参:${param.toJsonString()}")
|
||||
val response = repository.selfPurchaseGoodsAdd(param)
|
||||
if (!parseResponse(response)) {
|
||||
callback(false)
|
||||
return@launchWithLoading
|
||||
}
|
||||
callback(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_pressed="false">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/white"/>
|
||||
<stroke android:color="#FFDCDCF0" android:width="2dp"/>
|
||||
<corners android:radius="12dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:state_pressed="true">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/white"/>
|
||||
<stroke android:color="#ff999999" android:width="2dp"/>
|
||||
<corners android:radius="12dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
||||
@@ -56,6 +56,7 @@
|
||||
android:paddingHorizontal="20dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutTop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:gravity="center_vertical"
|
||||
@@ -68,12 +69,13 @@
|
||||
android:textColor="#ff333333"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:paddingVertical="8dp"
|
||||
tools:text="采购单号:CG2506190526" />
|
||||
|
||||
<androidx.camera.view.PreviewView
|
||||
android:id="@+id/previewView"
|
||||
android:layout_width="2dp"
|
||||
android:layout_height="2dp"
|
||||
<FrameLayout
|
||||
android:id="@+id/flCameraPreview"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginStart="5dp" />
|
||||
|
||||
<Space
|
||||
@@ -129,6 +131,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:overScrollMode="never"
|
||||
tools:listitem="@layout/list_item_receipt_goods"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:itemCount="8" />
|
||||
|
||||
|
||||
@@ -36,50 +36,60 @@
|
||||
android:layout_width="430dp"
|
||||
android:layout_height="322dp"
|
||||
android:layout_marginTop="40dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2_dash"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/llGoodsInfo">
|
||||
app:layout_constraintTop_toTopOf="@+id/llGoodsInfo"
|
||||
android:background="@drawable/bg_white_radius10_stroke2_dash">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llStartPreview"
|
||||
<!-- <LinearLayout-->
|
||||
<!-- android:id="@+id/llStartPreview"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_gravity="center"-->
|
||||
<!-- android:gravity="center"-->
|
||||
<!-- android:orientation="vertical"-->
|
||||
<!-- android:visibility="gone">-->
|
||||
|
||||
<!-- <ImageView-->
|
||||
<!-- android:layout_width="96dp"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_gravity="center"-->
|
||||
<!-- android:scaleType="centerCrop"-->
|
||||
<!-- android:src="@mipmap/ic_camera_gray"-->
|
||||
<!-- tools:ignore="ContentDescription" />-->
|
||||
|
||||
<!-- <TextView-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginTop="24dp"-->
|
||||
<!-- android:text="图片采集"-->
|
||||
<!-- android:textColor="#ffb4b4c8"-->
|
||||
<!-- android:textSize="24sp" />-->
|
||||
<!-- </LinearLayout>-->
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flCameraPreview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/cvImageBg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:cardBackgroundColor="@color/white"
|
||||
app:cardCornerRadius="10dp"
|
||||
android:layout_margin="3dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="96dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/ivGoodsImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@mipmap/ic_camera_gray"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="图片采集"
|
||||
android:textColor="#ffb4b4c8"
|
||||
android:textSize="24sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.camera.view.PreviewView
|
||||
android:id="@+id/previewView"
|
||||
android:layout_width="428dp"
|
||||
android:layout_height="320dp"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivGoodsImage"
|
||||
android:layout_width="428dp"
|
||||
android:layout_height="320dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
tools:ignore="ContentDescription" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
</FrameLayout>
|
||||
|
||||
<Button
|
||||
@@ -120,6 +130,20 @@
|
||||
tools:ignore="UseCompatTextViewDrawableXml" />
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnUploadImg"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginTop="39dp"
|
||||
android:background="@drawable/bg_white_stroke_green_ripple"
|
||||
android:text="上传图片"
|
||||
android:textColor="#FF14CD71"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="@id/btnTakePhoto"
|
||||
app:layout_constraintStart_toStartOf="@id/btnStartPreview"
|
||||
app:layout_constraintTop_toBottomOf="@id/btnTakePhoto" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llGoodsInfo"
|
||||
android:layout_width="0dp"
|
||||
@@ -242,7 +266,7 @@
|
||||
android:id="@+id/flGoodsType"
|
||||
android:layout_width="432dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
android:background="@drawable/bg_gray_radius10">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvGoodsType"
|
||||
@@ -253,7 +277,7 @@
|
||||
android:layout_marginEnd="20dp"
|
||||
android:ellipsize="end"
|
||||
android:hint="请选择"
|
||||
android:textColor="#ff141428"
|
||||
android:textColor="#ff96a0aa"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
@@ -265,7 +289,8 @@
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
tools:ignore="ContentDescription"
|
||||
android:visibility="invisible"/>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
|
||||
@@ -108,21 +108,20 @@
|
||||
android:background="#FFDCDCF0"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<!-- <Button-->
|
||||
<!-- android:id="@+id/btnAddGoods"-->
|
||||
<!-- android:layout_width="240dp"-->
|
||||
<!-- android:layout_height="80dp"-->
|
||||
<!-- android:background="@drawable/bg_white_stroke_blue_ripple"-->
|
||||
<!-- android:text="添加物品"-->
|
||||
<!-- android:textColor="#FF0033CC"-->
|
||||
<!-- android:textSize="30sp"-->
|
||||
<!-- android:textStyle="bold"-->
|
||||
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||
<!-- app:layout_constraintEnd_toStartOf="@+id/btnConfirm"-->
|
||||
<!-- app:layout_constraintHorizontal_chainStyle="packed"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toTopOf="@id/dividerLine"-->
|
||||
<!-- android:visibility="gone"/>-->
|
||||
<Button
|
||||
android:id="@+id/btnAddGoods"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_white_stroke_blue_ripple"
|
||||
android:text="添加物品"
|
||||
android:textColor="#FF0033CC"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/btnConfirm"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/dividerLine" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnConfirm"
|
||||
@@ -133,9 +132,10 @@
|
||||
android:textColor="@color/white"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginStart="30dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/btnAddGoods"
|
||||
app:layout_constraintTop_toTopOf="@id/dividerLine" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -170,6 +170,7 @@
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvCountUnit"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<androidx.camera.view.PreviewView
|
||||
android:id="@+id/previewView"
|
||||
android:layout_width="428dp"
|
||||
android:layout_height="320dp"
|
||||
android:layout_gravity="center"/>
|
||||
</merge>
|
||||
@@ -4,6 +4,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="10dp"
|
||||
android:padding="2dp"
|
||||
android:background="@drawable/bg_selector_radius12_stroke2"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<ImageView
|
||||
|
||||
Reference in New Issue
Block a user