优化-待测试
This commit is contained in:
@@ -1,13 +1,18 @@
|
||||
package com.sw.inbound.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.viewModels
|
||||
import androidx.camera.view.PreviewView
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.sw.inbound.R
|
||||
@@ -17,6 +22,7 @@ import com.sw.inbound.databinding.ActivityFoodCollectionBinding
|
||||
import com.sw.inbound.databinding.LayoutCameraPreviewBinding
|
||||
import com.sw.inbound.databinding.LayoutEmptySearchBinding
|
||||
import com.sw.inbound.dialog.CollectSearchDialog
|
||||
import com.sw.inbound.dialog.CustomDialog
|
||||
import com.sw.inbound.dialog.Loading
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.objbox.Food
|
||||
@@ -26,6 +32,7 @@ import com.sw.inbound.objbox.ObjectBox
|
||||
import com.sw.inbound.utils.BitmapCropper
|
||||
import com.sw.inbound.utils.BitmapSaver
|
||||
import com.sw.inbound.utils.CameraUtils
|
||||
import com.sw.inbound.utils.ImageUploader
|
||||
import com.sw.inbound.utils.ImageUtil
|
||||
import com.sw.inbound.utils.ext.addOnActionSearchListener
|
||||
import com.sw.inbound.utils.ext.clickWithDebounce
|
||||
@@ -41,7 +48,10 @@ import com.sw.inbound.viewmodel.ReceiptViewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.objectbox.Box
|
||||
import io.objectbox.kotlin.boxFor
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
@@ -77,8 +87,8 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
it.uploadSuccess = false
|
||||
}
|
||||
collectionAdapter.notifyItemChanged(position)
|
||||
val count = collectList.count { it.imageFile!=null && it.uploadSuccess.not() }
|
||||
binding.btnUploadImage.text = "待上传图片${count}张"
|
||||
val count = collectList.count { it.imageFile != null && it.uploadSuccess.not() }
|
||||
// binding.btnUploadImage.text = "待上传图片${count}张"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,14 +145,14 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
searchGoods()
|
||||
}
|
||||
}
|
||||
binding.btnUploadImage.setOnClickListener {
|
||||
val count = collectList.count { it.imageFile!=null && it.uploadSuccess.not() }
|
||||
if (count == 0) {
|
||||
toast("已全部上传成功")
|
||||
return@setOnClickListener
|
||||
}
|
||||
uploadAllImage()
|
||||
}
|
||||
// binding.btnUploadImage.setOnClickListener {
|
||||
// val count = collectList.count { it.imageFile!=null && it.uploadSuccess.not() }
|
||||
// if (count == 0) {
|
||||
// toast("已全部上传成功")
|
||||
// return@setOnClickListener
|
||||
// }
|
||||
// uploadAllImage()
|
||||
// }
|
||||
binding.btnSave.setOnClickListener { _ ->
|
||||
if (clickIndex == -1) {
|
||||
toast("请选择物品名称")
|
||||
@@ -153,8 +163,10 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
toast("请拍摄物品照片")
|
||||
return@setOnClickListener
|
||||
}
|
||||
vectorThread()
|
||||
uploadAllImage()
|
||||
// vectorThread()
|
||||
// uploadAllImage()
|
||||
|
||||
upload()
|
||||
}
|
||||
binding.btnTakePhoto.clickWithDebounce {
|
||||
takePhoto()
|
||||
@@ -182,7 +194,7 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
loadEmptyView()
|
||||
|
||||
binding.tvTitle.setOnClickListener {
|
||||
startActivity<LocalImagePreviewActivity> { }
|
||||
startActivity<LocalImagePreviewActivity> { }
|
||||
|
||||
// val goodsImage = GoodsImage(goodsId = "1993493094888140802", goodsName = "多宝鱼", startTime = 1764120531856L, endTime = 1764121842825L)
|
||||
// uploadImage(goodsImage)
|
||||
@@ -261,14 +273,14 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
searchAdapter.notifyDataSetChanged()
|
||||
loadEmptyView()
|
||||
binding.ivFinish.invisible()
|
||||
binding.btnUploadImage.text = "待上传图片${0}张"
|
||||
// binding.btnUploadImage.text = "待上传图片${0}张"
|
||||
}
|
||||
|
||||
private val cameraCallback: (Uri) -> Unit = { uri ->
|
||||
val index = collectList.indexOfFirst { it.imageFile == null }
|
||||
if (index == -1) {
|
||||
toast("每次只允许保存6条数据")
|
||||
rerurn@cameraCallback
|
||||
rerurn@ cameraCallback
|
||||
}
|
||||
try {
|
||||
ImageUtil.uriToBitmap(this, uri)?.let { bitmap ->
|
||||
@@ -286,7 +298,8 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
return@let
|
||||
}
|
||||
val foodList = FoodModule.queryFoodNameScore(imageVector)
|
||||
val filterList = foodList.filter { it.score < FoodModule.BAG_RATE && it.name.contains("黑袋子")}
|
||||
val filterList =
|
||||
foodList.filter { it.score < FoodModule.BAG_RATE && it.name.contains("黑袋子") }
|
||||
if (filterList.isNotEmpty()) {
|
||||
toast("当前物品可能被袋子遮挡,请检查后重试")
|
||||
return@let
|
||||
@@ -302,8 +315,8 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
it.isShowCamera = false
|
||||
}
|
||||
collectionAdapter.notifyItemChanged(index)
|
||||
val count = collectList.count { it.imageFile!=null && it.uploadSuccess.not() }
|
||||
binding.btnUploadImage.text = "待上传图片${count}张"
|
||||
val count = collectList.count { it.imageFile != null && it.uploadSuccess.not() }
|
||||
// binding.btnUploadImage.text = "待上传图片${count}张"
|
||||
if (cropBitmap.isRecycled.not()) {
|
||||
cropBitmap.recycle()
|
||||
}
|
||||
@@ -337,9 +350,10 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
}
|
||||
|
||||
private fun image2VectorTask(
|
||||
bitmap: Bitmap?=null,
|
||||
imageVector: FloatArray?=null,
|
||||
position: Int) {
|
||||
bitmap: Bitmap? = null,
|
||||
imageVector: FloatArray? = null,
|
||||
position: Int
|
||||
) {
|
||||
try {
|
||||
initBox()
|
||||
// val imageVector = try {
|
||||
@@ -443,51 +457,77 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
// private val failList = mutableListOf<File>()
|
||||
// private var successCount = 0
|
||||
private fun uploadAllImage() {
|
||||
Loading.show(this)
|
||||
val files = collectList.filter { it.imageFile!=null }.map { it.imageFile!! }
|
||||
if (files.isEmpty()) {
|
||||
return
|
||||
}
|
||||
// successCount = 0
|
||||
// failList.clear()
|
||||
val goods = searchGoodsList[clickIndex]
|
||||
for (index in collectList.indices step 5) {
|
||||
val end = if(index + 5 < collectList.size - 1) index + 5 else collectList.size - 1
|
||||
val subList = collectList.subList(index, end)
|
||||
val subFiles = subList.map { it.imageFile }
|
||||
viewModel.uploadMultipleImages(goods.id!!, goods.goodsName!!, subFiles) {isSuccess->
|
||||
Timber.tag(TAG).d("uploadMultipleImages: ${isSuccess}")
|
||||
//{"code":"00000","data":null,"msg":"成功","total":0}
|
||||
// val resp = result?.toObject<RespData>()
|
||||
// val isSuccess = resp?.code == "00000"
|
||||
subList.filter { it.imageFile!=null }.forEach { it.uploadSuccess = isSuccess }
|
||||
|
||||
val count = collectList.count { it.imageFile!=null && it.uploadSuccess.not() }
|
||||
runOnUiThread {
|
||||
binding.btnUploadImage.text = "待上传图片${count}张"
|
||||
if (count == 0) {
|
||||
Loading.dismiss()
|
||||
}
|
||||
}
|
||||
// binding.ivFinish.run {
|
||||
// if (isSuccess) visible() else invisible()
|
||||
// private fun uploadAllImage() {
|
||||
// Loading.show(this)
|
||||
// val files = collectList.filter { it.imageFile!=null }.map { it.imageFile!! }
|
||||
// if (files.isEmpty()) {
|
||||
// return
|
||||
// }
|
||||
// val goods = searchGoodsList[clickIndex]
|
||||
// for (index in collectList.indices step 5) {
|
||||
// val end = if(index + 5 < collectList.size - 1) index + 5 else collectList.size - 1
|
||||
// val subList = collectList.subList(index, end)
|
||||
// val subFiles = subList.map { it.imageFile }
|
||||
// viewModel.uploadMultipleImages(goods.id!!, goods.goodsName!!, subFiles) {isSuccess->
|
||||
// Timber.tag(TAG).d("uploadMultipleImages: ${isSuccess}")
|
||||
// subList.filter { it.imageFile!=null }.forEach { it.uploadSuccess = isSuccess }
|
||||
//
|
||||
// val count = collectList.count { it.imageFile!=null && it.uploadSuccess.not() }
|
||||
// runOnUiThread {
|
||||
// binding.btnUploadImage.text = "待上传图片${count}张"
|
||||
// if (count == 0) {
|
||||
// Loading.dismiss()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
// }
|
||||
// }
|
||||
private fun upload() {
|
||||
lifecycleScope.launch {
|
||||
val totalFileCount = collectList.count { it.imageFile != null }
|
||||
val goods = searchGoodsList[clickIndex]
|
||||
val params = HashMap<String, RequestBody>()
|
||||
//params["placeId"] = restId.toRequestBody()
|
||||
params["foodId"] = goods.id!!.toRequestBody()
|
||||
params["foodName"] = goods.goodsName!!.toRequestBody()
|
||||
//params["foodVector"] = foodVector.toRequestBody()
|
||||
ImageUploader(
|
||||
totalList = collectList,
|
||||
uploadImage = { batch ->
|
||||
val files = batch.map { it.imageFile }
|
||||
viewModel.uploadMultipleImages(files = files, params)
|
||||
},
|
||||
onProgress = { count, batch ->
|
||||
runOnUiThread {
|
||||
showWaitingDialog2("图片上传中$count/$totalFileCount")
|
||||
batch.forEach {
|
||||
it.uploadSuccess = true
|
||||
}
|
||||
}
|
||||
},
|
||||
onError = {
|
||||
runOnUiThread {
|
||||
hideWaitingDialog()
|
||||
toast("上传失败,请稍后重试")
|
||||
}
|
||||
},
|
||||
onComplete = {
|
||||
hideWaitingDialog()
|
||||
vectorThread()
|
||||
}
|
||||
).processUploads()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val receiptViewModel: ReceiptViewModel by viewModels()
|
||||
|
||||
fun searchGoodsInfoList(goodsName: String, block:(List<SearchGoodsInfo.Record>)->Unit) {
|
||||
runBlocking {
|
||||
val list = searchGoodsInfoList2(goodsName)
|
||||
block(list)
|
||||
}
|
||||
fun searchGoodsInfoList(goodsName: String, block: (List<SearchGoodsInfo.Record>) -> Unit) {
|
||||
runBlocking {
|
||||
val list = searchGoodsInfoList2(goodsName)
|
||||
block(list)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun searchGoodsInfoList2(
|
||||
goodsName: String,
|
||||
pageNo: Int = 1,
|
||||
@@ -496,18 +536,53 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
return receiptViewModel.searchGoodsInfoList2(goodsName, pageNo, pageSize)
|
||||
}
|
||||
|
||||
private var mDialogWaiting: CustomDialog? = null
|
||||
|
||||
/**
|
||||
* 显示等待提示框
|
||||
*/
|
||||
fun showWaitingDialog(tip: String?): Dialog? {
|
||||
hideWaitingDialog()
|
||||
val view = View.inflate(this, R.layout.dialog_waiting, null)
|
||||
if (!TextUtils.isEmpty(tip)) (view.findViewById<View?>(R.id.tvTip) as TextView).text = tip
|
||||
mDialogWaiting = CustomDialog(this, view, R.style.MyDialog)
|
||||
mDialogWaiting!!.show()
|
||||
mDialogWaiting!!.setCancelable(true)
|
||||
return mDialogWaiting
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏等待提示框
|
||||
*/
|
||||
fun hideWaitingDialog() {
|
||||
mDialogWaiting?.dismiss()
|
||||
mDialogWaiting = null
|
||||
}
|
||||
|
||||
fun showWaitingDialog2(tip: String?) {
|
||||
if (mDialogWaiting == null) {
|
||||
hideWaitingDialog()
|
||||
val view = View.inflate(this, R.layout.dialog_waiting, null)
|
||||
mDialogWaiting = CustomDialog(this, view, R.style.MyDialog)
|
||||
mDialogWaiting!!.show()
|
||||
mDialogWaiting!!.setCancelable(true)
|
||||
}
|
||||
val tvTip = findViewById<TextView>(R.id.tvTip)
|
||||
tvTip.text = tip
|
||||
}
|
||||
|
||||
data class RespData(
|
||||
var code:String?=null,
|
||||
var data:String?=null,
|
||||
var msg:String?=null,
|
||||
var code: String? = null,
|
||||
var data: String? = null,
|
||||
var msg: String? = null,
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
data class GoodsImage(
|
||||
var goodsId:String,
|
||||
var goodsName:String,
|
||||
var startTime:Long,
|
||||
var endTime:Long
|
||||
var goodsId: String,
|
||||
var goodsName: String,
|
||||
var startTime: Long,
|
||||
var endTime: Long
|
||||
)
|
||||
//
|
||||
// val goodsImageList = mutableListOf<GoodsImage>().apply {
|
||||
@@ -563,53 +638,53 @@ class FoodCollectionActivity : ComponentActivity() {
|
||||
// endTime = 1763696990541L
|
||||
// ))
|
||||
// }
|
||||
|
||||
private fun uploadImage(goodsImage: GoodsImage) {
|
||||
Loading.show(this)
|
||||
val cropFile = File(this.cacheDir, "crop")
|
||||
val list = mutableListOf<File>()
|
||||
val startTime = goodsImage.startTime
|
||||
val endTime = goodsImage.endTime
|
||||
cropFile.listFiles()?.forEach {
|
||||
if (it.isDirectory) {
|
||||
return@forEach
|
||||
}
|
||||
val start = "IMG_CROP_".length
|
||||
val end = it.name.indexOf(".jpg")
|
||||
val time = it.name.substring(start, end).toLong()
|
||||
if (time in startTime..endTime) {
|
||||
list.add(it)
|
||||
}
|
||||
if (list.size < 5) {
|
||||
return@forEach
|
||||
}
|
||||
viewModel.uploadMultipleImages(
|
||||
goodsId = goodsImage.goodsId,
|
||||
goodsName = goodsImage.goodsName,
|
||||
files = list
|
||||
) { isSuccess ->
|
||||
// val resp = data?.toObject<RespData>()
|
||||
// val isSuccess = resp?.code == "00000"
|
||||
binding.ivFinish.run {
|
||||
if (isSuccess) visible() else invisible()
|
||||
}
|
||||
}
|
||||
list.clear()
|
||||
}
|
||||
if (list.isNotEmpty()) {
|
||||
viewModel.uploadMultipleImages(
|
||||
goodsId = goodsImage.goodsId,
|
||||
goodsName = goodsImage.goodsName,
|
||||
files = list
|
||||
) { isSuccess ->
|
||||
// val resp = data?.toObject<RespData>()
|
||||
// val isSuccess = resp?.code == "00000"
|
||||
binding.ivFinish.run {
|
||||
if (isSuccess) visible() else invisible()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading.dismiss()
|
||||
}
|
||||
|
||||
// private fun uploadImage(goodsImage: GoodsImage) {
|
||||
// Loading.show(this)
|
||||
// val cropFile = File(this.cacheDir, "crop")
|
||||
// val list = mutableListOf<File>()
|
||||
// val startTime = goodsImage.startTime
|
||||
// val endTime = goodsImage.endTime
|
||||
// cropFile.listFiles()?.forEach {
|
||||
// if (it.isDirectory) {
|
||||
// return@forEach
|
||||
// }
|
||||
// val start = "IMG_CROP_".length
|
||||
// val end = it.name.indexOf(".jpg")
|
||||
// val time = it.name.substring(start, end).toLong()
|
||||
// if (time in startTime..endTime) {
|
||||
// list.add(it)
|
||||
// }
|
||||
// if (list.size < 5) {
|
||||
// return@forEach
|
||||
// }
|
||||
// viewModel.uploadMultipleImages(
|
||||
// goodsId = goodsImage.goodsId,
|
||||
// goodsName = goodsImage.goodsName,
|
||||
// files = list
|
||||
// ) { isSuccess ->
|
||||
//// val resp = data?.toObject<RespData>()
|
||||
//// val isSuccess = resp?.code == "00000"
|
||||
// binding.ivFinish.run {
|
||||
// if (isSuccess) visible() else invisible()
|
||||
// }
|
||||
// }
|
||||
// list.clear()
|
||||
// }
|
||||
// if (list.isNotEmpty()) {
|
||||
// viewModel.uploadMultipleImages(
|
||||
// goodsId = goodsImage.goodsId,
|
||||
// goodsName = goodsImage.goodsName,
|
||||
// files = list
|
||||
// ) { isSuccess ->
|
||||
//// val resp = data?.toObject<RespData>()
|
||||
//// val isSuccess = resp?.code == "00000"
|
||||
// binding.ivFinish.run {
|
||||
// if (isSuccess) visible() else invisible()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Loading.dismiss()
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import androidx.activity.viewModels
|
||||
import androidx.camera.view.PreviewView
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.shuwei.intelligent.shelves.utils.ext.appendText
|
||||
import com.shuwei.intelligent.shelves.utils.ext.buildSpannableString
|
||||
@@ -45,7 +46,10 @@ import com.sw.inbound.utils.ext.toJsonString
|
||||
import com.sw.inbound.utils.ext.toast
|
||||
import com.sw.inbound.viewmodel.ReceiptViewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import kotlin.math.abs
|
||||
@@ -180,8 +184,9 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
// Timber.tag(TAG).d(clazzName)
|
||||
if (DialogManager.getDialogList().size == 1 &&
|
||||
DialogManager.contains("GoodsRecognizeDialog") &&
|
||||
goodsRecognizeDialog?.isShowing == true) {
|
||||
goodsRecognizeDialog?.dismiss()
|
||||
goodsRecognizeDialog?.isShowing == true
|
||||
) {
|
||||
goodsRecognizeDialog?.dismiss()
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -313,7 +318,8 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
foodList.forEach {
|
||||
it.name = it.name.split("WP")[0]
|
||||
}
|
||||
val filterList = foodList.filter { it.score < FoodModule.BAG_RATE && it.name.contains("黑袋子")}
|
||||
val filterList =
|
||||
foodList.filter { it.score < FoodModule.BAG_RATE && it.name.contains("黑袋子") }
|
||||
if (filterList.isNotEmpty()) {
|
||||
runOnUiThread {
|
||||
toast("当前物品可能被袋子遮挡,请检查后重试")
|
||||
@@ -622,14 +628,17 @@ abstract class GoodsListActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
fun uploadImage(goodsId:String, goodsName:String, imageFile: File?) {
|
||||
if (imageFile == null) {
|
||||
return
|
||||
}
|
||||
val list = mutableListOf<File>()
|
||||
list.add(imageFile)
|
||||
viewModel.uploadMultipleImages(goodsId, goodsName, list) {
|
||||
Timber.tag(TAG).d("uploadMultipleImages: ${it}")
|
||||
fun uploadImage(goodsId: String, goodsName: String, imageFile: File?) {
|
||||
lifecycleScope.launch {
|
||||
if (imageFile == null) {
|
||||
return@launch
|
||||
}
|
||||
val list = mutableListOf<File>()
|
||||
list.add(imageFile)
|
||||
val map = hashMapOf<String, RequestBody>()
|
||||
map["goodsId"] = goodsId.toRequestBody()
|
||||
map["goodsName"] = goodsName.toRequestBody()
|
||||
viewModel.uploadMultipleImages(files = list, params = map)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -213,11 +213,11 @@ class RemoteRepository @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun uploadMultipleImages(fileList: List<File>, param: Map<String, String>): ApiResponse<String> {
|
||||
val paramsMap = hashMapOf<String, RequestBody>()
|
||||
param.forEach { (key, value) ->
|
||||
paramsMap[key] = value.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
}
|
||||
suspend fun uploadMultipleImages(fileList: List<File>, params: HashMap<String, RequestBody>): ApiResponse<String> {
|
||||
// val paramsMap = hashMapOf<String, RequestBody>()
|
||||
// param.forEach { (key, value) ->
|
||||
// paramsMap[key] = value.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
// }
|
||||
|
||||
// 准备文件参数
|
||||
val fileParts = mutableListOf<MultipartBody.Part>()
|
||||
@@ -232,7 +232,7 @@ class RemoteRepository @Inject constructor(
|
||||
fileParts.add(filePart)
|
||||
}
|
||||
return safeApiCall {
|
||||
apiService.uploadMultipleImages(params = paramsMap, goodsPics = fileParts)
|
||||
apiService.uploadMultipleImages(params = params, goodsPics = fileParts)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.sw.inbound.utils
|
||||
|
||||
import com.sw.inbound.objbox.FoodCollectionBean
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.collections.chunked
|
||||
import kotlin.collections.count
|
||||
|
||||
class ImageUploader(
|
||||
private val totalList: List<FoodCollectionBean>,
|
||||
private val uploadImage: suspend (List<FoodCollectionBean>)-> Boolean,
|
||||
private val onProgress: (Int, List<FoodCollectionBean>) -> Unit,
|
||||
private val onError:(List<FoodCollectionBean>) -> Unit,
|
||||
private val onComplete:() -> Unit
|
||||
) {
|
||||
companion object {
|
||||
private const val BATCH_SIZE = 5
|
||||
}
|
||||
private val uploadedCount = AtomicInteger(0)
|
||||
|
||||
suspend fun processUploads() {
|
||||
val batches = totalList.chunked(BATCH_SIZE)
|
||||
|
||||
for (batch in batches) {
|
||||
val success = uploadImage(batch)
|
||||
if (!success) {
|
||||
//println("上传失败,终止流程")
|
||||
onError(batch)
|
||||
return
|
||||
}
|
||||
val fileCount = batch.count { it.imageFile!=null }
|
||||
uploadedCount.addAndGet(fileCount)
|
||||
onProgress(uploadedCount.get(), batch)
|
||||
//println("已上传 ${uploadedCount.get()}/$totalImages")
|
||||
}
|
||||
|
||||
onComplete()
|
||||
//println("流程完成,总计上传 ${uploadedCount.get()} 张图片")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.repository.RemoteRepository
|
||||
import com.sw.inbound.utils.ext.toJsonString
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import okhttp3.RequestBody
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
@@ -347,7 +348,7 @@ class ReceiptViewModel @Inject constructor(
|
||||
// }
|
||||
// }
|
||||
|
||||
fun uploadImage(file:File, callback: (String?) -> Unit) {
|
||||
fun uploadImage(file: File, callback: (String?) -> Unit) {
|
||||
launchWithLoading {
|
||||
val resp = repository.uploadImage(file)
|
||||
if (!parseResponse(resp)) {
|
||||
@@ -377,23 +378,42 @@ class ReceiptViewModel @Inject constructor(
|
||||
callback(true)
|
||||
}
|
||||
}
|
||||
fun uploadMultipleImages(goodsId:String, goodsName:String, files:List<File?>, callback: (Boolean) -> Unit) {
|
||||
launchWithLoading {
|
||||
val map = mutableMapOf<String, String>()
|
||||
map["goodsId"] = goodsId
|
||||
map["goodsName"] = goodsName
|
||||
val fileList = files.filterNotNull()
|
||||
if (fileList.isEmpty()) {
|
||||
callback(false)
|
||||
return@launchWithLoading
|
||||
}
|
||||
val resp = repository.uploadMultipleImages(fileList = fileList, param = map)
|
||||
if (!parseResponse(resp)) {
|
||||
callback(false)
|
||||
return@launchWithLoading
|
||||
}
|
||||
callback(resp.code == "00000")
|
||||
// fun uploadMultipleImages(goodsId:String, goodsName:String, files:List<File?>, callback: (Boolean) -> Unit) {
|
||||
// launchWithLoading {
|
||||
// val map = mutableMapOf<String, String>()
|
||||
// map["goodsId"] = goodsId
|
||||
// map["goodsName"] = goodsName
|
||||
// val fileList = files.filterNotNull()
|
||||
// if (fileList.isEmpty()) {
|
||||
// callback(false)
|
||||
// return@launchWithLoading
|
||||
// }
|
||||
// val resp = repository.uploadMultipleImages(fileList = fileList, param = map)
|
||||
// if (!parseResponse(resp)) {
|
||||
// callback(false)
|
||||
// return@launchWithLoading
|
||||
// }
|
||||
// callback(resp.code == "00000")
|
||||
// }
|
||||
// }
|
||||
|
||||
suspend fun uploadMultipleImages(
|
||||
files: List<File?>,
|
||||
params: HashMap<String, RequestBody>
|
||||
): Boolean {
|
||||
// val map = mutableMapOf<String, String>()
|
||||
// map["goodsId"] = goodsId
|
||||
// map["goodsName"] = goodsName
|
||||
val fileList = files.filterNotNull()
|
||||
if (fileList.isEmpty()) {
|
||||
return true
|
||||
}
|
||||
val resp = repository.uploadMultipleImages(fileList = fileList, params = params)
|
||||
// if (!parseResponse(resp)) {
|
||||
// callback(false)
|
||||
// return@launchWithLoading
|
||||
// }
|
||||
return resp.code == "00000"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="10dp" />
|
||||
<solid android:color="@color/black" />
|
||||
</shape>
|
||||
@@ -353,18 +353,18 @@
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnUploadImage"
|
||||
android:layout_width="270dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:background="@drawable/bg_blue_ripple"
|
||||
android:gravity="center"
|
||||
android:text="待上传图片"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="26sp"
|
||||
android:textStyle="bold" />
|
||||
<!-- <TextView-->
|
||||
<!-- android:id="@+id/btnUploadImage"-->
|
||||
<!-- android:layout_width="270dp"-->
|
||||
<!-- android:layout_height="90dp"-->
|
||||
<!-- android:layout_gravity="center_vertical"-->
|
||||
<!-- android:layout_marginEnd="20dp"-->
|
||||
<!-- android:background="@drawable/bg_blue_ripple"-->
|
||||
<!-- android:gravity="center"-->
|
||||
<!-- android:text="待上传图片"-->
|
||||
<!-- android:textColor="@color/white"-->
|
||||
<!-- android:textSize="26sp"-->
|
||||
<!-- android:textStyle="bold" />-->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnSave"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/dialog_waiting"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:indeterminateTint="@color/teal_200"
|
||||
android:indeterminateTintMode="src_atop" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="请稍等"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="26sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -27,4 +27,18 @@
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
</style>
|
||||
|
||||
<!--圆角Dialog-->
|
||||
<style name="MyDialog" parent="@android:style/Theme.Dialog">
|
||||
<item name="android:windowFrame">@null</item>
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:background">@android:color/transparent</item>
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:backgroundDimEnabled">true</item>
|
||||
<item name="android:backgroundDimAmount">0.6</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user