diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3807eb2..fc8f696 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -56,6 +56,7 @@ android:windowSoftInputMode="adjustPan" /> + diff --git a/app/src/main/java/com/sw/inbound/activity/FoodCollectionActivity.kt b/app/src/main/java/com/sw/inbound/activity/FoodCollectionActivity.kt index a2733cb..57093f8 100644 --- a/app/src/main/java/com/sw/inbound/activity/FoodCollectionActivity.kt +++ b/app/src/main/java/com/sw/inbound/activity/FoodCollectionActivity.kt @@ -27,13 +27,13 @@ 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.ToastUtils import com.sw.inbound.utils.ext.addOnActionSearchListener import com.sw.inbound.utils.ext.clickWithDebounce import com.sw.inbound.utils.ext.dp import com.sw.inbound.utils.ext.gone import com.sw.inbound.utils.ext.hideKeyboard import com.sw.inbound.utils.ext.invisible +import com.sw.inbound.utils.ext.startActivity import com.sw.inbound.utils.ext.toObject import com.sw.inbound.utils.ext.toast import com.sw.inbound.utils.ext.visible @@ -69,11 +69,16 @@ class FoodCollectionActivity : ComponentActivity() { FoodCollectionAdapter(collectList).apply { addOnItemChildClickListener(R.id.ivDelete) { _, _, position -> collectList[position].let { + it.imageFile = null + it.imageVector = null it.bitmap = null it.isFinish = false it.isShowCamera = true + it.uploadSuccess = false } collectionAdapter.notifyItemChanged(position) + val count = collectList.count { it.imageFile!=null && it.uploadSuccess.not() } + binding.btnUploadImage.text = "待上传图片${count}张" } } } @@ -130,7 +135,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.btnSave.setOnClickListener { _ -> if (clickIndex == -1) { toast("请选择物品名称") @@ -142,7 +154,6 @@ class FoodCollectionActivity : ComponentActivity() { return@setOnClickListener } vectorThread() - uploadAllImage() } binding.btnTakePhoto.clickWithDebounce { @@ -170,9 +181,18 @@ class FoodCollectionActivity : ComponentActivity() { loadEmptyView() -// binding.tvTitle.setOnClickListener { -// uploadImage(goodsImageList[7]) -// } + binding.tvTitle.setOnClickListener { + startActivity { } + +// val goodsImage = GoodsImage(goodsId = "1993493094888140802", goodsName = "多宝鱼", startTime = 1764120531856L, endTime = 1764121842825L) +// uploadImage(goodsImage) + +// val goodsImage = GoodsImage(goodsId = "1986366073649287170", goodsName = "黑鱼(整条鱼)", startTime = 1764122703093L, endTime = 1764123156022L) +// uploadImage(goodsImage) + +// val goodsImage = GoodsImage(goodsId = "1986699063868801025", goodsName = "鸡腿肉", startTime = 1764123375841L, endTime = 1764124039162L) +// uploadImage(goodsImage) + } } private var pageNo = 1 @@ -224,8 +244,11 @@ class FoodCollectionActivity : ComponentActivity() { it.bitmap?.recycle() } it.bitmap = null + it.imageVector = null + it.imageFile = null it.isShowCamera = true it.isFinish = false + it.uploadSuccess = false } catch (e: Exception) { e.printStackTrace() } @@ -238,6 +261,7 @@ class FoodCollectionActivity : ComponentActivity() { searchAdapter.notifyDataSetChanged() loadEmptyView() binding.ivFinish.invisible() + binding.btnUploadImage.text = "待上传图片${0}张" } private val cameraCallback: (Uri) -> Unit = { uri -> @@ -279,6 +303,8 @@ class FoodCollectionActivity : ComponentActivity() { it.isShowCamera = false } collectionAdapter.notifyItemChanged(index) + val count = collectList.count { it.imageFile!=null && it.uploadSuccess.not() } + binding.btnUploadImage.text = "待上传图片${count}张" } } catch (e: Exception) { e.printStackTrace() @@ -409,20 +435,35 @@ class FoodCollectionActivity : ComponentActivity() { } } +// private val failList = mutableListOf() +// private var successCount = 0 private fun uploadAllImage() { - val goods = searchGoodsList[clickIndex] + Loading.show(this) val files = collectList.filter { it.imageFile!=null }.map { it.imageFile!! } if (files.isEmpty()) { return } - for (index in files.indices step 5) { - val end = if(index + 5 < files.size - 1) index + 5 else files.size - 1 - val list = files.subList(index, end) - viewModel.uploadMultipleImages(goods.id!!, goods.goodsName!!, list) { - Timber.tag(TAG).d("uploadMultipleImages: ${it}") +// 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 = it?.toObject() +// val resp = result?.toObject() // 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() // } @@ -515,52 +556,52 @@ class FoodCollectionActivity : ComponentActivity() { // )) // } -// private fun uploadImage(goodsImage: GoodsImage) { -// Loading.show(this) -// val cropFile = File(this.cacheDir, "crop") -// val list = mutableListOf() -// 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 -// ) { data -> + private fun uploadImage(goodsImage: GoodsImage) { + Loading.show(this) + val cropFile = File(this.cacheDir, "crop") + val list = mutableListOf() + 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() // 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 -// ) { data -> + 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() // val isSuccess = resp?.code == "00000" -// binding.ivFinish.run { -// if (isSuccess) visible() else invisible() -// } -// } -// } -// Loading.dismiss() -// } + binding.ivFinish.run { + if (isSuccess) visible() else invisible() + } + } + } + Loading.dismiss() + } } \ No newline at end of file diff --git a/app/src/main/java/com/sw/inbound/activity/LocalImagePreviewActivity.kt b/app/src/main/java/com/sw/inbound/activity/LocalImagePreviewActivity.kt new file mode 100644 index 0000000..e62d3e3 --- /dev/null +++ b/app/src/main/java/com/sw/inbound/activity/LocalImagePreviewActivity.kt @@ -0,0 +1,97 @@ +package com.sw.inbound.activity + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.activity.ComponentActivity +import androidx.recyclerview.widget.GridLayoutManager +import coil.load +import com.chad.library.adapter4.BaseQuickAdapter +import com.chad.library.adapter4.viewholder.QuickViewHolder +import com.sw.inbound.databinding.ActivityLocalImagePreviewBinding +import com.sw.inbound.databinding.ListItemImagePreviewBinding +import com.sw.inbound.dialog.Loading +import com.sw.inbound.utils.ext.copyText +import java.io.File + +class LocalImagePreviewActivity : ComponentActivity() { + + private lateinit var binding: ActivityLocalImagePreviewBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityLocalImagePreviewBinding.inflate(layoutInflater) + setContentView(binding.root) + + binding.recyclerView.let { + it.layoutManager = GridLayoutManager(this, 6, GridLayoutManager.VERTICAL, false) + it.adapter = imageAdapter + } + binding.btnBack.setOnClickListener { finish() } + loadData() + } + + + fun loadData() { + Thread { + runOnUiThread { + Loading.show(this) + } + val cropFile = File(this.cacheDir, "crop") + 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 >= 1764086400L) { + imageList.add(ImageBean(file = it, name = "$time")) + } + } + imageList.sortBy { it.name.toLong() } + runOnUiThread { + imageAdapter.notifyDataSetChanged() + Loading.dismiss() + } + }.start() + } + + private var isCycle = true + + private val imageList = mutableListOf() + private val imageAdapter: ImageAdapter by lazy { + ImageAdapter(imageList).apply { + setOnItemClickListener { _, _, position -> + imageList[position].name.copyText(this@LocalImagePreviewActivity) + } + } + } + + data class ImageBean( + var file: File, + var name: String + ) + + inner class ImageAdapter(var list: MutableList) : + BaseQuickAdapter(list) { + + inner class VH(var binding: ListItemImagePreviewBinding) : QuickViewHolder(binding.root) + + override fun onBindViewHolder(holder: VH, position: Int, item: ImageBean?) { + holder.binding.let { + it.imageView.load(item!!.file) + it.textView.text = item.name + } + } + + override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { + val inflater = LayoutInflater.from(context) + val binding = ListItemImagePreviewBinding.inflate(inflater, parent, false) + return VH(binding) + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/sw/inbound/network/api/ApiService.kt b/app/src/main/java/com/sw/inbound/network/api/ApiService.kt index b85d4c7..61929e1 100644 --- a/app/src/main/java/com/sw/inbound/network/api/ApiService.kt +++ b/app/src/main/java/com/sw/inbound/network/api/ApiService.kt @@ -159,7 +159,8 @@ interface ApiService { @Multipart @POST suspend fun uploadMultipleImages( - @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/inboundWeighingScale/add", +// @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/inboundWeighingScale/add", + @Url url: String = "${GlobalData.appBaseUrl}/terminal/neglect/inbound/pad/inboundWeighingScale/add", @PartMap params: HashMap, @Part goodsPics: List ): ApiResponse diff --git a/app/src/main/java/com/sw/inbound/objbox/DataBean.kt b/app/src/main/java/com/sw/inbound/objbox/DataBean.kt index 6d8e633..5c9532a 100644 --- a/app/src/main/java/com/sw/inbound/objbox/DataBean.kt +++ b/app/src/main/java/com/sw/inbound/objbox/DataBean.kt @@ -16,7 +16,8 @@ data class FoodCollectionBean( var imageFile: File? = null, var imageVector: FloatArray? = null, var isShowCamera: Boolean = false, - var isFinish:Boolean = false + var isFinish:Boolean = false, + var uploadSuccess:Boolean = false ) data class ReceiptGoodsInfo( diff --git a/app/src/main/java/com/sw/inbound/utils/ext/Common.kt b/app/src/main/java/com/sw/inbound/utils/ext/Common.kt index 62aeab7..639716c 100644 --- a/app/src/main/java/com/sw/inbound/utils/ext/Common.kt +++ b/app/src/main/java/com/sw/inbound/utils/ext/Common.kt @@ -2,6 +2,8 @@ package com.sw.inbound.utils.ext import android.annotation.SuppressLint import android.app.Activity +import android.content.ClipData +import android.content.ClipboardManager import android.content.Context import android.content.Intent import android.content.SharedPreferences @@ -225,3 +227,25 @@ fun View.hideKeyboard() { imm.hideSoftInputFromWindow(this.windowToken, 0) this.clearFocus() // 清除焦点避免键盘再次弹出 } + +/** + * 复制文本到剪贴板 + * @param context 上下文 + * @param text 要复制的文本内容 + * @param showToast 是否显示复制成功提示,默认为true + */ +fun String.copyText(context: Context, showToast: Boolean = true) { + // 获取剪贴板管理器 + val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + + // 创建ClipData对象,包含要复制的文本 + val clipData = ClipData.newPlainText("label", this) + + // 将数据设置到剪贴板 + clipboardManager.setPrimaryClip(clipData) + + // 显示复制成功提示 + if (showToast) { + Toast.makeText(context, "文本已复制到剪贴板", Toast.LENGTH_SHORT).show() + } +} diff --git a/app/src/main/java/com/sw/inbound/viewmodel/ReceiptViewModel.kt b/app/src/main/java/com/sw/inbound/viewmodel/ReceiptViewModel.kt index 36af5f9..9b9c622 100644 --- a/app/src/main/java/com/sw/inbound/viewmodel/ReceiptViewModel.kt +++ b/app/src/main/java/com/sw/inbound/viewmodel/ReceiptViewModel.kt @@ -377,17 +377,22 @@ class ReceiptViewModel @Inject constructor( callback(true) } } - fun uploadMultipleImages(goodsId:String, goodsName:String, files:List, callback: (String?) -> Unit) { + fun uploadMultipleImages(goodsId:String, goodsName:String, files:List, callback: (Boolean) -> Unit) { launchWithLoading { val map = mutableMapOf() map["goodsId"] = goodsId map["goodsName"] = goodsName - val resp = repository.uploadMultipleImages(fileList = files, param = map) - if (!parseResponse(resp)) { - callback(null) + val fileList = files.filterNotNull() + if (fileList.isEmpty()) { + callback(false) return@launchWithLoading } - callback(resp.data) + val resp = repository.uploadMultipleImages(fileList = fileList, param = map) + if (!parseResponse(resp)) { + callback(false) + return@launchWithLoading + } + callback(resp.code == "00000") } } diff --git a/app/src/main/res/layout/activity_food_collection.xml b/app/src/main/res/layout/activity_food_collection.xml index 792b30d..34f9c41 100644 --- a/app/src/main/res/layout/activity_food_collection.xml +++ b/app/src/main/res/layout/activity_food_collection.xml @@ -340,7 +340,6 @@ android:layout_height="match_parent" android:layout_weight="1" /> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/list_item_image_preview.xml b/app/src/main/res/layout/list_item_image_preview.xml new file mode 100644 index 0000000..8b6f154 --- /dev/null +++ b/app/src/main/res/layout/list_item_image_preview.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + \ No newline at end of file