初始代码提交
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
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.ImageView
|
||||
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.R
|
||||
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.BitmapCropper
|
||||
import com.sw.inbound.utils.BitmapSaver
|
||||
import com.sw.inbound.utils.CameraUtils
|
||||
import com.sw.inbound.utils.ImageUtil
|
||||
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
|
||||
private val cameraUtils: CameraUtils by lazy {
|
||||
CameraUtils(activity!!)
|
||||
}
|
||||
|
||||
override fun show() {
|
||||
super.show()
|
||||
cameraUtils.setPreviewController(previewView)
|
||||
cameraUtils.bind()
|
||||
window?.decorView?.postDelayed({
|
||||
binding.llCameraFlag.gone()
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
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()
|
||||
activity?.unBindCamera()
|
||||
setOnDismissListener {
|
||||
cameraUtils.unbind()
|
||||
}
|
||||
cameraUtils.initCamera()
|
||||
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 {
|
||||
cameraUtils.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,
|
||||
arrowImage = binding.ivProcurementArrow,
|
||||
list = GlobalData.unitTypeList,
|
||||
height = 2 * 71.dp
|
||||
)
|
||||
// showDropDownList(
|
||||
// binding.flGoodsType,
|
||||
// textView = binding.tvGoodsType,
|
||||
// list = GlobalData.goodsTypeList,
|
||||
// )
|
||||
showDropDownList(
|
||||
binding.flStorageType,
|
||||
textView = binding.tvStorageType,
|
||||
arrowImage = binding.ivStorageArrow,
|
||||
list = GlobalData.storageTypeList,
|
||||
)
|
||||
showDropDownList(
|
||||
dropdownView = binding.flWarehouseUnit,
|
||||
textView = binding.tvWarehouseUnit,
|
||||
arrowImage = binding.ivWarehouseArrow,
|
||||
list = GlobalData.unitTypeList,
|
||||
height = 3 * 71.dp
|
||||
) {
|
||||
binding.tvSelectUseUnit.text = it.value
|
||||
binding.tvSelectProcurementUnit.text = it.value
|
||||
}
|
||||
}
|
||||
|
||||
private fun showDropDownList(
|
||||
dropdownView: FrameLayout,
|
||||
textView: TextView,
|
||||
arrowImage: ImageView,
|
||||
list: List<DictType>,
|
||||
height: Int = 355.dp,
|
||||
block: (DictType) -> Unit = {}
|
||||
) {
|
||||
dropdownView.setOnClickListener { v ->
|
||||
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)
|
||||
}.also {
|
||||
it.arrowImage = arrowImage
|
||||
it.bgLayout = dropdownView
|
||||
}
|
||||
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
|
||||
if (goodsType == null || goodsType.toString().isBlank()) {
|
||||
context.toast("请录入物品类型")
|
||||
return
|
||||
}
|
||||
val storageType = binding.tvStorageType.tag
|
||||
if (storageType == null || storageType.toString().isBlank()) {
|
||||
context.toast("请录入存储方式")
|
||||
return
|
||||
}
|
||||
val warehouseUnit = binding.tvWarehouseUnit.tag
|
||||
if (warehouseUnit == null || warehouseUnit.toString().isBlank()) {
|
||||
context.toast("请录入库存单位")
|
||||
return
|
||||
}
|
||||
val purchaseUnit = binding.tvProcurementUnit.tag
|
||||
if (purchaseUnit == null || purchaseUnit.toString().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.toString(),
|
||||
storageType = storageType.toString(),
|
||||
unitId = warehouseUnit.toString(),
|
||||
consumeValue = costValue,
|
||||
purchaseUnit = purchaseUnit.toString(),
|
||||
purchaseValue = goodsCount.toSafeFloat(),
|
||||
purchasePrice = goodsPrice.toSafeBigDecimal(),
|
||||
)
|
||||
activity?.let {
|
||||
Loading.show(it)
|
||||
}
|
||||
ImageUtil.uriToBitmap(context, imageUri!!)?.let { bitmap ->
|
||||
val newBmp = BitmapCropper.cropCenter(
|
||||
original = bitmap,
|
||||
targetWidth = 1000, targetHeight = 1300,
|
||||
offsetX = 30, offsetY = 100
|
||||
)
|
||||
val file = BitmapSaver.saveToAppFilesDir(
|
||||
newBmp,
|
||||
context,
|
||||
"IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
)
|
||||
if(file == null) {
|
||||
context.toast("请重新拍照后再试")
|
||||
Loading.dismiss()
|
||||
return@let
|
||||
}
|
||||
activity?.createNewGoods(file, param) {
|
||||
Loading.dismiss()
|
||||
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)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//package com.sw.inbound.dialog
|
||||
//
|
||||
//import android.content.Context
|
||||
//import android.view.LayoutInflater
|
||||
//import android.view.View
|
||||
//import com.sw.inbound.databinding.DialogAddProcurementUnitBinding
|
||||
//
|
||||
//class AddProcurementUnitDialog(
|
||||
// context: Context,
|
||||
// var cancelBlock: () -> Unit = {},
|
||||
// var confirmBlock: () -> Unit = {},
|
||||
//) : BaseDialog(context) {
|
||||
//
|
||||
// private lateinit var binding: DialogAddProcurementUnitBinding
|
||||
// override fun getRootView(): View {
|
||||
// val inflater = LayoutInflater.from(context)
|
||||
// binding = DialogAddProcurementUnitBinding.inflate(inflater)
|
||||
// return binding.root
|
||||
// }
|
||||
//
|
||||
// override fun initView() {
|
||||
// binding.tvSelectUnit.text = "箱"
|
||||
// binding.btnCancel.setOnClickListener {
|
||||
// cancelBlock()
|
||||
// dismiss()
|
||||
// }
|
||||
// binding.btnConfirm.setOnClickListener {
|
||||
// confirmBlock()
|
||||
// dismiss()
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.activity.FoodCollectionActivity
|
||||
import com.sw.inbound.activity.GoodsListActivity
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
import com.sw.inbound.utils.ext.hideKeyboard
|
||||
|
||||
abstract class BaseDialog(
|
||||
context: Context,
|
||||
var defWidth: Int = 1500.dp,
|
||||
var defHeight: Int = 900.dp
|
||||
) : Dialog(context, R.style.DialogTheme) {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val rootView = getRootView()
|
||||
setContentView(rootView)
|
||||
setCancelable(false)
|
||||
setCanceledOnTouchOutside(false)
|
||||
window?.apply {
|
||||
setLayout(defWidth, defHeight)
|
||||
setBackgroundDrawable(ColorDrawable())
|
||||
setGravity(Gravity.CENTER)
|
||||
}
|
||||
rootView.setOnClickListener { it.hideKeyboard() }
|
||||
initView()
|
||||
}
|
||||
|
||||
abstract fun getRootView(): View
|
||||
|
||||
abstract fun initView()
|
||||
|
||||
fun getReceiptActivity(): GoodsListActivity? {
|
||||
var ctx = context
|
||||
while (ctx is ContextWrapper) {
|
||||
ctx = ctx.baseContext
|
||||
if (ctx is GoodsListActivity) {
|
||||
return ctx
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun getFoodCollectionActivity(): FoodCollectionActivity? {
|
||||
var ctx = context
|
||||
while (ctx is ContextWrapper) {
|
||||
ctx = ctx.baseContext
|
||||
if (ctx is FoodCollectionActivity) {
|
||||
return ctx
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun show() {
|
||||
super.show()
|
||||
DialogManager.addDialog(this)
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
super.dismiss()
|
||||
DialogManager.removeDialog(this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.activity.FoodCollectionActivity
|
||||
import com.sw.inbound.adapter.CollectSearchAdapter
|
||||
import com.sw.inbound.databinding.DialogCollectSearchBinding
|
||||
import com.sw.inbound.databinding.LayoutEmptySearchBinding
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.objbox.Food
|
||||
import com.sw.inbound.objbox.ObjectBox
|
||||
import com.sw.inbound.utils.ext.addOnActionSearchListener
|
||||
import com.sw.inbound.utils.ext.hideKeyboard
|
||||
import com.sw.inbound.utils.ext.toast
|
||||
import com.sw.inbound.viewmodel.ReceiptViewModel
|
||||
import io.objectbox.Box
|
||||
import io.objectbox.kotlin.boxFor
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
class CollectSearchDialog(
|
||||
context: Context
|
||||
) : BaseDialog(context) {
|
||||
|
||||
private lateinit var inflater: LayoutInflater
|
||||
private var emptyBinding: LayoutEmptySearchBinding? = null
|
||||
private lateinit var binding: DialogCollectSearchBinding
|
||||
override fun getRootView(): View {
|
||||
inflater = LayoutInflater.from(context)
|
||||
binding = DialogCollectSearchBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private var activity: FoodCollectionActivity? = null
|
||||
override fun initView() {
|
||||
activity = getFoodCollectionActivity()
|
||||
binding.ivClose.setOnClickListener { dismiss() }
|
||||
binding.ivGoodsSearch.setOnClickListener {
|
||||
val searchName = binding.etInputGoods.text.toString().trim()
|
||||
if (searchName.isBlank()) {
|
||||
activity?.toast("请输入物品名称")
|
||||
return@setOnClickListener
|
||||
}
|
||||
getCollectGoods(searchName)
|
||||
}
|
||||
binding.etInputGoods.let { v ->
|
||||
v.addOnActionSearchListener {
|
||||
val searchName = binding.etInputGoods.text.toString().trim()
|
||||
if (searchName.isBlank()) {
|
||||
activity?.toast("请输入物品名称")
|
||||
return@addOnActionSearchListener
|
||||
}
|
||||
getCollectGoods(searchName)
|
||||
}
|
||||
v.addTextChangedListener {
|
||||
if (it.isNullOrBlank()) {
|
||||
getCollectGoods()
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.btnConfirm.setOnClickListener {
|
||||
if (clickIndex == -1) {
|
||||
dismiss()
|
||||
return@setOnClickListener
|
||||
}
|
||||
deleteGoods(clickIndex) {
|
||||
it.postDelayed({dismiss()}, 500)
|
||||
}
|
||||
}
|
||||
binding.rvSearch.let {
|
||||
it.layoutManager = GridLayoutManager(context, 2, LinearLayoutManager.VERTICAL, false)
|
||||
it.adapter = searchAdapter
|
||||
}
|
||||
binding.refreshLayout.let {
|
||||
it.setEnableRefresh(true)
|
||||
it.setEnableLoadMore(false)
|
||||
it.setOnRefreshListener {
|
||||
pageNo = 1
|
||||
val searchName = binding.etInputGoods.text.toString().trim()
|
||||
getCollectGoods(searchName)
|
||||
}
|
||||
//it.setOnLoadMoreListener {
|
||||
// searchGoods()
|
||||
//}
|
||||
}
|
||||
getCollectGoods()
|
||||
//binding.root.clickWithDebounce {
|
||||
// Thread {
|
||||
// FoodModule.initDefFoodData(activity!!) {
|
||||
// activity?.runOnUiThread {
|
||||
// activity?.toast("添加完成")
|
||||
// getCollectGoods()
|
||||
// }
|
||||
// }
|
||||
// }.start()
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
private var pageNo = 1
|
||||
|
||||
private fun loadEmptyView() {
|
||||
binding.rvSearch.layoutManager =
|
||||
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
if (emptyBinding == null) {
|
||||
emptyBinding = LayoutEmptySearchBinding.inflate(inflater, binding.rvSearch, false)
|
||||
}
|
||||
emptyBinding?.tvContent?.text = "请检查物品名称,或稍后重新搜索"
|
||||
emptyBinding?.root?.let { layout ->
|
||||
layout.setOnClickListener { layout.hideKeyboard() }
|
||||
searchAdapter.stateView = layout
|
||||
}
|
||||
}
|
||||
|
||||
private var clickIndex = -1
|
||||
|
||||
private val list: MutableList<SearchGoodsInfo.Record> = mutableListOf()
|
||||
private val searchAdapter by lazy {
|
||||
CollectSearchAdapter(list).apply {
|
||||
isStateViewEnable = true
|
||||
//setOnItemClickListener { _, _, position ->
|
||||
// this@CollectSearchDialog.clickIndex = position
|
||||
// if (list[position].isSelected) {
|
||||
// return@setOnItemClickListener
|
||||
// }
|
||||
// list.forEach { item ->
|
||||
// item.isSelected = false
|
||||
// }
|
||||
// list[position].isSelected = true
|
||||
// notifyDataSetChanged()
|
||||
//}
|
||||
addOnItemChildClickListener(R.id.ivDelete) { _, _, position ->
|
||||
this@CollectSearchDialog.clickIndex = position
|
||||
list.forEach { item ->
|
||||
item.isSelected = false
|
||||
}
|
||||
list[position].isSelected = true
|
||||
notifyDataSetChanged()
|
||||
deleteGoods(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteGoods(position: Int, deleteAction:()-> Unit = {}) {
|
||||
WarnDialog(
|
||||
context = context,
|
||||
content = "请确认是否删除物品:${list[position].goodsName}?",
|
||||
confirmBlock = {
|
||||
Thread {
|
||||
activity?.runOnUiThread {
|
||||
Loading.show(activity!!)
|
||||
}
|
||||
val name = list[position].goodsName
|
||||
val filterIdList = box?.all?.filter { it.name == name }?.map { it.id }
|
||||
ObjectBox.boxStore.runInTx {
|
||||
box?.removeByIds(filterIdList)
|
||||
}
|
||||
activity?.runOnUiThread {
|
||||
Loading.dismiss()
|
||||
//list.remove(list[position])
|
||||
//searchAdapter.notifyDataSetChanged()
|
||||
searchAdapter.removeAt(position)
|
||||
activity?.toast("删除成功")
|
||||
if (list.isEmpty()) {
|
||||
loadEmptyView()
|
||||
}
|
||||
deleteAction()
|
||||
}
|
||||
}.start()
|
||||
}).show()
|
||||
}
|
||||
|
||||
private fun finishRefresh() {
|
||||
binding.refreshLayout.let {
|
||||
if (pageNo == 1) {
|
||||
it.finishRefresh(500)
|
||||
} else {
|
||||
it.finishLoadMore(500)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var box: Box<Food>? = null
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun getCollectGoods(searchName: String? = null) {
|
||||
if (box == null) {
|
||||
box = ObjectBox.boxStore.boxFor(Food::class)
|
||||
}
|
||||
list.clear()
|
||||
var queryList = box?.all?.distinctBy { it.name }
|
||||
if (searchName.isNullOrBlank().not()) {
|
||||
queryList = queryList?.filter { it.name?.contains(searchName!!) == true }
|
||||
}
|
||||
queryList?.forEach {
|
||||
list.add((SearchGoodsInfo.Record(goodsName = it.name)))
|
||||
}
|
||||
binding.rvSearch.layoutManager =
|
||||
GridLayoutManager(activity, 2, LinearLayoutManager.VERTICAL, false)
|
||||
searchAdapter.notifyDataSetChanged()
|
||||
if (list.isEmpty()) {
|
||||
loadEmptyView()
|
||||
}
|
||||
finishRefresh()
|
||||
binding.root.hideKeyboard()
|
||||
}
|
||||
|
||||
// fun test() {
|
||||
// val goodsName = "多宝鱼,黑鱼(整条鱼),鸡腿肉"
|
||||
// activity?.searchGoodsInfoList(goodsName = goodsName) { items->
|
||||
// items.forEach { goods ->
|
||||
// box?.all?.filter {
|
||||
// it.name?.contains(goods.goodsName?:"-") == true
|
||||
// }?.forEach {
|
||||
// activity?.runOnUiThread {
|
||||
// activity?.toast(goods.goodsName)
|
||||
// }
|
||||
// it.name = goods.goodsName + goods.goodsCode
|
||||
// box?.put(it)
|
||||
// }
|
||||
// }
|
||||
//// activity?.runOnUiThread {
|
||||
//// activity?.toast("已保存")
|
||||
//// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.sw.inbound.dialog;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sw.inbound.R;
|
||||
|
||||
/**
|
||||
* 加载进度条弹窗
|
||||
*/
|
||||
public class CustomDialog extends Dialog {
|
||||
|
||||
|
||||
/**
|
||||
* 宽高由布局文件中指定(但是最底层的宽度无效,可以多嵌套一层解决)
|
||||
*/
|
||||
public CustomDialog(Context context, View layout, int style) {
|
||||
|
||||
super(context, style);
|
||||
|
||||
setContentView(layout);
|
||||
|
||||
Window window = getWindow();
|
||||
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
|
||||
params.gravity = Gravity.CENTER;
|
||||
|
||||
window.setAttributes(params);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 宽高由该方法的参数设置
|
||||
*/
|
||||
public CustomDialog(Context context, int width, int height, View layout,
|
||||
int style) {
|
||||
super(context, style);
|
||||
// 设置内容
|
||||
setContentView(layout);
|
||||
// 设置窗口属性
|
||||
Window window = getWindow();
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
// 设置宽度、高度、密度、对齐方式
|
||||
float density = getDensity(context);
|
||||
params.width = (int) (width * density);
|
||||
params.height = (int) (height * density);
|
||||
params.gravity = Gravity.CENTER;
|
||||
window.setAttributes(params);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取显示密度
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public float getDensity(Context context) {
|
||||
Resources res = context.getResources();
|
||||
DisplayMetrics dm = res.getDisplayMetrics();
|
||||
return dm.density;
|
||||
}
|
||||
|
||||
private void fullScreenImmersive(View view) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
view.setSystemUiVisibility(uiOptions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public void show() {
|
||||
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||
super.show();
|
||||
// fullScreenImmersive(getWindow().getDecorView());
|
||||
// this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
object DialogManager {
|
||||
|
||||
private var dialogList: MutableList<BaseDialog> = mutableListOf()
|
||||
|
||||
fun addDialog(dialog: BaseDialog) {
|
||||
if (dialogList.contains(dialog).not()) {
|
||||
val className = dialog.javaClass.simpleName
|
||||
val item = dialogList.firstOrNull { it.javaClass.simpleName == className }
|
||||
item?.dismiss()
|
||||
dialogList.add(dialog)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeDialog(dialog: BaseDialog) {
|
||||
dialogList.remove(dialog)
|
||||
}
|
||||
|
||||
fun getDialogList(): MutableList<BaseDialog> {
|
||||
return dialogList
|
||||
}
|
||||
|
||||
fun dismissAll() {
|
||||
dialogList.forEach {
|
||||
it.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
fun dismissAllExcept(dialog: BaseDialog) {
|
||||
dialogList.forEach {
|
||||
if (it != dialog) {
|
||||
it.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun contains(vararg className: String): Boolean {
|
||||
val item = dialogList.firstOrNull { className.contains(it.javaClass.simpleName) }
|
||||
return item != null
|
||||
}
|
||||
|
||||
fun hasShowDialog(): Boolean {
|
||||
val item = dialogList.firstOrNull { it.isShowing }
|
||||
return item != null
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.PopupWindow
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.adapter.DropdownAdapter
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
|
||||
class DropdownPopup(
|
||||
var context: Context,
|
||||
var list: MutableList<DictType>,
|
||||
var popWidth: Int = 280.dp,
|
||||
var popHeight: Int = 284.dp,
|
||||
var onPopupItemClick: (DictType) -> Unit
|
||||
) : PopupWindow() {
|
||||
|
||||
init {
|
||||
// 初始化PopupWindow
|
||||
val popupView = LayoutInflater.from(context).inflate(R.layout.layout_popup_dropdown, null)
|
||||
contentView = popupView
|
||||
width = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
// 设置透明背景,避免覆盖圆角
|
||||
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
|
||||
isOutsideTouchable = true
|
||||
isFocusable = true
|
||||
|
||||
// 设置动画样式
|
||||
// animationStyle = R.style.PopupAnimation
|
||||
|
||||
// 初始化视图和事件
|
||||
initViews(popupView)
|
||||
}
|
||||
|
||||
private fun initViews(view: View) {
|
||||
// 获取关闭按钮并设置点击事件
|
||||
view.findViewById<RecyclerView>(R.id.rvWarehouse)?.let {
|
||||
it.updateLayoutParams {
|
||||
width = popWidth
|
||||
height = popHeight
|
||||
}
|
||||
it.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
it.adapter = DropdownAdapter(list).setOnItemClickListener { adapter, view, position ->
|
||||
onPopupItemClick(list[position])
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var arrowImage: ImageView? = null
|
||||
|
||||
var bgLayout: ViewGroup? = null
|
||||
|
||||
var defLayoutBgResId = R.drawable.bg_white_radius10_stroke2
|
||||
|
||||
override fun showAsDropDown(anchor: View?) {
|
||||
super.showAsDropDown(anchor)
|
||||
bgLayout?.setBackgroundResource(R.drawable.bg_white_stroke_blue)
|
||||
arrowImage?.setImageResource(R.mipmap.ic_triangle_up)
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
super.dismiss()
|
||||
bgLayout?.setBackgroundResource(defLayoutBgResId)
|
||||
arrowImage?.setImageResource(R.mipmap.ic_triangle_down)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.sw.inbound.activity.GoodsListActivity
|
||||
import com.sw.inbound.adapter.RecognizeAdapter
|
||||
import com.sw.inbound.databinding.DialogGoodsRecognizeBinding
|
||||
import com.sw.inbound.databinding.LayoutEmptyRecognizeBinding
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.utils.ext.gone
|
||||
import com.sw.inbound.utils.ext.toast
|
||||
import com.sw.inbound.utils.ext.visible
|
||||
import java.io.File
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
class GoodsRecognizeDialog(
|
||||
context: Context,
|
||||
var goodsFile: File? = null,
|
||||
var goodsName: String? = null,
|
||||
var list: MutableList<SearchGoodsInfo.Record>,
|
||||
//var closeCallback:()->Unit,
|
||||
var findGoods: () -> Unit
|
||||
) : BaseDialog(context) {
|
||||
|
||||
private lateinit var binding: DialogGoodsRecognizeBinding
|
||||
private lateinit var inflater: LayoutInflater
|
||||
override fun getRootView(): View {
|
||||
inflater = LayoutInflater.from(context)
|
||||
binding = DialogGoodsRecognizeBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
// override fun show() {
|
||||
// super.show()
|
||||
// binding.ivGoods.load(goodsFile)
|
||||
// binding.tvGoods.text = goodsName
|
||||
// }
|
||||
|
||||
private val recognizeAdapter by lazy {
|
||||
RecognizeAdapter(list).apply {
|
||||
// isStateViewEnable = true
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
if (list[position].isSelected) {
|
||||
showGoodsStoreDialog(position)
|
||||
return@setOnItemClickListener
|
||||
}
|
||||
list.forEach { item ->
|
||||
item.isSelected = false
|
||||
}
|
||||
list[position].isSelected = true
|
||||
notifyDataSetChanged()
|
||||
showGoodsStoreDialog(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showGoodsStoreDialog(position: Int) {
|
||||
GoodsStoreDialog(
|
||||
context = context,
|
||||
funcType = 0,
|
||||
goods = list[position]
|
||||
) {
|
||||
activity?.addGoods(it)
|
||||
//activity?.startTime = System.currentTimeMillis()
|
||||
dismiss()
|
||||
}.show()
|
||||
}
|
||||
|
||||
private var activity: GoodsListActivity? = null
|
||||
override fun initView() {
|
||||
activity = getReceiptActivity()
|
||||
binding.rvRecognize.let {
|
||||
it.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
it.adapter = recognizeAdapter
|
||||
}
|
||||
val isEmpty = list.isEmpty()
|
||||
if (isEmpty) {
|
||||
// loadEmptyView()
|
||||
binding.rvRecognize.gone()
|
||||
binding.flEmptyLayout.visible()
|
||||
} else {
|
||||
binding.rvRecognize.visible()
|
||||
binding.flEmptyLayout.gone()
|
||||
}
|
||||
// if (recognizeAdapter.list.isEmpty()) {
|
||||
// loadEmptyView()
|
||||
// }
|
||||
binding.ivClose.setOnClickListener {
|
||||
dismiss()
|
||||
activity?.delayRecognizeFood()
|
||||
//activity?.startTime = System.currentTimeMillis()
|
||||
}
|
||||
binding.btnManuallyFind.setOnClickListener {
|
||||
findGoods()
|
||||
//dismiss()
|
||||
}
|
||||
binding.btnAgainRecognize.setOnClickListener {
|
||||
//dismiss()
|
||||
activity?.againRecognizeFood { goodsList ->
|
||||
//binding.rvRecognize.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
if (goodsList.isEmpty()) {
|
||||
// loadEmptyView()
|
||||
binding.rvRecognize.gone()
|
||||
binding.flEmptyLayout.visible()
|
||||
return@againRecognizeFood
|
||||
}
|
||||
list.clear()
|
||||
list.addAll(goodsList)
|
||||
// recognizeAdapter.isStateViewEnable = false
|
||||
recognizeAdapter.notifyDataSetChanged()
|
||||
|
||||
binding.rvRecognize.visible()
|
||||
binding.flEmptyLayout.gone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private var emptyBinding: LayoutEmptyRecognizeBinding? = null
|
||||
private fun loadEmptyView() {
|
||||
// if (emptyBinding == null) {
|
||||
// emptyBinding = LayoutEmptyRecognizeBinding.inflate(inflater, binding.flEmptyLayout, false)
|
||||
// }
|
||||
// binding.flEmptyLayout.removeAllViews()
|
||||
// emptyBinding?.root.let {
|
||||
// binding.flEmptyLayout.addView(it)
|
||||
// }
|
||||
binding.rvRecognize.gone()
|
||||
binding.flEmptyLayout.visible()
|
||||
// emptyBinding?.root?.let {
|
||||
// recognizeAdapter.isStateViewEnable = true
|
||||
// recognizeAdapter.stateView = it
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
override fun dismiss() {
|
||||
super.dismiss()
|
||||
activity?.run {
|
||||
isShowRecognizeDialog = true
|
||||
goodsRecognizeDialog = null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.sw.inbound.activity.GoodsListActivity
|
||||
import com.sw.inbound.adapter.GoodsSearchAdapter
|
||||
import com.sw.inbound.databinding.DialogGoodsSearchBinding
|
||||
import com.sw.inbound.databinding.LayoutEmptySearchBinding
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.utils.ext.addOnActionSearchListener
|
||||
import com.sw.inbound.utils.ext.hideKeyboard
|
||||
import com.sw.inbound.utils.ext.toast
|
||||
|
||||
class GoodsSearchDialog(
|
||||
context: Context
|
||||
) : BaseDialog(context) {
|
||||
|
||||
private lateinit var inflater: LayoutInflater
|
||||
private var emptyBinding: LayoutEmptySearchBinding? = null
|
||||
private lateinit var binding: DialogGoodsSearchBinding
|
||||
override fun getRootView(): View {
|
||||
inflater = LayoutInflater.from(context)
|
||||
binding = DialogGoodsSearchBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private var activity: GoodsListActivity? = null
|
||||
override fun initView() {
|
||||
activity = getReceiptActivity()
|
||||
binding.ivClose.setOnClickListener { dismiss() }
|
||||
binding.ivGoodsSearch.setOnClickListener { searchGoods() }
|
||||
binding.etInputGoods.let { v ->
|
||||
v.addOnActionSearchListener {
|
||||
searchGoods()
|
||||
}
|
||||
}
|
||||
binding.btnAddGoods.setOnClickListener {
|
||||
AddGoodsDialog(
|
||||
context = context,
|
||||
cancelBlock = {},
|
||||
confirmBlock = { goodsName->
|
||||
pageNo = 1
|
||||
binding.etInputGoods.setText(goodsName)
|
||||
searchGoods()
|
||||
}
|
||||
).apply {
|
||||
setOnDismissListener {
|
||||
//activity?.bindCamera()
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
binding.btnConfirm.setOnClickListener {
|
||||
if (list.isEmpty()) {
|
||||
context.toast("请搜索物品")
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (clickIndex == -1) {
|
||||
context.toast("请选择物品")
|
||||
return@setOnClickListener
|
||||
}
|
||||
GoodsStoreDialog(
|
||||
context = context,
|
||||
funcType = 1,
|
||||
goods = list[clickIndex]
|
||||
) {
|
||||
activity?.addGoods(it)
|
||||
//activity?.startTime = System.currentTimeMillis()
|
||||
activity?.goodsRecognizeDialog?.dismiss()
|
||||
dismiss()
|
||||
}.show()
|
||||
}
|
||||
binding.rvSearch.let {
|
||||
it.layoutManager = GridLayoutManager(context, 2, LinearLayoutManager.VERTICAL, false)
|
||||
it.adapter = searchAdapter
|
||||
}
|
||||
binding.refreshLayout.let {
|
||||
it.setEnableRefresh(true)
|
||||
it.setEnableLoadMore(false)
|
||||
it.setOnRefreshListener {
|
||||
pageNo = 1
|
||||
searchGoods()
|
||||
}
|
||||
it.setOnLoadMoreListener {
|
||||
searchGoods()
|
||||
}
|
||||
}
|
||||
loadEmptyView()
|
||||
}
|
||||
|
||||
private var pageNo = 1
|
||||
|
||||
companion object {
|
||||
private const val PAGE_SIZE = 10
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun searchGoods() {
|
||||
val searchName = binding.etInputGoods.text.toString().trim()
|
||||
if (searchName.isBlank()) {
|
||||
activity?.toast("请输入物品名称")
|
||||
finishRefresh()
|
||||
return
|
||||
}
|
||||
activity?.searchGoods(
|
||||
searchName = searchName,
|
||||
pageNo = pageNo,
|
||||
pageSize = PAGE_SIZE
|
||||
) { records ->
|
||||
finishRefresh()
|
||||
binding.etInputGoods.hideKeyboard()
|
||||
if (pageNo == 1) {
|
||||
list.clear()
|
||||
}
|
||||
list.addAll(records)
|
||||
if (list.isEmpty()) {
|
||||
loadEmptyView()
|
||||
return@searchGoods
|
||||
}
|
||||
val enableLoadMore = records.size >= PAGE_SIZE
|
||||
binding.refreshLayout.setEnableLoadMore(enableLoadMore)
|
||||
if (enableLoadMore) {
|
||||
pageNo++
|
||||
}
|
||||
binding.rvSearch.layoutManager =
|
||||
GridLayoutManager(context, 2, GridLayoutManager.VERTICAL, false)
|
||||
searchAdapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadEmptyView() {
|
||||
binding.rvSearch.layoutManager =
|
||||
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
if (emptyBinding == null) {
|
||||
emptyBinding = LayoutEmptySearchBinding.inflate(inflater, binding.rvSearch, false)
|
||||
}
|
||||
emptyBinding?.root?.let { layout ->
|
||||
layout.setOnClickListener { layout.hideKeyboard() }
|
||||
searchAdapter.stateView = layout
|
||||
}
|
||||
}
|
||||
|
||||
private var clickIndex = -1
|
||||
|
||||
private val list: MutableList<SearchGoodsInfo.Record> = mutableListOf()
|
||||
private val searchAdapter by lazy {
|
||||
GoodsSearchAdapter(list).apply {
|
||||
isStateViewEnable = true
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
this@GoodsSearchDialog.clickIndex = position
|
||||
if (list[position].isSelected) {
|
||||
return@setOnItemClickListener
|
||||
}
|
||||
list.forEach { item ->
|
||||
item.isSelected = false
|
||||
}
|
||||
list[position].isSelected = true
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun finishRefresh() {
|
||||
binding.refreshLayout.let {
|
||||
if (pageNo == 1) {
|
||||
it.finishRefresh(500)
|
||||
} else {
|
||||
it.finishLoadMore(500)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,471 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import android.net.Uri
|
||||
import android.text.InputType
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.text.style.StyleSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import androidx.camera.view.PreviewView
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import coil.load
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import com.sw.inbound.utils.ext.appendText
|
||||
import com.sw.inbound.utils.ext.buildSpannableString
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.activity.GoodsListActivity
|
||||
import com.sw.inbound.databinding.DialogGoodsStoreBinding
|
||||
import com.sw.inbound.databinding.LayoutImagePreviewBinding
|
||||
import com.sw.inbound.databinding.LayoutTakePhotoBinding
|
||||
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.Food
|
||||
import com.sw.inbound.objbox.FoodModule
|
||||
import com.sw.inbound.objbox.ObjectBox
|
||||
import com.sw.inbound.sdk.SensorScaleUtils
|
||||
import com.sw.inbound.utils.BitmapCropper
|
||||
import com.sw.inbound.utils.BitmapSaver
|
||||
import com.sw.inbound.utils.CameraUtils
|
||||
import com.sw.inbound.utils.ImageUtil
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
import com.sw.inbound.utils.ext.gone
|
||||
import com.sw.inbound.utils.ext.roundedDecimalPlace
|
||||
import com.sw.inbound.utils.ext.toast
|
||||
import com.sw.inbound.utils.ext.visible
|
||||
import com.sw.inbound.utils.removeTrailingZeros
|
||||
import io.objectbox.Box
|
||||
import io.objectbox.kotlin.boxFor
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import kotlin.Int
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.min
|
||||
|
||||
class GoodsStoreDialog(
|
||||
context: Context,
|
||||
var goods: SearchGoodsInfo.Record,
|
||||
var funcType: Int,
|
||||
var cancelBlock: () -> Unit = {},
|
||||
var confirmBlock: (GoodsInfo) -> Unit = {},
|
||||
) : BaseDialog(context) {
|
||||
|
||||
private lateinit var binding: DialogGoodsStoreBinding
|
||||
private lateinit var inflater: LayoutInflater
|
||||
override fun getRootView(): View {
|
||||
inflater = LayoutInflater.from(context)
|
||||
binding = DialogGoodsStoreBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private val dropdownList: MutableList<DictType> = mutableListOf()
|
||||
|
||||
private var dropdownPopup: DropdownPopup? = null
|
||||
private var realWeight: Int = 0
|
||||
private var activity: GoodsListActivity? = null
|
||||
override fun initView() {
|
||||
activity = getReceiptActivity()
|
||||
if (goods.unitVoList.isNullOrEmpty()) {
|
||||
activity?.toast("未匹配到合适的入库单位")
|
||||
dismiss()
|
||||
return
|
||||
}
|
||||
dropdownList.clear()
|
||||
goods.unitVoList!!.forEach {
|
||||
dropdownList.add(DictType(id = it.businessUnitId, value = it.purchaseUnitName))
|
||||
}
|
||||
//binding.etProcurementCount.isEnabled = false
|
||||
binding.etGoodsName.run {
|
||||
setText(goods.goodsName)
|
||||
isEnabled = false
|
||||
}
|
||||
//binding.ivGoodsImage.load(goods.relativeUrl)
|
||||
addChildToContainer()
|
||||
//flContainer
|
||||
binding.btnCancel.setOnClickListener {
|
||||
cancelBlock()
|
||||
dismiss()
|
||||
}
|
||||
binding.btnConfirm.setOnClickListener {
|
||||
confirmInputData()
|
||||
}
|
||||
binding.tvTitle.setOnClickListener {
|
||||
SensorScaleUtils.startScale(autoScale = true)
|
||||
}
|
||||
// binding.ivAddUnit.setOnClickListener {
|
||||
// AddProcurementUnitDialog(context).show()
|
||||
// }
|
||||
binding.flUnitDropdown.setOnClickListener { v ->
|
||||
if (dropdownPopup == null) {
|
||||
dropdownPopup = DropdownPopup(
|
||||
context = context,
|
||||
list = dropdownList,
|
||||
popWidth = 428.dp,
|
||||
popHeight = min(dropdownList.size, 4) * 71.dp
|
||||
) { dictType ->
|
||||
try {
|
||||
binding.tvProcurementUnit.run {
|
||||
text = dictType.value
|
||||
tag = dictType.id
|
||||
}
|
||||
val unit = dictType.value
|
||||
binding.tvCountUnit.text = unit
|
||||
binding.etProcurementCount.let {
|
||||
//it.isEnabled = true
|
||||
it.inputType = if (unit == "千克" || unit == "公斤" || unit == "斤") {
|
||||
InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
|
||||
} else {
|
||||
InputType.TYPE_CLASS_NUMBER
|
||||
}
|
||||
}
|
||||
val first = goods.unitVoList!!.first { it.businessUnitId == dictType.id }
|
||||
val stringBuilder =
|
||||
StringBuilder().append("1").append(dictType.value).append("=")
|
||||
.append(first.purchaseValue!!.toInt().toString())
|
||||
.append(goods.kcUnitName).append(",").append("1")
|
||||
.append(goods.kcUnitName).append("=").append(first.consumeValue)
|
||||
.append("克")
|
||||
binding.tvUnitCalculate.text = stringBuilder.toString()
|
||||
//val count = getUnitCount(dictType.id!!)
|
||||
//if (count.isBlank() || "0" == count) {
|
||||
// //context.toast("入库数量不能为0")
|
||||
// return@DropdownPopup
|
||||
//}
|
||||
//binding.etProcurementCount.let {
|
||||
// it.setText(count)
|
||||
// it.setSelection(it.length())
|
||||
//}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}.also {
|
||||
it.arrowImage = binding.ivDropdown
|
||||
it.bgLayout = binding.flUnitDropdown
|
||||
}
|
||||
}
|
||||
dropdownPopup?.showAsDropDown(v)
|
||||
}
|
||||
binding.btnClearZero.setOnClickListener {
|
||||
SensorScaleUtils.tare()
|
||||
}
|
||||
//addPriceInputListener(binding.etProcurementPrice) {
|
||||
// val countText = binding.etProcurementCount.text.trim().toString()
|
||||
// val count = if (countText.isNotBlank()) countText.toInt() else 0
|
||||
// val amount = (it * count).toFormattedString(2)
|
||||
// binding.etProcurementAmount.setText(amount)
|
||||
//}
|
||||
addPriceInputListener(binding.etProcurementAmount) {
|
||||
val countText = binding.etProcurementCount.text.trim().toString()
|
||||
val count = if (countText.isNotBlank()) countText.toDouble() else 0.toDouble()
|
||||
if (count == 0.toDouble()) {
|
||||
//context.toast("入库数量不能为0")
|
||||
return@addPriceInputListener
|
||||
}
|
||||
val price = (it / count).roundedDecimalPlace(2)
|
||||
binding.tvProcurementPrice.text = price.removeTrailingZeros()
|
||||
}
|
||||
binding.etProcurementCount.run {
|
||||
addTextChangedListener(onTextChanged = { it, _, _, _ ->
|
||||
try {
|
||||
if (it.isNullOrBlank()) {
|
||||
if (it.isNullOrBlank()) {
|
||||
binding.tvProcurementPrice.text = ""
|
||||
}
|
||||
return@addTextChangedListener
|
||||
}
|
||||
val amountText = binding.etProcurementAmount.text.toString().trim()
|
||||
if (amountText.isBlank()) {
|
||||
return@addTextChangedListener
|
||||
}
|
||||
val input = it.toString()
|
||||
val count = input.toDouble()
|
||||
if (count == 0.toDouble()) {
|
||||
//context.toast("入库数量不能为0")
|
||||
return@addTextChangedListener
|
||||
}
|
||||
val amount = amountText.toDouble()
|
||||
val price = (amount / count).roundedDecimalPlace(2)
|
||||
binding.tvProcurementPrice.text = price.removeTrailingZeros()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
})
|
||||
}
|
||||
addWeightListener()
|
||||
}
|
||||
|
||||
private fun addWeightListener() {
|
||||
activity?.readWeightInfo { weight ->
|
||||
if (abs(this.realWeight - weight) < 10 && binding.etProcurementCount.text.isNotBlank()) {
|
||||
//两次数据差在10克内,认为无变化,不进行操作
|
||||
return@readWeightInfo
|
||||
}
|
||||
this.realWeight = weight
|
||||
binding.tvTotalWeight.text = getSpannable(weight)
|
||||
if (binding.etProcurementCount.isFocused) {
|
||||
return@readWeightInfo
|
||||
}
|
||||
val unitTag = binding.tvProcurementUnit.tag
|
||||
if (unitTag == null || unitTag.toString().isBlank()) {
|
||||
return@readWeightInfo
|
||||
}
|
||||
val id = unitTag.toString()
|
||||
val count = getUnitCount(id)
|
||||
if (count.isBlank() || "0" == count) {
|
||||
binding.etProcurementCount.setText("")
|
||||
return@readWeightInfo
|
||||
}
|
||||
val currentCount = binding.etProcurementCount.text.toString().trim()
|
||||
if (currentCount == count) {
|
||||
return@readWeightInfo
|
||||
}
|
||||
binding.etProcurementCount.let {
|
||||
it.setText(count)
|
||||
it.setSelection(it.length())
|
||||
//it.isEnabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addPriceInputListener(editText: EditText, action: (Double) -> Unit) {
|
||||
editText.run {
|
||||
addTextChangedListener(onTextChanged = { it, _, _, _ ->
|
||||
try {
|
||||
if (it.isNullOrBlank()) {
|
||||
return@addTextChangedListener
|
||||
}
|
||||
val input = it.toString()
|
||||
if (input.startsWith(".")) {
|
||||
setText("0.")
|
||||
setSelection(length())
|
||||
} else if (input.contains(".")) {
|
||||
val index = input.indexOf(".")
|
||||
if (input.length - index > 3) {
|
||||
setText(input.substring(0, index + 3))
|
||||
setSelection(length())
|
||||
}
|
||||
}
|
||||
val value = if (input == "0.") 0.0 else input.toDouble()
|
||||
action(value)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSpannable(num: Int): SpannableStringBuilder {
|
||||
return buildSpannableString {
|
||||
appendText(
|
||||
num.toString(),
|
||||
ForegroundColorSpan("#FF141428".toColorInt()),
|
||||
StyleSpan(Typeface.BOLD)
|
||||
)
|
||||
appendText(
|
||||
" 克", ForegroundColorSpan("#FF000033".toColorInt()), StyleSpan(Typeface.BOLD)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun confirmInputData() {
|
||||
if (funcType == 1 && imageUri == null) {
|
||||
context.toast("请采集图片")
|
||||
return
|
||||
}
|
||||
val unit = binding.tvProcurementUnit.text.trim().toString()
|
||||
if (unit.isBlank()) {
|
||||
context.toast("请选择入库单位")
|
||||
return
|
||||
}
|
||||
val countText = binding.etProcurementCount.text.trim().toString()
|
||||
if (countText.isBlank() || "0" == countText) {
|
||||
context.toast("请录入入库数量")
|
||||
return
|
||||
}
|
||||
val amountText = binding.etProcurementAmount.text.trim().toString()
|
||||
if (amountText.isBlank()) {
|
||||
context.toast("请录入入库金额")
|
||||
return
|
||||
}
|
||||
val priceText = binding.tvProcurementPrice.text.trim().toString()
|
||||
if (priceText.isBlank()) {
|
||||
context.toast("请录入入库单价")
|
||||
return
|
||||
}
|
||||
if (realWeight <= 0) {
|
||||
context.toast("物品重量需大于0")
|
||||
return
|
||||
}
|
||||
val count = countText.toDoubleOrNull() ?: 0.toDouble()
|
||||
if (count == 0.toDouble()) {
|
||||
context.toast("入库数量不能为0")
|
||||
return
|
||||
}
|
||||
val price = priceText.toDoubleOrNull() ?: 0.toDouble()
|
||||
if (price == 0.toDouble()) {
|
||||
context.toast("入库单价不能为0")
|
||||
return
|
||||
}
|
||||
val totalPrice = amountText.toDoubleOrNull()
|
||||
if (totalPrice == 0.toDouble()) {
|
||||
context.toast("入库金额不能为0")
|
||||
return
|
||||
}
|
||||
if (funcType == 1) {
|
||||
collectGoodsVector()
|
||||
}
|
||||
val id = binding.tvProcurementUnit.tag.toString()
|
||||
val unitVo = goods.unitVoList!!.first { it.businessUnitId == id }
|
||||
activity?.uploadImage(goods.id!!, goods.goodsName!!, imageFile)
|
||||
confirmBlock(
|
||||
GoodsInfo(
|
||||
goodId = goods.id,
|
||||
goodName = goods.goodsName,
|
||||
consumeValue = goods.purchaseValue,
|
||||
//goodsPurId = binding.tvProcurementUnit.tag.toString(),
|
||||
kcUnitId = binding.tvProcurementUnit.tag.toString(),
|
||||
unitName = unit,
|
||||
//收货接口-数量
|
||||
receivedNum = count,
|
||||
//收货接口-单价(含税)
|
||||
recUnitPriceTaxIn = price,
|
||||
//收货接口-金额(含税)
|
||||
recPriceInItem = totalPrice,
|
||||
goodsWeight = realWeight.toBigDecimal(),
|
||||
isLocalGoods = true,
|
||||
|
||||
goodsCount = count,
|
||||
goodsUnitPrice = price,
|
||||
goodsPrice = totalPrice,
|
||||
buyToInventoryValue = unitVo.buyToInventoryValue,
|
||||
|
||||
unitHint = binding.tvUnitCalculate.text.toString()
|
||||
)
|
||||
)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
private fun getUnitCount(id: String): String {
|
||||
val first = goods.unitVoList!!.first { it.businessUnitId == id }
|
||||
val count = first.getPurchaseUnitValue(this.realWeight)
|
||||
return count
|
||||
}
|
||||
|
||||
private val cameraUtils: CameraUtils by lazy {
|
||||
CameraUtils(activity!!)
|
||||
}
|
||||
|
||||
override fun show() {
|
||||
super.show()
|
||||
if (funcType == 1) {
|
||||
takePhotoBinding?.let {
|
||||
cameraUtils.setPreviewController(previewView)
|
||||
cameraUtils.bind()
|
||||
it.llCameraFlag.run {
|
||||
postDelayed({
|
||||
gone()
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.root.postDelayed({
|
||||
SensorScaleUtils.startScale()
|
||||
}, 2600)
|
||||
}
|
||||
|
||||
private var imageUri: Uri? = null
|
||||
private val takePhotoCallback: (Uri) -> Unit = { uri ->
|
||||
takePhotoBinding?.let {
|
||||
imageUri = uri
|
||||
it.flCameraPreview.gone()
|
||||
it.cvImageBg.visible()
|
||||
it.ivGoodsImage.load(uri)
|
||||
}
|
||||
}
|
||||
|
||||
private var previewView: PreviewView? = null
|
||||
private var takePhotoBinding: LayoutTakePhotoBinding? = null
|
||||
private var imagePreviewBinding: LayoutImagePreviewBinding? = null
|
||||
private fun addChildToContainer() {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
if (funcType == 1) {
|
||||
//预览及拍照
|
||||
takePhotoBinding = LayoutTakePhotoBinding.inflate(inflater, binding.flContainer, true)
|
||||
activity?.unBindCamera()
|
||||
setOnDismissListener {
|
||||
cameraUtils.unbind()
|
||||
}
|
||||
cameraUtils.initCamera()
|
||||
takePhotoBinding?.let {
|
||||
previewView = it.previewView
|
||||
it.flCameraPreview.visible()
|
||||
it.cvImageBg.gone()
|
||||
it.btnStartPreview.setOnClickListener { _ ->
|
||||
it.cvImageBg.gone()
|
||||
it.flCameraPreview.visible()
|
||||
}
|
||||
it.btnTakePhoto.setOnClickListener { _ ->
|
||||
cameraUtils.takePhoto(takePhotoCallback)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
//只显示原始图片
|
||||
imagePreviewBinding = LayoutImagePreviewBinding.inflate(inflater, binding.flContainer)
|
||||
imagePreviewBinding?.imageView?.load(goods.relativeUrl) {
|
||||
transformations(RoundedCornersTransformation(radius = 10.dp.toFloat()))
|
||||
}
|
||||
binding.flContainer.let {
|
||||
it.setBackgroundResource(R.drawable.bg_white_radius10_stroke2)
|
||||
it.updateLayoutParams<LinearLayout.LayoutParams> {
|
||||
width = 488.dp
|
||||
height = 356.dp
|
||||
bottomMargin = 35.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
private var imageFile: File?=null
|
||||
private var box: Box<Food>? = null
|
||||
private fun collectGoodsVector() {
|
||||
try {
|
||||
ImageUtil.uriToBitmap(context, imageUri!!)?.let { bitmap ->
|
||||
val cropBitmap = BitmapCropper.cropCenter(
|
||||
original = bitmap,
|
||||
targetWidth = 1000,
|
||||
targetHeight = 1300,
|
||||
offsetX = 30,
|
||||
offsetY = 100
|
||||
)
|
||||
val file = BitmapSaver.saveToAppFilesDir(
|
||||
cropBitmap, context, "IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
)
|
||||
imageFile = file
|
||||
Timber.d("${this.javaClass.simpleName}-collectGoodsVector-裁剪bitmap保存文件路径:${file?.absolutePath}")
|
||||
if (box == null) {
|
||||
box = ObjectBox.boxStore.boxFor(Food::class)
|
||||
}
|
||||
Thread {
|
||||
try {
|
||||
val imageVector = FoodModule.bitmap2FloatArray(bitmap, true)
|
||||
if (imageVector != null) {
|
||||
ObjectBox.boxStore.runInTx {
|
||||
box?.put(Food(name = goods.goodsName + goods.goodsCode, foodIdx = 0, foodVector = imageVector))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.databinding.DialogLoadingBinding
|
||||
import kotlin.let
|
||||
import kotlin.run
|
||||
|
||||
object Loading {
|
||||
|
||||
private var dialog: LoadingDialog? = null
|
||||
|
||||
fun show(activity: Activity) {
|
||||
try {
|
||||
if (activity.isFinishing || activity.isDestroyed) {
|
||||
return
|
||||
}
|
||||
if (dialog?.isShowing == true) {
|
||||
dialog?.dismiss()
|
||||
}
|
||||
if (dialog == null) {
|
||||
dialog = LoadingDialog(activity)
|
||||
}
|
||||
dialog?.show()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun dismiss() {
|
||||
try {
|
||||
dialog?.let {
|
||||
if (it.isShowing) {
|
||||
it.dismiss()
|
||||
}
|
||||
}
|
||||
dialog = null
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class LoadingDialog(
|
||||
context: Context,
|
||||
message: String = "加载中……",
|
||||
private var onDismiss: () -> Unit = {}
|
||||
) : Dialog(context, R.style.LoadingDialog) {
|
||||
init {
|
||||
val binding = DialogLoadingBinding.inflate(LayoutInflater.from(context))
|
||||
binding.tvMessage.text = message
|
||||
setContentView(binding.root)
|
||||
setCancelable(true)
|
||||
setCanceledOnTouchOutside(true)
|
||||
window?.run {
|
||||
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
|
||||
// setFlags(
|
||||
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
||||
// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
// )
|
||||
}
|
||||
setOnDismissListener {
|
||||
onDismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//package com.sw.inbound.dialog
|
||||
//
|
||||
//import android.content.Context
|
||||
//import android.view.LayoutInflater
|
||||
//import android.view.View
|
||||
//import com.sw.inbound.databinding.DialogNotReceiptWarnBinding
|
||||
//import com.sw.inbound.utils.ext.dp
|
||||
//
|
||||
//class NotReceiptWarnDialog(
|
||||
// context: Context,
|
||||
// var cancelBlock: () -> Unit = {},
|
||||
// var confirmBlock: () -> Unit = {},
|
||||
//) : BaseDialog(context = context, defWidth = 960.dp, defHeight = 540.dp) {
|
||||
//
|
||||
// private lateinit var binding: DialogNotReceiptWarnBinding
|
||||
// override fun getRootView(): View {
|
||||
// val inflater = LayoutInflater.from(context)
|
||||
// binding = DialogNotReceiptWarnBinding.inflate(inflater)
|
||||
// return binding.root
|
||||
// }
|
||||
//
|
||||
// override fun initView() {
|
||||
// binding.btnCancel.setOnClickListener {
|
||||
// cancelBlock()
|
||||
// dismiss()
|
||||
// }
|
||||
// binding.btnConfirm.setOnClickListener {
|
||||
// confirmBlock()
|
||||
// dismiss()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
//}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import com.sw.inbound.databinding.DialogNotReceiptWarnBinding
|
||||
import com.sw.inbound.databinding.DialogWarnBinding
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
|
||||
class WarnDialog(
|
||||
context: Context,
|
||||
var content:String,
|
||||
var cancelBlock: () -> Unit = {},
|
||||
var confirmBlock: () -> Unit = {},
|
||||
) : BaseDialog(context = context, defWidth = 660.dp, defHeight = 360.dp) {
|
||||
|
||||
private lateinit var binding: DialogWarnBinding
|
||||
override fun getRootView(): View {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
binding = DialogWarnBinding.inflate(inflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
binding.tvWarnContent.text = content
|
||||
binding.btnCancel.setOnClickListener {
|
||||
cancelBlock()
|
||||
dismiss()
|
||||
}
|
||||
binding.btnConfirm.setOnClickListener {
|
||||
confirmBlock()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user