出入库功能改版
This commit is contained in:
+26
-4
@@ -1,10 +1,15 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
id("com.google.devtools.ksp")
|
||||
// alias(libs.plugins.android.application)
|
||||
// alias(libs.plugins.kotlin.android)
|
||||
// alias(libs.plugins.kotlin.compose)
|
||||
id("com.android.application")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
id("com.google.dagger.hilt.android")
|
||||
id("com.google.devtools.ksp")
|
||||
id("kotlin-parcelize")
|
||||
// id("compose.compiler")
|
||||
kotlin("kapt")
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -54,7 +59,11 @@ android {
|
||||
}
|
||||
buildFeatures {
|
||||
compose = true
|
||||
viewBinding = true
|
||||
}
|
||||
// composeOptions {
|
||||
// kotlinCompilerExtensionVersion = "1.5.4"
|
||||
// }
|
||||
sourceSets {
|
||||
named("main") {
|
||||
jniLibs.srcDirs("libs")
|
||||
@@ -119,7 +128,20 @@ dependencies {
|
||||
|
||||
implementation(libs.core)
|
||||
implementation(libs.android.core)
|
||||
implementation(libs.material)
|
||||
|
||||
implementation("androidx.recyclerview:recyclerview:1.4.0")
|
||||
|
||||
implementation("androidx.compose.foundation:foundation:1.7.0")
|
||||
implementation("androidx.compose.foundation:foundation-layout:1.7.0")
|
||||
implementation (libs.pytorch.android)
|
||||
implementation (libs.pytorch.android.torchvision)
|
||||
|
||||
implementation("io.github.scwang90:refresh-layout-kernel:3.0.0-alpha")
|
||||
implementation("io.github.scwang90:refresh-header-classics:3.0.0-alpha")
|
||||
val objectboxVersion = "5.0.1"
|
||||
debugImplementation("io.objectbox:objectbox-android-objectbrowser:$objectboxVersion")
|
||||
// releaseImplementation("io.objectbox:objectbox-android:$objectboxVersion")
|
||||
}
|
||||
|
||||
apply(plugin = "io.objectbox")
|
||||
Binary file not shown.
@@ -49,6 +49,9 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.sw.inbound.activity.ReceiptActivity"
|
||||
android:screenOrientation="landscape"/>
|
||||
<activity android:name="com.sw.inbound.activity.SelfProcurementActivity" />
|
||||
|
||||
<!-- <activity-->
|
||||
<!-- android:name=".InitActivity"-->
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"class_names": [
|
||||
"上海青",
|
||||
"土豆",
|
||||
"胡萝卜",
|
||||
"芹菜",
|
||||
"茄子",
|
||||
"蒜苔",
|
||||
"西红柿",
|
||||
"青椒",
|
||||
"黄瓜"
|
||||
],
|
||||
"class_to_idx": {
|
||||
"上海青": 0,
|
||||
"土豆": 1,
|
||||
"胡萝卜": 2,
|
||||
"芹菜": 3,
|
||||
"茄子": 4,
|
||||
"蒜苔": 5,
|
||||
"西红柿": 6,
|
||||
"青椒": 7,
|
||||
"黄瓜": 8
|
||||
},
|
||||
"idx_to_class": {
|
||||
"0": "上海青",
|
||||
"1": "土豆",
|
||||
"2": "胡萝卜",
|
||||
"3": "芹菜",
|
||||
"4": "茄子",
|
||||
"5": "蒜苔",
|
||||
"6": "西红柿",
|
||||
"7": "青椒",
|
||||
"8": "黄瓜"
|
||||
},
|
||||
"embedding_dim": 512,
|
||||
"total_images": 450,
|
||||
"build_time": "2025-10-21T10:14:29.510882"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]
|
||||
@@ -43,7 +43,7 @@ object GlobalData {
|
||||
/**
|
||||
* 具体业务baseurl
|
||||
*/
|
||||
var appBaseUrl: String = ""
|
||||
var appBaseUrl: String = "http://192.168.1.201:14801"
|
||||
|
||||
/**
|
||||
* 设备id
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.sw.inbound
|
||||
|
||||
import android.app.Application
|
||||
import com.sw.inbound.objbox.ObjectBox
|
||||
import com.sw.inbound.utils.AppUtil
|
||||
import com.sw.inbound.utils.ContextUtils
|
||||
import com.sw.inbound.utils.CrashHandler
|
||||
@@ -12,20 +13,22 @@ import timber.log.Timber
|
||||
class MyApp : Application() {
|
||||
companion object {
|
||||
const val DEBUG: Boolean = true
|
||||
var instance: MyApp?=null
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
instance = this
|
||||
Timber.plant(Timber.DebugTree())
|
||||
ContextUtils.initAppContext(this)
|
||||
GlobalData.appVersion = AppUtil.getAppVersionCode(this).toString()
|
||||
var deviceId = AppUtil.getUDID(this)
|
||||
deviceId = "6ce7cd59-b875-38b2-b73d-88a570be3212"
|
||||
///deviceId = "6ce7cd59-b875-38b2-b73d-88a570be3212"
|
||||
GlobalData.deviceId = deviceId
|
||||
|
||||
val spUtil = SPUtil.getInstance(context = ContextUtils.getAppContext())
|
||||
GlobalData.appToken = spUtil.get(GlobalKey.KEY_TOKEN, "") as String
|
||||
|
||||
ObjectBox.init(this)
|
||||
// 初始化崩溃处理器
|
||||
CrashHandler.init(this)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,410 @@
|
||||
package com.sw.inbound.activity
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.viewModels
|
||||
import androidx.camera.core.CameraSelector
|
||||
import androidx.camera.view.CameraController
|
||||
import androidx.camera.view.LifecycleCameraController
|
||||
import androidx.camera.view.PreviewView
|
||||
import androidx.core.graphics.toColorInt
|
||||
import com.shuwei.intelligent.shelves.utils.ext.appendText
|
||||
import com.shuwei.intelligent.shelves.utils.ext.buildSpannableString
|
||||
import com.sw.inbound.GlobalData
|
||||
import com.sw.inbound.databinding.ActivityGoodsListBinding
|
||||
import com.sw.inbound.databinding.ListItemReceiptGoodsBinding
|
||||
import com.sw.inbound.databinding.ListItemSelfProcurementBinding
|
||||
import com.sw.inbound.dialog.DropdownPopup
|
||||
import com.sw.inbound.dialog.GoodsRecognizeDialog
|
||||
import com.sw.inbound.dialog.GoodsSearchDialog
|
||||
import com.sw.inbound.dialog.NotReceiptWarnDialog
|
||||
import com.sw.inbound.model.request.PurchaseWarehouseParam
|
||||
import com.sw.inbound.model.request.UploadInfo
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.model.response.GoodsInfo
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.objbox.FoodModule
|
||||
import com.sw.inbound.utils.BitmapCropper
|
||||
import com.sw.inbound.utils.BitmapSaver
|
||||
import com.sw.inbound.utils.ImageUtil
|
||||
import com.sw.inbound.utils.PhotoCaptureHelper
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
import com.sw.inbound.utils.ext.gone
|
||||
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.runBlocking
|
||||
import timber.log.Timber
|
||||
import kotlin.math.min
|
||||
|
||||
@AndroidEntryPoint
|
||||
abstract class GoodsListActivity : ComponentActivity() {
|
||||
|
||||
companion object {
|
||||
public const val ID = "id"
|
||||
public const val SUPPLIER_ID = "supplierId"
|
||||
|
||||
public const val IS_RECEIPT_PAGE = "isReceiptPage"
|
||||
public const val IS_NEW_RECEIPT = "isNewReceipt"
|
||||
|
||||
const val PAGE_SIZE = 10
|
||||
}
|
||||
|
||||
var isReceiptPage: Boolean = false
|
||||
var isNewReceipt: Boolean = false
|
||||
var id: String = ""
|
||||
var supplierId: String = ""
|
||||
lateinit var binding: ActivityGoodsListBinding
|
||||
val viewModel: ReceiptViewModel by viewModels()
|
||||
val goodsList: MutableList<GoodsInfo> = mutableListOf()
|
||||
|
||||
abstract fun initRecyclerView()
|
||||
abstract fun initView()
|
||||
abstract fun getWarehouseList(): List<DictType>
|
||||
private lateinit var backPressedCallback: OnBackPressedCallback
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityGoodsListBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
initBackDispatcher()
|
||||
isReceiptPage = intent.getBooleanExtra(IS_RECEIPT_PAGE, true)
|
||||
isNewReceipt = intent.getBooleanExtra(IS_NEW_RECEIPT, false)
|
||||
id = intent.getStringExtra(ID) ?: ""
|
||||
supplierId = intent.getStringExtra(SUPPLIER_ID) ?: ""
|
||||
FoodModule.init(this)
|
||||
initCamera()
|
||||
replaceIncludeContent()
|
||||
initRecyclerView()
|
||||
initView()
|
||||
|
||||
binding.btnBack.setOnClickListener { handleBackEvent() }
|
||||
|
||||
binding.flWarehouseDropdown.setOnClickListener { v ->
|
||||
if (GlobalData.warehouseTypeList.isEmpty()) {
|
||||
toast("暂无仓库数据")
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (dropdownPopup == null) {
|
||||
dropdownList.clear()
|
||||
dropdownList.addAll(GlobalData.warehouseTypeList)
|
||||
dropdownPopup = DropdownPopup(
|
||||
context = this,
|
||||
list = dropdownList,
|
||||
popHeight = min(355.dp, dropdownList.size * 71.dp)
|
||||
) {
|
||||
binding.tvWareHouse.run {
|
||||
text = it.value
|
||||
tag = it.id
|
||||
}
|
||||
}
|
||||
}
|
||||
dropdownPopup?.showAsDropDown(v)
|
||||
}
|
||||
binding.tvUserName.text = GlobalData.deviceId
|
||||
binding.ivLogout.gone()
|
||||
|
||||
setPreviewController(binding.previewView)
|
||||
|
||||
viewModel.startSensorScale()
|
||||
binding.root.postDelayed({
|
||||
viewModel.readWeight {
|
||||
weightCallback?.invoke(it)
|
||||
recognizeWeight(weight = it)
|
||||
}
|
||||
}, 5 * 1000)
|
||||
}
|
||||
|
||||
private var weightCallback: ((weight: Int) -> Unit)? = null
|
||||
fun readWeightInfo(callback: (weight: Int) -> Unit) {
|
||||
weightCallback = callback
|
||||
}
|
||||
|
||||
private fun recognizeWeight(weight: Int) {
|
||||
if (weight < 200) {
|
||||
return
|
||||
}
|
||||
if (searchFoodEnable.not()) {
|
||||
return
|
||||
}
|
||||
runOnUiThread {
|
||||
recognizeFood()
|
||||
}
|
||||
}
|
||||
|
||||
fun recognizeFood() {
|
||||
searchFoodEnable = false
|
||||
takePhoto { uri ->
|
||||
Thread {
|
||||
searchFood(uri)
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
|
||||
private var dropdownPopup: DropdownPopup? = null
|
||||
|
||||
private val dropdownList: MutableList<DictType> = mutableListOf()
|
||||
|
||||
fun getSpannable(text: String, num: Int, color: String): SpannableStringBuilder {
|
||||
return buildSpannableString {
|
||||
appendText(text, ForegroundColorSpan("#FF141428".toColorInt()))
|
||||
appendText(num.toString(), ForegroundColorSpan(color.toColorInt()))
|
||||
}
|
||||
}
|
||||
|
||||
private var searchFoodEnable = true
|
||||
private fun searchFood(uri: Uri) {
|
||||
ImageUtil.uriToBitmap(this, uri)?.let { bitmap ->
|
||||
val newBmp = BitmapCropper.cropCenter(
|
||||
original = bitmap,
|
||||
targetWidth = 1000, targetHeight = 1300,
|
||||
offsetX = 30, offsetY = 100
|
||||
)
|
||||
val file = BitmapSaver.saveToAppFilesDir(
|
||||
newBmp,
|
||||
this,
|
||||
"IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
)
|
||||
Timber.d("${this.javaClass.simpleName}-searchFood-裁剪bitmap保存文件路径:${file?.absolutePath}")
|
||||
val foodNameList = FoodModule.queryFood(newBmp)
|
||||
searchMultipleGoods(foodNameList) { goodsList ->
|
||||
//if (goodsList.size != foodNameList.size) {
|
||||
// toast("系统异常,请稍后重试!!!")
|
||||
// searchFoodEnable = true
|
||||
// return@searchMultipleGoods
|
||||
//}
|
||||
handleGoodsResult(
|
||||
if (goodsList.size == foodNameList.size) goodsList
|
||||
else mutableListOf()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleGoodsResult(goodsList: MutableList<SearchGoodsInfo.Record>) {
|
||||
runOnUiThread {
|
||||
if (goodsRecognizeDialog?.isShowing == true) {
|
||||
searchFoodEnable = true
|
||||
return@runOnUiThread
|
||||
}
|
||||
goodsRecognizeDialog = GoodsRecognizeDialog(this, goodsList, {
|
||||
goodsRecognizeDialog = null
|
||||
searchFoodEnable = true
|
||||
}) {
|
||||
GoodsSearchDialog(this).show()
|
||||
}.apply {
|
||||
if (isFinishing || isDestroyed) {
|
||||
return@apply
|
||||
}
|
||||
show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var goodsRecognizeDialog: GoodsRecognizeDialog? = null
|
||||
|
||||
private var cameraController: LifecycleCameraController? = null
|
||||
private var photoCaptureHelper: PhotoCaptureHelper? = null
|
||||
private var isCameraReady = false
|
||||
fun takePhoto(cameraCallback: (Uri) -> Unit) {
|
||||
cameraController?.let {
|
||||
if (photoCaptureHelper == null) {
|
||||
photoCaptureHelper = PhotoCaptureHelper(
|
||||
context = this,
|
||||
cameraController = cameraController!!,
|
||||
onSuccess = cameraCallback,
|
||||
onError = { msg ->
|
||||
//toast(msg)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
photoCaptureHelper?.takePhoto()
|
||||
}
|
||||
|
||||
fun setPreviewController(previewView: PreviewView?) {
|
||||
previewView?.controller = cameraController
|
||||
}
|
||||
|
||||
fun initCamera() {
|
||||
if (cameraController == null) {
|
||||
cameraController = LifecycleCameraController(this).apply {
|
||||
// 必须设置有效的用例
|
||||
setEnabledUseCases(
|
||||
CameraController.IMAGE_CAPTURE or
|
||||
CameraController.VIDEO_CAPTURE
|
||||
)
|
||||
cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
|
||||
}
|
||||
cameraController?.bindToLifecycle(this)
|
||||
}
|
||||
|
||||
// if (isCameraReady.not()) {
|
||||
// try {
|
||||
// cameraController!!.initializationFuture.addListener({
|
||||
// isCameraReady = true
|
||||
// Timber.d("Camera initialized successfully")
|
||||
// }, ContextCompat.getMainExecutor(this))
|
||||
// } catch (e: Exception) {
|
||||
// Timber.d("Camera initialized error = ${e.message}")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private fun replaceIncludeContent() {
|
||||
binding.flContainer.removeAllViews()
|
||||
if (isReceiptPage) {
|
||||
val tempBinding =
|
||||
ListItemReceiptGoodsBinding.inflate(layoutInflater, binding.flContainer, false)
|
||||
binding.flContainer.addView(tempBinding.root)
|
||||
} else {
|
||||
val tempBinding =
|
||||
ListItemSelfProcurementBinding.inflate(layoutInflater, binding.flContainer, false)
|
||||
binding.flContainer.addView(tempBinding.root)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
cameraController?.unbind()
|
||||
viewModel.stopSensorScale()
|
||||
isCameraReady = false
|
||||
}
|
||||
|
||||
fun addGoods(it: GoodsInfo) {
|
||||
goodsList.add(it)
|
||||
binding.rvGoodsList.adapter?.notifyItemInserted(goodsList.size - 1)
|
||||
}
|
||||
|
||||
fun searchGoods(
|
||||
searchName: String,
|
||||
pageNo: Int,
|
||||
pageSize: Int = PAGE_SIZE,
|
||||
callback: (List<SearchGoodsInfo.Record>) -> Unit
|
||||
) {
|
||||
runBlocking {
|
||||
val records = searchGoodsBlock(searchName, pageNo, pageSize)
|
||||
runOnUiThread {
|
||||
callback(records)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun searchGoodsBlock(
|
||||
searchName: String,
|
||||
pageNo: Int,
|
||||
pageSize: Int = PAGE_SIZE
|
||||
): List<SearchGoodsInfo.Record> {
|
||||
return viewModel.searchGoodsInfoList2(
|
||||
goodsName = searchName,
|
||||
pageNo = pageNo,
|
||||
pageSize = pageSize
|
||||
)
|
||||
}
|
||||
|
||||
fun searchMultipleGoods(
|
||||
goodsNameList: List<String>,
|
||||
callback: (MutableList<SearchGoodsInfo.Record>) -> Unit
|
||||
) {
|
||||
runBlocking {
|
||||
val list = mutableListOf<SearchGoodsInfo.Record>()
|
||||
for (goodsName in goodsNameList) {
|
||||
val records = searchGoodsBlock(goodsName, 1, 1)
|
||||
if (records.isNotEmpty()) {
|
||||
list.add(records[0])
|
||||
}
|
||||
}
|
||||
callback(list)
|
||||
}
|
||||
}
|
||||
|
||||
private fun initBackDispatcher() {
|
||||
// 创建回调,true表示初始启用状态
|
||||
backPressedCallback = object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
handleBackEvent()
|
||||
}
|
||||
}
|
||||
// 注册回调,使用lifecycleOwner确保生命周期安全
|
||||
onBackPressedDispatcher.addCallback(this, backPressedCallback)
|
||||
}
|
||||
|
||||
private fun handleBackEvent() {
|
||||
val count = goodsList.count { it.isLocalGoods }
|
||||
// 处理返回事件
|
||||
if (count > 0) {
|
||||
NotReceiptWarnDialog(context = this@GoodsListActivity) {
|
||||
//onBackPressedDispatcher.onBackPressed()
|
||||
finish()
|
||||
}.show()
|
||||
} else {
|
||||
// 允许默认行为
|
||||
backPressedCallback.isEnabled = false
|
||||
//onBackPressedDispatcher.onBackPressed()
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
fun receiptSubmit() {
|
||||
if (binding.tvWareHouse.tag == null) {
|
||||
toast("请选择仓库")
|
||||
return
|
||||
}
|
||||
val submitData = goodsList.filter { it.isSelected }.also {
|
||||
it.forEach { goodsInfo ->
|
||||
goodsInfo.warehouseId = binding.tvWareHouse.tag.toString()
|
||||
goodsInfo.warehouseName = binding.tvWareHouse.text.toString()
|
||||
}
|
||||
}
|
||||
val uploadInfo = UploadInfo(
|
||||
id = id,
|
||||
supplierId = supplierId,
|
||||
receiveGoodsInfos = submitData
|
||||
)
|
||||
Timber.tag("SelfProcurementActivity")
|
||||
.d("receiptSubmit确认收货提交数据:${uploadInfo.toJsonString()}")
|
||||
viewModel.confirmReceipt(uploadInfo) { success ->
|
||||
if (success) {
|
||||
toast("确认收货成功")
|
||||
finish()
|
||||
} else {
|
||||
toast("确认收货失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun selfProcurementSubmit() {
|
||||
if (binding.tvWareHouse.tag == null) {
|
||||
toast("请选择仓库")
|
||||
return
|
||||
}
|
||||
val submitData = goodsList.map {
|
||||
PurchaseWarehouseParam(
|
||||
goodsId = it.goodId ?: "",
|
||||
goodsName = it.goodName,
|
||||
kcUnitId = it.kcUnitId,
|
||||
goodsCount = it.receiveCount ?: 0.0,
|
||||
goodsUnitPrice = it.recUnitPriceTaxIn ?: 0.0,
|
||||
goodsPrice = it.recPriceExItem ?: 0.0,
|
||||
//goodPurId = it.goodsPurId,
|
||||
warehouseId = binding.tvWareHouse.tag.toString(),
|
||||
buyToInventoryValue = it.consumeValue ?: ""
|
||||
)
|
||||
}
|
||||
Timber.tag("SelfProcurementActivity")
|
||||
.d("selfProcurementSubmit自采入库提交数据:${submitData.toJsonString()}")
|
||||
viewModel.addToWarehouse(submitData) { success ->
|
||||
if (success) {
|
||||
toast("提交入库成功")
|
||||
finish()
|
||||
} else {
|
||||
toast("提交入库失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.sw.inbound.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.sw.inbound.adapter.ReceiptGoodsAdapter
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.utils.ext.gone
|
||||
import com.sw.inbound.utils.ext.toast
|
||||
import com.sw.inbound.utils.ext.visible
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ReceiptActivity : GoodsListActivity() {
|
||||
|
||||
private val adapter by lazy {
|
||||
ReceiptGoodsAdapter(goodsList).apply {
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
goodsList[position].let {
|
||||
it.isSelected = it.isSelected.not()
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun initRecyclerView() {
|
||||
binding.rvGoodsList.let {
|
||||
it.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
||||
it.adapter = adapter
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
override fun initView() {
|
||||
//initRvTestData()
|
||||
binding.tvConfirmNum.run {
|
||||
if (isNewReceipt) gone() else visible()
|
||||
}
|
||||
binding.tvNotConfirmNum.run {
|
||||
if (isNewReceipt) gone() else visible()
|
||||
}
|
||||
binding.btnConfirmReceipt.setOnClickListener {
|
||||
if (isNewReceipt) {
|
||||
selfProcurementSubmit()
|
||||
} else {
|
||||
receiptSubmit()
|
||||
}
|
||||
}
|
||||
if (isNewReceipt.not()) {
|
||||
viewModel.getReceiveDetail(id) { detail ->
|
||||
runOnUiThread {
|
||||
if (detail == null) {
|
||||
toast("未查询到数据")
|
||||
return@runOnUiThread
|
||||
}
|
||||
binding.tvPurchaseNo.text = "采购单号:${detail.purCode}"
|
||||
val list = detail.receiveGoodsInfoList
|
||||
goodsList.addAll(list)
|
||||
adapter.notifyDataSetChanged()
|
||||
val confirmOrderCount = list.count { it.isAdjusted }
|
||||
binding.tvConfirmNum.text =
|
||||
getSpannable("已确认 ", num = confirmOrderCount, color = "#FF009632")
|
||||
val notConfirmOrderCount = goodsList.size - confirmOrderCount
|
||||
binding.tvNotConfirmNum.text =
|
||||
getSpannable("未确认 ", num = notConfirmOrderCount, color = "#FFFF0000")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
binding.tvPurchaseNo.text = "新增收货"
|
||||
}
|
||||
|
||||
// lifecycleScope.launch {
|
||||
// repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||
// launch {
|
||||
// viewModel.adjustedOrders.collect {
|
||||
// val confirmOrderCount = it.size
|
||||
// binding.tvConfirmNum.text = getSpannable("已确认 ", num = confirmOrderCount, color = "#FF009632")
|
||||
// val notConfirmOrderCount = goodsList.size - confirmOrderCount
|
||||
// binding.tvNotConfirmNum.text = getSpannable("未确认 ", num = notConfirmOrderCount, color = "#FF009632")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
override fun getWarehouseList(): List<DictType> {
|
||||
return goodsList.filter {
|
||||
it.warehouseId.isNullOrBlank().not() && it.warehouseName.isNullOrBlank().not()
|
||||
}
|
||||
.distinctBy { it.warehouseId }
|
||||
.map {
|
||||
DictType(id = it.warehouseId!!, value = it.warehouseName!!)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.sw.inbound.activity
|
||||
|
||||
import android.util.Log
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.adapter.SelfProcurementAdapter
|
||||
import com.sw.inbound.model.request.PurchaseWarehouseParam
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.utils.ext.toJsonString
|
||||
import com.sw.inbound.utils.ext.toast
|
||||
import timber.log.Timber
|
||||
import kotlin.getValue
|
||||
|
||||
class SelfProcurementActivity : GoodsListActivity() {
|
||||
|
||||
private val adapter by lazy {
|
||||
SelfProcurementAdapter(goodsList).apply {
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
goodsList[position].let {
|
||||
it.isSelected = it.isSelected.not()
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
addOnItemChildClickListener(R.id.ivState) { adapter, view, position ->
|
||||
removeAt(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun initRecyclerView() {
|
||||
binding.rvGoodsList.let {
|
||||
it.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
||||
it.adapter = adapter
|
||||
}
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
binding.tvPurchaseNo.text = "自采入库"
|
||||
binding.btnConfirmReceipt.setOnClickListener {
|
||||
selfProcurementSubmit()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getWarehouseList(): List<DictType> {
|
||||
return goodsList.filter {
|
||||
it.warehouseId.isNullOrBlank().not() && it.warehouseName.isNullOrBlank().not()
|
||||
}
|
||||
.distinctBy { it.warehouseId }
|
||||
.map {
|
||||
DictType(id = it.warehouseId!!, value = it.warehouseName!!)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.sw.inbound.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.sw.inbound.databinding.ListItemDropdownBinding
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.utils.ext.gone
|
||||
import com.sw.inbound.utils.ext.visible
|
||||
|
||||
class DropdownAdapter(var list: MutableList<DictType>) :
|
||||
BaseQuickAdapter<DictType, DropdownAdapter.VH>(list) {
|
||||
|
||||
inner class VH(var binding: ListItemDropdownBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = ListItemDropdownBinding.inflate(inflater, parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int, item: DictType?) {
|
||||
holder.binding.tvDropdown.text = item?.value
|
||||
holder.binding.divider.run {
|
||||
if (position == list.size - 1) gone() else visible()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.sw.inbound.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.graphics.toColorInt
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.databinding.ListItemGoodsSearchBinding
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
import com.sw.inbound.utils.ext.setShapeDrawable
|
||||
|
||||
class GoodsSearchAdapter(var list: MutableList<SearchGoodsInfo.Record>) :
|
||||
BaseQuickAdapter<SearchGoodsInfo.Record, GoodsSearchAdapter.VH>(list) {
|
||||
|
||||
inner class VH(var binding: ListItemGoodsSearchBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = ListItemGoodsSearchBinding.inflate(inflater, parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int, item: SearchGoodsInfo.Record?) {
|
||||
holder.binding.let {
|
||||
it.tvGoodsName.run {
|
||||
text = item!!.goodsName
|
||||
setTextColor(if (item!!.isSelected) "#FF0032C8".toColorInt() else "#FF666666".toColorInt())
|
||||
}
|
||||
it.root.run {
|
||||
if (item!!.isSelected) {
|
||||
setShapeDrawable(
|
||||
solidColor = "#FFEAF0FF",
|
||||
strokeColor = "#FF0033CC",
|
||||
strokeWidth = 2.dp,
|
||||
radius = 10.dp
|
||||
)
|
||||
} else {
|
||||
setShapeDrawable(
|
||||
solidColor = "#FFF5F5F5",
|
||||
radius = 10.dp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.sw.inbound.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.databinding.ListItemReceiptGoodsBinding
|
||||
import com.sw.inbound.model.bean.ReceiptGoodsInfo
|
||||
import com.sw.inbound.model.response.GoodsInfo
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
import com.sw.inbound.utils.ext.gone
|
||||
import com.sw.inbound.utils.ext.ifNullOrBlank
|
||||
import com.sw.inbound.utils.ext.ifNullOrZero
|
||||
import com.sw.inbound.utils.ext.setShapeDrawable
|
||||
import com.sw.inbound.utils.ext.visible
|
||||
|
||||
class ReceiptGoodsAdapter(var list: MutableList<GoodsInfo>) :
|
||||
BaseQuickAdapter<GoodsInfo, ReceiptGoodsAdapter.VH>(list) {
|
||||
|
||||
inner class VH(var binding: ListItemReceiptGoodsBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = ListItemReceiptGoodsBinding.inflate(inflater, parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int, item: GoodsInfo?) {
|
||||
holder.binding.run {
|
||||
root.updateLayoutParams<RecyclerView.LayoutParams> {
|
||||
height = 100.dp
|
||||
topMargin = 2.dp
|
||||
bottomMargin = 3.dp
|
||||
}
|
||||
root.setShapeDrawable(
|
||||
solidColor = if (item!!.isSelected) "#FFD5E1FF" else "#FFFFFFFF",
|
||||
radius = 6.dp
|
||||
)
|
||||
updateTextView(
|
||||
tvGoodsName, tvProcurementUnit,
|
||||
tvProcurementCount, tvProcurementPrice,
|
||||
tvProcurementAmount, tvReceiptCount, tvGoodsWeight,
|
||||
)
|
||||
tvGoodsName.text = item.goodName.ifNullOrBlank("-")
|
||||
tvProcurementUnit.text = item.unitName.ifNullOrBlank("-")
|
||||
tvProcurementCount.text = item.receiveCountStr.ifNullOrBlank("-")
|
||||
tvProcurementPrice.text = item.recUnitPriceTaxInStr.ifNullOrBlank("-")
|
||||
tvProcurementAmount.text = item.recPriceExItemStr.ifNullOrBlank("-")
|
||||
tvReceiptCount.text = item.receivedNumStr.ifNullOrBlank("-")
|
||||
tvGoodsWeight.text = item.goodsWeightStr.ifNullOrBlank("-")
|
||||
|
||||
tvState.gone()
|
||||
ivState.run {
|
||||
visible()
|
||||
setImageResource(
|
||||
if (item.isSelected.not()) R.mipmap.ic_receipt_no
|
||||
else if (item.isLocalGoods) R.mipmap.ic_receipt_local
|
||||
else if ((item.receivedNum?:0.toDouble()) < (item.receiveCount?:0.toDouble())) R.mipmap.ic_receipt_part
|
||||
else R.mipmap.ic_receipt_all
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTextView(vararg views: TextView) {
|
||||
views.forEach {
|
||||
it.setTextColor("#FF1E2832".toColorInt())
|
||||
it.paint.isFakeBoldText = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.sw.inbound.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import coil.load
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.sw.inbound.databinding.ListItemRecognizeBinding
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
import com.sw.inbound.utils.ext.setShapeDrawable
|
||||
import com.sw.inbound.utils.ext.setShapeDrawable2
|
||||
|
||||
class RecognizeAdapter(var list: MutableList<SearchGoodsInfo.Record>) :
|
||||
BaseQuickAdapter<SearchGoodsInfo.Record, RecognizeAdapter.VH>(list) {
|
||||
|
||||
inner class VH(var binding: ListItemRecognizeBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = ListItemRecognizeBinding.inflate(inflater, parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int, item: SearchGoodsInfo.Record?) {
|
||||
holder.binding.let {
|
||||
it.tvRecName.run {
|
||||
text = item?.goodsName
|
||||
setShapeDrawable2(
|
||||
solidColor = "#DEF5F5F5",
|
||||
bottomRightRadius = 12.dp,
|
||||
bottomLeftRadius = 12.dp
|
||||
)
|
||||
}
|
||||
it.ivRecImage.load(item!!.relativeUrl)
|
||||
it.root.run {
|
||||
setShapeDrawable(
|
||||
strokeColor = if (item.isSelected) "#FF0033CC" else "#FFDCDCF0",
|
||||
strokeWidth = 2.dp,
|
||||
radius = 12.dp
|
||||
)
|
||||
//setPadding(if (item.isSelected) 2.dp else 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.sw.inbound.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.sw.inbound.databinding.ListItemSelfProcurementBinding
|
||||
import com.sw.inbound.model.response.GoodsInfo
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
import com.sw.inbound.utils.ext.gone
|
||||
import com.sw.inbound.utils.ext.ifNullOrBlank
|
||||
import com.sw.inbound.utils.ext.setShapeDrawable
|
||||
import com.sw.inbound.utils.ext.visible
|
||||
|
||||
class SelfProcurementAdapter(var list: MutableList<GoodsInfo>) :
|
||||
BaseQuickAdapter<GoodsInfo, SelfProcurementAdapter.VH>(list) {
|
||||
|
||||
inner class VH(var binding: ListItemSelfProcurementBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = ListItemSelfProcurementBinding.inflate(inflater, parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int, item: GoodsInfo?) {
|
||||
holder.binding.run {
|
||||
root.updateLayoutParams<RecyclerView.LayoutParams> {
|
||||
height = 100.dp
|
||||
topMargin = 2.dp
|
||||
bottomMargin = 3.dp
|
||||
}
|
||||
root.setShapeDrawable(
|
||||
solidColor = if (item!!.isSelected) "#FFD5E1FF" else "#FFFFFFFF",
|
||||
radius = 6.dp
|
||||
)
|
||||
updateTextView(
|
||||
tvGoodsName, tvProcurementUnit,
|
||||
tvProcurementCount, tvProcurementPrice,
|
||||
tvProcurementAmount
|
||||
)
|
||||
tvGoodsName.text = item.goodName.ifNullOrBlank("-")
|
||||
tvProcurementUnit.text = item.unitName.ifNullOrBlank("-")
|
||||
tvProcurementCount.text = item.receiveCountStr.ifNullOrBlank("-")
|
||||
tvProcurementPrice.text = item.recUnitPriceTaxInStr.ifNullOrBlank("-")
|
||||
tvProcurementAmount.text = item.recPriceExItemStr.ifNullOrBlank("-")
|
||||
|
||||
tvState.gone()
|
||||
ivState.visible()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTextView(vararg views: TextView) {
|
||||
views.forEach {
|
||||
it.setTextColor("#FF1E2832".toColorInt())
|
||||
it.paint.isFakeBoldText = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
//package com.sw.inbound.dialog
|
||||
//
|
||||
//import android.content.Context
|
||||
//import android.graphics.SurfaceTexture
|
||||
//import android.view.LayoutInflater
|
||||
//import android.view.TextureView
|
||||
//import android.view.View
|
||||
//import android.widget.FrameLayout
|
||||
//import android.widget.TextView
|
||||
//import androidx.compose.ui.text.style.LineHeightStyle
|
||||
//import com.sw.inbound.GlobalData
|
||||
//import com.sw.inbound.activity.GoodsListActivity
|
||||
//import com.sw.inbound.databinding.DialogAddGoodsBinding
|
||||
//import com.sw.inbound.model.response.DictType
|
||||
//import com.sw.inbound.utils.ext.dp
|
||||
//import com.sw.inbound.utils.ext.gone
|
||||
//import com.sw.inbound.utils.ext.toast
|
||||
//import com.sw.inbound.utils.ext.visible
|
||||
//import kotlin.math.min
|
||||
//
|
||||
//class AddGoodsDialog(
|
||||
// context: Context,
|
||||
// var cancelBlock: () -> Unit = {},
|
||||
// var confirmBlock: () -> Unit = {},
|
||||
//) : BaseDialog(context) {
|
||||
//
|
||||
// private lateinit var binding: DialogAddGoodsBinding
|
||||
// override fun getRootView(): View {
|
||||
// val inflater = LayoutInflater.from(context)
|
||||
// binding = DialogAddGoodsBinding.inflate(inflater)
|
||||
// return binding.root
|
||||
// }
|
||||
//
|
||||
// private var dropdownPopup: DropdownPopup? = null
|
||||
//
|
||||
// private val dropdownList: MutableList<DictType> = mutableListOf()
|
||||
// private var activity: GoodsListActivity? = null
|
||||
// override fun initView() {
|
||||
// activity = getReceiptActivity()
|
||||
// binding.previewView.let {
|
||||
// it.visible()
|
||||
// activity?.setPreviewController(it)
|
||||
// activity?.setPreviewController(it)
|
||||
//// val textureView = it.getChildAt(0) as? TextureView
|
||||
//// textureView?.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
|
||||
//// override fun onSurfaceTextureAvailable(
|
||||
//// surface: SurfaceTexture,
|
||||
//// width: Int,
|
||||
//// height: Int
|
||||
//// ) {
|
||||
//// it.visible()
|
||||
//// activity?.setPreviewController(it)
|
||||
//// }
|
||||
////
|
||||
//// override fun onSurfaceTextureSizeChanged(
|
||||
//// surface: SurfaceTexture,
|
||||
//// width: Int,
|
||||
//// height: Int
|
||||
//// ) {
|
||||
//// }
|
||||
////
|
||||
//// override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
|
||||
//// return true
|
||||
//// }
|
||||
////
|
||||
//// override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
|
||||
//// }
|
||||
//// }
|
||||
// }
|
||||
// binding.ivGoodsImage.gone()
|
||||
// binding.btnClose.setOnClickListener {
|
||||
// cancelBlock()
|
||||
// dismiss()
|
||||
// }
|
||||
// binding.btnConfirm.setOnClickListener {
|
||||
// confirmBlock()
|
||||
// dismiss()
|
||||
// }
|
||||
// binding.btnStartPreview.setOnClickListener {
|
||||
// binding.ivGoodsImage.gone()
|
||||
// }
|
||||
// binding.btnTakePhoto.setOnClickListener {
|
||||
// activity?.takePhoto { uri ->
|
||||
// binding.ivGoodsImage.setImageURI(uri)
|
||||
// binding.ivGoodsImage.visible()
|
||||
// }
|
||||
// }
|
||||
// showDropDownList(
|
||||
// binding.flProcurementUnit,
|
||||
// textView = binding.tvProcurementUnit,
|
||||
// list = GlobalData.unitTypeList,
|
||||
// height = 213.dp
|
||||
// )
|
||||
// showDropDownList(
|
||||
// binding.flGoodsType,
|
||||
// textView = binding.tvGoodsType,
|
||||
// list = GlobalData.goodsTypeList,
|
||||
// )
|
||||
// showDropDownList(
|
||||
// binding.flStorageType,
|
||||
// textView = binding.tvStorageType,
|
||||
// list = GlobalData.storageTypeList,
|
||||
// )
|
||||
// showDropDownList(
|
||||
// dropdownView = binding.flWarehouseUnit,
|
||||
// textView = binding.tvWarehouseUnit,
|
||||
// list = GlobalData.unitTypeList
|
||||
// ) {
|
||||
// binding.tvSelectUseUnit.text = it.value
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun showDropDownList(
|
||||
// dropdownView: FrameLayout,
|
||||
// textView: TextView,
|
||||
// list: List<DictType>,
|
||||
// height: Int = 355.dp,
|
||||
// block:(DictType)-> Unit= {}
|
||||
// ) {
|
||||
// dropdownView.setOnClickListener {
|
||||
// dropdownList.clear()
|
||||
// val tempList =
|
||||
// list.filter { it.id.isNullOrBlank().not() && it.value.isNullOrBlank().not() }
|
||||
// if (tempList.isEmpty()) {
|
||||
// context.toast("暂无下拉数据")
|
||||
// return@setOnClickListener
|
||||
// }
|
||||
// dropdownList.addAll(tempList)
|
||||
// val realHeight = min(height, dropdownList.size * 71.dp)
|
||||
// dropdownPopup = DropdownPopup(
|
||||
// context = context,
|
||||
// list = dropdownList,
|
||||
// popWidth = dropdownView.width,
|
||||
// popHeight = realHeight
|
||||
// ) {
|
||||
// textView.text = it.value
|
||||
// block(it)
|
||||
// }
|
||||
// dropdownPopup?.showAsDropDown(dropdownView)
|
||||
// dropdownPopup?.setOnDismissListener {
|
||||
// dropdownPopup = null
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -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,50 @@
|
||||
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.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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
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.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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
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
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
class GoodsRecognizeDialog(
|
||||
context: Context,
|
||||
var list: MutableList<SearchGoodsInfo.Record>,
|
||||
var dismissDialog: () -> 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 dismiss() {
|
||||
dismissDialog()
|
||||
super.dismiss()
|
||||
}
|
||||
|
||||
private val recognizeAdapter by lazy {
|
||||
RecognizeAdapter(list).apply {
|
||||
isStateViewEnable = true
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
if (list[position].isSelected) {
|
||||
GoodsStoreDialog(context, list[position]) {
|
||||
activity?.addGoods(it)
|
||||
}.show()
|
||||
return@setOnItemClickListener
|
||||
}
|
||||
list.forEach { item ->
|
||||
item.isSelected = false
|
||||
}
|
||||
list[position].isSelected = true
|
||||
notifyDataSetChanged()
|
||||
GoodsStoreDialog(context, list[position]) {
|
||||
activity?.addGoods(it)
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var activity: GoodsListActivity? = null
|
||||
override fun initView() {
|
||||
activity = getReceiptActivity()
|
||||
binding.rvRecognize.let {
|
||||
it.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
it.adapter = recognizeAdapter
|
||||
}
|
||||
if (recognizeAdapter.list.isEmpty()) {
|
||||
loadEmptyView()
|
||||
}
|
||||
binding.ivClose.setOnClickListener { dismiss() }
|
||||
binding.btnManuallyFind.setOnClickListener {
|
||||
findGoods()
|
||||
//dismiss()
|
||||
}
|
||||
binding.btnAgainRecognize.setOnClickListener {
|
||||
dismiss()
|
||||
activity?.recognizeFood()
|
||||
}
|
||||
}
|
||||
|
||||
private var emptyBinding: LayoutEmptyRecognizeBinding? = null
|
||||
private fun loadEmptyView() {
|
||||
if (emptyBinding == null) {
|
||||
emptyBinding = LayoutEmptyRecognizeBinding.inflate(inflater, binding.rvRecognize, false)
|
||||
}
|
||||
emptyBinding?.root?.let {
|
||||
recognizeAdapter.stateView = it
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
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).show()
|
||||
// }
|
||||
binding.btnConfirm.setOnClickListener {
|
||||
if (list.isEmpty()) {
|
||||
context.toast("请搜索物品")
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (clickIndex == -1) {
|
||||
context.toast("请选择物品")
|
||||
return@setOnClickListener
|
||||
}
|
||||
GoodsStoreDialog(context, list[clickIndex]) {
|
||||
activity?.addGoods(it)
|
||||
}.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,205 @@
|
||||
package com.sw.inbound.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
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 androidx.core.graphics.toColorInt
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import coil.load
|
||||
import com.shuwei.intelligent.shelves.utils.ext.appendText
|
||||
import com.shuwei.intelligent.shelves.utils.ext.buildSpannableString
|
||||
import com.sw.inbound.GlobalData
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.activity.GoodsListActivity
|
||||
import com.sw.inbound.databinding.DialogGoodsStoreBinding
|
||||
import com.sw.inbound.ext.toFormattedString
|
||||
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.sdk.SensorScaleUtils
|
||||
import com.sw.inbound.utils.ext.dp
|
||||
import com.sw.inbound.utils.ext.toast
|
||||
import kotlin.Int
|
||||
|
||||
class GoodsStoreDialog(
|
||||
context: Context,
|
||||
var goods: SearchGoodsInfo.Record,
|
||||
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()
|
||||
activity?.readWeightInfo { weight ->
|
||||
this.realWeight = weight
|
||||
binding.tvTotalWeight.text = getSpannable(weight)
|
||||
}
|
||||
binding.etGoodsName.run {
|
||||
setText(goods.goodsName)
|
||||
isEnabled = false
|
||||
}
|
||||
binding.ivGoodsImage.load(goods.relativeUrl)
|
||||
binding.btnCancel.setOnClickListener {
|
||||
cancelBlock()
|
||||
dismiss()
|
||||
}
|
||||
binding.btnConfirm.setOnClickListener {
|
||||
confirmInputData()
|
||||
}
|
||||
// binding.ivAddUnit.setOnClickListener {
|
||||
// AddProcurementUnitDialog(context).show()
|
||||
// }
|
||||
binding.flUnitDropdown.setOnClickListener { v ->
|
||||
if (dropdownPopup == null) {
|
||||
dropdownList.clear()
|
||||
dropdownList.addAll(GlobalData.unitTypeList)
|
||||
dropdownPopup = DropdownPopup(
|
||||
context = context,
|
||||
list = dropdownList,
|
||||
popWidth = 428.dp
|
||||
) {
|
||||
binding.tvProcurementUnit.run {
|
||||
text = it.value
|
||||
tag = it.id
|
||||
}
|
||||
}
|
||||
}
|
||||
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.toInt() else 0
|
||||
val price = (it / count).toFormattedString(2)
|
||||
binding.tvProcurementPrice.text = price
|
||||
}
|
||||
binding.etProcurementCount.run {
|
||||
addTextChangedListener(onTextChanged = { it, _, _, _ ->
|
||||
try {
|
||||
if (isFocused.not()) {
|
||||
return@addTextChangedListener
|
||||
}
|
||||
val amountText = binding.etProcurementAmount.text.toString().trim()
|
||||
if (amountText.isEmpty()) {
|
||||
return@addTextChangedListener
|
||||
}
|
||||
val input = it ?: ""
|
||||
val count = if (input.isNotBlank()) input.toString().toInt() else 0
|
||||
val amount = amountText.toDouble()
|
||||
val price = amount / count
|
||||
binding.tvProcurementPrice.text = price.toFormattedString(2)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun addPriceInputListener(editText: EditText, action: (Double) -> Unit) {
|
||||
editText.run {
|
||||
addTextChangedListener(onTextChanged = { it, _, _, _ ->
|
||||
try {
|
||||
if (editText.isFocused.not()) {
|
||||
return@addTextChangedListener
|
||||
}
|
||||
val input = it ?: ""
|
||||
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.toString() == "0.") 0.0 else input.toString().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() {
|
||||
val unit = binding.tvProcurementUnit.text.trim().toString()
|
||||
if (unit.isBlank()) {
|
||||
context.toast("请选择单位")
|
||||
return
|
||||
}
|
||||
val countText = binding.etProcurementCount.text.trim().toString()
|
||||
if (countText.isBlank()) {
|
||||
context.toast("请录入数量")
|
||||
return
|
||||
}
|
||||
val priceText = binding.tvProcurementPrice.text.trim().toString()
|
||||
if (priceText.isBlank()) {
|
||||
context.toast("请录入单价")
|
||||
return
|
||||
}
|
||||
val amountText = binding.etProcurementAmount.text.trim().toString()
|
||||
if (amountText.isBlank()) {
|
||||
context.toast("请录入金额")
|
||||
return
|
||||
}
|
||||
confirmBlock(
|
||||
GoodsInfo(
|
||||
goodId = goods.id,
|
||||
goodName = goods.goodsName,
|
||||
consumeValue = goods.purchaseValue,
|
||||
//goodsPurId = binding.tvProcurementUnit.tag.toString(),
|
||||
kcUnitId = binding.tvProcurementUnit.tag.toString(),
|
||||
unitName = unit,
|
||||
receiveCount = countText.toDoubleOrNull(),
|
||||
recUnitPriceTaxIn = priceText.toDoubleOrNull(),
|
||||
recPriceExItem = amountText.toDoubleOrNull(),
|
||||
goodsWeight = realWeight.toBigDecimal(),
|
||||
isLocalGoods = true
|
||||
)
|
||||
)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,48 @@
|
||||
package com.sw.inbound.model.bean
|
||||
|
||||
data class ReceiptGoodsInfo(
|
||||
var goodsId: String? = "",
|
||||
var goodsName: String? = "",
|
||||
var procurementUnit: String? = "",
|
||||
var procurementCount: Int? = 0,
|
||||
var procurementPrice: Double? = 0.0,
|
||||
var procurementAmount: Double? = 0.0,
|
||||
var receiptCount: Int? = 0,
|
||||
var goodsWeight: Int? = 0,
|
||||
var goodsState: String? = "",
|
||||
var isSelected: Boolean = false,
|
||||
var isLocalGoods: Boolean = false
|
||||
)
|
||||
|
||||
//data class DropdownInfo(
|
||||
// var id: String,
|
||||
// var name: String
|
||||
//)
|
||||
|
||||
//data class RecognizeResult(
|
||||
// var name: String? = null,
|
||||
// var image: String? = null,
|
||||
// var isSelected: Boolean = false
|
||||
//)
|
||||
|
||||
//data class GoodsSearchInfo(
|
||||
// var id: String? = null,
|
||||
// var name: String? = null,
|
||||
// var isSelected: Boolean = false
|
||||
//)
|
||||
|
||||
data class OperateBean(
|
||||
var obj: Any? = null,
|
||||
var typeList: MutableList<OperateType> = mutableListOf(),
|
||||
var isSelected: Boolean = false,
|
||||
var isLocalGoods: Boolean = false,
|
||||
var isReceiptPage: Boolean = true
|
||||
)
|
||||
|
||||
data class OperateType(
|
||||
var value: String = "",
|
||||
var width: Int = 0,
|
||||
var textColor: String = "#FF999999",
|
||||
var isBoldFont: Boolean = false,
|
||||
var isShowIcon: Boolean = false
|
||||
)
|
||||
@@ -21,7 +21,8 @@ data class GoodsAddParam(
|
||||
/**
|
||||
* 物品类型
|
||||
*/
|
||||
var goodType: Int? = null,
|
||||
// var goodType: Int? = null,
|
||||
var goodType: String? = null,
|
||||
|
||||
/**
|
||||
* 存储方式
|
||||
@@ -85,7 +86,7 @@ data class GoodsAddParam(
|
||||
storageTypeStr = value
|
||||
}
|
||||
get() {
|
||||
return GlobalData.storageTypeList.find { it.id == storageType }?.value ?: ""
|
||||
return GlobalData.storageTypeList.find { it.id == storageType.toString() }?.value ?: ""
|
||||
}
|
||||
|
||||
val netRateStr: String
|
||||
@@ -99,7 +100,7 @@ data class GoodsAddParam(
|
||||
|
||||
val unitIdStr: String
|
||||
get() {
|
||||
return GlobalData.unitTypeList.find { it.id == unitId }?.value ?: ""
|
||||
return GlobalData.unitTypeList.find { it.id == unitId.toString() }?.value ?: ""
|
||||
}
|
||||
|
||||
val unitIdStrPlace: String
|
||||
@@ -121,13 +122,13 @@ data class GoodsAddParam(
|
||||
if (purchaseUnit == 0) {
|
||||
return ""
|
||||
}
|
||||
return GlobalData.unitTypeList.find { it.id == purchaseUnit }?.value ?: ""
|
||||
return GlobalData.unitTypeList.find { it.id == purchaseUnit.toString() }?.value ?: ""
|
||||
}
|
||||
|
||||
fun hasNullField(): String? {
|
||||
if (goodName == null || goodName!!.isEmpty())
|
||||
return "请录入物品名称"
|
||||
if (goodType == null || goodType == 0) {
|
||||
if (goodType.isNullOrBlank() || goodType == "0") {
|
||||
return "请选择物品类型"
|
||||
}
|
||||
if (storageType == null || storageType == 0) {
|
||||
|
||||
@@ -19,7 +19,7 @@ data class GoodsPurchaseUnitParam(
|
||||
val unitIdStr: String
|
||||
get() {
|
||||
if (unitId == 0) return ""
|
||||
return GlobalData.unitTypeList.find { it.id == unitId }?.value ?: ""
|
||||
return GlobalData.unitTypeList.find { it.id == unitId.toString() }?.value ?: ""
|
||||
}
|
||||
|
||||
val purchaseUnitStr: String
|
||||
@@ -27,7 +27,7 @@ data class GoodsPurchaseUnitParam(
|
||||
if (purchaseUnit == 0) {
|
||||
return ""
|
||||
}
|
||||
return GlobalData.unitTypeList.find { it.id == purchaseUnit }?.value ?: ""
|
||||
return GlobalData.unitTypeList.find { it.id == purchaseUnit.toString() }?.value ?: ""
|
||||
}
|
||||
|
||||
fun hasNullField(): String? {
|
||||
|
||||
@@ -17,11 +17,11 @@ data class PurchaseWarehouseParam(
|
||||
/**
|
||||
* 物品id
|
||||
*/
|
||||
var goodsId: Int = 0,
|
||||
var goodsId: String = "",
|
||||
/**
|
||||
* 库存单位
|
||||
*/
|
||||
var kcUnitId: Int = -1,
|
||||
var kcUnitId: String? = "",
|
||||
/**
|
||||
* 入库数量
|
||||
*/
|
||||
@@ -45,11 +45,11 @@ data class PurchaseWarehouseParam(
|
||||
/**
|
||||
* (物品列表里 businessUnitId字段的值)
|
||||
*/
|
||||
var goodPurId: Int = -1,
|
||||
var goodPurId: String?="",
|
||||
/**
|
||||
* 仓库id
|
||||
*/
|
||||
var warehouseId: Int = -1,
|
||||
var warehouseId: String?="",
|
||||
|
||||
/**
|
||||
* 采购库存转换关系
|
||||
@@ -75,10 +75,10 @@ data class PurchaseWarehouseParam(
|
||||
|
||||
val warehouseNameStr: String
|
||||
get() {
|
||||
if (warehouseId == -1) {
|
||||
if (warehouseId.isNullOrBlank()) {
|
||||
return ""
|
||||
}
|
||||
return GlobalData.warehouseTypeList.find { it.id == warehouseId }?.value ?: ""
|
||||
return GlobalData.warehouseTypeList.find { it.id == warehouseId.toString() }?.value ?: ""
|
||||
// if (warehouseName == null) {
|
||||
// return ""
|
||||
// }
|
||||
@@ -111,15 +111,15 @@ data class PurchaseWarehouseParam(
|
||||
return goodsName!!
|
||||
}
|
||||
|
||||
val unitDictTypeList: List<DictType>
|
||||
get() {
|
||||
return if (unitList == null) emptyList()
|
||||
else {
|
||||
unitList!!.filter { it.businessUnitId != null && it.purchaseUnitName != null }.map {
|
||||
DictType(it.businessUnitId?.toInt() ?: 0, it.purchaseUnitName ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
// val unitDictTypeList: List<DictType>
|
||||
// get() {
|
||||
// return if (unitList == null) emptyList()
|
||||
// else {
|
||||
// unitList!!.filter { it.businessUnitId != null && it.purchaseUnitName != null }.map {
|
||||
// DictType(it.businessUnitId?.toInt() ?: 0, it.purchaseUnitName ?: "")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
val unitNameStr: String
|
||||
get() {
|
||||
@@ -152,12 +152,12 @@ data class PurchaseWarehouseParam(
|
||||
}
|
||||
|
||||
fun hasNullField(): String? {
|
||||
if (goodsId == null || goodsId == 0 || goodsName == null || goodsName!!.isEmpty())
|
||||
if (goodsId.isNullOrBlank() || goodsName == null || goodsName!!.isEmpty())
|
||||
return "请选择物品"
|
||||
if (warehouseId == null || warehouseId == -1) {
|
||||
if (warehouseId.isNullOrBlank()) {
|
||||
return "请选择仓库"
|
||||
}
|
||||
if (goodPurId == null || goodPurId == -1) {
|
||||
if (goodPurId.isNullOrBlank()) {
|
||||
return "请选择采购单位"
|
||||
}
|
||||
if (goodsCount == null || goodsCount == 0.0) {
|
||||
|
||||
@@ -14,11 +14,11 @@ data class UploadInfo(
|
||||
/**
|
||||
* 收货单id
|
||||
*/
|
||||
var id: Int,
|
||||
var id: String,
|
||||
/**
|
||||
* 供应商id
|
||||
*/
|
||||
var supplierId: Int? = null,
|
||||
var supplierId: String? = null,
|
||||
/**
|
||||
*
|
||||
* 物品信息 【全部收货使用】
|
||||
@@ -77,7 +77,7 @@ private data class UploadGoodsInfo(
|
||||
/**
|
||||
* 采购单位id
|
||||
*/
|
||||
var purchaseUnitId: Int = 0,
|
||||
var purchaseUnitId: String = "",
|
||||
|
||||
/**
|
||||
* 收货数量
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
package com.sw.inbound.model.response
|
||||
|
||||
//data class ApiResponse<T>(
|
||||
// val code: Int,
|
||||
// val success: Boolean? = false,
|
||||
// val message: String? = "",
|
||||
// val result: T? = null,
|
||||
// val timestamp: Long? = 0
|
||||
//) {
|
||||
// fun isSuccess(): Boolean = code == 200
|
||||
//}
|
||||
|
||||
data class ApiResponse<T>(
|
||||
val code: Int,
|
||||
val success: Boolean? = false,
|
||||
val message: String? = "",
|
||||
val result: T? = null,
|
||||
val timestamp: Long? = 0
|
||||
val code: String,
|
||||
val msg: String? = "",
|
||||
val data: T? = null
|
||||
) {
|
||||
fun isSuccess(): Boolean = code == 200
|
||||
fun isSuccess(): Boolean = code == "00000"
|
||||
|
||||
val result: T?
|
||||
get() = data
|
||||
val message: String?
|
||||
get() = msg
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@ import kotlinx.parcelize.Parcelize
|
||||
*/
|
||||
@Parcelize
|
||||
data class DictType(
|
||||
val id: Int,
|
||||
val value: String
|
||||
val id: String?=null,
|
||||
val value: String?=null
|
||||
) : Parcelable
|
||||
|
||||
@@ -16,11 +16,11 @@ data class GoodsInfo(
|
||||
/**
|
||||
* 数据id
|
||||
*/
|
||||
var id: Int? = 0,
|
||||
var id: String? = "",
|
||||
/**
|
||||
* 物品Id
|
||||
*/
|
||||
var goodId: Int? = 0,
|
||||
var goodId: String? = "",
|
||||
/**
|
||||
* 物品名称
|
||||
*/
|
||||
@@ -28,7 +28,7 @@ data class GoodsInfo(
|
||||
/**
|
||||
* 单价
|
||||
*/
|
||||
var recUnitPriceTaxIn: Float? = null,
|
||||
var recUnitPriceTaxIn: Double? = null,
|
||||
|
||||
// 单价 界面显示
|
||||
var recUnitPriceTaxInTemp: String = "",
|
||||
@@ -36,7 +36,7 @@ data class GoodsInfo(
|
||||
/**
|
||||
* 新单价 部分收货需要
|
||||
*/
|
||||
var newRecUnitPriceTaxIn: Float? = null,
|
||||
var newRecUnitPriceTaxIn: Double? = null,
|
||||
|
||||
var newRecUnitPriceTaxInTemp: String = "",
|
||||
/**
|
||||
@@ -47,22 +47,22 @@ data class GoodsInfo(
|
||||
/**
|
||||
* 采购单位id
|
||||
*/
|
||||
var purchaseUnitId: Int? = null,
|
||||
var purchaseUnitId: String? = null,
|
||||
/**
|
||||
* 采购数量
|
||||
*/
|
||||
var receiveCount: Float? = null,
|
||||
var receiveCount: Double? = null,
|
||||
|
||||
/**
|
||||
* 金额
|
||||
*/
|
||||
var recPriceExItem: Float? = null,
|
||||
var recPriceExItem: Double? = null,
|
||||
// 金额 界面显示
|
||||
var recPriceExItemTemp: String = "",
|
||||
/**
|
||||
* 仓库id
|
||||
*/
|
||||
var warehouseId: Int? = null,
|
||||
var warehouseId: String? = null,
|
||||
/**
|
||||
* 仓库名称
|
||||
*/
|
||||
@@ -71,7 +71,7 @@ data class GoodsInfo(
|
||||
/**
|
||||
* 物品采购单位关系
|
||||
*/
|
||||
var goodsPurId: Int? = 0,
|
||||
var goodsPurId: String? = "",
|
||||
/**
|
||||
* 采购库存转换值
|
||||
*/
|
||||
@@ -86,7 +86,7 @@ data class GoodsInfo(
|
||||
var consumeValue: String? = "",
|
||||
|
||||
// 收货数量 收货入参
|
||||
var receivedNum: Float? = null,
|
||||
var receivedNum: Double? = null,
|
||||
// 收货数量显示
|
||||
var receivedNumTemp: String = "",
|
||||
// 重量 收货入参
|
||||
@@ -96,7 +96,12 @@ data class GoodsInfo(
|
||||
var isAdjusted: Boolean = false,
|
||||
|
||||
// 选中物品的可选单位
|
||||
var unitList: List<UnitVo> = emptyList<UnitVo>()
|
||||
var unitList: List<UnitVo> = emptyList<UnitVo>(),
|
||||
//--------------------------------------------------------
|
||||
var isSelected: Boolean = false,
|
||||
var isLocalGoods: Boolean = false,
|
||||
var kcUnitId: String?=""
|
||||
//--------------------------------------------------------
|
||||
) : Parcelable, BaseBean() {
|
||||
|
||||
val goodNameStr: String
|
||||
@@ -120,7 +125,7 @@ data class GoodsInfo(
|
||||
|
||||
val receivedNumCount: String
|
||||
get() {
|
||||
if (receivedNum == null || receivedNum == 0f)
|
||||
if (receivedNum == null || receivedNum == 0.toDouble())
|
||||
return "0"
|
||||
|
||||
return receivedNum?.toSafeString(unitName) ?: "0"
|
||||
@@ -128,9 +133,9 @@ data class GoodsInfo(
|
||||
|
||||
val dualCountStr: String
|
||||
get() {
|
||||
return if (receivedNum != null && receivedNum != 0f && receiveCount != null && receiveCount != 0f) {
|
||||
return if (receivedNum != null && receivedNum != 0.toDouble() && receiveCount != null && receiveCount != 0.toDouble()) {
|
||||
"${receivedNum.toSafeString(unitName)}/${receiveCount.toSafeString(unitName)}"
|
||||
} else if (receivedNum != null && receivedNum != 0f) {
|
||||
} else if (receivedNum != null && receivedNum != 0.toDouble()) {
|
||||
"${receivedNum.toSafeString(unitName)}/-"
|
||||
} else {
|
||||
receiveCountListStr
|
||||
@@ -139,33 +144,33 @@ data class GoodsInfo(
|
||||
|
||||
val recUnitPriceTaxInStr: String
|
||||
get() {
|
||||
if (recUnitPriceTaxIn == 0f) return ""
|
||||
if (recUnitPriceTaxIn == 0.toDouble()) return ""
|
||||
return recUnitPriceTaxIn?.toFormattedString() ?: ""
|
||||
}
|
||||
|
||||
val recUnitPriceTaxInListStr: String
|
||||
get() {
|
||||
if (recUnitPriceTaxIn == 0f) return "-"
|
||||
if (recUnitPriceTaxIn == 0.toDouble()) return "-"
|
||||
return recUnitPriceTaxIn?.toFormattedString() ?: "-"
|
||||
}
|
||||
|
||||
val newRecUnitPriceTaxInListStr: String
|
||||
get() {
|
||||
if (newRecUnitPriceTaxIn == 0f) return "-"
|
||||
if (newRecUnitPriceTaxIn == 0.toDouble()) return "-"
|
||||
return newRecUnitPriceTaxIn?.toFormattedString() ?: "-"
|
||||
}
|
||||
|
||||
val receiveCountStr: String
|
||||
get() {
|
||||
return when (receiveCount) {
|
||||
0f -> ""
|
||||
0.toDouble() -> ""
|
||||
else -> receiveCount?.toSafeString(unitName) ?: ""
|
||||
}
|
||||
}
|
||||
val receiveCountListStr: String
|
||||
get() {
|
||||
return when (receiveCount) {
|
||||
0f -> "-"
|
||||
0.toDouble() -> "-"
|
||||
else -> receiveCount?.toSafeString(unitName) ?: "-"
|
||||
}
|
||||
}
|
||||
@@ -173,14 +178,14 @@ data class GoodsInfo(
|
||||
val recPriceExItemStr: String
|
||||
get() {
|
||||
return when (recPriceExItem) {
|
||||
0f -> ""
|
||||
0.toDouble() -> ""
|
||||
else -> recPriceExItem?.toFormattedString() ?: ""
|
||||
}
|
||||
}
|
||||
val recPriceExItemListStr: String
|
||||
get() {
|
||||
return when (recPriceExItem) {
|
||||
0f -> "-"
|
||||
0.toDouble() -> "-"
|
||||
else -> recPriceExItem?.toFormattedString() ?: "-"
|
||||
}
|
||||
}
|
||||
@@ -217,7 +222,7 @@ data class GoodsInfo(
|
||||
purchaseUnitIdStr = value
|
||||
}
|
||||
get() {
|
||||
return GlobalData.unitTypeList.find { it.id == purchaseUnitId }?.value ?: ""
|
||||
return GlobalData.unitTypeList.find { it.id == purchaseUnitId.toString() }?.value ?: ""
|
||||
}
|
||||
|
||||
val warehouseNameStr: String
|
||||
@@ -229,16 +234,16 @@ data class GoodsInfo(
|
||||
}
|
||||
|
||||
fun hasNullField(): String? {
|
||||
if (warehouseId == null) {
|
||||
if (warehouseId.isNullOrBlank()) {
|
||||
return "请选择仓库"
|
||||
}
|
||||
if (receivedNum == null || receivedNum == 0f) {
|
||||
if (receivedNum == null || receivedNum == 0.toDouble()) {
|
||||
return "请输入收货数量或进行称重"
|
||||
}
|
||||
if (newRecUnitPriceTaxIn == null || newRecUnitPriceTaxIn == 0f) {
|
||||
if (newRecUnitPriceTaxIn == null || newRecUnitPriceTaxIn == 0.toDouble()) {
|
||||
return "请输入收货单价"
|
||||
}
|
||||
if (recPriceExItem == null || recPriceExItem == 0f) {
|
||||
if (recPriceExItem == null || recPriceExItem == 0.toDouble()) {
|
||||
return "请输入收货金额"
|
||||
}
|
||||
if (goodsWeight == null || goodsWeight!!.toFloat() <= 0) {
|
||||
|
||||
@@ -27,7 +27,7 @@ data class GoodsType(
|
||||
* 物品id
|
||||
*/
|
||||
@SerializedName("id")
|
||||
val id: Int? = 0,
|
||||
val id: String? = "",
|
||||
@SerializedName("idResult")
|
||||
val idResult: String? = "",
|
||||
@SerializedName("kidTypes")
|
||||
@@ -37,7 +37,7 @@ data class GoodsType(
|
||||
@SerializedName("pageSize")
|
||||
val pageSize: String? = "",
|
||||
@SerializedName("status")
|
||||
val status: Int? = 0,
|
||||
val status: Boolean? = false,
|
||||
@SerializedName("superName")
|
||||
val superName: String? = "",
|
||||
@SerializedName("typeCode")
|
||||
|
||||
@@ -7,11 +7,11 @@ data class PurchaseInfo(
|
||||
/**
|
||||
* 单据id
|
||||
*/
|
||||
var id: Int = 0,
|
||||
var id: String,
|
||||
/**
|
||||
* 供应商id
|
||||
*/
|
||||
var supplierId: Int = 0,
|
||||
var supplierId: String,
|
||||
/**
|
||||
* 供应商名称
|
||||
*/
|
||||
|
||||
@@ -31,13 +31,17 @@ data class SearchGoodsInfo(
|
||||
) : Parcelable {
|
||||
@Parcelize
|
||||
data class Record(
|
||||
@SerializedName("relativeUrl")
|
||||
val relativeUrl: String? = "",
|
||||
@SerializedName("goodsCode")
|
||||
val goodsCode: String? = "",
|
||||
@SerializedName("id")
|
||||
val id: String? = "",
|
||||
/**
|
||||
* 物品id
|
||||
*/
|
||||
@SerializedName("goodsId")
|
||||
val goodsId: Int? = 0,
|
||||
val goodsId: String? = "",
|
||||
/**
|
||||
* 物品名称
|
||||
*/
|
||||
@@ -58,6 +62,7 @@ data class SearchGoodsInfo(
|
||||
* 库存与克的转换值
|
||||
*/
|
||||
val consumeValue: String? = "",
|
||||
val purchaseValue: String? = "",
|
||||
|
||||
@SerializedName("specification")
|
||||
val specification: String? = "",
|
||||
@@ -71,7 +76,8 @@ data class SearchGoodsInfo(
|
||||
@SerializedName("unitVoList")
|
||||
val unitVoList: List<UnitVo>? = listOf(),
|
||||
@SerializedName("zjmCode")
|
||||
val zjmCode: String? = ""
|
||||
val zjmCode: String? = "",
|
||||
var isSelected: Boolean = false
|
||||
) : Parcelable {
|
||||
val goodsNameStr: String
|
||||
get() {
|
||||
|
||||
@@ -1,53 +1,62 @@
|
||||
package com.sw.inbound.model.response
|
||||
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
//import android.os.Parcelable
|
||||
//import com.google.gson.annotations.SerializedName
|
||||
//import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
* 存储方式
|
||||
*/
|
||||
@Parcelize
|
||||
|
||||
data class StorageType(
|
||||
@SerializedName("childList")
|
||||
val childList: List<String?>? = listOf(),
|
||||
@SerializedName("createTime")
|
||||
val createTime: String? = "",
|
||||
@SerializedName("createUserNo")
|
||||
val createUserNo: String? = "",
|
||||
@SerializedName("depth")
|
||||
val depth: String? = "",
|
||||
@SerializedName("description")
|
||||
val description: String? = "",
|
||||
@SerializedName("dictId")
|
||||
val dictId: String? = "",
|
||||
@SerializedName("eaId")
|
||||
val eaId: Int? = 0,
|
||||
@SerializedName("fid")
|
||||
val fid: String? = "",
|
||||
@SerializedName("id")
|
||||
val id: Int? = 0,
|
||||
@SerializedName("idc")
|
||||
val idc: String? = "",
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@SerializedName("itemText")
|
||||
val itemText: String? = "",
|
||||
/**
|
||||
* 对应值
|
||||
*/
|
||||
@SerializedName("itemValue")
|
||||
val itemValue: String? = "",
|
||||
@SerializedName("level")
|
||||
val level: Int? = 0,
|
||||
@SerializedName("sortOrder")
|
||||
val sortOrder: Int? = 0,
|
||||
@SerializedName("status")
|
||||
val status: Int? = 0,
|
||||
@SerializedName("updateTime")
|
||||
val updateTime: String? = "",
|
||||
@SerializedName("updateUserNo")
|
||||
val updateUserNo: String? = ""
|
||||
) : Parcelable
|
||||
val id:String?=null,
|
||||
val value:String?=null,
|
||||
val text:String?=null,
|
||||
val title:String?=null,
|
||||
val label:String?=null,
|
||||
|
||||
)
|
||||
//@Parcelize
|
||||
//data class StorageType(
|
||||
// @SerializedName("childList")
|
||||
// val childList: List<String?>? = listOf(),
|
||||
// @SerializedName("createTime")
|
||||
// val createTime: String? = "",
|
||||
// @SerializedName("createUserNo")
|
||||
// val createUserNo: String? = "",
|
||||
// @SerializedName("depth")
|
||||
// val depth: String? = "",
|
||||
// @SerializedName("description")
|
||||
// val description: String? = "",
|
||||
// @SerializedName("dictId")
|
||||
// val dictId: String? = "",
|
||||
// @SerializedName("eaId")
|
||||
// val eaId: Int? = 0,
|
||||
// @SerializedName("fid")
|
||||
// val fid: String? = "",
|
||||
// @SerializedName("id")
|
||||
// val id: String? = "",
|
||||
// @SerializedName("idc")
|
||||
// val idc: String? = "",
|
||||
// /**
|
||||
// * 名称
|
||||
// */
|
||||
// @SerializedName("itemText")
|
||||
// val itemText: String? = "",
|
||||
// /**
|
||||
// * 对应值
|
||||
// */
|
||||
// @SerializedName("itemValue")
|
||||
// val itemValue: String? = "",
|
||||
// @SerializedName("level")
|
||||
// val level: Int? = 0,
|
||||
// @SerializedName("sortOrder")
|
||||
// val sortOrder: Int? = 0,
|
||||
// @SerializedName("status")
|
||||
// val status: Int? = 0,
|
||||
// @SerializedName("updateTime")
|
||||
// val updateTime: String? = "",
|
||||
// @SerializedName("updateUserNo")
|
||||
// val updateUserNo: String? = ""
|
||||
//) : Parcelable
|
||||
@@ -33,7 +33,7 @@ data class SupplierInfo(
|
||||
* 订单id
|
||||
*/
|
||||
@SerializedName("id")
|
||||
val id: Int = 0,
|
||||
val id: String? = "",
|
||||
@SerializedName("pageNum")
|
||||
val pageNum: String? = "",
|
||||
@SerializedName("pageSize")
|
||||
@@ -100,7 +100,7 @@ data class SupplierInfo(
|
||||
* 供应商id
|
||||
*/
|
||||
@SerializedName("supplierId")
|
||||
val supplierId: Int = 0,
|
||||
val supplierId: String ? = "",
|
||||
/**
|
||||
* 供应商
|
||||
*/
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.sw.inbound.model.response.GoodsType
|
||||
import com.sw.inbound.model.response.PurchaseInfo
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.model.response.StorageType
|
||||
import com.sw.inbound.model.response.SupplierInfo
|
||||
import com.sw.inbound.model.response.SupplierResponse
|
||||
import com.sw.inbound.model.response.User
|
||||
import okhttp3.MultipartBody
|
||||
@@ -30,6 +31,10 @@ import retrofit2.http.Url
|
||||
* api接口
|
||||
*/
|
||||
interface ApiService {
|
||||
|
||||
private val apiPrefix: String
|
||||
get() = "/terminal/neglect/inbound"
|
||||
|
||||
/**
|
||||
* device获取token
|
||||
*/
|
||||
@@ -56,28 +61,33 @@ interface ApiService {
|
||||
suspend fun login(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/sys/loginPad",
|
||||
@Body body: LoginParam,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
|
||||
): ApiResponse<User>
|
||||
|
||||
/**
|
||||
* 采购单入库-列表
|
||||
*/
|
||||
@GET//("pad/receivePage")
|
||||
// @GET//("pad/receivePage")
|
||||
// suspend fun getReceiveList(
|
||||
// @Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/receivePage",
|
||||
// @Query("pageNo") pageNo: Int,
|
||||
// @Query("pageSize") pageSize: Int,
|
||||
//
|
||||
// ): ApiResponse<SupplierResponse>
|
||||
|
||||
@POST
|
||||
suspend fun getReceiveList(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/pad/receivePage",
|
||||
@Query("pageNo") pageNo: Int,
|
||||
@Query("pageSize") pageSize: Int,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
): ApiResponse<SupplierResponse>
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/receivePage",
|
||||
@Body param:Map<String, String>
|
||||
): ApiResponse<List<SupplierInfo>?>
|
||||
|
||||
/**
|
||||
* 采购单入库-详情
|
||||
*/
|
||||
@GET//("pad/receiveDetail")
|
||||
suspend fun getReceiveDetail(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/pad/receiveDetail",
|
||||
@Query("id") id: Int,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/receiveDetail",
|
||||
@Query("id") id: String
|
||||
): ApiResponse<PurchaseInfo>
|
||||
|
||||
/**
|
||||
@@ -85,9 +95,8 @@ interface ApiService {
|
||||
*/
|
||||
@POST//("pad/partialReceiptGoods")
|
||||
suspend fun partialReceipt(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/pad/partialReceiptGoods",
|
||||
@Body uploadInfo: UploadInfo,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/partialReceiptGoods",
|
||||
@Body uploadInfo: UploadInfo
|
||||
): ApiResponse<Boolean>
|
||||
|
||||
/**
|
||||
@@ -95,9 +104,8 @@ interface ApiService {
|
||||
*/
|
||||
@POST//("pad/saveAndReceiveAndGoWare")
|
||||
suspend fun confirmReceipt(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/pad/saveAndReceiveAndGoWare",
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/saveAndReceiveAndGoWare",
|
||||
@Body uploadInfo: UploadInfo,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
): ApiResponse<Boolean>
|
||||
|
||||
/**
|
||||
@@ -105,9 +113,10 @@ interface ApiService {
|
||||
*/
|
||||
@GET//("sys/dict/getDictItemByF")
|
||||
suspend fun getGoodsStorageType(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/sys/dict/getDictItemByF",
|
||||
@Query("dictCode") dictCode: String = "goods_storage_type",
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
// @Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/sys/dict/getDictItemByF",
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/getDictItemByF",
|
||||
// @Query("dictCode") dictCode: String = "goods_storage_type",
|
||||
@Query("dictCode") dictCode: String = "ccfs",
|
||||
): ApiResponse<List<StorageType>>
|
||||
|
||||
/**
|
||||
@@ -115,8 +124,7 @@ interface ApiService {
|
||||
*/
|
||||
@GET//("pad/notLimitList")
|
||||
suspend fun getGoodsType(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/pad/notLimitList",
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/notLimitList",
|
||||
): ApiResponse<GoodsType>
|
||||
|
||||
/**
|
||||
@@ -124,9 +132,8 @@ interface ApiService {
|
||||
*/
|
||||
@GET//("pad/dataList")
|
||||
suspend fun getDictType(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/pad/dataList",
|
||||
@Query("type") type: String,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/dataList",
|
||||
@Query("type") type: String
|
||||
): ApiResponse<List<DictType>>
|
||||
|
||||
/**
|
||||
@@ -135,22 +142,21 @@ interface ApiService {
|
||||
@Multipart
|
||||
@POST//("sys/common/upload")
|
||||
suspend fun uploadImage(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/sys/common/upload",
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/sys/common/upload",
|
||||
@Part("code") code: RequestBody,
|
||||
@Part file: MultipartBody.Part,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
): ApiResponse<String>
|
||||
|
||||
/**
|
||||
* 搜索物品列表
|
||||
*/
|
||||
@GET//("pad/goodsInfoList")
|
||||
@POST//("pad/goodsInfoList")
|
||||
suspend fun searchGoodsInfoList(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/pad/goodsInfoList",
|
||||
@Query("goodsName") goodsName: String,
|
||||
@Query("pageNo") pageNo: Int,
|
||||
@Query("pageSize") pageSize: Int,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/goodsInfoList",
|
||||
@Body param:Map<String, String>
|
||||
// @Query("goodsName") goodsName: String,
|
||||
// @Query("pageNum" ) pageNo: Int,
|
||||
// @Query("pageSize" ) pageSize: Int,
|
||||
): ApiResponse<SearchGoodsInfo>
|
||||
|
||||
/**
|
||||
@@ -158,9 +164,8 @@ interface ApiService {
|
||||
*/
|
||||
@POST//("pad/goodsAdd")
|
||||
suspend fun selfPurchaseGoodsAdd(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/pad/goodsAdd",
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/goodsAdd",
|
||||
@Body goodsAddParam: GoodsAddParam,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
): ApiResponse<SearchGoodsInfo>
|
||||
|
||||
/**
|
||||
@@ -168,9 +173,8 @@ interface ApiService {
|
||||
*/
|
||||
@POST//("pad/goodsAddUnit")
|
||||
suspend fun goodsAddUnit(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/pad/goodsAddUnit",
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/goodsAddUnit",
|
||||
@Body purchaseUnitParam: GoodsPurchaseUnitParam,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
): ApiResponse<Boolean>
|
||||
|
||||
/**
|
||||
@@ -178,9 +182,8 @@ interface ApiService {
|
||||
*/
|
||||
@POST//("pad/SelfPurchasedGoods")
|
||||
suspend fun selfPurchaseWarehousing(
|
||||
@Url url: String = "${GlobalData.appBaseUrl}/pad/SelfPurchasedGoods",
|
||||
@Url url: String = "${GlobalData.appBaseUrl}${apiPrefix}/pad/selfPurchasedGoods",
|
||||
@Body list: List<PurchaseWarehouseParam>,
|
||||
@Header("x-access-token") token: String = GlobalData.appToken
|
||||
): ApiResponse<Boolean>
|
||||
|
||||
}
|
||||
@@ -17,6 +17,8 @@ class RequestInterceptor : Interceptor {
|
||||
.header("Content-Type", "application/json")
|
||||
.header("Accept", "application/json")
|
||||
.header("deviceId", GlobalData.deviceId)
|
||||
.header("X-DEVICE-CODE", GlobalData.deviceId)
|
||||
.header("x-access-token", GlobalData.appToken)
|
||||
// .header("Authorization", "Bearer ${getToken()}")
|
||||
// .header("x-access-token", getToken())
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.sw.inbound.objbox
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
|
||||
data class FoodClassInfo(
|
||||
var class_names: List<String>,
|
||||
var class_to_idx: Map<String, Int>,
|
||||
var idx_to_class: Map<String, String>
|
||||
)
|
||||
|
||||
data class FoodCollectionBean(
|
||||
var imageUri: Uri? = null,
|
||||
var bitmap: Bitmap? = null,
|
||||
var imageVector: FloatArray? = null,
|
||||
var isShowCamera: Boolean = false,
|
||||
var isFinish:Boolean = false
|
||||
)
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.sw.inbound.objbox
|
||||
|
||||
import io.objectbox.annotation.Entity
|
||||
import io.objectbox.annotation.HnswIndex
|
||||
import io.objectbox.annotation.Id
|
||||
import io.objectbox.annotation.VectorDistanceType
|
||||
|
||||
@Entity
|
||||
data class Food(
|
||||
@Id var id: Long = 0,
|
||||
var name: String? = null,
|
||||
var foodIdx: Int = 0,
|
||||
@HnswIndex(dimensions = 512, distanceType = VectorDistanceType.DOT_PRODUCT)
|
||||
var foodVector: FloatArray? = null
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Food
|
||||
|
||||
if (id != other.id) return false
|
||||
if (foodIdx != other.foodIdx) return false
|
||||
if (name != other.name) return false
|
||||
if (!foodVector.contentEquals(other.foodVector)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = id.hashCode()
|
||||
result = 31 * result + foodIdx
|
||||
result = 31 * result + (name?.hashCode() ?: 0)
|
||||
result = 31 * result + (foodVector?.contentHashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package com.sw.inbound.objbox
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.sw.inbound.MyApp
|
||||
import com.sw.inbound.utils.AssetsTool
|
||||
import com.sw.inbound.utils.ImageUtil
|
||||
import io.objectbox.Box
|
||||
import io.objectbox.kotlin.boxFor
|
||||
import io.objectbox.query.Query
|
||||
import org.pytorch.IValue
|
||||
import org.pytorch.Module
|
||||
import org.pytorch.torchvision.TensorImageUtils
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
object FoodModule {
|
||||
|
||||
private lateinit var module_mobile: Module
|
||||
private lateinit var box: Box<Food>
|
||||
private lateinit var embeddingsList: List<List<Float>>
|
||||
private lateinit var labelsList: IntArray
|
||||
private lateinit var classInfo: FoodClassInfo
|
||||
val NO_MEAN_RGB = floatArrayOf(0.0f, 0.0f, 0.0f)
|
||||
val NO_STD_RGB = floatArrayOf(1.0f, 1.0f, 1.0f)
|
||||
|
||||
fun init(context: Context) {
|
||||
Thread{
|
||||
module_mobile = Module.load(copyAssetToCache(context, "best_embedding_model_mobile.pt"))
|
||||
box = ObjectBox.boxStore.boxFor(Food::class)
|
||||
// if (box.all.isNotEmpty()) {
|
||||
// box.removeAll()
|
||||
// }
|
||||
if (box.all.isEmpty()) {
|
||||
initFoodData(context)
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
fun uri2FloatArray(uri: Uri): FloatArray? {
|
||||
return MyApp.instance?.let { context ->
|
||||
ImageUtil.uriToBitmap(context, uri)?.let {
|
||||
bitmap2FloatArray(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun bitmap2FloatArray(bitmap: Bitmap): FloatArray {
|
||||
val inputTensor = TensorImageUtils.bitmapToFloat32Tensor(
|
||||
bitmap,
|
||||
NO_MEAN_RGB, // [0.485, 0.456, 0.406] TORCHVISION_NORM_MEAN_RGB
|
||||
NO_STD_RGB // [0.229, 0.224, 0.225] TORCHVISION_NORM_STD_RGB
|
||||
)
|
||||
val outputTensor = module_mobile.forward(IValue.from(inputTensor)).toTensor()
|
||||
return outputTensor.dataAsFloatArray
|
||||
}
|
||||
|
||||
fun queryFood(uri: Uri, queryCount:Int = 15): List<String>? {
|
||||
return uri2FloatArray(uri)?.let {
|
||||
queryFood(it, queryCount)
|
||||
}
|
||||
}
|
||||
fun queryFood(bitmap: Bitmap, queryCount:Int = 15): List<String> {
|
||||
val inputTensor = TensorImageUtils.bitmapToFloat32Tensor(
|
||||
bitmap,
|
||||
NO_MEAN_RGB, // [0.485, 0.456, 0.406] TORCHVISION_NORM_MEAN_RGB
|
||||
NO_STD_RGB // [0.229, 0.224, 0.225] TORCHVISION_NORM_STD_RGB
|
||||
)
|
||||
val outputTensor = module_mobile.forward(IValue.from(inputTensor)).toTensor()
|
||||
val floatArray = outputTensor.dataAsFloatArray
|
||||
return queryFood(floatArray,queryCount)
|
||||
}
|
||||
|
||||
fun queryFood(floatArray: FloatArray, queryCount:Int = 15): List<String> {
|
||||
val query: Query<Food> = box.query(Food_.foodVector.nearestNeighbors(floatArray, queryCount)).build()
|
||||
//查询比较分数
|
||||
// val tempList = query.findWithScores().sortedBy { it.score }.map { "${it.get().name}|${it.get().foodIdx}|${it.score}" }
|
||||
val map = mutableMapOf<String, Int>()
|
||||
query.findIdsWithScores().forEach {
|
||||
val food = box.get(it.id)
|
||||
//FoodQueryResult(id = it.id, name = food.name, foodIdx = food.foodIdx, score = it.score)
|
||||
food.name?.let { key ->
|
||||
val count = map[key] ?: 0
|
||||
map.put(key, count + 1)
|
||||
}
|
||||
}
|
||||
val list = map.entries.sortedByDescending { it.value }.map { it.key }
|
||||
return list
|
||||
}
|
||||
|
||||
|
||||
private fun initFoodData(context: Context) {
|
||||
if (box.all.isNotEmpty()) {
|
||||
return
|
||||
}
|
||||
val embeddingsJson = AssetsTool.readAssetsFile(context, "data/embeddings.json")
|
||||
val labelsJson = AssetsTool.readAssetsFile(context, "data/labels.json")
|
||||
val classInfoJson = AssetsTool.readAssetsFile(context, "data/class_info.json")
|
||||
|
||||
embeddingsList =
|
||||
Gson().fromJson(embeddingsJson, object : TypeToken<List<List<Float>>>() {}.type)
|
||||
labelsList = Gson().fromJson(labelsJson, IntArray::class.java)
|
||||
classInfo =
|
||||
Gson().fromJson(classInfoJson, FoodClassInfo::class.java)
|
||||
|
||||
val foodMap = classInfo.idx_to_class
|
||||
embeddingsList.forEachIndexed { index, floatList ->
|
||||
val classIdx = labelsList[index]
|
||||
val foodName = foodMap["$classIdx"]
|
||||
val array = floatList.toFloatArray()
|
||||
box.put(Food(name = foodName, foodVector = array, foodIdx = index))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ,此方法的主要目的是:从assets 拷贝到 app的cache目录
|
||||
* @param context
|
||||
* @param fileName
|
||||
* @return 例如是这样:/data/user/0/com.frizzle.pluginhookandroid9/cache/plugin-debug.apk
|
||||
*
|
||||
* 不可能反正SD
|
||||
*/
|
||||
fun copyAssetToCache(context: Context, fileName: String): String? {
|
||||
// 此app的缓存目录 --> 会默认在 cache目录...,可以自己去看看哦
|
||||
val cacheDir = context.getCacheDir()
|
||||
if (!cacheDir.exists()) {
|
||||
cacheDir.mkdirs() // TODO 如果没有缓存目录,就创建
|
||||
}
|
||||
val outPath = File(cacheDir, fileName) // TODO 创建输出的文件位置
|
||||
if (outPath.exists()) {
|
||||
outPath.delete() // TODO 如果该文件已经存在,就删掉
|
||||
}
|
||||
var `is`: InputStream? = null // 读取
|
||||
var fos: FileOutputStream? = null // 写入
|
||||
try {
|
||||
// 创建文件,如果创建成功,就返回true
|
||||
val res = outPath.createNewFile()
|
||||
if (res) {
|
||||
`is` = context.getAssets().open(fileName) // 拿到main/assets目录的输入流,用于读取字节
|
||||
fos = FileOutputStream(outPath) // 读取出来的字节最终写到outPath
|
||||
val buf = ByteArray(`is`.available()) // 缓存区
|
||||
var byteCount: Int
|
||||
|
||||
// 开始循环读取
|
||||
while ((`is`.read(buf).also { byteCount = it }) != -1) {
|
||||
fos.write(buf, 0, byteCount)
|
||||
}
|
||||
return outPath.getAbsolutePath()
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
try {
|
||||
// TODO 一定要记得关闭资源,为了不去性能的磨损
|
||||
fos!!.flush()
|
||||
`is`!!.close()
|
||||
fos.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2024 ObjectBox Ltd. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.sw.inbound.objbox
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import io.objectbox.BoxStore
|
||||
import io.objectbox.BoxStoreBuilder
|
||||
import io.objectbox.android.Admin
|
||||
import io.objectbox.exception.DbException
|
||||
import io.objectbox.exception.FileCorruptException
|
||||
import io.objectbox.sync.Sync
|
||||
import java.io.File
|
||||
import java.util.zip.GZIPOutputStream
|
||||
import kotlin.io.copyTo
|
||||
import kotlin.io.inputStream
|
||||
import kotlin.io.outputStream
|
||||
import kotlin.io.use
|
||||
import kotlin.jvm.java
|
||||
import kotlin.jvm.javaClass
|
||||
|
||||
/**
|
||||
* Singleton to keep BoxStore reference and provide current list of Notes Objects.
|
||||
* Inserts demo data if no Objects are stored.
|
||||
*/
|
||||
object ObjectBox {
|
||||
|
||||
// 确保所有设备/版本使用相同的objectbox-models/default.json
|
||||
// 避免直接修改自动生成的MyObjectBox类
|
||||
// 跨版本升级时使用boxStore.runInTx执行数据迁移
|
||||
|
||||
|
||||
private const val TAG = "ObjectBox"
|
||||
|
||||
lateinit var boxStore: BoxStore
|
||||
private set
|
||||
|
||||
/**
|
||||
* If building the [boxStore] failed, contains the thrown error message.
|
||||
*/
|
||||
var dbExceptionMessage: String? = null
|
||||
private set
|
||||
|
||||
fun init(context: Context) {
|
||||
// On Android make sure to pass a Context when building the Store.
|
||||
boxStore = try {
|
||||
MyObjectBox.builder()
|
||||
.androidContext(context.applicationContext)
|
||||
.build()
|
||||
} catch (e: DbException) {
|
||||
if (e.javaClass.equals(DbException::class.java) || e is FileCorruptException) {
|
||||
// Failed to build BoxStore due to database file issue, store message;
|
||||
// checked in NoteListActivity to notify user.
|
||||
dbExceptionMessage = e.toString()
|
||||
return
|
||||
} else {
|
||||
// Failed to build BoxStore due to developer error.
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
// if (BuildConfig.DEBUG) {
|
||||
var syncAvailable = if (Sync.isAvailable()) "available" else "unavailable"
|
||||
Log.d(TAG,"Using ObjectBox ${BoxStore.getVersion()} (${BoxStore.getVersionNative()}, sync $syncAvailable)")
|
||||
// Enable ObjectBox Admin on debug builds.
|
||||
// https://docs.objectbox.io/data-browser
|
||||
Admin(boxStore).start(context.applicationContext)
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the database file is not in use, compresses (GZIP) and copies it to the given [target].
|
||||
*/
|
||||
fun copyAndGzipDatabaseFileTo(target: File, context: Context): Boolean {
|
||||
if (BoxStore.isDatabaseOpen(context, null)) {
|
||||
// Do not copy if database file is still in use.
|
||||
// If it would be open, the copy will likely get corrupted
|
||||
// as BoxStore may currently write data to the file.
|
||||
Log.e(TAG, "Database file is still in use, can not copy.")
|
||||
return false
|
||||
}
|
||||
|
||||
// If a name was given when building BoxStore use that instead of the default below.
|
||||
val dbName = BoxStoreBuilder.DEFAULT_NAME
|
||||
File(context.filesDir, "objectbox/$dbName/data.mdb").inputStream().use { input ->
|
||||
target.parentFile?.mkdirs()
|
||||
GZIPOutputStream(target.outputStream()).use { output ->
|
||||
input.copyTo(output, DEFAULT_BUFFER_SIZE)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package com.sw.inbound.receiver
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.sw.inbound.InitActivity
|
||||
import com.sw.inbound.MainActivity
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
@@ -14,7 +14,7 @@ class BootReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (Intent.ACTION_BOOT_COMPLETED == intent.action) {
|
||||
Timber.d("设备启动完成,开始执行自启动逻辑")
|
||||
val intent = Intent(context, InitActivity::class.java)
|
||||
val intent = Intent(context, MainActivity::class.java)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
@@ -25,31 +25,31 @@ abstract class BaseRepository {
|
||||
// } else {
|
||||
// "HTTP Error: ${e.code()} - ${e.message()}"
|
||||
// }
|
||||
ApiResponse(code = e.code(), message = e.message())
|
||||
ApiResponse(code = "${e.code()}", msg = e.message())
|
||||
}
|
||||
|
||||
is SocketTimeoutException -> {
|
||||
ApiResponse(code = -2, message = "请求超时: ${e.message}")
|
||||
ApiResponse(code = "-2", msg = "请求超时: ${e.message}")
|
||||
}
|
||||
|
||||
is ConnectException -> {
|
||||
ApiResponse(code = -3, message = "连接失败: ${e.message}")
|
||||
ApiResponse(code = "-3", msg = "连接失败: ${e.message}")
|
||||
}
|
||||
|
||||
is SSLHandshakeException -> {
|
||||
ApiResponse(code = -4, message = "SSL握手失败: ${e.message}")
|
||||
ApiResponse(code = "-4", msg = "SSL握手失败: ${e.message}")
|
||||
}
|
||||
|
||||
is JsonParseException -> {
|
||||
ApiResponse(code = -5, message = "JSON解析错误: ${e.message}")
|
||||
ApiResponse(code = "-5", msg = "JSON解析错误: ${e.message}")
|
||||
}
|
||||
|
||||
is IOException -> {
|
||||
ApiResponse(code = -6, message = "网络IO错误: ${e.message}")
|
||||
ApiResponse(code = "-6", msg = "网络IO错误: ${e.message}")
|
||||
}
|
||||
|
||||
else -> {
|
||||
ApiResponse(code = -1, message = "未知错误: ${e.message ?: "无错误信息"}")
|
||||
ApiResponse(code = "-1", msg = "未知错误: ${e.message ?: "无错误信息"}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
//package com.sw.inbound.repository
|
||||
//
|
||||
//import com.google.gson.JsonParseException
|
||||
//import com.sw.inbound.model.response.ApiResponse
|
||||
//import retrofit2.HttpException
|
||||
//import timber.log.Timber
|
||||
//import java.io.IOException
|
||||
//import java.net.ConnectException
|
||||
//import java.net.SocketTimeoutException
|
||||
//import javax.net.ssl.SSLHandshakeException
|
||||
//
|
||||
//abstract class BaseRepositoryBak {
|
||||
// suspend fun <T> safeApiCall(apiCall: suspend () -> ApiResponse<T>): ApiResponse<T> {
|
||||
// return try {
|
||||
// apiCall()
|
||||
// } catch (e: Exception) {
|
||||
// Timber.e("safeApiCall Exception: ${e.stackTraceToString()}")
|
||||
//
|
||||
// when (e) {
|
||||
// is HttpException -> {
|
||||
// // 对于HTTP异常,尝试从响应体中获取错误信息
|
||||
//// val errorBody = e.response()?.errorBody()?.string()
|
||||
//// val errorMsg = if (!errorBody.isNullOrEmpty()) {
|
||||
//// errorBody
|
||||
//// } else {
|
||||
//// "HTTP Error: ${e.code()} - ${e.message()}"
|
||||
//// }
|
||||
// ApiResponse(code = e.code(), message = e.message())
|
||||
// }
|
||||
//
|
||||
// is SocketTimeoutException -> {
|
||||
// ApiResponse(code = -2, message = "请求超时: ${e.message}")
|
||||
// }
|
||||
//
|
||||
// is ConnectException -> {
|
||||
// ApiResponse(code = -3, message = "连接失败: ${e.message}")
|
||||
// }
|
||||
//
|
||||
// is SSLHandshakeException -> {
|
||||
// ApiResponse(code = -4, message = "SSL握手失败: ${e.message}")
|
||||
// }
|
||||
//
|
||||
// is JsonParseException -> {
|
||||
// ApiResponse(code = -5, message = "JSON解析错误: ${e.message}")
|
||||
// }
|
||||
//
|
||||
// is IOException -> {
|
||||
// ApiResponse(code = -6, message = "网络IO错误: ${e.message}")
|
||||
// }
|
||||
//
|
||||
// else -> {
|
||||
// ApiResponse(code = -1, message = "未知错误: ${e.message ?: "无错误信息"}")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -13,6 +13,7 @@ import com.sw.inbound.model.response.GoodsType
|
||||
import com.sw.inbound.model.response.PurchaseInfo
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.model.response.StorageType
|
||||
import com.sw.inbound.model.response.SupplierInfo
|
||||
import com.sw.inbound.model.response.SupplierResponse
|
||||
import com.sw.inbound.model.response.User
|
||||
import com.sw.inbound.network.api.ApiService
|
||||
@@ -56,13 +57,18 @@ class RemoteRepository @Inject constructor(
|
||||
return safeApiCall { apiService.login(body = loginParam) }
|
||||
}
|
||||
|
||||
suspend fun getReceiveList(pageNum: Int, pageSize: Int): ApiResponse<SupplierResponse> {
|
||||
suspend fun getReceiveList(pageNum: Int, pageSize: Int): ApiResponse<List<SupplierInfo>?> {
|
||||
return safeApiCall {
|
||||
apiService.getReceiveList(pageNo = pageNum, pageSize = pageSize)
|
||||
apiService.getReceiveList(
|
||||
param = mutableMapOf(
|
||||
"pageNum" to pageNum.toString(),
|
||||
"pageSize" to pageSize.toString(),
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getReceiveDetail(id: Int): ApiResponse<PurchaseInfo> {
|
||||
suspend fun getReceiveDetail(id: String): ApiResponse<PurchaseInfo> {
|
||||
return safeApiCall {
|
||||
apiService.getReceiveDetail(id = id)
|
||||
}
|
||||
@@ -115,7 +121,7 @@ class RemoteRepository @Inject constructor(
|
||||
val part =
|
||||
FileUtils.genRequestPart(context = ContextUtils.getAppContext(), imageUri = uri)
|
||||
if (part == null) {
|
||||
ApiResponse(code = -1, message = "解析图片失败", result = "")
|
||||
ApiResponse(code = "-1", msg = "解析图片失败")
|
||||
} else {
|
||||
apiService.uploadImage(code = codeRequestBody, file = part)
|
||||
}
|
||||
@@ -146,11 +152,12 @@ class RemoteRepository @Inject constructor(
|
||||
pageSize: Int = 10
|
||||
): ApiResponse<SearchGoodsInfo> {
|
||||
return safeApiCall {
|
||||
apiService.searchGoodsInfoList(
|
||||
goodsName = goodsName,
|
||||
pageNo = pageNo,
|
||||
pageSize = pageSize
|
||||
val map = mutableMapOf(
|
||||
"goodsName" to goodsName,
|
||||
"pageNum" to pageNo.toString(),
|
||||
"pageSize" to pageSize.toString()
|
||||
)
|
||||
apiService.searchGoodsInfoList(param = map)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ import com.sw.inbound.R
|
||||
import com.sw.inbound.ui.page.HomeScreen
|
||||
import com.sw.inbound.ui.page.LoginScreen
|
||||
import com.sw.inbound.ui.page.PurchaseOrderScreen
|
||||
import com.sw.inbound.ui.page.ReceiptProductScreen
|
||||
import com.sw.inbound.ui.page.SelfProcurementScreen
|
||||
import com.sw.inbound.ui.page.TestScreen
|
||||
//import com.sw.inbound.ui.page.ReceiptProductScreen
|
||||
//import com.sw.inbound.ui.page.SelfProcurementScreen
|
||||
//import com.sw.inbound.ui.page.TestScreen
|
||||
import com.sw.inbound.ui.weight.GlobalLoading
|
||||
import com.sw.inbound.utils.SPUtil
|
||||
import com.sw.inbound.utils.ToastUtils
|
||||
@@ -107,11 +107,12 @@ private fun NavHost(
|
||||
.fillMaxSize()
|
||||
.padding(padding),
|
||||
navController = navController,
|
||||
startDestination = if (token.isEmpty()) Screen.Login.route else Screen.Home.route
|
||||
//startDestination = if (token.isEmpty()) Screen.Login.route else Screen.Home.route
|
||||
startDestination = Screen.Home.route
|
||||
) {
|
||||
composable(Screen.Test.route) {
|
||||
TestScreen(modifier = Modifier, navController)
|
||||
}
|
||||
// composable(Screen.Test.route) {
|
||||
// TestScreen(modifier = Modifier, navController)
|
||||
// }
|
||||
// 首页
|
||||
composable(Screen.Home.route) {
|
||||
HomeScreen(modifier = Modifier, navController, onBackRequest = onBackRequest)
|
||||
@@ -128,28 +129,28 @@ private fun NavHost(
|
||||
) {
|
||||
PurchaseOrderScreen(modifier = Modifier.fillMaxSize(), navController)
|
||||
}
|
||||
// 自采单
|
||||
composable(
|
||||
Screen.SelfProcurement.route,
|
||||
enterTransition = { fadeIn(animationSpec = tween(0)) }, // 无进入动画
|
||||
exitTransition = { fadeOut(animationSpec = tween(0)) } // 无退出动画
|
||||
) {
|
||||
SelfProcurementScreen(modifier = Modifier, navController)
|
||||
}
|
||||
// 收货
|
||||
composable(
|
||||
Screen.ReceiptProduct.route,
|
||||
enterTransition = { fadeIn(animationSpec = tween(0)) }, // 无进入动画
|
||||
exitTransition = { fadeOut(animationSpec = tween(0)) }, // 无退出动画
|
||||
arguments = listOf(
|
||||
navArgument(name = "id", builder = { type = NavType.IntType }),
|
||||
navArgument(name = "supplierId", builder = { type = NavType.IntType })
|
||||
)
|
||||
) { backStackEntry ->
|
||||
val id = backStackEntry.arguments?.getInt("id") ?: 0
|
||||
val supplierId = backStackEntry.arguments?.getInt("supplierId") ?: 0
|
||||
ReceiptProductScreen(modifier = Modifier, navController, id, supplierId)
|
||||
}
|
||||
// // 自采单
|
||||
// composable(
|
||||
// Screen.SelfProcurement.route,
|
||||
// enterTransition = { fadeIn(animationSpec = tween(0)) }, // 无进入动画
|
||||
// exitTransition = { fadeOut(animationSpec = tween(0)) } // 无退出动画
|
||||
// ) {
|
||||
// SelfProcurementScreen(modifier = Modifier, navController)
|
||||
// }
|
||||
// // 收货
|
||||
// composable(
|
||||
// Screen.ReceiptProduct.route,
|
||||
// enterTransition = { fadeIn(animationSpec = tween(0)) }, // 无进入动画
|
||||
// exitTransition = { fadeOut(animationSpec = tween(0)) }, // 无退出动画
|
||||
// arguments = listOf(
|
||||
// navArgument(name = "id", builder = { type = NavType.IntType }),
|
||||
// navArgument(name = "supplierId", builder = { type = NavType.IntType })
|
||||
// )
|
||||
// ) { backStackEntry ->
|
||||
// val id = backStackEntry.arguments?.getString("id") ?: ""
|
||||
// val supplierId = backStackEntry.arguments?.getString("supplierId") ?: ""
|
||||
// ReceiptProductScreen(modifier = Modifier, navController, id, supplierId)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,15 +162,15 @@ sealed class Screen(val route: String) {
|
||||
data object PurchaseOrder : Screen("purchase_order")
|
||||
|
||||
// 自采单入库
|
||||
data object SelfProcurement : Screen("self_procurement")
|
||||
// data object SelfProcurement : Screen("self_procurement")
|
||||
|
||||
// 收货
|
||||
data object ReceiptProduct : Screen("receipt_product?id={id}&supplierId={supplierId}") {
|
||||
fun createRoute(id: Int, supplierId: Int) =
|
||||
"receipt_product?id=${id}&supplierId=${supplierId}"
|
||||
}
|
||||
// data object ReceiptProduct : Screen("receipt_product?id={id}&supplierId={supplierId}") {
|
||||
// fun createRoute(id: Int, supplierId: Int) =
|
||||
// "receipt_product?id=${id}&supplierId=${supplierId}"
|
||||
// }
|
||||
|
||||
// 添加物品
|
||||
data object AddProduct : Screen("addProduct")
|
||||
data object Test : Screen("Test")
|
||||
// data object AddProduct : Screen("addProduct")
|
||||
// data object Test : Screen("Test")
|
||||
}
|
||||
@@ -23,11 +23,13 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.activity.GoodsListActivity
|
||||
import com.sw.inbound.activity.SelfProcurementActivity
|
||||
import com.sw.inbound.ui.Screen
|
||||
import com.sw.inbound.ui.weight.TopTitleBar
|
||||
import com.sw.inbound.utils.ext.startActivity
|
||||
import com.sw.inbound.viewmodel.UserViewModel
|
||||
import timber.log.Timber
|
||||
|
||||
@@ -78,6 +80,11 @@ fun HomeScreen(
|
||||
indication = null
|
||||
) {
|
||||
navController.navigate(Screen.PurchaseOrder.route)
|
||||
//navController.context.startActivity<ReceiptActivity> {
|
||||
// putExtra(GoodsListActivity.ID, "123123")
|
||||
// putExtra(GoodsListActivity.SUPPLIER_ID, "123123123123")
|
||||
// putExtra(GoodsListActivity.IS_RECEIPT_PAGE, true)
|
||||
//}
|
||||
},
|
||||
painter = painterResource(R.mipmap.ic_order_purchase),
|
||||
contentDescription = "采购单入库"
|
||||
@@ -91,14 +98,19 @@ fun HomeScreen(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null
|
||||
) {
|
||||
navController.navigate(
|
||||
Screen.SelfProcurement.route, navOptions = NavOptions.Builder()
|
||||
.setEnterAnim(0)
|
||||
.setExitAnim(0)
|
||||
.setPopEnterAnim(0)
|
||||
.setPopExitAnim(0)
|
||||
.build()
|
||||
)
|
||||
// navController.navigate(
|
||||
// Screen.SelfProcurement.route, navOptions = NavOptions.Builder()
|
||||
// .setEnterAnim(0)
|
||||
// .setExitAnim(0)
|
||||
// .setPopEnterAnim(0)
|
||||
// .setPopExitAnim(0)
|
||||
// .build()
|
||||
// )
|
||||
navController.context.startActivity<SelfProcurementActivity> {
|
||||
putExtra(GoodsListActivity.ID, "2342342343")
|
||||
putExtra(GoodsListActivity.SUPPLIER_ID, "23423423424234")
|
||||
putExtra(GoodsListActivity.IS_RECEIPT_PAGE, false)
|
||||
}
|
||||
},
|
||||
painter = painterResource(R.mipmap.ic_order_self_procurement),
|
||||
contentDescription = "自采入库"
|
||||
|
||||
@@ -49,7 +49,6 @@ import com.sw.inbound.ui.theme.AppTypography
|
||||
import com.sw.inbound.ui.weight.CustomButton
|
||||
import com.sw.inbound.utils.QRCodeUtil
|
||||
import com.sw.inbound.utils.SPUtil
|
||||
import com.sw.inbound.utils.ToastUtils
|
||||
import com.sw.inbound.viewmodel.UserViewModel
|
||||
import timber.log.Timber
|
||||
|
||||
@@ -120,12 +119,17 @@ fun LoginScreen(
|
||||
.height(120.dp),
|
||||
text = "登录",
|
||||
onClick = {
|
||||
if (username.isEmpty() || password.isEmpty()) {
|
||||
ToastUtils.showToast("用户名或密码不能为空")
|
||||
return@CustomButton
|
||||
}
|
||||
//if (username.isEmpty() || password.isEmpty()) {
|
||||
// ToastUtils.showToast("用户名或密码不能为空")
|
||||
// return@CustomButton
|
||||
//}
|
||||
viewModel.login(username, password)
|
||||
// viewModel.test()
|
||||
// TODO: 测试功能,临时打开新页面
|
||||
controller.navigate(Screen.Home.route)
|
||||
// controller.context.startActivity<ReceiptActivity> {
|
||||
// putExtra(GoodsListActivity.ID, "123123")
|
||||
// putExtra(GoodsListActivity.SUPPLIER_ID, "123123123123")
|
||||
// }
|
||||
},
|
||||
borderColor = colorResource(R.color.blue),
|
||||
textColor = colorResource(R.color.white),
|
||||
|
||||
@@ -51,14 +51,17 @@ import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.activity.GoodsListActivity
|
||||
import com.sw.inbound.activity.ReceiptActivity
|
||||
import com.sw.inbound.activity.SelfProcurementActivity
|
||||
import com.sw.inbound.ext.dashedBorder
|
||||
import com.sw.inbound.ext.toFormattedString
|
||||
import com.sw.inbound.model.response.SupplierInfo
|
||||
import com.sw.inbound.ui.Screen
|
||||
import com.sw.inbound.ui.theme.AppTypography.blackTextStyle
|
||||
import com.sw.inbound.ui.theme.AppTypography.grayTextStyle
|
||||
import com.sw.inbound.ui.weight.BottomActionBar
|
||||
import com.sw.inbound.ui.weight.TopTitleBar
|
||||
import com.sw.inbound.utils.ext.startActivity
|
||||
import com.sw.inbound.viewmodel.PurchaseOrderViewModel
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
@@ -148,14 +151,20 @@ fun PurchaseOrderScreen(
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(30.dp)
|
||||
) {
|
||||
items(items = products, key = { it!!.id }) {
|
||||
items(items = products, key = { it!!.id?:"" }) {
|
||||
PurchaseOrderItem(it!!) {
|
||||
navController.navigate(
|
||||
Screen.ReceiptProduct.createRoute(
|
||||
it.id,
|
||||
it.supplierId
|
||||
)
|
||||
)
|
||||
// navController.navigate(
|
||||
// Screen.ReceiptProduct.createRoute(
|
||||
// it.id,
|
||||
// it.supplierId
|
||||
// )
|
||||
// )
|
||||
navController.context.startActivity<ReceiptActivity> {
|
||||
putExtra(GoodsListActivity.ID,it!!.id)
|
||||
putExtra(GoodsListActivity.SUPPLIER_ID,it.supplierId)
|
||||
putExtra(GoodsListActivity.IS_RECEIPT_PAGE,true)
|
||||
putExtra(GoodsListActivity.IS_NEW_RECEIPT,false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +189,14 @@ fun PurchaseOrderScreen(
|
||||
modifier = Modifier, onLeftButtonClick = {
|
||||
navController.popBackStack()
|
||||
}, onRight2ButtonClick = {
|
||||
navController.navigate(Screen.SelfProcurement.route)
|
||||
//navController.navigate(Screen.SelfProcurement.route)
|
||||
navController.context.startActivity<SelfProcurementActivity> {}
|
||||
//navController.context.startActivity<ReceiptActivity> {
|
||||
// //xtra(GoodsListActivity.ID,it!!.id)
|
||||
// //xtra(GoodsListActivity.SUPPLIER_ID,it.supplierId)
|
||||
// putExtra(GoodsListActivity.IS_RECEIPT_PAGE,true)
|
||||
// putExtra(GoodsListActivity.IS_NEW_RECEIPT,true)
|
||||
//}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -336,7 +352,7 @@ fun PurchaseOrderItem(product: SupplierInfo, onItemClick: (SupplierInfo) -> Unit
|
||||
}) {
|
||||
Text(
|
||||
if (product.receiveStatus == 4) "部分收货" else "收货",
|
||||
style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 30.sp)
|
||||
style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 26.sp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,15 @@
|
||||
package com.sw.inbound.ui.page
|
||||
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavHostController
|
||||
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@Composable
|
||||
fun TestScreen(modifier: Modifier.Companion, navController: NavHostController) {
|
||||
|
||||
}
|
||||
|
||||
//package com.sw.inbound.ui.page
|
||||
//
|
||||
//
|
||||
//import android.annotation.SuppressLint
|
||||
//import androidx.compose.runtime.Composable
|
||||
//import androidx.compose.ui.Modifier
|
||||
//import androidx.navigation.NavHostController
|
||||
//
|
||||
//
|
||||
//@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
//@Composable
|
||||
//fun TestScreen(modifier: Modifier.Companion, navController: NavHostController) {
|
||||
//
|
||||
//}
|
||||
//
|
||||
|
||||
@@ -1,113 +1,113 @@
|
||||
package com.sw.inbound.ui.weight
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MenuAnchorType.Companion.PrimaryNotEditable
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.ui.theme.AppTypography
|
||||
import com.sw.inbound.ui.theme.Black_141428
|
||||
|
||||
/**
|
||||
* 表单中的下拉菜单
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun CustomDropdownTextField(
|
||||
value: String,
|
||||
onValueChange: (String) -> Unit,
|
||||
dropdownItems: List<DictType>,
|
||||
modifier: Modifier = Modifier,
|
||||
placeholderValue: String = "请选择",
|
||||
textAlign: TextAlign = TextAlign.Start,
|
||||
textStyle: TextStyle? = null,
|
||||
enabled: Boolean = true,
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
var newTextStyle = textStyle
|
||||
?: LocalTextStyle.current.copy(
|
||||
color = Black_141428,
|
||||
fontSize = 24.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
textAlign = textAlign
|
||||
)
|
||||
|
||||
ExposedDropdownMenuBox(
|
||||
modifier = modifier,
|
||||
expanded = expanded || !enabled,
|
||||
onExpandedChange = { expanded = it },
|
||||
) {
|
||||
TextField(
|
||||
value = value,
|
||||
onValueChange = onValueChange,
|
||||
readOnly = true,
|
||||
textStyle = newTextStyle,
|
||||
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
trailingIcon = {
|
||||
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
|
||||
},
|
||||
colors = ExposedDropdownMenuDefaults.textFieldColors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
focusedIndicatorColor = Color.Transparent,
|
||||
unfocusedIndicatorColor = Color.Transparent
|
||||
),
|
||||
placeholder = {
|
||||
Text(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
text = placeholderValue, style = AppTypography.gray96a0aaTextStyle.copy(
|
||||
textAlign = textAlign
|
||||
)
|
||||
)
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(Color.Transparent)
|
||||
.border(
|
||||
width = 2.dp,
|
||||
color = colorResource(R.color.border_line),
|
||||
shape = RoundedCornerShape(10.dp)
|
||||
)
|
||||
.menuAnchor(PrimaryNotEditable, true)
|
||||
)
|
||||
|
||||
ExposedDropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
dropdownItems.forEach { item ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(text = item.value, style = AppTypography.black141428TextStyle) },
|
||||
onClick = {
|
||||
onValueChange(item.value)
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//package com.sw.inbound.ui.weight
|
||||
//
|
||||
//import androidx.compose.foundation.background
|
||||
//import androidx.compose.foundation.border
|
||||
//import androidx.compose.foundation.layout.fillMaxWidth
|
||||
//import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
//import androidx.compose.material3.DropdownMenuItem
|
||||
//import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
//import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
//import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
//import androidx.compose.material3.LocalTextStyle
|
||||
//import androidx.compose.material3.MenuAnchorType.Companion.PrimaryNotEditable
|
||||
//import androidx.compose.material3.Text
|
||||
//import androidx.compose.material3.TextField
|
||||
//import androidx.compose.runtime.Composable
|
||||
//import androidx.compose.runtime.getValue
|
||||
//import androidx.compose.runtime.mutableStateOf
|
||||
//import androidx.compose.runtime.remember
|
||||
//import androidx.compose.runtime.setValue
|
||||
//import androidx.compose.ui.Modifier
|
||||
//import androidx.compose.ui.graphics.Color
|
||||
//import androidx.compose.ui.res.colorResource
|
||||
//import androidx.compose.ui.text.TextStyle
|
||||
//import androidx.compose.ui.text.font.FontWeight
|
||||
//import androidx.compose.ui.text.style.TextAlign
|
||||
//import androidx.compose.ui.unit.dp
|
||||
//import androidx.compose.ui.unit.sp
|
||||
//import com.sw.inbound.R
|
||||
//import com.sw.inbound.model.response.DictType
|
||||
//import com.sw.inbound.ui.theme.AppTypography
|
||||
//import com.sw.inbound.ui.theme.Black_141428
|
||||
//
|
||||
///**
|
||||
// * 表单中的下拉菜单
|
||||
// */
|
||||
//@OptIn(ExperimentalMaterial3Api::class)
|
||||
//@Composable
|
||||
//fun CustomDropdownTextField(
|
||||
// value: String,
|
||||
// onValueChange: (String) -> Unit,
|
||||
// dropdownItems: List<DictType>,
|
||||
// modifier: Modifier = Modifier,
|
||||
// placeholderValue: String = "请选择",
|
||||
// textAlign: TextAlign = TextAlign.Start,
|
||||
// textStyle: TextStyle? = null,
|
||||
// enabled: Boolean = true,
|
||||
//) {
|
||||
// var expanded by remember { mutableStateOf(false) }
|
||||
// var newTextStyle = textStyle
|
||||
// ?: LocalTextStyle.current.copy(
|
||||
// color = Black_141428,
|
||||
// fontSize = 24.sp,
|
||||
// fontWeight = FontWeight.Bold,
|
||||
// textAlign = textAlign
|
||||
// )
|
||||
//
|
||||
// ExposedDropdownMenuBox(
|
||||
// modifier = modifier,
|
||||
// expanded = expanded || !enabled,
|
||||
// onExpandedChange = { expanded = it },
|
||||
// ) {
|
||||
// TextField(
|
||||
// value = value,
|
||||
// onValueChange = onValueChange,
|
||||
// readOnly = true,
|
||||
// textStyle = newTextStyle,
|
||||
//
|
||||
// shape = RoundedCornerShape(10.dp),
|
||||
// trailingIcon = {
|
||||
// ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
|
||||
// },
|
||||
// colors = ExposedDropdownMenuDefaults.textFieldColors(
|
||||
// focusedContainerColor = Color.Transparent,
|
||||
// unfocusedContainerColor = Color.Transparent,
|
||||
// disabledContainerColor = Color.Transparent,
|
||||
// focusedIndicatorColor = Color.Transparent,
|
||||
// unfocusedIndicatorColor = Color.Transparent
|
||||
// ),
|
||||
// placeholder = {
|
||||
// Text(
|
||||
// modifier = modifier.fillMaxWidth(),
|
||||
// text = placeholderValue, style = AppTypography.gray96a0aaTextStyle.copy(
|
||||
// textAlign = textAlign
|
||||
// )
|
||||
// )
|
||||
// },
|
||||
// modifier = Modifier
|
||||
// .fillMaxWidth()
|
||||
// .background(Color.Transparent)
|
||||
// .border(
|
||||
// width = 2.dp,
|
||||
// color = colorResource(R.color.border_line),
|
||||
// shape = RoundedCornerShape(10.dp)
|
||||
// )
|
||||
// .menuAnchor(PrimaryNotEditable, true)
|
||||
// )
|
||||
//
|
||||
// ExposedDropdownMenu(
|
||||
// expanded = expanded,
|
||||
// onDismissRequest = { expanded = false }
|
||||
// ) {
|
||||
// dropdownItems.forEach { item ->
|
||||
// DropdownMenuItem(
|
||||
// text = { Text(text = item.value?:"", style = AppTypography.black141428TextStyle) },
|
||||
// onClick = {
|
||||
// onValueChange(item.value?:"")
|
||||
// expanded = false
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -1,106 +1,106 @@
|
||||
package com.sw.inbound.ui.weight
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
import androidx.compose.material3.MenuAnchorType.Companion.PrimaryNotEditable
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.model.response.DictType
|
||||
|
||||
/**
|
||||
* 自定义顶部仓库下拉
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun CustomSpinner(
|
||||
items: List<DictType>,
|
||||
selectedItem: String,
|
||||
onItemSelected: (DictType) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
// var expanded by remember { mutableStateOf(false) }
|
||||
var expanded by remember { mutableStateOf(true) }
|
||||
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = !expanded },
|
||||
modifier = modifier.background(
|
||||
color = Color(0x80FFFFFF),
|
||||
shape = RoundedCornerShape(10.dp) // 圆角背景
|
||||
)
|
||||
) {
|
||||
TextField(
|
||||
value = selectedItem,
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
textStyle = TextStyle(
|
||||
color = Color.White,
|
||||
fontSize = 24.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
trailingIcon = {
|
||||
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
|
||||
},
|
||||
colors = ExposedDropdownMenuDefaults.textFieldColors(
|
||||
focusedContainerColor = colorResource(R.color.blue),
|
||||
unfocusedContainerColor = colorResource(R.color.blue),
|
||||
disabledContainerColor = colorResource(R.color.blue),
|
||||
focusedTextColor = Color.White,
|
||||
unfocusedTextColor = Color.White,
|
||||
cursorColor = Color.White,
|
||||
focusedIndicatorColor = Color.Transparent,
|
||||
unfocusedIndicatorColor = Color.Transparent,
|
||||
focusedLabelColor = Color.White.copy(alpha = 0.8f),
|
||||
unfocusedLabelColor = Color.White.copy(alpha = 0.8f),
|
||||
focusedTrailingIconColor = Color.White,
|
||||
unfocusedTrailingIconColor = Color.White
|
||||
),
|
||||
modifier = Modifier.menuAnchor(PrimaryNotEditable, true)
|
||||
)
|
||||
|
||||
ExposedDropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false },
|
||||
modifier = Modifier
|
||||
.background(colorResource(R.color.blue))
|
||||
.exposedDropdownSize(matchTextFieldWidth = true)
|
||||
) {
|
||||
items.forEach { item ->
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(
|
||||
text = item.value,
|
||||
style = TextStyle(
|
||||
color = Color.White,
|
||||
fontSize = 24.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
onItemSelected(item)
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//package com.sw.inbound.ui.weight
|
||||
//
|
||||
//import androidx.compose.foundation.background
|
||||
//import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
//import androidx.compose.material3.DropdownMenuItem
|
||||
//import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
//import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
//import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
//import androidx.compose.material3.MenuAnchorType.Companion.PrimaryNotEditable
|
||||
//import androidx.compose.material3.Text
|
||||
//import androidx.compose.material3.TextField
|
||||
//import androidx.compose.runtime.Composable
|
||||
//import androidx.compose.runtime.getValue
|
||||
//import androidx.compose.runtime.mutableStateOf
|
||||
//import androidx.compose.runtime.remember
|
||||
//import androidx.compose.runtime.setValue
|
||||
//import androidx.compose.ui.Modifier
|
||||
//import androidx.compose.ui.graphics.Color
|
||||
//import androidx.compose.ui.res.colorResource
|
||||
//import androidx.compose.ui.text.TextStyle
|
||||
//import androidx.compose.ui.text.font.FontWeight
|
||||
//import androidx.compose.ui.unit.dp
|
||||
//import androidx.compose.ui.unit.sp
|
||||
//import com.sw.inbound.R
|
||||
//import com.sw.inbound.model.response.DictType
|
||||
//
|
||||
///**
|
||||
// * 自定义顶部仓库下拉
|
||||
// */
|
||||
//@OptIn(ExperimentalMaterial3Api::class)
|
||||
//@Composable
|
||||
//fun CustomSpinner(
|
||||
// items: List<DictType>,
|
||||
// selectedItem: String,
|
||||
// onItemSelected: (DictType) -> Unit,
|
||||
// modifier: Modifier = Modifier,
|
||||
//) {
|
||||
//// var expanded by remember { mutableStateOf(false) }
|
||||
// var expanded by remember { mutableStateOf(true) }
|
||||
//
|
||||
// ExposedDropdownMenuBox(
|
||||
// expanded = expanded,
|
||||
// onExpandedChange = { expanded = !expanded },
|
||||
// modifier = modifier.background(
|
||||
// color = Color(0x80FFFFFF),
|
||||
// shape = RoundedCornerShape(10.dp) // 圆角背景
|
||||
// )
|
||||
// ) {
|
||||
// TextField(
|
||||
// value = selectedItem,
|
||||
// onValueChange = {},
|
||||
// readOnly = true,
|
||||
// textStyle = TextStyle(
|
||||
// color = Color.White,
|
||||
// fontSize = 24.sp,
|
||||
// fontWeight = FontWeight.Bold
|
||||
// ),
|
||||
// shape = RoundedCornerShape(10.dp),
|
||||
// trailingIcon = {
|
||||
// ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
|
||||
// },
|
||||
// colors = ExposedDropdownMenuDefaults.textFieldColors(
|
||||
// focusedContainerColor = colorResource(R.color.blue),
|
||||
// unfocusedContainerColor = colorResource(R.color.blue),
|
||||
// disabledContainerColor = colorResource(R.color.blue),
|
||||
// focusedTextColor = Color.White,
|
||||
// unfocusedTextColor = Color.White,
|
||||
// cursorColor = Color.White,
|
||||
// focusedIndicatorColor = Color.Transparent,
|
||||
// unfocusedIndicatorColor = Color.Transparent,
|
||||
// focusedLabelColor = Color.White.copy(alpha = 0.8f),
|
||||
// unfocusedLabelColor = Color.White.copy(alpha = 0.8f),
|
||||
// focusedTrailingIconColor = Color.White,
|
||||
// unfocusedTrailingIconColor = Color.White
|
||||
// ),
|
||||
// modifier = Modifier.menuAnchor(PrimaryNotEditable, true)
|
||||
// )
|
||||
//
|
||||
// ExposedDropdownMenu(
|
||||
// expanded = expanded,
|
||||
// onDismissRequest = { expanded = false },
|
||||
// modifier = Modifier
|
||||
// .background(colorResource(R.color.blue))
|
||||
// .exposedDropdownSize(matchTextFieldWidth = true)
|
||||
// ) {
|
||||
// items.forEach { item ->
|
||||
// DropdownMenuItem(
|
||||
// text = {
|
||||
// Text(
|
||||
// text = item.value?:"",
|
||||
// style = TextStyle(
|
||||
// color = Color.White,
|
||||
// fontSize = 24.sp,
|
||||
// fontWeight = FontWeight.Bold
|
||||
// ),
|
||||
// )
|
||||
// },
|
||||
// onClick = {
|
||||
// onItemSelected(item)
|
||||
// expanded = false
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -1,216 +1,216 @@
|
||||
package com.sw.inbound.ui.weight
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.camera.view.CameraController
|
||||
import androidx.camera.view.LifecycleCameraController
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableDoubleStateOf
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import com.sw.inbound.ext.medium
|
||||
import com.sw.inbound.model.request.PurchaseWarehouseParam
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.ui.theme.AppTypography
|
||||
import com.sw.inbound.utils.InteractionUtils.Debouncer
|
||||
import com.sw.inbound.utils.rememberPhotoCapture
|
||||
import com.sw.inbound.viewmodel.BaseViewModel
|
||||
import com.sw.inbound.viewmodel.ReceiptViewModel
|
||||
import com.sw.inbound.viewmodel.SelfProcurementViewModel
|
||||
import timber.log.Timber
|
||||
|
||||
enum class PageType {
|
||||
/**
|
||||
* 自采
|
||||
*/
|
||||
SELF_PROCUREMENT,
|
||||
|
||||
/**
|
||||
* 收货
|
||||
*/
|
||||
RECEIPT_PRODUCT
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜品识别组件
|
||||
*/
|
||||
@Composable
|
||||
fun IdentityView(
|
||||
showSearchView: Boolean = false,
|
||||
onOptionSelected: (SearchGoodsInfo.Record) -> Unit = {},
|
||||
checkedItem: PurchaseWarehouseParam? = null,
|
||||
baseViewModel: BaseViewModel,
|
||||
pageType: PageType
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
val weightInfo by baseViewModel.weightInfo.collectAsState()
|
||||
val identityList by baseViewModel.identityListItems.collectAsState()
|
||||
val receiptList by baseViewModel.receiptList.collectAsState()
|
||||
val searchList by baseViewModel.searchListItems.collectAsState()
|
||||
// var lastWeight by remember { mutableStateOf<Double?>(null) }
|
||||
var lastWeight by remember { mutableDoubleStateOf(0.0) }
|
||||
val lastPhotoUri by baseViewModel.lastPhotoUri.collectAsState()
|
||||
var pageNum by remember { mutableIntStateOf(1) }
|
||||
val isMoreLoading by baseViewModel.isMoreLoading.collectAsState()
|
||||
val canLoadMore by baseViewModel.canLoadMore.collectAsState()
|
||||
var list = if (identityList.isNotEmpty()) {
|
||||
identityList
|
||||
} else {
|
||||
searchList
|
||||
}
|
||||
val debouncer = remember { Debouncer(2000) }
|
||||
var isCameraReady by remember { mutableStateOf(false) }
|
||||
|
||||
// CameraX 控制器
|
||||
val cameraController = remember {
|
||||
LifecycleCameraController(context).apply {
|
||||
// 必须设置有效的用例
|
||||
setEnabledUseCases(
|
||||
CameraController.IMAGE_CAPTURE or
|
||||
CameraController.VIDEO_CAPTURE
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 需要搜索的信息
|
||||
var searchInfo by remember { mutableStateOf("") }
|
||||
// 创建拍照工具实例
|
||||
val (photoCaptureHelper, takePhoto) = rememberPhotoCapture(
|
||||
cameraController = cameraController,
|
||||
onSuccess = { savedUri ->
|
||||
// 处理拍照成功的逻辑
|
||||
baseViewModel.updateLastPhotoUri(savedUri)
|
||||
Timber.d("photoUri = $savedUri")
|
||||
if (pageType == PageType.SELF_PROCUREMENT) {
|
||||
(baseViewModel as SelfProcurementViewModel).updateSelectedItem(null)
|
||||
} else if (pageType == PageType.RECEIPT_PRODUCT) {
|
||||
(baseViewModel as ReceiptViewModel).updateSelectedItem(null)
|
||||
}
|
||||
baseViewModel.getIdentityList(savedUri)
|
||||
},
|
||||
onError = { error ->
|
||||
// 处理拍照失败的逻辑
|
||||
Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
|
||||
baseViewModel.updateLastPhotoUri(null)
|
||||
}
|
||||
)
|
||||
|
||||
// 绑定生命周期
|
||||
DisposableEffect(lifecycleOwner) {
|
||||
cameraController.bindToLifecycle(lifecycleOwner)
|
||||
onDispose {
|
||||
cameraController.unbind()
|
||||
isCameraReady = false
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(weightInfo) {
|
||||
Timber.d("LaunchedEffect weightInfo1 = $weightInfo, lastWeight = $lastWeight")
|
||||
if (weightInfo - lastWeight > 1.0) {
|
||||
Timber.d("LaunchedEffect pageType = $pageType, receiptList = ${receiptList.size}")
|
||||
var canIdentity = false
|
||||
if (pageType == PageType.RECEIPT_PRODUCT) {
|
||||
val selectItem = (baseViewModel as ReceiptViewModel).selectedItem.value
|
||||
canIdentity =
|
||||
receiptList.isNotEmpty() && (selectItem == null || selectItem.goodId == 0)
|
||||
} else if (pageType == PageType.SELF_PROCUREMENT) {
|
||||
val selectItem = (baseViewModel as SelfProcurementViewModel).selectedItem.value
|
||||
canIdentity = selectItem == null || selectItem.goodsId == 0
|
||||
}
|
||||
Timber.d("LaunchedEffect canIdentity = $canIdentity")
|
||||
if (canIdentity) {
|
||||
debouncer.debounce {
|
||||
Timber.d("LaunchedEffect isCameraReady = $isCameraReady")
|
||||
if (isCameraReady) {
|
||||
takePhoto()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lastWeight = weightInfo
|
||||
}
|
||||
|
||||
// 监听相机初始化
|
||||
LaunchedEffect(Unit) {
|
||||
try {
|
||||
cameraController.initializationFuture.addListener({
|
||||
isCameraReady = true
|
||||
Timber.d("Camera initialized successfully")
|
||||
}, ContextCompat.getMainExecutor(context))
|
||||
} catch (e: Exception) {
|
||||
Timber.d("Camera initialized error = ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
CameraPreview(
|
||||
modifier = Modifier
|
||||
.width(397.dp)
|
||||
.height(298.dp),
|
||||
controller = cameraController,
|
||||
photoUri = lastPhotoUri
|
||||
)
|
||||
if (showSearchView) {
|
||||
Spacer(modifier = Modifier.height(30.dp))
|
||||
CustomSearchView(onSearchClick = {
|
||||
if (pageType == PageType.SELF_PROCUREMENT) {
|
||||
(baseViewModel as SelfProcurementViewModel).updateSelectedItem(null)
|
||||
}
|
||||
searchInfo = it
|
||||
baseViewModel.searchGoodsInfoList(it)
|
||||
})
|
||||
}
|
||||
Spacer(modifier = Modifier.height(30.dp))
|
||||
if (showSearchView) {
|
||||
SingleSelectButtonGroup(
|
||||
modifier = Modifier
|
||||
.height(64.dp)
|
||||
.width(192.dp), options = list,
|
||||
onOptionSelected = onOptionSelected,
|
||||
onLoadMore = {
|
||||
Timber.d("加载更多 canLoadMore = $canLoadMore")
|
||||
if (!canLoadMore) {
|
||||
return@SingleSelectButtonGroup
|
||||
}
|
||||
pageNum++
|
||||
baseViewModel.searchGoodsInfoList(goodsName = searchInfo, pageNo = pageNum)
|
||||
},
|
||||
checkedItem = list.find { it.goodsId == checkedItem?.goodsId },
|
||||
isMoreLoading = isMoreLoading,
|
||||
canLoadMore = canLoadMore
|
||||
)
|
||||
} else {
|
||||
SingleSelectButtonGroup(
|
||||
modifier = Modifier
|
||||
.height(70.dp)
|
||||
.width(215.dp),
|
||||
options = list,
|
||||
horizontalSpacing = 30.dp,
|
||||
verticalSpacing = 20.dp,
|
||||
onOptionSelected = onOptionSelected,
|
||||
unSelectedTextStyle = AppTypography.blackTextStyle.medium()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
//package com.sw.inbound.ui.weight
|
||||
//
|
||||
//import android.widget.Toast
|
||||
//import androidx.camera.view.CameraController
|
||||
//import androidx.camera.view.LifecycleCameraController
|
||||
//import androidx.compose.foundation.layout.Column
|
||||
//import androidx.compose.foundation.layout.Spacer
|
||||
//import androidx.compose.foundation.layout.fillMaxSize
|
||||
//import androidx.compose.foundation.layout.height
|
||||
//import androidx.compose.foundation.layout.width
|
||||
//import androidx.compose.runtime.Composable
|
||||
//import androidx.compose.runtime.DisposableEffect
|
||||
//import androidx.compose.runtime.LaunchedEffect
|
||||
//import androidx.compose.runtime.collectAsState
|
||||
//import androidx.compose.runtime.getValue
|
||||
//import androidx.compose.runtime.mutableDoubleStateOf
|
||||
//import androidx.compose.runtime.mutableIntStateOf
|
||||
//import androidx.compose.runtime.mutableStateOf
|
||||
//import androidx.compose.runtime.remember
|
||||
//import androidx.compose.runtime.setValue
|
||||
//import androidx.compose.ui.Alignment
|
||||
//import androidx.compose.ui.Modifier
|
||||
//import androidx.compose.ui.platform.LocalContext
|
||||
//import androidx.compose.ui.unit.dp
|
||||
//import androidx.core.content.ContextCompat
|
||||
//import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
//import com.sw.inbound.ext.medium
|
||||
//import com.sw.inbound.model.request.PurchaseWarehouseParam
|
||||
//import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
//import com.sw.inbound.ui.theme.AppTypography
|
||||
//import com.sw.inbound.utils.InteractionUtils.Debouncer
|
||||
//import com.sw.inbound.utils.rememberPhotoCapture
|
||||
//import com.sw.inbound.viewmodel.BaseViewModel
|
||||
//import com.sw.inbound.viewmodel.ReceiptViewModel
|
||||
//import com.sw.inbound.viewmodel.SelfProcurementViewModel
|
||||
//import timber.log.Timber
|
||||
//
|
||||
//enum class PageType {
|
||||
// /**
|
||||
// * 自采
|
||||
// */
|
||||
// SELF_PROCUREMENT,
|
||||
//
|
||||
// /**
|
||||
// * 收货
|
||||
// */
|
||||
// RECEIPT_PRODUCT
|
||||
//}
|
||||
//
|
||||
///**
|
||||
// * 菜品识别组件
|
||||
// */
|
||||
//@Composable
|
||||
//fun IdentityView(
|
||||
// showSearchView: Boolean = false,
|
||||
// onOptionSelected: (SearchGoodsInfo.Record) -> Unit = {},
|
||||
// checkedItem: PurchaseWarehouseParam? = null,
|
||||
// baseViewModel: BaseViewModel,
|
||||
// pageType: PageType
|
||||
//) {
|
||||
// val context = LocalContext.current
|
||||
// val lifecycleOwner = LocalLifecycleOwner.current
|
||||
// val weightInfo by baseViewModel.weightInfo.collectAsState()
|
||||
// val identityList by baseViewModel.identityListItems.collectAsState()
|
||||
// val receiptList by baseViewModel.receiptList.collectAsState()
|
||||
// val searchList by baseViewModel.searchListItems.collectAsState()
|
||||
//// var lastWeight by remember { mutableStateOf<Double?>(null) }
|
||||
// var lastWeight by remember { mutableDoubleStateOf(0.0) }
|
||||
// val lastPhotoUri by baseViewModel.lastPhotoUri.collectAsState()
|
||||
// var pageNum by remember { mutableIntStateOf(1) }
|
||||
// val isMoreLoading by baseViewModel.isMoreLoading.collectAsState()
|
||||
// val canLoadMore by baseViewModel.canLoadMore.collectAsState()
|
||||
// var list = if (identityList.isNotEmpty()) {
|
||||
// identityList
|
||||
// } else {
|
||||
// searchList
|
||||
// }
|
||||
// val debouncer = remember { Debouncer(2000) }
|
||||
// var isCameraReady by remember { mutableStateOf(false) }
|
||||
//
|
||||
// // CameraX 控制器
|
||||
// val cameraController = remember {
|
||||
// LifecycleCameraController(context).apply {
|
||||
// // 必须设置有效的用例
|
||||
// setEnabledUseCases(
|
||||
// CameraController.IMAGE_CAPTURE or
|
||||
// CameraController.VIDEO_CAPTURE
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 需要搜索的信息
|
||||
// var searchInfo by remember { mutableStateOf("") }
|
||||
// // 创建拍照工具实例
|
||||
// val (photoCaptureHelper, takePhoto) = rememberPhotoCapture(
|
||||
// cameraController = cameraController,
|
||||
// onSuccess = { savedUri ->
|
||||
// // 处理拍照成功的逻辑
|
||||
// baseViewModel.updateLastPhotoUri(savedUri)
|
||||
// Timber.d("photoUri = $savedUri")
|
||||
// if (pageType == PageType.SELF_PROCUREMENT) {
|
||||
// (baseViewModel as SelfProcurementViewModel).updateSelectedItem(null)
|
||||
// } else if (pageType == PageType.RECEIPT_PRODUCT) {
|
||||
// (baseViewModel as ReceiptViewModel).updateSelectedItem(null)
|
||||
// }
|
||||
// baseViewModel.getIdentityList(savedUri)
|
||||
// },
|
||||
// onError = { error ->
|
||||
// // 处理拍照失败的逻辑
|
||||
// Toast.makeText(context, error, Toast.LENGTH_SHORT).show()
|
||||
// baseViewModel.updateLastPhotoUri(null)
|
||||
// }
|
||||
// )
|
||||
//
|
||||
// // 绑定生命周期
|
||||
// DisposableEffect(lifecycleOwner) {
|
||||
// cameraController.bindToLifecycle(lifecycleOwner)
|
||||
// onDispose {
|
||||
// cameraController.unbind()
|
||||
// isCameraReady = false
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// LaunchedEffect(weightInfo) {
|
||||
// Timber.d("LaunchedEffect weightInfo1 = $weightInfo, lastWeight = $lastWeight")
|
||||
// if (weightInfo - lastWeight > 1.0) {
|
||||
// Timber.d("LaunchedEffect pageType = $pageType, receiptList = ${receiptList.size}")
|
||||
// var canIdentity = false
|
||||
// if (pageType == PageType.RECEIPT_PRODUCT) {
|
||||
// val selectItem = (baseViewModel as ReceiptViewModel).selectedItem.value
|
||||
// canIdentity =
|
||||
// receiptList.isNotEmpty() && (selectItem == null || selectItem.goodId.isNullOrBlank())
|
||||
// } else if (pageType == PageType.SELF_PROCUREMENT) {
|
||||
// val selectItem = (baseViewModel as SelfProcurementViewModel).selectedItem.value
|
||||
// canIdentity = selectItem == null || selectItem.goodsId.isNullOrBlank()
|
||||
// }
|
||||
// Timber.d("LaunchedEffect canIdentity = $canIdentity")
|
||||
// if (canIdentity) {
|
||||
// debouncer.debounce {
|
||||
// Timber.d("LaunchedEffect isCameraReady = $isCameraReady")
|
||||
// if (isCameraReady) {
|
||||
// takePhoto()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// lastWeight = weightInfo
|
||||
// }
|
||||
//
|
||||
// // 监听相机初始化
|
||||
// LaunchedEffect(Unit) {
|
||||
// try {
|
||||
// cameraController.initializationFuture.addListener({
|
||||
// isCameraReady = true
|
||||
// Timber.d("Camera initialized successfully")
|
||||
// }, ContextCompat.getMainExecutor(context))
|
||||
// } catch (e: Exception) {
|
||||
// Timber.d("Camera initialized error = ${e.message}")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Column(
|
||||
// modifier = Modifier
|
||||
// .fillMaxSize(),
|
||||
// horizontalAlignment = Alignment.CenterHorizontally
|
||||
// ) {
|
||||
// CameraPreview(
|
||||
// modifier = Modifier
|
||||
// .width(397.dp)
|
||||
// .height(298.dp),
|
||||
// controller = cameraController,
|
||||
// photoUri = lastPhotoUri
|
||||
// )
|
||||
// if (showSearchView) {
|
||||
// Spacer(modifier = Modifier.height(30.dp))
|
||||
// CustomSearchView(onSearchClick = {
|
||||
// if (pageType == PageType.SELF_PROCUREMENT) {
|
||||
// (baseViewModel as SelfProcurementViewModel).updateSelectedItem(null)
|
||||
// }
|
||||
// searchInfo = it
|
||||
// baseViewModel.searchGoodsInfoList(it)
|
||||
// })
|
||||
// }
|
||||
// Spacer(modifier = Modifier.height(30.dp))
|
||||
// if (showSearchView) {
|
||||
// SingleSelectButtonGroup(
|
||||
// modifier = Modifier
|
||||
// .height(64.dp)
|
||||
// .width(192.dp), options = list,
|
||||
// onOptionSelected = onOptionSelected,
|
||||
// onLoadMore = {
|
||||
// Timber.d("加载更多 canLoadMore = $canLoadMore")
|
||||
// if (!canLoadMore) {
|
||||
// return@SingleSelectButtonGroup
|
||||
// }
|
||||
// pageNum++
|
||||
// baseViewModel.searchGoodsInfoList(goodsName = searchInfo, pageNo = pageNum)
|
||||
// },
|
||||
// checkedItem = list.find { it.goodsId == checkedItem?.goodsId },
|
||||
// isMoreLoading = isMoreLoading,
|
||||
// canLoadMore = canLoadMore
|
||||
// )
|
||||
// } else {
|
||||
// SingleSelectButtonGroup(
|
||||
// modifier = Modifier
|
||||
// .height(70.dp)
|
||||
// .width(215.dp),
|
||||
// options = list,
|
||||
// horizontalSpacing = 30.dp,
|
||||
// verticalSpacing = 20.dp,
|
||||
// onOptionSelected = onOptionSelected,
|
||||
// unSelectedTextStyle = AppTypography.blackTextStyle.medium()
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -1,83 +1,83 @@
|
||||
package com.sw.inbound.ui.weight
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.sw.inbound.R
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.ui.theme.AppTypography
|
||||
|
||||
/**
|
||||
* 横向输入框 包含左侧文件+右侧输入框
|
||||
*/
|
||||
@Composable
|
||||
fun RowInputLayout(
|
||||
label: String, // 左侧文字
|
||||
value: String,
|
||||
onValueChange: (String) -> Unit,
|
||||
dropdownItems: List<DictType>? = null, // 下拉列表
|
||||
hasNext: Boolean = true, // 键盘显示下一步
|
||||
inputType: InputType = InputType.Text,
|
||||
trailingLabel: String? = null, // 尾部文字
|
||||
keyboardOptions: KeyboardOptions? = null,
|
||||
keyboardActions: KeyboardActions? = null,
|
||||
isInitUpdate: Boolean = false, // 是否根据原始数据更新
|
||||
showRightButton: Boolean = false,
|
||||
onRightButtonClick: () -> Unit = {},
|
||||
) {
|
||||
val textWidth = if (showRightButton) 218.dp else 290.dp
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.height(60.dp)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 30.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(label, style = AppTypography.black141428TextStyle)
|
||||
// Spacer(modifier = Modifier.width(67.dp))
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
if (dropdownItems == null) {
|
||||
CustomTextField(
|
||||
modifier = Modifier.width(textWidth),
|
||||
value = value, onValueChange = onValueChange,
|
||||
textAlign = TextAlign.End,
|
||||
trailingLabel = trailingLabel,
|
||||
hasNext = hasNext,
|
||||
inputType = inputType,
|
||||
keyboardOptions = keyboardOptions,
|
||||
keyboardActions = keyboardActions,
|
||||
isInitUpdate = isInitUpdate
|
||||
)
|
||||
} else {
|
||||
CustomDropdownTextField(
|
||||
modifier = Modifier.width(textWidth),
|
||||
value = value,
|
||||
dropdownItems = dropdownItems,
|
||||
onValueChange = onValueChange,
|
||||
textAlign = TextAlign.End
|
||||
)
|
||||
}
|
||||
if (showRightButton) {
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Image(modifier = Modifier.clickable {
|
||||
onRightButtonClick()
|
||||
}, painter = painterResource(R.drawable.ic_add), contentDescription = "添加")
|
||||
}
|
||||
}
|
||||
}
|
||||
//package com.sw.inbound.ui.weight
|
||||
//
|
||||
//import androidx.compose.foundation.Image
|
||||
//import androidx.compose.foundation.clickable
|
||||
//import androidx.compose.foundation.layout.Arrangement
|
||||
//import androidx.compose.foundation.layout.Row
|
||||
//import androidx.compose.foundation.layout.Spacer
|
||||
//import androidx.compose.foundation.layout.fillMaxWidth
|
||||
//import androidx.compose.foundation.layout.height
|
||||
//import androidx.compose.foundation.layout.padding
|
||||
//import androidx.compose.foundation.layout.width
|
||||
//import androidx.compose.foundation.text.KeyboardActions
|
||||
//import androidx.compose.foundation.text.KeyboardOptions
|
||||
//import androidx.compose.material3.Text
|
||||
//import androidx.compose.runtime.Composable
|
||||
//import androidx.compose.ui.Alignment
|
||||
//import androidx.compose.ui.Modifier
|
||||
//import androidx.compose.ui.res.painterResource
|
||||
//import androidx.compose.ui.text.style.TextAlign
|
||||
//import androidx.compose.ui.unit.dp
|
||||
//import com.sw.inbound.R
|
||||
//import com.sw.inbound.model.response.DictType
|
||||
//import com.sw.inbound.ui.theme.AppTypography
|
||||
//
|
||||
///**
|
||||
// * 横向输入框 包含左侧文件+右侧输入框
|
||||
// */
|
||||
//@Composable
|
||||
//fun RowInputLayout(
|
||||
// label: String, // 左侧文字
|
||||
// value: String,
|
||||
// onValueChange: (String) -> Unit,
|
||||
// dropdownItems: List<DictType>? = null, // 下拉列表
|
||||
// hasNext: Boolean = true, // 键盘显示下一步
|
||||
// inputType: InputType = InputType.Text,
|
||||
// trailingLabel: String? = null, // 尾部文字
|
||||
// keyboardOptions: KeyboardOptions? = null,
|
||||
// keyboardActions: KeyboardActions? = null,
|
||||
// isInitUpdate: Boolean = false, // 是否根据原始数据更新
|
||||
// showRightButton: Boolean = false,
|
||||
// onRightButtonClick: () -> Unit = {},
|
||||
//) {
|
||||
// val textWidth = if (showRightButton) 218.dp else 290.dp
|
||||
// Row(
|
||||
// modifier = Modifier
|
||||
// .height(60.dp)
|
||||
// .fillMaxWidth()
|
||||
// .padding(horizontal = 30.dp),
|
||||
// horizontalArrangement = Arrangement.SpaceBetween,
|
||||
// verticalAlignment = Alignment.CenterVertically
|
||||
// ) {
|
||||
// Text(label, style = AppTypography.black141428TextStyle)
|
||||
//// Spacer(modifier = Modifier.width(67.dp))
|
||||
// Spacer(modifier = Modifier.weight(1f))
|
||||
// if (dropdownItems == null) {
|
||||
// CustomTextField(
|
||||
// modifier = Modifier.width(textWidth),
|
||||
// value = value, onValueChange = onValueChange,
|
||||
// textAlign = TextAlign.End,
|
||||
// trailingLabel = trailingLabel,
|
||||
// hasNext = hasNext,
|
||||
// inputType = inputType,
|
||||
// keyboardOptions = keyboardOptions,
|
||||
// keyboardActions = keyboardActions,
|
||||
// isInitUpdate = isInitUpdate
|
||||
// )
|
||||
// } else {
|
||||
// CustomDropdownTextField(
|
||||
// modifier = Modifier.width(textWidth),
|
||||
// value = value,
|
||||
// dropdownItems = dropdownItems,
|
||||
// onValueChange = onValueChange,
|
||||
// textAlign = TextAlign.End
|
||||
// )
|
||||
// }
|
||||
// if (showRightButton) {
|
||||
// Spacer(modifier = Modifier.width(12.dp))
|
||||
// Image(modifier = Modifier.clickable {
|
||||
// onRightButtonClick()
|
||||
// }, painter = painterResource(R.drawable.ic_add), contentDescription = "添加")
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -48,7 +48,8 @@ import kotlinx.coroutines.delay
|
||||
@Composable
|
||||
fun TopTitleBar(
|
||||
modifier: Modifier = Modifier,
|
||||
title: String = "采购单入库",
|
||||
// title: String = "采购单入库",
|
||||
title: String = "出入库管理",
|
||||
user: User? = null,
|
||||
onLogoutClick: () -> Unit = {}
|
||||
) {
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.sw.inbound.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import java.io.BufferedReader
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
|
||||
|
||||
object AssetsTool {
|
||||
|
||||
// fun readJson(context: Context, fileName: String): List<String> {
|
||||
// val json = readAssetsFile(context, fileName)
|
||||
// val json2 = json.replace("[[", "[").replaceAfterLast("]]", "]")
|
||||
// val list = json2.split("],")
|
||||
// val resultList = mutableListOf<String>()
|
||||
// var count = 0
|
||||
// val tempList = mutableListOf<String>()
|
||||
// list.forEachIndexed { index, text ->
|
||||
// if (count >= 500) {
|
||||
// val tempJson = "[${tempList.joinToString (",")}]"
|
||||
// resultList.add(tempJson)
|
||||
// tempList.clear()
|
||||
// count = 0
|
||||
// }
|
||||
// val newText = if (index == list.size - 1) text else "${text}]"
|
||||
// tempList.add(newText)
|
||||
// count++
|
||||
// }
|
||||
// if (count < 500) {
|
||||
// val tempJson = "[${tempList.joinToString(",")}]"
|
||||
// resultList.add(tempJson)
|
||||
// }
|
||||
// return resultList
|
||||
// }
|
||||
|
||||
fun readAssetsFile(context: Context, fileName: String): String {
|
||||
val stringBuilder = StringBuilder()
|
||||
try {
|
||||
val bf = BufferedReader(InputStreamReader(context.assets.open(fileName)))
|
||||
bf.useLines { lines -> lines.forEach { stringBuilder.append(it) } }
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return stringBuilder.toString()
|
||||
}
|
||||
|
||||
fun loadImagesFromAssets(context: Context, subPath: String): MutableList<Bitmap> {
|
||||
val bitmaps: MutableList<Bitmap> = mutableListOf()
|
||||
val assetManager = context.assets
|
||||
|
||||
try {
|
||||
val files = assetManager.list(subPath)
|
||||
files?.forEach { file ->
|
||||
assetManager.open("$subPath/$file").use { `is` ->
|
||||
val bitmap = BitmapFactory.decodeStream(`is`)
|
||||
if (bitmap != null) {
|
||||
bitmaps.add(bitmap)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return bitmaps
|
||||
}
|
||||
|
||||
fun loadImageBitmapFromAssets(context: Context, imagePath:String, action:(bmp: Bitmap)-> Unit) {
|
||||
context.assets.open(imagePath).use { `is` ->
|
||||
val bitmap = BitmapFactory.decodeStream(`is`)
|
||||
action(bitmap)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.sw.inbound.utils
|
||||
import android.graphics.Bitmap
|
||||
|
||||
object BitmapCropper {
|
||||
/**
|
||||
* 裁剪Bitmap中心区域为指定尺寸
|
||||
* @param original 原始Bitmap
|
||||
* @param targetWidth 目标宽度
|
||||
* @param targetHeight 目标高度
|
||||
* @return 裁剪后的Bitmap
|
||||
*/
|
||||
fun cropCenter(original: Bitmap, targetWidth: Int, targetHeight: Int, offsetX:Int = 0, offsetY:Int = 0): Bitmap {
|
||||
val originalWidth = original.width
|
||||
val originalHeight = original.height
|
||||
|
||||
// 计算中心点坐标
|
||||
var startX = (originalWidth - targetWidth) / 2 + offsetX
|
||||
var startY = (originalHeight - targetHeight) / 2 + offsetY
|
||||
|
||||
// 边界检查
|
||||
startX = startX.coerceAtLeast(0)
|
||||
startY = startY.coerceAtLeast(0)
|
||||
val actualWidth = minOf(targetWidth, originalWidth - startX)
|
||||
val actualHeight = minOf(targetHeight, originalHeight - startY)
|
||||
|
||||
return Bitmap.createBitmap(original, startX, startY, actualWidth, actualHeight)
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
//fun main() {
|
||||
// // 假设这是从资源加载的Bitmap
|
||||
// val originalBitmap = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888)
|
||||
|
||||
// // 裁剪中心500x500区域
|
||||
// val croppedBitmap = BitmapCropper.cropCenter(originalBitmap, 500, 500)
|
||||
// println("裁剪后尺寸:${croppedBitmap.width}x${croppedBitmap.height}")
|
||||
//}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.sw.inbound.utils
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Environment
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
object BitmapSaver {
|
||||
// 保存到公共目录(需WRITE_EXTERNAL_STORAGE权限)
|
||||
fun saveToPublicDirectory(
|
||||
bitmap: Bitmap,
|
||||
folderName: String = Environment.DIRECTORY_PICTURES,
|
||||
fileName: String,
|
||||
format: Bitmap.CompressFormat = Bitmap.CompressFormat.PNG,
|
||||
quality: Int = 100
|
||||
): File? {
|
||||
val dir = Environment.getExternalStoragePublicDirectory(folderName)
|
||||
if (!dir.exists()) dir.mkdirs()
|
||||
|
||||
return saveBitmap(bitmap, File(dir, fileName), format, quality)
|
||||
}
|
||||
|
||||
// 保存到应用私有目录(无需权限)
|
||||
fun saveToAppFilesDir(
|
||||
bitmap: Bitmap,
|
||||
context: Context,
|
||||
fileName: String,
|
||||
format: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG,
|
||||
quality: Int = 100
|
||||
): File? {
|
||||
//val dir = context.getExternalFilesDir(null)
|
||||
val dir = context.cacheDir
|
||||
val cropFile = File(dir, "crop")
|
||||
if (cropFile.exists().not()) {
|
||||
cropFile.mkdirs()
|
||||
}
|
||||
return saveBitmap(bitmap, File(cropFile, fileName), format, quality)
|
||||
}
|
||||
|
||||
private fun saveBitmap(
|
||||
bitmap: Bitmap,
|
||||
outputFile: File,
|
||||
format: Bitmap.CompressFormat,
|
||||
quality: Int
|
||||
): File? {
|
||||
return try {
|
||||
FileOutputStream(outputFile).use { fos ->
|
||||
bitmap.compress(format, quality, fos)
|
||||
fos.flush()
|
||||
}
|
||||
outputFile
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.sw.inbound.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
|
||||
object ImageUtil {
|
||||
|
||||
fun uriToBitmap(context: Context, uri: Uri): Bitmap? {
|
||||
return try {
|
||||
context.contentResolver.openInputStream(uri)?.use { stream ->
|
||||
BitmapFactory.decodeStream(stream)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
package com.sw.inbound.utils.ext
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.ActivityOptionsCompat
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
||||
fun Context.toast(
|
||||
message: String?,
|
||||
duration: Int = Toast.LENGTH_SHORT,
|
||||
) {
|
||||
if (message.isNullOrBlank()) {
|
||||
return
|
||||
}
|
||||
Handler(Looper.getMainLooper()).post {
|
||||
Toast.makeText(this, message, duration).show()
|
||||
}
|
||||
}
|
||||
|
||||
fun Fragment.toast(
|
||||
message: String?,
|
||||
duration: Int = 2000
|
||||
) {
|
||||
activity?.toast(message, duration)
|
||||
}
|
||||
|
||||
|
||||
fun View.visible() {
|
||||
visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
fun View.invisible() {
|
||||
visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
fun View.gone() {
|
||||
visibility = View.GONE
|
||||
}
|
||||
|
||||
inline fun <reified T : Activity> Context.startActivity(
|
||||
bundle: Bundle? = null,
|
||||
options: ActivityOptionsCompat? = null
|
||||
) {
|
||||
Intent(this, T::class.java).apply {
|
||||
bundle?.let { putExtras(it) }
|
||||
if (options != null && this@startActivity is Activity) {
|
||||
startActivity(this, options.toBundle())
|
||||
} else {
|
||||
startActivity(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> Context.startActivity(
|
||||
block: Intent.() -> Unit = {}
|
||||
) {
|
||||
Intent(this, T::class.java).apply {
|
||||
block()
|
||||
startActivity(this)
|
||||
}
|
||||
}
|
||||
|
||||
//inline fun <reified T : Activity> Context.startActivity(action:(bundle: Bundle)-> Unit) {
|
||||
// Intent(this, T::class.java).apply {
|
||||
// action(Bundle())
|
||||
// startActivity(this)
|
||||
// }
|
||||
//}
|
||||
|
||||
inline fun <reified T> String.toType(gson: Gson? = null, typeToken: TypeToken<T>): T {
|
||||
return (gson ?: Gson()).fromJson(this, typeToken.type)
|
||||
}
|
||||
|
||||
inline fun <reified T> String.toObject(gson: Gson? = null): T {
|
||||
return (gson ?: Gson()).fromJson(this, T::class.java)
|
||||
}
|
||||
|
||||
fun Any?.toJsonString(gson: Gson? = null): String {
|
||||
return (gson ?: Gson()).toJson(this) ?: ""
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
inline fun SharedPreferences.edit(
|
||||
commit: Boolean = false,
|
||||
action: SharedPreferences.Editor.() -> Unit
|
||||
) {
|
||||
val editor = edit()
|
||||
action(editor)
|
||||
if (commit) editor.commit() else editor.apply()
|
||||
}
|
||||
|
||||
fun SharedPreferences.put(vararg pairs: Pair<String, Any>) {
|
||||
edit {
|
||||
pairs.forEach { (key, value) ->
|
||||
when (value) {
|
||||
is Int -> putInt(key, value)
|
||||
is String -> putString(key, value)
|
||||
is Boolean -> putBoolean(key, value)
|
||||
is Float -> putFloat(key, value)
|
||||
is Long -> putLong(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val Float.dp: Float
|
||||
get() = TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
this,
|
||||
Resources.getSystem().displayMetrics
|
||||
)
|
||||
|
||||
val Int.dp: Int
|
||||
get() = this.toFloat().dp.toInt()
|
||||
|
||||
fun EditText.addOnActionSearchListener(searchCallback: () -> Unit) {
|
||||
setOnEditorActionListener { v, actionId, event ->
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
// 处理搜索逻辑
|
||||
searchCallback()
|
||||
return@setOnEditorActionListener true // 阻止事件继续传递
|
||||
}
|
||||
return@setOnEditorActionListener false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun View.clickWithDebounce(delay: Long = 300, action: () -> Unit) {
|
||||
var job: Job? = null
|
||||
setOnClickListener {
|
||||
job?.cancel()
|
||||
job = CoroutineScope(Dispatchers.Main).launch {
|
||||
delay(delay)
|
||||
action()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Double.roundedDecimalPlace(num: Int): Double {
|
||||
return BigDecimal(this).setScale(num, RoundingMode.HALF_UP).toDouble()
|
||||
}
|
||||
|
||||
fun Double.roundedOneDecimalPlace(): Double {
|
||||
return this.roundedDecimalPlace(1)
|
||||
}
|
||||
|
||||
fun View.setShapeDrawable(
|
||||
solidColor: String = "#FFFFFF",
|
||||
strokeWidth: Int = 0,
|
||||
strokeColor: String = "#FFFFFF",
|
||||
radius: Int = 0
|
||||
) {
|
||||
background = GradientDrawable().apply {
|
||||
setColor(solidColor.toColorInt())
|
||||
setStroke(strokeWidth, strokeColor.toColorInt())
|
||||
cornerRadius = radius.toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
fun View.setShapeDrawable2(
|
||||
solidColor: String = "#FFFFFF",
|
||||
strokeWidth: Int = 0,
|
||||
strokeColor: String = "#FFFFFF",
|
||||
topLeftRadius: Int = 0,
|
||||
topRightRadius: Int = 0,
|
||||
bottomRightRadius: Int = 0,
|
||||
bottomLeftRadius: Int = 0
|
||||
) {
|
||||
background = GradientDrawable().apply {
|
||||
setColor(solidColor.toColorInt())
|
||||
setStroke(strokeWidth, strokeColor.toColorInt())
|
||||
|
||||
setCornerRadii(
|
||||
floatArrayOf(
|
||||
topLeftRadius.toFloat(), topLeftRadius.toFloat(),
|
||||
topRightRadius.toFloat(), topRightRadius.toFloat(),
|
||||
bottomRightRadius.toFloat(), bottomRightRadius.toFloat(),
|
||||
bottomLeftRadius.toFloat(), bottomLeftRadius.toFloat()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun String?.ifNullOrBlank(defaultValue: String): String {
|
||||
return if (this.isNullOrBlank()) defaultValue else this
|
||||
}
|
||||
|
||||
fun Int?.ifNullOrZero(defaultValue: String): String {
|
||||
return if (this == null || this == 0) defaultValue else this.toString()
|
||||
}
|
||||
|
||||
fun Double?.ifNullOrZero(defaultValue: String): String {
|
||||
return if (this == null || this == 0.toDouble()) defaultValue else this.toString()
|
||||
}
|
||||
|
||||
fun View.hideKeyboard() {
|
||||
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(this.windowToken, 0)
|
||||
this.clearFocus() // 清除焦点避免键盘再次弹出
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.shuwei.intelligent.shelves.utils.ext
|
||||
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
|
||||
|
||||
inline fun buildSpannableString(builderAction: SpannableStringBuilder.() -> Unit): SpannableStringBuilder {
|
||||
return SpannableStringBuilder().apply(builderAction)
|
||||
}
|
||||
|
||||
fun SpannableStringBuilder.appendText(text: String, vararg spans: Any): SpannableStringBuilder {
|
||||
val start = length
|
||||
append(text)
|
||||
spans.forEach { span ->
|
||||
setSpan(span, start, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun SpannableStringBuilder.withSpan(span: Any, block: SpannableStringBuilder.() -> Unit) {
|
||||
val start = length
|
||||
block()
|
||||
setSpan(span, start, length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.sw.inbound.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewConfiguration
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kotlin.math.abs
|
||||
|
||||
|
||||
class NestedRecyclerView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : RecyclerView(context, attrs, defStyleAttr) {
|
||||
|
||||
private var lastY = 0f
|
||||
private var isDragging = false
|
||||
|
||||
private var touchSlop = ViewConfiguration.get(context).scaledTouchSlop
|
||||
|
||||
override fun onInterceptTouchEvent(e: MotionEvent): Boolean {
|
||||
when (e.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
lastY = e.y
|
||||
parent.requestDisallowInterceptTouchEvent(true)
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
val dy = e.y - lastY
|
||||
if (!canScrollVertically(-1) && dy > 0) {
|
||||
parent.requestDisallowInterceptTouchEvent(false)
|
||||
return false
|
||||
} else if (!canScrollVertically(1) && dy < 0) {
|
||||
parent.requestDisallowInterceptTouchEvent(false)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onInterceptTouchEvent(e)
|
||||
}
|
||||
|
||||
override fun onTouchEvent(e: MotionEvent): Boolean {
|
||||
when (e.action) {
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
if (!isDragging && abs(e.y - lastY) > touchSlop) {
|
||||
isDragging = true
|
||||
}
|
||||
}
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||
isDragging = false
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(e)
|
||||
}
|
||||
|
||||
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
|
||||
when (ev.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
stopNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL)
|
||||
}
|
||||
}
|
||||
return super.dispatchTouchEvent(ev)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.sw.inbound.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class NonScrollRecyclerView extends RecyclerView {
|
||||
|
||||
public NonScrollRecyclerView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public NonScrollRecyclerView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
// 请求父View不拦截事件,确保子View能接收到事件
|
||||
getParent().requestDisallowInterceptTouchEvent(true);
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.sw.inbound.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class ParentRecyclerView extends RecyclerView {
|
||||
private float downX, downY;
|
||||
private boolean isIntercept = false;
|
||||
|
||||
public ParentRecyclerView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ParentRecyclerView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
downX = ev.getX();
|
||||
downY = ev.getY();
|
||||
isIntercept = false;
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
float deltaX = Math.abs(ev.getX() - downX);
|
||||
float deltaY = Math.abs(ev.getY() - downY);
|
||||
|
||||
// 判断滑动方向,如果是垂直滑动则让父RecyclerView处理
|
||||
if (deltaY > deltaX && deltaY > getTouchSlop()) {
|
||||
isIntercept = true;
|
||||
} else {
|
||||
isIntercept = false; // 水平滑动不拦截
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
isIntercept = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return isIntercept;
|
||||
}
|
||||
|
||||
private int getTouchSlop() {
|
||||
return ViewConfiguration.get(getContext()).getScaledTouchSlop();
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import kotlin.collections.List
|
||||
|
||||
abstract class BaseViewModel(
|
||||
private val repository: RemoteRepository
|
||||
@@ -94,8 +95,8 @@ abstract class BaseViewModel(
|
||||
if (response.isSuccess()) {
|
||||
return true
|
||||
}
|
||||
Timber.d("msg = ${response.message}, code = ${response.code}")
|
||||
ToastUtils.showToast("${response.message}(${response.code})")
|
||||
Timber.d("msg = ${response.msg}, code = ${response.code}")
|
||||
//ToastUtils.showToast("${response.msg}(${response.code})")
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -182,10 +183,25 @@ abstract class BaseViewModel(
|
||||
/**
|
||||
* 搜索物品
|
||||
*/
|
||||
fun searchGoodsInfoList(
|
||||
|
||||
suspend fun searchGoodsInfoList2(
|
||||
goodsName: String,
|
||||
pageNo: Int = 1,
|
||||
pageSize: Int = 10
|
||||
): List<SearchGoodsInfo.Record> {
|
||||
val response = repository.searchGoodsInfoList(goodsName, pageNo, pageSize)
|
||||
return if (parseResponse(response)) {
|
||||
response.result?.records ?: mutableListOf()
|
||||
} else {
|
||||
mutableListOf()
|
||||
}
|
||||
}
|
||||
|
||||
fun searchGoodsInfoList(
|
||||
goodsName: String,
|
||||
pageNo: Int = 1,
|
||||
pageSize: Int = 10,
|
||||
searchCallback: ((pageNo: Int, List<SearchGoodsInfo.Record>) -> Unit)? = null
|
||||
) {
|
||||
launch {
|
||||
if (pageNo > 1) {
|
||||
@@ -203,9 +219,11 @@ abstract class BaseViewModel(
|
||||
} else {
|
||||
_searchListItems.value = data.records
|
||||
}
|
||||
searchCallback?.invoke(pageNo, _searchListItems.value)
|
||||
}
|
||||
} else {
|
||||
_searchListItems.value = emptyList<SearchGoodsInfo.Record>()
|
||||
searchCallback?.invoke(pageNo, _searchListItems.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,10 +235,11 @@ abstract class BaseViewModel(
|
||||
if (parseResponse(response)) {
|
||||
Timber.d("getGoodsStorageType data = ${response.result}")
|
||||
response.result?.let {
|
||||
// val dictType = DictType(response.data)
|
||||
val list = mutableListOf<DictType>()
|
||||
for (type in response.result) {
|
||||
list.add(DictType(type.itemValue!!.toInt(), type.itemText!!))
|
||||
val list: MutableList<DictType> = mutableListOf()
|
||||
response.result
|
||||
?.filter { it.id.isNullOrBlank().not() && it.title.isNullOrBlank().not() }
|
||||
?.forEach {
|
||||
list.add(DictType(id = it.id, value = it.title))
|
||||
}
|
||||
GlobalData.storageTypeList = list
|
||||
}
|
||||
@@ -230,42 +249,53 @@ abstract class BaseViewModel(
|
||||
val response1 = repository.getGoodsType()
|
||||
if (parseResponse(response1)) {
|
||||
Timber.d("getGoodsType data = ${response1.result?.allType}")
|
||||
response1.result?.let {
|
||||
if (response1.result.allType != null) {
|
||||
val list = mutableListOf<DictType>()
|
||||
for (type in response1.result.allType) {
|
||||
list.add(DictType(type!!.id!!, type.typeName!!))
|
||||
}
|
||||
GlobalData.goodsTypeList = list
|
||||
}
|
||||
response1.result
|
||||
?.allType
|
||||
?.filter { it?.id.isNullOrBlank().not() && it.typeName.isNullOrBlank().not() }
|
||||
?.forEach {
|
||||
list.add(DictType(it!!.id, it.typeName!!))
|
||||
}
|
||||
GlobalData.goodsTypeList = list.toList()
|
||||
} else {
|
||||
Timber.e("getGoodsType msg = ${response1.message}, code = ${response1.code}")
|
||||
}
|
||||
val response2 = repository.getDictType(RemoteRepository.TypeEnum.WAREHOUSE)
|
||||
if (parseResponse(response2)) {
|
||||
Timber.d("getDictType WAREHOUSE data = ${response2.result}")
|
||||
response2.result?.let {
|
||||
GlobalData.warehouseTypeList = response2.result
|
||||
val list: MutableList<DictType> = mutableListOf()
|
||||
response2.result
|
||||
?.filter { it.id.isNullOrBlank().not() && it.value.isNullOrBlank().not() }
|
||||
?.forEach {
|
||||
list.add(DictType(id = it.id, value = it.value))
|
||||
}
|
||||
GlobalData.warehouseTypeList = list.toList()
|
||||
} else {
|
||||
Timber.e("getDictType WAREHOUSE msg = ${response2.message}, code = ${response2.code}")
|
||||
}
|
||||
val response3 = repository.getDictType(RemoteRepository.TypeEnum.SUPPLIER)
|
||||
if (parseResponse(response3)) {
|
||||
Timber.d("getDictType SUPPLIER data = ${response3.result}")
|
||||
response3.result?.let {
|
||||
GlobalData.supplierTypeList = response3.result
|
||||
val list: MutableList<DictType> = mutableListOf()
|
||||
response3.result
|
||||
?.filter { it.id.isNullOrBlank().not() && it.value.isNullOrBlank().not() }
|
||||
?.forEach {
|
||||
list.add(DictType(id = it.id, value = it.value))
|
||||
}
|
||||
GlobalData.supplierTypeList = list.toList()
|
||||
} else {
|
||||
Timber.e("getDictType SUPPLIER msg = ${response3.message}, code = ${response3.code}")
|
||||
}
|
||||
val response4 = repository.getDictType(RemoteRepository.TypeEnum.UNIT)
|
||||
if (parseResponse(response4)) {
|
||||
Timber.d("getDictType UNIT data = ${response4.result}")
|
||||
response4.result?.let {
|
||||
GlobalData.unitTypeList = response4.result
|
||||
val list: MutableList<DictType> = mutableListOf()
|
||||
response4.result
|
||||
?.filter { it.id.isNullOrBlank().not() && it.value.isNullOrBlank().not() }
|
||||
?.forEach {
|
||||
list.add(DictType(id = it.id, value = it.value))
|
||||
}
|
||||
GlobalData.unitTypeList = list.toList()
|
||||
} else {
|
||||
Timber.e("getDictType UNIT msg = ${response4.message}, code = ${response4.code}")
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class PurchaseOrderViewModel @Inject constructor(
|
||||
val response = repository.getReceiveList(pageNum, pageSize)
|
||||
updateMoreLoading(false)
|
||||
if (parseResponse(response)) {
|
||||
response.result?.records?.let {
|
||||
response.result?.let {
|
||||
updateCanLoadMore(it.size >= pageSize)
|
||||
Timber.d("加载更多 canLoadMore =${it.size >= pageSize}")
|
||||
_supplierList.value = _supplierList.value + it
|
||||
@@ -42,7 +42,7 @@ class PurchaseOrderViewModel @Inject constructor(
|
||||
launchWithLoading {
|
||||
val response = repository.getReceiveList(pageNum, pageSize)
|
||||
if (parseResponse(response)) {
|
||||
response.result?.records?.let {
|
||||
response.result?.let {
|
||||
_supplierList.value = it
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.sw.inbound.ext.toFormattedString
|
||||
import com.sw.inbound.ext.toSafeBigDecimal
|
||||
import com.sw.inbound.ext.toSafeDouble
|
||||
import com.sw.inbound.ext.toSafeFloat
|
||||
import com.sw.inbound.model.request.PurchaseWarehouseParam
|
||||
import com.sw.inbound.model.request.UploadInfo
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.model.response.GoodsInfo
|
||||
@@ -99,11 +100,11 @@ class ReceiptViewModel @Inject constructor(
|
||||
_showReceiptDialog.value = showDialog
|
||||
}
|
||||
|
||||
fun updateSelectedItemWithSwitch(purchaseOrder: GoodsInfo?) {
|
||||
viewModelScope.launch {
|
||||
updateSelectedItem(purchaseOrder)
|
||||
}
|
||||
}
|
||||
// fun updateSelectedItemWithSwitch(purchaseOrder: GoodsInfo?) {
|
||||
// viewModelScope.launch {
|
||||
// updateSelectedItem(purchaseOrder)
|
||||
// }
|
||||
// }
|
||||
|
||||
override fun handleIdentityItem(goodsInfo: SearchGoodsInfo.Record) {
|
||||
val firstItem = unadjustedOrders.value.find { order ->
|
||||
@@ -118,41 +119,42 @@ class ReceiptViewModel @Inject constructor(
|
||||
/**
|
||||
* 更新选中的item
|
||||
*/
|
||||
fun updateSelectedItem(purchaseOrder: GoodsInfo?) {
|
||||
if (purchaseOrder != null) {
|
||||
if (purchaseOrder.receivedNum != null && purchaseOrder.receivedNum != 0f) {
|
||||
if (purchaseOrder.newRecUnitPriceTaxInTemp.isNotEmpty()) { // 计算金额 单价不为空,并且金额没有手动输入
|
||||
val result =
|
||||
purchaseOrder.receivedNum!!.times(purchaseOrder.newRecUnitPriceTaxIn!!)
|
||||
purchaseOrder.recPriceExItem = result.toSafeFloat()
|
||||
purchaseOrder.recPriceExItemTemp = result.toFormattedString()
|
||||
} else if (purchaseOrder.recPriceExItemTemp.isNotEmpty()) { // 计算单价 金额不为空,并且单价没有手动输入
|
||||
val result =
|
||||
purchaseOrder.recPriceExItem!!.div(purchaseOrder.receivedNum!!)
|
||||
purchaseOrder.newRecUnitPriceTaxIn = result.toSafeFloat()
|
||||
purchaseOrder.newRecUnitPriceTaxInTemp = result.toFormattedString()
|
||||
}
|
||||
} else {
|
||||
if (_priceUserInput.value) {
|
||||
purchaseOrder.recPriceExItem = 0f
|
||||
purchaseOrder.recPriceExItemTemp = ""
|
||||
} else if (_amountUserInput.value) {
|
||||
purchaseOrder.newRecUnitPriceTaxIn = 0f
|
||||
purchaseOrder.newRecUnitPriceTaxInTemp = ""
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_countUserInput.value = false
|
||||
_priceUserInput.value = false
|
||||
_amountUserInput.value = false
|
||||
}
|
||||
_selectedItem.value = purchaseOrder
|
||||
}
|
||||
// fun updateSelectedItem(purchaseOrder: GoodsInfo?) {
|
||||
// if (purchaseOrder != null) {
|
||||
// if (purchaseOrder.receivedNum != null && purchaseOrder.receivedNum != 0f) {
|
||||
// if (purchaseOrder.newRecUnitPriceTaxInTemp.isNotEmpty()) { // 计算金额 单价不为空,并且金额没有手动输入
|
||||
// val result =
|
||||
// purchaseOrder.receivedNum!!.times(purchaseOrder.newRecUnitPriceTaxIn!!)
|
||||
// purchaseOrder.recPriceExItem = result.toSafeFloat()
|
||||
// purchaseOrder.recPriceExItemTemp = result.toFormattedString()
|
||||
// } else if (purchaseOrder.recPriceExItemTemp.isNotEmpty()) { // 计算单价 金额不为空,并且单价没有手动输入
|
||||
// val result =
|
||||
// purchaseOrder.recPriceExItem!!.div(purchaseOrder.receivedNum!!)
|
||||
// purchaseOrder.newRecUnitPriceTaxIn = result.toSafeFloat()
|
||||
// purchaseOrder.newRecUnitPriceTaxInTemp = result.toFormattedString()
|
||||
// }
|
||||
// } else {
|
||||
// if (_priceUserInput.value) {
|
||||
// purchaseOrder.recPriceExItem = 0f
|
||||
// purchaseOrder.recPriceExItemTemp = ""
|
||||
// } else if (_amountUserInput.value) {
|
||||
// purchaseOrder.newRecUnitPriceTaxIn = 0f
|
||||
// purchaseOrder.newRecUnitPriceTaxInTemp = ""
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// _countUserInput.value = false
|
||||
// _priceUserInput.value = false
|
||||
// _amountUserInput.value = false
|
||||
// }
|
||||
// _selectedItem.value = purchaseOrder
|
||||
// }
|
||||
|
||||
fun getReceiveDetail(id: Int) {
|
||||
fun getReceiveDetail(id: String, action:(PurchaseInfo?)->Unit = {}) {
|
||||
launchWithLoading {
|
||||
val response = repository.getReceiveDetail(id)
|
||||
if (parseResponse(response)) {
|
||||
action(response.result)
|
||||
_currentPurchaseInfo.value = response.result
|
||||
initOrders()
|
||||
}
|
||||
@@ -199,23 +201,23 @@ class ReceiptViewModel @Inject constructor(
|
||||
/**
|
||||
* 更新所有商品仓库
|
||||
*/
|
||||
fun updateAllPurchaseStore(warehouse: DictType, predicate: (GoodsInfo) -> Boolean = { true }) {
|
||||
_orders.update { currentList ->
|
||||
currentList.map { order ->
|
||||
if (predicate(order)) order.copy(
|
||||
warehouseId = warehouse.id,
|
||||
warehouseName = warehouse.value
|
||||
) else order
|
||||
}
|
||||
}
|
||||
}
|
||||
// fun updateAllPurchaseStore(warehouse: DictType, predicate: (GoodsInfo) -> Boolean = { true }) {
|
||||
// _orders.update { currentList ->
|
||||
// currentList.map { order ->
|
||||
// if (predicate(order)) order.copy(
|
||||
// warehouseId = warehouse.id,
|
||||
// warehouseName = warehouse.value
|
||||
// ) else order
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// 删除订单
|
||||
fun removePurchaseOrder(orderId: Int) {
|
||||
_orders.update { current ->
|
||||
current.filterNot { it.goodId == orderId }
|
||||
}
|
||||
}
|
||||
// fun removePurchaseOrder(orderId: Int) {
|
||||
// _orders.update { current ->
|
||||
// current.filterNot { it.goodId == orderId }
|
||||
// }
|
||||
// }
|
||||
|
||||
// 清空列表
|
||||
fun clearPurchaseOrders() {
|
||||
@@ -243,67 +245,72 @@ class ReceiptViewModel @Inject constructor(
|
||||
_amountUserInput.value = boolean
|
||||
}
|
||||
|
||||
private var weightCallback:((Int)->Unit)?=null
|
||||
fun readWeight(callback:(Int)->Unit) {
|
||||
weightCallback = callback
|
||||
}
|
||||
override fun handleSensorScale(weight: Double) {
|
||||
val currentItem = _selectedItem.value
|
||||
|
||||
currentItem?.let { info ->
|
||||
// 用户输入数量后不再通过重量反算
|
||||
if (_countUserInput.value) {
|
||||
_selectedItem.value = info.copy(
|
||||
goodsWeight = weight.toSafeBigDecimal(),
|
||||
)
|
||||
return
|
||||
}
|
||||
var consumeValue = currentItem.consumeValue?.toSafeDouble() ?: 1.0
|
||||
var purchaseValue = currentItem.purchaseValue?.toDouble() ?: 1.0
|
||||
if (consumeValue == 0.0) {
|
||||
consumeValue = 1.0
|
||||
}
|
||||
if (purchaseValue == 0.0) {
|
||||
purchaseValue = 1.0
|
||||
}
|
||||
val count =
|
||||
weight * 1000 / consumeValue / purchaseValue
|
||||
val finalCount = count.toSafeFloat(currentItem.unitName)
|
||||
Timber.d("startSensorScale weight = $weight, count = $count, finalCount = $finalCount, consumeValue = $consumeValue, purchaseValue = $purchaseValue")
|
||||
// 计算单价
|
||||
val finalPrice = when {
|
||||
finalCount == 0f -> {
|
||||
0f
|
||||
}
|
||||
|
||||
_amountUserInput.value && !_priceUserInput.value -> {
|
||||
info.recPriceExItem!!.div(finalCount).toSafeFloat()
|
||||
}
|
||||
|
||||
else -> 0f
|
||||
}
|
||||
// 计算金额
|
||||
val finalAmount = when {
|
||||
finalCount == 0f -> {
|
||||
0f
|
||||
}
|
||||
|
||||
_priceUserInput.value && !_amountUserInput.value -> {
|
||||
finalCount.times(info.newRecUnitPriceTaxIn!!).toSafeFloat()
|
||||
}
|
||||
|
||||
else -> 0f
|
||||
}
|
||||
|
||||
_selectedItem.value = info.copy(
|
||||
goodsWeight = weight.toSafeBigDecimal(),
|
||||
// 收货数量
|
||||
receivedNumTemp = finalCount.toFormattedString(),
|
||||
receivedNum = finalCount,
|
||||
// 单价
|
||||
newRecUnitPriceTaxIn = if (_priceUserInput.value) info.newRecUnitPriceTaxIn else finalPrice,
|
||||
newRecUnitPriceTaxInTemp = if (_priceUserInput.value) info.newRecUnitPriceTaxInTemp else finalPrice.toFormattedString(),
|
||||
// 金额
|
||||
recPriceExItem = if (_amountUserInput.value) info.recPriceExItem else finalAmount,
|
||||
recPriceExItemTemp = if (_amountUserInput.value) info.recPriceExItemTemp else finalAmount.toFormattedString(),
|
||||
)
|
||||
}
|
||||
weightCallback?.invoke((weight*1000).toInt())
|
||||
// val currentItem = _selectedItem.value
|
||||
//
|
||||
// currentItem?.let { info ->
|
||||
// // 用户输入数量后不再通过重量反算
|
||||
// if (_countUserInput.value) {
|
||||
// _selectedItem.value = info.copy(
|
||||
// goodsWeight = weight.toSafeBigDecimal(),
|
||||
// )
|
||||
// return
|
||||
// }
|
||||
// var consumeValue = currentItem.consumeValue?.toSafeDouble() ?: 1.0
|
||||
// var purchaseValue = currentItem.purchaseValue?.toDouble() ?: 1.0
|
||||
// if (consumeValue == 0.0) {
|
||||
// consumeValue = 1.0
|
||||
// }
|
||||
// if (purchaseValue == 0.0) {
|
||||
// purchaseValue = 1.0
|
||||
// }
|
||||
// val count =
|
||||
// weight * 1000 / consumeValue / purchaseValue
|
||||
// val finalCount = count.toSafeFloat(currentItem.unitName)
|
||||
// Timber.d("startSensorScale weight = $weight, count = $count, finalCount = $finalCount, consumeValue = $consumeValue, purchaseValue = $purchaseValue")
|
||||
// // 计算单价
|
||||
// val finalPrice = when {
|
||||
// finalCount == 0f -> {
|
||||
// 0f
|
||||
// }
|
||||
//
|
||||
// _amountUserInput.value && !_priceUserInput.value -> {
|
||||
// info.recPriceExItem!!.div(finalCount).toSafeFloat()
|
||||
// }
|
||||
//
|
||||
// else -> 0f
|
||||
// }
|
||||
// // 计算金额
|
||||
// val finalAmount = when {
|
||||
// finalCount == 0f -> {
|
||||
// 0f
|
||||
// }
|
||||
//
|
||||
// _priceUserInput.value && !_amountUserInput.value -> {
|
||||
// finalCount.times(info.newRecUnitPriceTaxIn!!).toSafeFloat()
|
||||
// }
|
||||
//
|
||||
// else -> 0f
|
||||
// }
|
||||
//
|
||||
// _selectedItem.value = info.copy(
|
||||
// goodsWeight = weight.toSafeBigDecimal(),
|
||||
// // 收货数量
|
||||
// receivedNumTemp = finalCount.toFormattedString(),
|
||||
// receivedNum = finalCount,
|
||||
// // 单价
|
||||
// newRecUnitPriceTaxIn = if (_priceUserInput.value) info.newRecUnitPriceTaxIn else finalPrice,
|
||||
// newRecUnitPriceTaxInTemp = if (_priceUserInput.value) info.newRecUnitPriceTaxInTemp else finalPrice.toFormattedString(),
|
||||
// // 金额
|
||||
// recPriceExItem = if (_amountUserInput.value) info.recPriceExItem else finalAmount,
|
||||
// recPriceExItemTemp = if (_amountUserInput.value) info.recPriceExItemTemp else finalAmount.toFormattedString(),
|
||||
// )
|
||||
// }
|
||||
}
|
||||
|
||||
fun partialReceipt(uploadInfo: UploadInfo) {
|
||||
@@ -325,4 +332,18 @@ class ReceiptViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun confirmReceipt(uploadInfo: UploadInfo, callback: (Boolean) -> Unit) {
|
||||
launchWithLoading {
|
||||
val resp = repository.confirmReceipt(uploadInfo)
|
||||
callback(resp.data == true)
|
||||
}
|
||||
}
|
||||
|
||||
fun addToWarehouse(list: List<PurchaseWarehouseParam>, callback: (Boolean) -> Unit) {
|
||||
launchWithLoading {
|
||||
val resp = repository.selfPurchaseWarehousing(list)
|
||||
callback(resp.data == true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,410 +1,411 @@
|
||||
package com.sw.inbound.viewmodel
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.sw.inbound.GlobalData
|
||||
import com.sw.inbound.ext.toFormattedString
|
||||
import com.sw.inbound.ext.toSafeBigDecimal
|
||||
import com.sw.inbound.ext.toSafeDouble
|
||||
import com.sw.inbound.model.request.GoodsAddParam
|
||||
import com.sw.inbound.model.request.GoodsPurchaseUnitParam
|
||||
import com.sw.inbound.model.request.PurchaseWarehouseParam
|
||||
import com.sw.inbound.model.response.DictType
|
||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
import com.sw.inbound.repository.RemoteRepository
|
||||
import com.sw.inbound.utils.ContextUtils
|
||||
import com.sw.inbound.utils.FileUtils
|
||||
import com.sw.inbound.utils.ToastUtils
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* 自采购
|
||||
*/
|
||||
@HiltViewModel
|
||||
class SelfProcurementViewModel @Inject constructor(
|
||||
private val repository: RemoteRepository
|
||||
) : BaseViewModel(repository) {
|
||||
|
||||
private val _addGoodsResult = MutableStateFlow<Boolean>(false)
|
||||
val addGoodsResult: StateFlow<Boolean> = _addGoodsResult
|
||||
|
||||
private val _addGoodsPurchaseUnitResult = MutableStateFlow<Boolean>(false)
|
||||
val addGoodsPurchaseUnitResult: StateFlow<Boolean> = _addGoodsPurchaseUnitResult
|
||||
|
||||
private val _addToWarehouseResult = MutableStateFlow<Boolean>(false)
|
||||
val addToWarehouseResult: StateFlow<Boolean> = _addToWarehouseResult
|
||||
|
||||
private val _selectedItem = MutableStateFlow<PurchaseWarehouseParam?>(null)
|
||||
val selectedItem: StateFlow<PurchaseWarehouseParam?> = _selectedItem
|
||||
|
||||
// 全局仓库信息
|
||||
private val _globalWarehouse = MutableStateFlow<DictType>(DictType(-1, "选择仓库"))
|
||||
val globalWarehouse: StateFlow<DictType> = _globalWarehouse
|
||||
|
||||
// 采购列表
|
||||
private val _purchaseList = MutableStateFlow<List<PurchaseWarehouseParam>>(emptyList())
|
||||
val purchaseList: StateFlow<List<PurchaseWarehouseParam>> = _purchaseList
|
||||
|
||||
// 表单状态
|
||||
private val _goodsAddParam = MutableStateFlow<GoodsAddParam>(GoodsAddParam())
|
||||
val goodsAddParam: StateFlow<GoodsAddParam> = _goodsAddParam
|
||||
|
||||
private val _goodsAddUnitParam =
|
||||
MutableStateFlow<GoodsPurchaseUnitParam>(GoodsPurchaseUnitParam())
|
||||
val goodsAddUnitParam: StateFlow<GoodsPurchaseUnitParam> = _goodsAddUnitParam
|
||||
|
||||
// 快速添加弹窗状态
|
||||
private val _showAddProductDialog = MutableStateFlow<Boolean>(false)
|
||||
val showAddProductDialog: StateFlow<Boolean> = _showAddProductDialog
|
||||
|
||||
// 添加采购单位弹窗状态
|
||||
private val _showAddPurchaseUnitDialog = MutableStateFlow<Boolean>(false)
|
||||
val showAddPurchaseUnitDialog: StateFlow<Boolean> = _showAddPurchaseUnitDialog
|
||||
|
||||
|
||||
// 是否可以修改库存单位
|
||||
private val _canChangeKcUnit = MutableStateFlow<Boolean>(false)
|
||||
val canChangeKcUnit: StateFlow<Boolean> = _canChangeKcUnit
|
||||
|
||||
// 是否可以修改消耗值
|
||||
private val _canChangeConsumeValue = MutableStateFlow<Boolean>(false)
|
||||
val canChangeConsumeValue: StateFlow<Boolean> = _canChangeConsumeValue
|
||||
|
||||
/**
|
||||
* 数量是否是用户输入的值
|
||||
*/
|
||||
private val _countUserInput = MutableStateFlow<Boolean>(false)
|
||||
|
||||
/**
|
||||
* 单价是否是用户输入的值
|
||||
*/
|
||||
private val _priceUserInput = MutableStateFlow<Boolean>(false)
|
||||
|
||||
/**
|
||||
* 金额输入状态
|
||||
*/
|
||||
private val _amountUserInput = MutableStateFlow<Boolean>(false)
|
||||
|
||||
// private val _storeSelectState = MutableStateFlow<String>("")
|
||||
// val storeSelectState = _storeSelectState
|
||||
// fun updateStoreState(store:String) {
|
||||
// _storeSelectState.value = store
|
||||
//package com.sw.inbound.viewmodel
|
||||
//
|
||||
//import androidx.lifecycle.viewModelScope
|
||||
//import com.sw.inbound.GlobalData
|
||||
//import com.sw.inbound.ext.toFormattedString
|
||||
//import com.sw.inbound.ext.toSafeBigDecimal
|
||||
//import com.sw.inbound.ext.toSafeDouble
|
||||
//import com.sw.inbound.model.request.GoodsAddParam
|
||||
//import com.sw.inbound.model.request.GoodsPurchaseUnitParam
|
||||
//import com.sw.inbound.model.request.PurchaseWarehouseParam
|
||||
//import com.sw.inbound.model.response.DictType
|
||||
//import com.sw.inbound.model.response.SearchGoodsInfo
|
||||
//import com.sw.inbound.repository.RemoteRepository
|
||||
//import com.sw.inbound.utils.ContextUtils
|
||||
//import com.sw.inbound.utils.FileUtils
|
||||
//import com.sw.inbound.utils.ToastUtils
|
||||
//import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
//import kotlinx.coroutines.delay
|
||||
//import kotlinx.coroutines.flow.MutableStateFlow
|
||||
//import kotlinx.coroutines.flow.StateFlow
|
||||
//import kotlinx.coroutines.flow.update
|
||||
//import kotlinx.coroutines.launch
|
||||
//import timber.log.Timber
|
||||
//import javax.inject.Inject
|
||||
//
|
||||
///**
|
||||
// * 自采购
|
||||
// */
|
||||
//@HiltViewModel
|
||||
//class SelfProcurementViewModel @Inject constructor(
|
||||
// private val repository: RemoteRepository
|
||||
//) : BaseViewModel(repository) {
|
||||
//
|
||||
// private val _addGoodsResult = MutableStateFlow<Boolean>(false)
|
||||
// val addGoodsResult: StateFlow<Boolean> = _addGoodsResult
|
||||
//
|
||||
// private val _addGoodsPurchaseUnitResult = MutableStateFlow<Boolean>(false)
|
||||
// val addGoodsPurchaseUnitResult: StateFlow<Boolean> = _addGoodsPurchaseUnitResult
|
||||
//
|
||||
// private val _addToWarehouseResult = MutableStateFlow<Boolean>(false)
|
||||
// val addToWarehouseResult: StateFlow<Boolean> = _addToWarehouseResult
|
||||
//
|
||||
// private val _selectedItem = MutableStateFlow<PurchaseWarehouseParam?>(null)
|
||||
// val selectedItem: StateFlow<PurchaseWarehouseParam?> = _selectedItem
|
||||
//
|
||||
// // 全局仓库信息
|
||||
// private val _globalWarehouse = MutableStateFlow<DictType>(DictType("", "选择仓库"))
|
||||
// val globalWarehouse: StateFlow<DictType> = _globalWarehouse
|
||||
//
|
||||
// // 采购列表
|
||||
// private val _purchaseList = MutableStateFlow<List<PurchaseWarehouseParam>>(emptyList())
|
||||
// val purchaseList: StateFlow<List<PurchaseWarehouseParam>> = _purchaseList
|
||||
//
|
||||
// // 表单状态
|
||||
// private val _goodsAddParam = MutableStateFlow<GoodsAddParam>(GoodsAddParam())
|
||||
// val goodsAddParam: StateFlow<GoodsAddParam> = _goodsAddParam
|
||||
//
|
||||
// private val _goodsAddUnitParam =
|
||||
// MutableStateFlow<GoodsPurchaseUnitParam>(GoodsPurchaseUnitParam())
|
||||
// val goodsAddUnitParam: StateFlow<GoodsPurchaseUnitParam> = _goodsAddUnitParam
|
||||
//
|
||||
// // 快速添加弹窗状态
|
||||
// private val _showAddProductDialog = MutableStateFlow<Boolean>(false)
|
||||
// val showAddProductDialog: StateFlow<Boolean> = _showAddProductDialog
|
||||
//
|
||||
// // 添加采购单位弹窗状态
|
||||
// private val _showAddPurchaseUnitDialog = MutableStateFlow<Boolean>(false)
|
||||
// val showAddPurchaseUnitDialog: StateFlow<Boolean> = _showAddPurchaseUnitDialog
|
||||
//
|
||||
//
|
||||
// // 是否可以修改库存单位
|
||||
// private val _canChangeKcUnit = MutableStateFlow<Boolean>(false)
|
||||
// val canChangeKcUnit: StateFlow<Boolean> = _canChangeKcUnit
|
||||
//
|
||||
// // 是否可以修改消耗值
|
||||
// private val _canChangeConsumeValue = MutableStateFlow<Boolean>(false)
|
||||
// val canChangeConsumeValue: StateFlow<Boolean> = _canChangeConsumeValue
|
||||
//
|
||||
// /**
|
||||
// * 数量是否是用户输入的值
|
||||
// */
|
||||
// private val _countUserInput = MutableStateFlow<Boolean>(false)
|
||||
//
|
||||
// /**
|
||||
// * 单价是否是用户输入的值
|
||||
// */
|
||||
// private val _priceUserInput = MutableStateFlow<Boolean>(false)
|
||||
//
|
||||
// /**
|
||||
// * 金额输入状态
|
||||
// */
|
||||
// private val _amountUserInput = MutableStateFlow<Boolean>(false)
|
||||
//
|
||||
//// private val _storeSelectState = MutableStateFlow<String>("")
|
||||
//// val storeSelectState = _storeSelectState
|
||||
//// fun updateStoreState(store:String) {
|
||||
//// _storeSelectState.value = store
|
||||
//// }
|
||||
// /**
|
||||
// * 更新全局仓库
|
||||
// */
|
||||
// fun updateGlobalWarehouse(dictType: DictType) {
|
||||
// _globalWarehouse.value = dictType
|
||||
// }
|
||||
/**
|
||||
* 更新全局仓库
|
||||
*/
|
||||
fun updateGlobalWarehouse(dictType: DictType) {
|
||||
_globalWarehouse.value = dictType
|
||||
}
|
||||
|
||||
override fun handleSensorScale(weight: Double) {
|
||||
val currentItem = _selectedItem.value
|
||||
|
||||
currentItem?.let { info ->
|
||||
val selectUnitType = currentItem.selectUnitType
|
||||
// 用户输入数量后不再通过重量反算
|
||||
if (_countUserInput.value || selectUnitType == null) {
|
||||
_selectedItem.value = info.copy(
|
||||
goodsWeight = weight.toSafeBigDecimal(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
//
|
||||
// override fun handleSensorScale(weight: Double) {
|
||||
// val currentItem = _selectedItem.value
|
||||
//
|
||||
// currentItem?.let { info ->
|
||||
// val selectUnitType = currentItem.selectUnitType
|
||||
// if (selectUnitType == null) return@startScale
|
||||
|
||||
var consumeValue = selectUnitType.consumeValue?.toSafeDouble() ?: 1.0
|
||||
var purchaseValue = selectUnitType.purchaseValue?.toDouble() ?: 1.0
|
||||
if (consumeValue == 0.0) {
|
||||
consumeValue = 1.0
|
||||
}
|
||||
if (purchaseValue == 0.0) {
|
||||
purchaseValue = 1.0
|
||||
}
|
||||
val count =
|
||||
weight * 1000 / consumeValue / purchaseValue
|
||||
val finalCount = count.toSafeDouble(currentItem.unitName)
|
||||
Timber.d("startSensorScale weight = $weight, count = $count, finalCount = $finalCount, consumeValue = $consumeValue, purchaseValue = $purchaseValue")
|
||||
|
||||
Timber.d("startSensorScale goodsUnitPrice = ${info.goodsUnitPrice}, goodsPrice = ${info.goodsPrice} ")
|
||||
// 计算单价 金额不为空,数量也不为空, 不是数量输入 也不是单价输入
|
||||
val finalPrice =
|
||||
if (finalCount == 0.0) {
|
||||
0.0
|
||||
} else if (_amountUserInput.value && !_priceUserInput.value) {
|
||||
info.goodsPrice.div(finalCount).toSafeDouble()
|
||||
} else 0.0
|
||||
|
||||
// 计算金额 单价不为空,不是数量输入 也不是金额输入
|
||||
val finalAmount =
|
||||
if (finalCount == 0.0) {
|
||||
0.0
|
||||
} else if (_priceUserInput.value && !_amountUserInput.value) {
|
||||
finalCount.times(info.goodsUnitPrice).toSafeDouble()
|
||||
} else 0.0
|
||||
Timber.d("startSensorScale finalPrice = $finalPrice, finalAmount = $finalAmount ")
|
||||
_selectedItem.value = info.copy(
|
||||
goodsWeight = weight.toSafeBigDecimal(),
|
||||
// 数量
|
||||
goodsCountTemp = finalCount.toFormattedString(),
|
||||
goodsCount = finalCount,
|
||||
// 单价
|
||||
goodsUnitPrice = if (_priceUserInput.value) info.goodsUnitPrice else finalPrice,
|
||||
goodsUnitPriceTemp = if (_priceUserInput.value) info.goodsUnitPriceTemp else finalPrice.toFormattedString(),
|
||||
// 金额
|
||||
goodsPrice = if (_amountUserInput.value) info.goodsPrice else finalAmount,
|
||||
goodsPriceTemp = if (_amountUserInput.value) info.goodsPriceTemp else finalAmount.toFormattedString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateAddProductDialog(show: Boolean) {
|
||||
_showAddProductDialog.value = show
|
||||
if (!show) {
|
||||
_goodsAddParam.value = GoodsAddParam()
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSelectedItem(purchaseOrder: PurchaseWarehouseParam?) {
|
||||
// updateLastPhotoUri(null)
|
||||
if (purchaseOrder != null) {
|
||||
if (purchaseOrder.goodsCount != 0.0) {
|
||||
if (purchaseOrder.goodsUnitPriceTemp.isNotEmpty()) { // 计算金额 单价不为空,并且金额没有手动输入
|
||||
Timber.d("updateSelectedItem 计算金额")
|
||||
val result =
|
||||
purchaseOrder.goodsCount.times(purchaseOrder.goodsUnitPrice)
|
||||
purchaseOrder.goodsPrice = result.toSafeDouble()
|
||||
purchaseOrder.goodsPriceTemp = result.toFormattedString()
|
||||
} else if (purchaseOrder.goodsPriceTemp.isNotEmpty()) { // 计算单价 金额不为空,并且单价没有手动输入
|
||||
Timber.d("updateSelectedItem 计算单价")
|
||||
val result =
|
||||
purchaseOrder.goodsPrice.div(purchaseOrder.goodsCount)
|
||||
purchaseOrder.goodsUnitPrice = result.toSafeDouble()
|
||||
purchaseOrder.goodsUnitPriceTemp = result.toFormattedString()
|
||||
}
|
||||
} else {
|
||||
if (_priceUserInput.value) {
|
||||
purchaseOrder.goodsPrice = 0.0
|
||||
purchaseOrder.goodsPriceTemp = ""
|
||||
} else if (_amountUserInput.value) {
|
||||
purchaseOrder.goodsUnitPrice = 0.0
|
||||
purchaseOrder.goodsUnitPriceTemp = ""
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 重置输入状态
|
||||
Timber.d("重置输入状态")
|
||||
_countUserInput.value = false
|
||||
_priceUserInput.value = false
|
||||
_amountUserInput.value = false
|
||||
}
|
||||
_selectedItem.value = purchaseOrder
|
||||
Timber.d("updateSelectedItem 更新,goodsUnitPrice = ${_selectedItem.value?.goodsUnitPrice}, ${_selectedItem.value?.goodsUnitPriceTemp}")
|
||||
}
|
||||
|
||||
fun updateGoodsAddParam(newState: GoodsAddParam) {
|
||||
_goodsAddParam.value = newState
|
||||
}
|
||||
|
||||
fun cleanGoodsAddParam() {
|
||||
_goodsAddParam.value = GoodsAddParam()
|
||||
}
|
||||
|
||||
// 添加订单
|
||||
fun addPurchaseItem(purchaseOrder: PurchaseWarehouseParam) {
|
||||
_purchaseList.update { currentList ->
|
||||
currentList + purchaseOrder
|
||||
}
|
||||
updateSelectedItem(null)
|
||||
}
|
||||
|
||||
// 更新订单
|
||||
fun updatePurchaseItem(purchaseOrder: PurchaseWarehouseParam) {
|
||||
_purchaseList.update { currentList ->
|
||||
currentList.map { order ->
|
||||
if (order.goodsId == purchaseOrder.goodsId) purchaseOrder else order
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除订单
|
||||
fun removePurchaseOrder(orderId: Int) {
|
||||
_purchaseList.update { currentList ->
|
||||
currentList.filterNot { it.goodsId == orderId }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据位置删除物品
|
||||
*/
|
||||
fun removePurchaseOrderByIndex(index: Int) {
|
||||
_purchaseList.update { currentList ->
|
||||
currentList.toMutableList().apply {
|
||||
removeAt(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 清空列表
|
||||
fun clearPurchaseOrders() {
|
||||
_purchaseList.value = emptyList()
|
||||
}
|
||||
|
||||
override fun handleIdentityItem(goodsInfo: SearchGoodsInfo.Record) {
|
||||
updateSelectedItemWithSearch(goodsInfo)
|
||||
}
|
||||
|
||||
fun updateSelectedItemWithSearch(searchFirst: SearchGoodsInfo.Record) {
|
||||
val warehouse = _globalWarehouse.value
|
||||
viewModelScope.launch {
|
||||
updateSelectedItem(null)
|
||||
delay(50)
|
||||
_selectedItem.value = PurchaseWarehouseParam(
|
||||
warehouseId = warehouse.id,
|
||||
goodsId = searchFirst.goodsId ?: 0,
|
||||
goodsName = searchFirst.goodsName,
|
||||
kcUnitId = searchFirst.kcUnitId ?: 0,
|
||||
unitList = searchFirst.unitVoList,
|
||||
consumeValue = searchFirst.consumeValue ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 数量输入状态
|
||||
*/
|
||||
fun updateCountInputState(boolean: Boolean) {
|
||||
_countUserInput.value = boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 单价输入状态
|
||||
*/
|
||||
fun updatePriceInputState(boolean: Boolean) {
|
||||
_priceUserInput.value = boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 金额输入状态
|
||||
*/
|
||||
fun updateAmountInputState(boolean: Boolean) {
|
||||
_amountUserInput.value = boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加商品
|
||||
*/
|
||||
fun addGoodsInfo() {
|
||||
val imageUri = GlobalData.imageUri
|
||||
if (imageUri == null) {
|
||||
ToastUtils.showToast("请先进行图片采集")
|
||||
return
|
||||
}
|
||||
val errInfo = _goodsAddParam.value.hasNullField()
|
||||
if (errInfo != null) {
|
||||
ToastUtils.showToast(errInfo)
|
||||
return
|
||||
}
|
||||
|
||||
launchWithLoading {
|
||||
val uploadResponse = repository.uploadImage(imageUri)
|
||||
if (!parseResponse(uploadResponse)) {
|
||||
return@launchWithLoading
|
||||
}
|
||||
// ToastUtils.showToast("图片上传成功,${uploadResponse.data}")
|
||||
GlobalData.imageUri = null
|
||||
_goodsAddParam.value.relativeUrl = uploadResponse.result
|
||||
val response = repository.selfPurchaseGoodsAdd(_goodsAddParam.value)
|
||||
if (!parseResponse(response)) {
|
||||
return@launchWithLoading
|
||||
}
|
||||
FileUtils.deleteFileWithUri(context = ContextUtils.getAppContext(), uri = imageUri)
|
||||
_showAddProductDialog.value = false
|
||||
_goodsAddParam.value = GoodsAddParam()
|
||||
val searchFirst = response.result!!.records?.get(0)
|
||||
searchFirst?.let {
|
||||
updateSelectedItemWithSearch(searchFirst)
|
||||
}
|
||||
_addGoodsResult.value = true
|
||||
}
|
||||
}
|
||||
|
||||
fun updateAddPurchaseUnitDialog(show: Boolean) {
|
||||
if (_selectedItem.value == null) return
|
||||
_showAddPurchaseUnitDialog.value = show
|
||||
if (show) {
|
||||
val hasUnitId = GlobalData.unitTypeList.any { it.id == _selectedItem.value!!.kcUnitId }
|
||||
_canChangeKcUnit.value = !hasUnitId
|
||||
_canChangeConsumeValue.value =
|
||||
_selectedItem.value!!.consumeValue.trim().isEmpty() == true
|
||||
} else {
|
||||
_goodsAddUnitParam.value = GoodsPurchaseUnitParam()
|
||||
}
|
||||
}
|
||||
|
||||
fun updateGoodsPurchaseUnit(goodsPurchaseUnitParam: GoodsPurchaseUnitParam?) {
|
||||
if (goodsPurchaseUnitParam == null) {
|
||||
_goodsAddUnitParam.value = GoodsPurchaseUnitParam()
|
||||
} else {
|
||||
_goodsAddUnitParam.value = goodsPurchaseUnitParam
|
||||
}
|
||||
}
|
||||
|
||||
fun updateDropdownTextChange(canChange: Boolean) {
|
||||
_canChangeKcUnit.value == canChange
|
||||
}
|
||||
|
||||
fun addGoodsPurchaseUnit() {
|
||||
val errorInfo = _goodsAddUnitParam.value.hasNullField()
|
||||
if (errorInfo != null) {
|
||||
ToastUtils.showToast(errorInfo)
|
||||
return
|
||||
}
|
||||
launchWithLoading {
|
||||
val response = repository.selfPurchaseGoodsAddUnit(_goodsAddUnitParam.value)
|
||||
if (parseResponse(response)) {
|
||||
_showAddPurchaseUnitDialog.value = false
|
||||
_goodsAddUnitParam.value = GoodsPurchaseUnitParam()
|
||||
// _addGoodsPurchaseUnitResult.value = true
|
||||
ToastUtils.showToast("采购单位添加成功")
|
||||
|
||||
// 通过id搜索物品,补充采购单位
|
||||
val response = repository.searchGoodsInfoList(
|
||||
goodsName = "${_selectedItem.value?.goodsId}"
|
||||
)
|
||||
if (parseResponse(response)) {
|
||||
val searchList: List<SearchGoodsInfo.Record> =
|
||||
response.result?.records ?: emptyList()
|
||||
if (searchList.isNotEmpty()) {
|
||||
val searchItem = searchList[0]
|
||||
_selectedItem.value = _selectedItem.value?.copy(
|
||||
unitList = searchItem.unitVoList,
|
||||
kcUnitId = searchItem.kcUnitId ?: 0,
|
||||
consumeValue = searchItem.consumeValue ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 物品提交入库
|
||||
*/
|
||||
fun addToWarehouse() {
|
||||
if (_purchaseList.value.isEmpty()) {
|
||||
ToastUtils.showToast("采购列表为空")
|
||||
return
|
||||
}
|
||||
launchWithLoading {
|
||||
val response = repository.selfPurchaseWarehousing(_purchaseList.value)
|
||||
_addToWarehouseResult.value = parseResponse(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
// // 用户输入数量后不再通过重量反算
|
||||
// if (_countUserInput.value || selectUnitType == null) {
|
||||
// _selectedItem.value = info.copy(
|
||||
// goodsWeight = weight.toSafeBigDecimal(),
|
||||
// )
|
||||
// return
|
||||
// }
|
||||
//
|
||||
//// val selectUnitType = currentItem.selectUnitType
|
||||
//// if (selectUnitType == null) return@startScale
|
||||
//
|
||||
// var consumeValue = selectUnitType.consumeValue?.toSafeDouble() ?: 1.0
|
||||
// var purchaseValue = selectUnitType.purchaseValue?.toDouble() ?: 1.0
|
||||
// if (consumeValue == 0.0) {
|
||||
// consumeValue = 1.0
|
||||
// }
|
||||
// if (purchaseValue == 0.0) {
|
||||
// purchaseValue = 1.0
|
||||
// }
|
||||
// val count =
|
||||
// weight * 1000 / consumeValue / purchaseValue
|
||||
// val finalCount = count.toSafeDouble(currentItem.unitName)
|
||||
// Timber.d("startSensorScale weight = $weight, count = $count, finalCount = $finalCount, consumeValue = $consumeValue, purchaseValue = $purchaseValue")
|
||||
//
|
||||
// Timber.d("startSensorScale goodsUnitPrice = ${info.goodsUnitPrice}, goodsPrice = ${info.goodsPrice} ")
|
||||
// // 计算单价 金额不为空,数量也不为空, 不是数量输入 也不是单价输入
|
||||
// val finalPrice =
|
||||
// if (finalCount == 0.0) {
|
||||
// 0.0
|
||||
// } else if (_amountUserInput.value && !_priceUserInput.value) {
|
||||
// info.goodsPrice.div(finalCount).toSafeDouble()
|
||||
// } else 0.0
|
||||
//
|
||||
// // 计算金额 单价不为空,不是数量输入 也不是金额输入
|
||||
// val finalAmount =
|
||||
// if (finalCount == 0.0) {
|
||||
// 0.0
|
||||
// } else if (_priceUserInput.value && !_amountUserInput.value) {
|
||||
// finalCount.times(info.goodsUnitPrice).toSafeDouble()
|
||||
// } else 0.0
|
||||
// Timber.d("startSensorScale finalPrice = $finalPrice, finalAmount = $finalAmount ")
|
||||
// _selectedItem.value = info.copy(
|
||||
// goodsWeight = weight.toSafeBigDecimal(),
|
||||
// // 数量
|
||||
// goodsCountTemp = finalCount.toFormattedString(),
|
||||
// goodsCount = finalCount,
|
||||
// // 单价
|
||||
// goodsUnitPrice = if (_priceUserInput.value) info.goodsUnitPrice else finalPrice,
|
||||
// goodsUnitPriceTemp = if (_priceUserInput.value) info.goodsUnitPriceTemp else finalPrice.toFormattedString(),
|
||||
// // 金额
|
||||
// goodsPrice = if (_amountUserInput.value) info.goodsPrice else finalAmount,
|
||||
// goodsPriceTemp = if (_amountUserInput.value) info.goodsPriceTemp else finalAmount.toFormattedString()
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun updateAddProductDialog(show: Boolean) {
|
||||
// _showAddProductDialog.value = show
|
||||
// if (!show) {
|
||||
// _goodsAddParam.value = GoodsAddParam()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun updateSelectedItem(purchaseOrder: PurchaseWarehouseParam?) {
|
||||
//// updateLastPhotoUri(null)
|
||||
// if (purchaseOrder != null) {
|
||||
// if (purchaseOrder.goodsCount != 0.0) {
|
||||
// if (purchaseOrder.goodsUnitPriceTemp.isNotEmpty()) { // 计算金额 单价不为空,并且金额没有手动输入
|
||||
// Timber.d("updateSelectedItem 计算金额")
|
||||
// val result =
|
||||
// purchaseOrder.goodsCount.times(purchaseOrder.goodsUnitPrice)
|
||||
// purchaseOrder.goodsPrice = result.toSafeDouble()
|
||||
// purchaseOrder.goodsPriceTemp = result.toFormattedString()
|
||||
// } else if (purchaseOrder.goodsPriceTemp.isNotEmpty()) { // 计算单价 金额不为空,并且单价没有手动输入
|
||||
// Timber.d("updateSelectedItem 计算单价")
|
||||
// val result =
|
||||
// purchaseOrder.goodsPrice.div(purchaseOrder.goodsCount)
|
||||
// purchaseOrder.goodsUnitPrice = result.toSafeDouble()
|
||||
// purchaseOrder.goodsUnitPriceTemp = result.toFormattedString()
|
||||
// }
|
||||
// } else {
|
||||
// if (_priceUserInput.value) {
|
||||
// purchaseOrder.goodsPrice = 0.0
|
||||
// purchaseOrder.goodsPriceTemp = ""
|
||||
// } else if (_amountUserInput.value) {
|
||||
// purchaseOrder.goodsUnitPrice = 0.0
|
||||
// purchaseOrder.goodsUnitPriceTemp = ""
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// // 重置输入状态
|
||||
// Timber.d("重置输入状态")
|
||||
// _countUserInput.value = false
|
||||
// _priceUserInput.value = false
|
||||
// _amountUserInput.value = false
|
||||
// }
|
||||
// _selectedItem.value = purchaseOrder
|
||||
// Timber.d("updateSelectedItem 更新,goodsUnitPrice = ${_selectedItem.value?.goodsUnitPrice}, ${_selectedItem.value?.goodsUnitPriceTemp}")
|
||||
// }
|
||||
//
|
||||
// fun updateGoodsAddParam(newState: GoodsAddParam) {
|
||||
// _goodsAddParam.value = newState
|
||||
// }
|
||||
//
|
||||
// fun cleanGoodsAddParam() {
|
||||
// _goodsAddParam.value = GoodsAddParam()
|
||||
// }
|
||||
//
|
||||
// // 添加订单
|
||||
// fun addPurchaseItem(purchaseOrder: PurchaseWarehouseParam) {
|
||||
// _purchaseList.update { currentList ->
|
||||
// currentList + purchaseOrder
|
||||
// }
|
||||
// updateSelectedItem(null)
|
||||
// }
|
||||
//
|
||||
// // 更新订单
|
||||
// fun updatePurchaseItem(purchaseOrder: PurchaseWarehouseParam) {
|
||||
// _purchaseList.update { currentList ->
|
||||
// currentList.map { order ->
|
||||
// if (order.goodsId == purchaseOrder.goodsId) purchaseOrder else order
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 删除订单
|
||||
//// fun removePurchaseOrder(orderId: Int) {
|
||||
//// _purchaseList.update { currentList ->
|
||||
//// currentList.filterNot { it.goodsId == orderId }
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
// /**
|
||||
// * 根据位置删除物品
|
||||
// */
|
||||
// fun removePurchaseOrderByIndex(index: Int) {
|
||||
// _purchaseList.update { currentList ->
|
||||
// currentList.toMutableList().apply {
|
||||
// removeAt(index)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 清空列表
|
||||
// fun clearPurchaseOrders() {
|
||||
// _purchaseList.value = emptyList()
|
||||
// }
|
||||
//
|
||||
// override fun handleIdentityItem(goodsInfo: SearchGoodsInfo.Record) {
|
||||
//// updateSelectedItemWithSearch(goodsInfo)
|
||||
// }
|
||||
//
|
||||
//// fun updateSelectedItemWithSearch(searchFirst: SearchGoodsInfo.Record) {
|
||||
//// val warehouse = _globalWarehouse.value
|
||||
//// viewModelScope.launch {
|
||||
//// updateSelectedItem(null)
|
||||
//// delay(50)
|
||||
//// _selectedItem.value = PurchaseWarehouseParam(
|
||||
//// warehouseId = warehouse.id,
|
||||
//// goodsId = searchFirst.goodsId ?: 0,
|
||||
//// goodsName = searchFirst.goodsName,
|
||||
//// kcUnitId = searchFirst.kcUnitId ?: 0,
|
||||
//// unitList = searchFirst.unitVoList,
|
||||
//// consumeValue = searchFirst.consumeValue ?: ""
|
||||
//// )
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
// /**
|
||||
// * 数量输入状态
|
||||
// */
|
||||
// fun updateCountInputState(boolean: Boolean) {
|
||||
// _countUserInput.value = boolean
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 单价输入状态
|
||||
// */
|
||||
// fun updatePriceInputState(boolean: Boolean) {
|
||||
// _priceUserInput.value = boolean
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 金额输入状态
|
||||
// */
|
||||
// fun updateAmountInputState(boolean: Boolean) {
|
||||
// _amountUserInput.value = boolean
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 添加商品
|
||||
// */
|
||||
//// fun addGoodsInfo() {
|
||||
//// val imageUri = GlobalData.imageUri
|
||||
//// if (imageUri == null) {
|
||||
//// ToastUtils.showToast("请先进行图片采集")
|
||||
//// return
|
||||
//// }
|
||||
//// val errInfo = _goodsAddParam.value.hasNullField()
|
||||
//// if (errInfo != null) {
|
||||
//// ToastUtils.showToast(errInfo)
|
||||
//// return
|
||||
//// }
|
||||
////
|
||||
//// launchWithLoading {
|
||||
//// val uploadResponse = repository.uploadImage(imageUri)
|
||||
//// if (!parseResponse(uploadResponse)) {
|
||||
//// return@launchWithLoading
|
||||
//// }
|
||||
////// ToastUtils.showToast("图片上传成功,${uploadResponse.data}")
|
||||
//// GlobalData.imageUri = null
|
||||
//// _goodsAddParam.value.relativeUrl = uploadResponse.result
|
||||
//// val response = repository.selfPurchaseGoodsAdd(_goodsAddParam.value)
|
||||
//// if (!parseResponse(response)) {
|
||||
//// return@launchWithLoading
|
||||
//// }
|
||||
//// FileUtils.deleteFileWithUri(context = ContextUtils.getAppContext(), uri = imageUri)
|
||||
//// _showAddProductDialog.value = false
|
||||
//// _goodsAddParam.value = GoodsAddParam()
|
||||
//// val searchFirst = response.result!!.records?.get(0)
|
||||
//// searchFirst?.let {
|
||||
//// updateSelectedItemWithSearch(searchFirst)
|
||||
//// }
|
||||
//// _addGoodsResult.value = true
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
// fun updateAddPurchaseUnitDialog(show: Boolean) {
|
||||
// if (_selectedItem.value == null) return
|
||||
// _showAddPurchaseUnitDialog.value = show
|
||||
// if (show) {
|
||||
// val hasUnitId =
|
||||
// GlobalData.unitTypeList.any { it.id == _selectedItem.value!!.kcUnitId.toString() }
|
||||
// _canChangeKcUnit.value = !hasUnitId
|
||||
// _canChangeConsumeValue.value =
|
||||
// _selectedItem.value!!.consumeValue.trim().isEmpty() == true
|
||||
// } else {
|
||||
// _goodsAddUnitParam.value = GoodsPurchaseUnitParam()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun updateGoodsPurchaseUnit(goodsPurchaseUnitParam: GoodsPurchaseUnitParam?) {
|
||||
// if (goodsPurchaseUnitParam == null) {
|
||||
// _goodsAddUnitParam.value = GoodsPurchaseUnitParam()
|
||||
// } else {
|
||||
// _goodsAddUnitParam.value = goodsPurchaseUnitParam
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun updateDropdownTextChange(canChange: Boolean) {
|
||||
// _canChangeKcUnit.value == canChange
|
||||
// }
|
||||
//
|
||||
// fun addGoodsPurchaseUnit() {
|
||||
// val errorInfo = _goodsAddUnitParam.value.hasNullField()
|
||||
// if (errorInfo != null) {
|
||||
// ToastUtils.showToast(errorInfo)
|
||||
// return
|
||||
// }
|
||||
// launchWithLoading {
|
||||
// val response = repository.selfPurchaseGoodsAddUnit(_goodsAddUnitParam.value)
|
||||
// if (parseResponse(response)) {
|
||||
// _showAddPurchaseUnitDialog.value = false
|
||||
// _goodsAddUnitParam.value = GoodsPurchaseUnitParam()
|
||||
//// _addGoodsPurchaseUnitResult.value = true
|
||||
// ToastUtils.showToast("采购单位添加成功")
|
||||
//
|
||||
// // 通过id搜索物品,补充采购单位
|
||||
// val response = repository.searchGoodsInfoList(
|
||||
// goodsName = "${_selectedItem.value?.goodsId}"
|
||||
// )
|
||||
// if (parseResponse(response)) {
|
||||
// val searchList: List<SearchGoodsInfo.Record> =
|
||||
// response.result?.records ?: emptyList()
|
||||
// if (searchList.isNotEmpty()) {
|
||||
// val searchItem = searchList[0]
|
||||
// _selectedItem.value = _selectedItem.value?.copy(
|
||||
// unitList = searchItem.unitVoList,
|
||||
// kcUnitId = searchItem.kcUnitId ?: 0,
|
||||
// consumeValue = searchItem.consumeValue ?: ""
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 物品提交入库
|
||||
// */
|
||||
// fun addToWarehouse() {
|
||||
// if (_purchaseList.value.isEmpty()) {
|
||||
// ToastUtils.showToast("采购列表为空")
|
||||
// return
|
||||
// }
|
||||
// launchWithLoading {
|
||||
// val response = repository.selfPurchaseWarehousing(_purchaseList.value)
|
||||
// _addToWarehouseResult.value = parseResponse(response)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -28,12 +28,12 @@ class UserViewModel @Inject constructor(
|
||||
|
||||
fun getInitInfo() {
|
||||
Timber.d("getInitInfo isFirstLaunch = $isFirstLaunch")
|
||||
if (isFirstLaunch) {
|
||||
//if (isFirstLaunch) {
|
||||
|
||||
getUserInfo()
|
||||
getDictType()
|
||||
isFirstLaunch = false
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
fun login(userName: String, password: String) = launchWithLoading {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#FF0032C8"/>
|
||||
<corners android:radius="10dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#30000000">
|
||||
<item android:drawable="@drawable/bg_blue_radius10"/>
|
||||
</ripple>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#FFFEFDFC"/>
|
||||
<corners android:radius="12dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#FFDCDCF0"/>
|
||||
<corners android:radius="10dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#30000000">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#FF14CD71"/>
|
||||
<corners android:radius="6dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#99FFFFFF"/>
|
||||
<corners android:radius="6dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/white"/>
|
||||
<corners android:radius="10dp"/>
|
||||
<stroke android:color="#FFD5E1FF" android:width="2dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/white"/>
|
||||
<corners android:radius="10dp"/>
|
||||
<stroke android:color="#FFDCDCF0" android:width="2dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<corners android:radius="10dp" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="#FFDCDCF0"
|
||||
android:dashWidth="10dp"
|
||||
android:dashGap="3dp" />
|
||||
</shape>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/white"/>
|
||||
<corners android:radius="12dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#30000000">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/white"/>
|
||||
<stroke android:color="#FF0032C8" android:width="2dp"/>
|
||||
<corners android:radius="10dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#30000000">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/white"/>
|
||||
<stroke android:color="#FF14CD71" android:width="2dp"/>
|
||||
<corners android:radius="6dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="#30000000">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#99FFFFFF"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -0,0 +1,206 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@mipmap/bg"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="40dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:text="出入库管理"
|
||||
android:textColor="#141428"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvUserName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="#141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="冯厨子" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivLogout"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginEnd="40dp"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:src="@mipmap/ic_logout"
|
||||
tools:ignore="ContentDescription" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/bg_white_alpha40_radius6"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="20dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPurchaseNo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#ff333333"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="采购单号:CG2506190526" />
|
||||
|
||||
<androidx.camera.view.PreviewView
|
||||
android:id="@+id/previewView"
|
||||
android:layout_width="2dp"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginStart="5dp" />
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flWarehouseDropdown"
|
||||
android:layout_width="280dp"
|
||||
android:layout_height="70dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke"
|
||||
android:paddingHorizontal="30dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWareHouse"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="选择仓库"
|
||||
android:textColor="#000033"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivDropdown"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#FFD5E1FF" />
|
||||
|
||||
<!-- <include layout="@layout/list_item_receipt_goods" />-->
|
||||
<!-- <include layout="@layout/list_item_self_procurement" />-->
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvGoodsList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:overScrollMode="never"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:itemCount="8" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="130dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/btnBack"
|
||||
android:layout_width="270dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="@drawable/bg_blue_ripple">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:drawableStart="@mipmap/ic_back_white2"
|
||||
android:drawablePadding="32dp"
|
||||
android:gravity="center"
|
||||
android:text="返回"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="UseCompatTextViewDrawableXml" />
|
||||
</FrameLayout>
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvConfirmNum"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="已确认 3"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvNotConfirmNum"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="未确认 6"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnConfirmReceipt"
|
||||
android:layout_width="270dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:background="@drawable/bg_blue_ripple"
|
||||
android:gravity="center"
|
||||
android:text="确认收货"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,588 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="1500dp"
|
||||
android:layout_height="900dp"
|
||||
android:background="@drawable/bg_white_radius12"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="120dp"
|
||||
android:gravity="center"
|
||||
android:text="新增物品"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginHorizontal="40dp"
|
||||
android:background="#FFDCDCF0" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="40dp">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flImageCollect"
|
||||
android:layout_width="430dp"
|
||||
android:layout_height="322dp"
|
||||
android:layout_marginTop="40dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2_dash"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/llGoodsInfo">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llStartPreview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="96dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@mipmap/ic_camera_gray"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="图片采集"
|
||||
android:textColor="#ffb4b4c8"
|
||||
android:textSize="24sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.camera.view.PreviewView
|
||||
android:id="@+id/previewView"
|
||||
android:layout_width="428dp"
|
||||
android:layout_height="320dp"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivGoodsImage"
|
||||
android:layout_width="428dp"
|
||||
android:layout_height="320dp"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnStartPreview"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginTop="39dp"
|
||||
android:background="@drawable/bg_white_stroke_green_ripple"
|
||||
android:text="取消"
|
||||
android:textColor="#FF14CD71"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="@id/flImageCollect"
|
||||
app:layout_constraintTop_toBottomOf="@id/flImageCollect" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/btnTakePhoto"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:background="@drawable/bg_green_ripple"
|
||||
android:gravity="center"
|
||||
app:layout_constraintBottom_toBottomOf="@id/btnStartPreview"
|
||||
app:layout_constraintEnd_toEndOf="@id/flImageCollect"
|
||||
app:layout_constraintStart_toEndOf="@id/btnStartPreview"
|
||||
app:layout_constraintTop_toTopOf="@id/btnStartPreview">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableStart="@mipmap/ic_camera_white"
|
||||
android:drawablePadding="11dp"
|
||||
android:gravity="center"
|
||||
android:text="采集"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="UseCompatTextViewDrawableXml" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llGoodsInfo"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="80dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/flImageCollect">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="432dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="物品名称"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="40dp"
|
||||
android:text="净材率"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etGoodsName"
|
||||
android:layout_width="432dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:hint="请录入"
|
||||
android:maxLines="1"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="432dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginStart="40dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNetMaterialRate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:hint="请录入"
|
||||
android:maxLines="1"
|
||||
android:layout_marginEnd="60dp"
|
||||
android:inputType="numberDecimal"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:background="#00000000"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="match_parent"
|
||||
android:text="%"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:textColor="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="432dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="物品类型"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="40dp"
|
||||
android:text="存储方式"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flGoodsType"
|
||||
android:layout_width="432dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvGoodsType"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:ellipsize="end"
|
||||
android:hint="请选择"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flStorageType"
|
||||
android:layout_width="432dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginStart="40dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStorageType"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:ellipsize="end"
|
||||
android:hint="请选择"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="432dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="库存单位"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="40dp"
|
||||
android:text="消耗单位"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flWarehouseUnit"
|
||||
android:layout_width="432dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWarehouseUnit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:ellipsize="end"
|
||||
android:hint="请选择"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="40dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etUseUnit"
|
||||
android:layout_width="188dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:gravity="start|center_vertical"
|
||||
android:hint="请输入"
|
||||
android:inputType="number"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:textColor="#FF000000"
|
||||
android:textColorHint="#FFC7C8DC"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="82dp"
|
||||
android:layout_height="60dp"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="29dp"
|
||||
android:text="克"
|
||||
android:textColor="#ffa0a0b4"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="60dp"
|
||||
android:gravity="center_vertical"
|
||||
android:text="="
|
||||
android:textColor="#ff96a0aa"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSelectUseUnit"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_gray_radius10"
|
||||
android:gravity="center"
|
||||
android:textColor="#ff96a0aa"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="瓶" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:text="采购单位"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="92dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2_dash"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="61dp"
|
||||
android:layout_height="60dp"
|
||||
android:gravity="center"
|
||||
android:text="1"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flProcurementUnit"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProcurementUnit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:ellipsize="end"
|
||||
android:hint="请选择"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivDropdown"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="60dp"
|
||||
android:gravity="center"
|
||||
android:text="="
|
||||
android:textColor="#FF96A0AA"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etGoodsCount"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:gravity="center"
|
||||
android:hint="请录入"
|
||||
android:inputType="number"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="25dp"
|
||||
android:paddingEnd="25dp"
|
||||
android:textColor="#FF000000"
|
||||
android:textColorHint="#FFC7C8DC"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSelectProcurementUnit"
|
||||
android:layout_width="112dp"
|
||||
android:layout_height="60dp"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="30dp"
|
||||
android:textColor="#FF141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="RtlSymmetry"
|
||||
tools:text="瓶" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="78dp"
|
||||
android:layout_height="60dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="#FF141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:text="单价" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etGoodsPrice"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:gravity="center"
|
||||
android:hint="请录入"
|
||||
android:inputType="numberDecimal"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="25dp"
|
||||
android:paddingEnd="25dp"
|
||||
android:textColor="#FF000000"
|
||||
android:textColorHint="#FFC7C8DC"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="82dp"
|
||||
android:layout_height="60dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#FFA0A0B4"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:text="元" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginHorizontal="40dp"
|
||||
android:background="#FFDCDCF0" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="160dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="50dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnClose"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_white_stroke_blue_ripple"
|
||||
android:text="关闭"
|
||||
android:textColor="#FF0033CC"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnConfirm"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginStart="30dp"
|
||||
android:background="@drawable/bg_blue_ripple"
|
||||
android:text="确定"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,273 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="1190dp"
|
||||
android:layout_height="840dp"
|
||||
android:background="@drawable/bg_white_radius12"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="184dp"
|
||||
android:gravity="center"
|
||||
android:text="添加采购单位"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginHorizontal="30dp"
|
||||
android:background="#FFDCDCF0" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="802dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="370dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="库存单位"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="62dp"
|
||||
android:text="消耗单位"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flWarehouseUnit"
|
||||
android:layout_width="370dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvWarehouseUnit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:ellipsize="end"
|
||||
android:hint="请选择"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etUseUnit"
|
||||
android:layout_width="158dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginStart="62dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:gravity="start|center_vertical"
|
||||
android:hint="请输入"
|
||||
android:inputType="number"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="25dp"
|
||||
android:paddingEnd="25dp"
|
||||
android:textColor="#FF000000"
|
||||
android:textColorHint="#FFC7C8DC"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="76dp"
|
||||
android:layout_height="60dp"
|
||||
android:text="克"
|
||||
android:textStyle="bold"
|
||||
android:paddingStart="24dp"
|
||||
android:paddingEnd="30dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="#ffa0a0b4"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="60dp"
|
||||
android:text="="
|
||||
android:gravity="center_vertical"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#ff96a0aa"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSelectUnit"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="60dp"
|
||||
tools:text="瓶"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/bg_gray_radius10"
|
||||
android:textColor="#ff96a0aa"
|
||||
android:textSize="24sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="采购单位"
|
||||
android:textColor="#ff141428"
|
||||
android:layout_marginTop="30dp"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="92dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="30dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2_dash">
|
||||
|
||||
<TextView
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="60dp"
|
||||
android:text="1"
|
||||
android:gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flProcurementUnit"
|
||||
android:layout_width="260dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProcurementUnit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:ellipsize="end"
|
||||
android:hint="请选择"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivDropdown"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="102dp"
|
||||
android:layout_height="60dp"
|
||||
android:text="="
|
||||
android:gravity="center"
|
||||
android:textColor="#FF96A0AA"
|
||||
android:textSize="24sp" />
|
||||
<EditText
|
||||
android:id="@+id/etInputWeight"
|
||||
android:layout_width="260dp"
|
||||
android:layout_height="60dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:gravity="center"
|
||||
android:hint="请录入"
|
||||
android:maxLines="1"
|
||||
android:inputType="numberDecimal"
|
||||
android:paddingStart="25dp"
|
||||
android:paddingEnd="25dp"
|
||||
android:textColor="#FF000000"
|
||||
android:textColorHint="#FFC7C8DC"
|
||||
android:textStyle="bold"
|
||||
android:textSize="24sp"
|
||||
tools:ignore="Autofill" />
|
||||
<TextView
|
||||
android:layout_width="108dp"
|
||||
android:layout_height="60dp"
|
||||
android:text="千克"
|
||||
android:gravity="center"
|
||||
android:textColor="#FF96A0AA"
|
||||
android:textSize="24sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="完善更多单位信息请登录后台维护,建议及时操作以确保信息准确"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="24sp"
|
||||
android:layout_marginTop="50dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginHorizontal="30dp"
|
||||
android:background="#FFDCDCF0" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="160dp"
|
||||
android:gravity="end|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="30dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCancel"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_white_stroke_blue_ripple"
|
||||
android:text="取消"
|
||||
android:textColor="#FF0033CC"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnConfirm"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:background="@drawable/bg_blue_ripple"
|
||||
android:text="确定"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="1500dp"
|
||||
android:layout_height="900dp"
|
||||
android:background="@drawable/bg_white_radius12"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivClose"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:padding="10dp"
|
||||
android:src="@mipmap/ic_close"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDialogTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="物品识别结果"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@+id/rvRecognize"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvRecognize"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="340dp"
|
||||
android:layout_marginTop="180dp"
|
||||
tools:itemCount="5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:overScrollMode="never"
|
||||
android:layout_marginHorizontal="30dp"
|
||||
tools:listitem="@layout/list_item_recognize"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/dividerLine"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#FFDCDCF0"
|
||||
android:layout_marginBottom="160dp"
|
||||
android:layout_marginHorizontal="40dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnManuallyFind"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:text="手动查找"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toTopOf="@id/dividerLine"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintEnd_toStartOf="@+id/btnAgainRecognize"
|
||||
android:textColor="#FF0033CC"
|
||||
android:textSize="30sp"
|
||||
android:background="@drawable/bg_white_stroke_blue_ripple"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnAgainRecognize"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:text="重新识别"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toTopOf="@id/dividerLine"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/btnManuallyFind"
|
||||
android:textColor="@color/white"
|
||||
android:layout_marginStart="30dp"
|
||||
android:textSize="30sp"
|
||||
android:background="@drawable/bg_blue_ripple"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="若以上识别结果都不是该物品,请点击“重新识别”或“手动查找”"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="30sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/dividerLine"
|
||||
android:layout_marginBottom="60dp"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="1500dp"
|
||||
android:layout_height="900dp"
|
||||
android:background="@drawable/bg_white_radius12"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivClose"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="30dp"
|
||||
android:padding="10dp"
|
||||
android:src="@mipmap/ic_close"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDialogTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="物品检索"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@+id/flSearchBlock"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flSearchBlock"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginHorizontal="150dp"
|
||||
android:layout_marginTop="180dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etInputGoods"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#00000000"
|
||||
android:gravity="center"
|
||||
android:hint="输入物品名称"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="80dp"
|
||||
android:textColor="#FF666666"
|
||||
android:textColorHint="#FFC7C8DC"
|
||||
android:textSize="30sp"
|
||||
android:inputType="text"
|
||||
android:imeOptions="actionSearch" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivGoodsSearch"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:padding="14dp"
|
||||
android:src="@mipmap/ic_goods_search" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<com.scwang.smart.refresh.layout.SmartRefreshLayout
|
||||
android:id="@+id/refreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginHorizontal="130dp"
|
||||
android:layout_marginTop="40dp"
|
||||
android:layout_marginBottom="58dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/dividerLine"
|
||||
app:layout_constraintTop_toBottomOf="@id/flSearchBlock">
|
||||
|
||||
<com.scwang.smart.refresh.header.ClassicsHeader
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvSearch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:overScrollMode="never"
|
||||
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
|
||||
app:spanCount="2"
|
||||
tools:itemCount="8"
|
||||
tools:listitem="@layout/list_item_goods_search" />
|
||||
|
||||
<com.scwang.smart.refresh.footer.ClassicsFooter
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/dividerLine"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginHorizontal="40dp"
|
||||
android:layout_marginBottom="160dp"
|
||||
android:background="#FFDCDCF0"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<!-- <Button-->
|
||||
<!-- android:id="@+id/btnAddGoods"-->
|
||||
<!-- android:layout_width="240dp"-->
|
||||
<!-- android:layout_height="80dp"-->
|
||||
<!-- android:background="@drawable/bg_white_stroke_blue_ripple"-->
|
||||
<!-- android:text="添加物品"-->
|
||||
<!-- android:textColor="#FF0033CC"-->
|
||||
<!-- android:textSize="30sp"-->
|
||||
<!-- android:textStyle="bold"-->
|
||||
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||
<!-- app:layout_constraintEnd_toStartOf="@+id/btnConfirm"-->
|
||||
<!-- app:layout_constraintHorizontal_chainStyle="packed"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toTopOf="@id/dividerLine"-->
|
||||
<!-- android:visibility="gone"/>-->
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnConfirm"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_blue_ripple"
|
||||
android:text="确定"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/dividerLine" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,388 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="1500dp"
|
||||
android:layout_height="900dp"
|
||||
android:background="@drawable/bg_white_radius12"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="142dp"
|
||||
android:gravity="center"
|
||||
android:text="物品入库"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginHorizontal="40dp"
|
||||
android:background="#FFDCDCF0" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.6" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toStartOf="@id/guideline"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="70dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="物品名称"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etGoodsName"
|
||||
android:layout_width="428dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="57dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:hint="请录入"
|
||||
android:maxLines="1"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="入库单位"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flUnitDropdown"
|
||||
android:layout_width="428dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="57dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProcurementUnit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:ellipsize="end"
|
||||
android:hint="请选择"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivDropdown"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivAddUnit"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:src="@mipmap/ic_add_unit"
|
||||
tools:ignore="ContentDescription"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="入库数量"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="428dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="57dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etProcurementCount"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginEnd="70dp"
|
||||
android:background="#00000000"
|
||||
android:hint="请录入"
|
||||
android:maxLines="1"
|
||||
android:inputType="number"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:gravity="center"
|
||||
android:text="-"
|
||||
android:textColor="#ff96a0aa"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="入库单价"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="428dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="57dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProcurementPrice"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginEnd="70dp"
|
||||
android:background="#00000000"
|
||||
android:hint="由入库数量和金额计算生成"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:gravity="center"
|
||||
android:text="元"
|
||||
android:textColor="#ff96a0aa"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="入库金额"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="428dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginStart="57dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etProcurementAmount"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginEnd="70dp"
|
||||
android:background="#00000000"
|
||||
android:hint="请录入"
|
||||
android:maxLines="1"
|
||||
android:inputType="numberDecimal"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:textColor="#ff141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:gravity="center"
|
||||
android:text="元"
|
||||
android:textColor="#ff96a0aa"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/guideline">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="488dp"
|
||||
android:layout_height="356dp"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:padding="2dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivGoodsImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="fitCenter"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:src="@mipmap/ic_launcher"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="488dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginTop="37dp"
|
||||
android:background="@drawable/bg_gray_radius10">
|
||||
|
||||
<TextView
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:gravity="center"
|
||||
android:text="累计"
|
||||
android:textColor="#FF141428"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTotalWeight"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="120dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#FF141428"
|
||||
android:textSize="24sp"
|
||||
tools:text="6300 克" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/btnClearZero"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="end"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:gravity="center"
|
||||
android:text="清零"
|
||||
android:textColor="#FF141428"
|
||||
android:textSize="24sp" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginHorizontal="40dp"
|
||||
android:background="#FFDCDCF0" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="160dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="50dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCancel"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_white_stroke_blue_ripple"
|
||||
android:text="取消"
|
||||
android:textColor="#FF0033CC"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnConfirm"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginStart="30dp"
|
||||
android:background="@drawable/bg_blue_ripple"
|
||||
android:text="确定"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="960dp"
|
||||
android:layout_height="540dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/bg_white_radius12"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:src="@mipmap/ic_tip_warn"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="80dp"
|
||||
android:layout_marginVertical="50dp"
|
||||
android:gravity="center"
|
||||
android:text="存在未收货的物品,请确认是否放弃收货,若放弃则数据不会保存?"
|
||||
android:textColor="#ff141428"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="点击“取消”按钮返回页面,去收货;点击“确认”按钮关闭页面,放弃收货。"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="24sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="20dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCancel"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:background="@drawable/bg_white_stroke_blue_ripple"
|
||||
android:text="取消"
|
||||
android:textColor="#FF0033CC"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnConfirm"
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_marginStart="50dp"
|
||||
android:background="@drawable/bg_blue_ripple"
|
||||
android:text="确认"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="30sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="HardcodedText,UseCompoundDrawables">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="80dp"
|
||||
android:src="@mipmap/ic_tip_warn"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="50dp"
|
||||
android:text="系统异常,请稍后重试!"
|
||||
android:textColor="#ff000000"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="80dp"
|
||||
android:src="@mipmap/ic_empty_view"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginBottom="39dp"
|
||||
android:text="暂无该物品"
|
||||
android:textColor="#ff000000"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="请检查物品名称,或点击“添加物品”按钮新增物品信息"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="30sp" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvWarehouse"
|
||||
android:layout_width="280dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:itemCount="10"
|
||||
android:layout_margin="1dp"
|
||||
android:overScrollMode="never"
|
||||
tools:listitem="@layout/list_item_dropdown"
|
||||
android:background="@drawable/bg_white_radius10_stroke" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/ripple_effect_light">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDropdown"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#ff000033"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="选择仓库" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#90D5E1FF" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="82dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
tools:background="@drawable/bg_white_stroke_blue_ripple">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvGoodsName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
tools:text="高杆白菜"
|
||||
android:textColor="#ff666666"
|
||||
android:textSize="30sp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textStyle="bold" />
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="86dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvGoodsName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.5"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:text="物品名称"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProcurementUnit"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:text="采购单位"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProcurementCount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:text="采购数量"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProcurementPrice"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:text="采购单价(元)"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvProcurementAmount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:text="采购金额(元)"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvReceiptCount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:text="收货数量"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvGoodsWeight"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:text="物品重量(克)"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.6">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvState"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:text="状态"
|
||||
android:textColor="#ff999999"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivState"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/ic_receipt_no"
|
||||
android:visibility="gone"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user