初始代码提交

This commit is contained in:
2026-01-14 10:36:27 +08:00
parent 600aa4dbb0
commit 196cacfe5a
268 changed files with 22545 additions and 2 deletions
@@ -0,0 +1,334 @@
package com.sw.inbound.viewmodel
import android.net.Uri
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sw.inbound.GlobalData
import com.sw.inbound.model.response.ApiResponse
import com.sw.inbound.model.response.DictType
import com.sw.inbound.model.response.EquipmentInfo
import com.sw.inbound.model.response.GoodsInfo
import com.sw.inbound.model.response.SearchGoodsInfo
import com.sw.inbound.network.LoadingState
import com.sw.inbound.objbox.FoodModule
import com.sw.inbound.repository.RemoteRepository
import com.sw.inbound.utils.ToastUtils
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import retrofit2.HttpException
import timber.log.Timber
import java.io.IOException
import kotlin.collections.List
import kotlin.math.roundToInt
abstract class BaseViewModel(
private val repository: RemoteRepository
) : ViewModel() {
// 需要拍照
private val _takePhotoState = MutableStateFlow(false)
val takePhotoState: StateFlow<Boolean> = _takePhotoState
// 称重结果
private val _weightInfo = MutableStateFlow<Double>(0.0)
val weightInfo: StateFlow<Double> = _weightInfo
// 搜索物品列表
private val _searchListItems = MutableStateFlow<List<SearchGoodsInfo.Record>>(emptyList())
val searchListItems: StateFlow<List<SearchGoodsInfo.Record>> = _searchListItems
// 识别列表
private val _identityListItems = MutableStateFlow<List<SearchGoodsInfo.Record>>(emptyList())
val identityListItems: StateFlow<List<SearchGoodsInfo.Record>> = _identityListItems
// 待收货的列表 用于识别时从中获取
private val _receiptList = MutableStateFlow<List<SearchGoodsInfo.Record>>(emptyList())
val receiptList: StateFlow<List<SearchGoodsInfo.Record>> = _receiptList
// 拍照uri
private val _lastPhotoUri = MutableStateFlow<Uri?>(null)
val lastPhotoUri: StateFlow<Uri?> = _lastPhotoUri
/**
* 是否可以加载更多
*/
private val _canLoadMore = MutableStateFlow(true)
val canLoadMore: StateFlow<Boolean> = _canLoadMore
/**
* 是否显示进度条
*/
private val _isMoreLoading = MutableStateFlow(false)
val isMoreLoading = _isMoreLoading
/**
* 带进度条的请求
*/
protected fun launchWithLoading(block: suspend () -> Unit) {
viewModelScope.launch {
try {
LoadingState.show()
block()
} catch (e: Exception) {
// 错误处理可被子类重写
handleError(e)
} finally {
LoadingState.hide()
}
}
}
/**
* 不带进度条的请求
*/
protected fun launch(block: suspend () -> Unit) {
viewModelScope.launch() {
try {
block()
} catch (e: Exception) {
// 错误处理可被子类重写
handleError(e)
}
}
}
protected open fun parseResponse(response: ApiResponse<*>): Boolean {
if (response.isSuccess()) {
return true
}
Timber.d("msg = ${response.msg}, code = ${response.code}")
//ToastUtils.showToast("${response.msg}(${response.code})")
return false
}
protected open fun handleError(e: Exception) = {
Timber.e(e)
val message = when (e) {
is IOException -> "网络连接异常"
is HttpException -> "服务器错误: ${e.code()}"
else -> "操作失败: ${e.message}"
}
ToastUtils.showToast(message)
}
// fun startSensorScale() {
// Timber.d("开始称重")
// SensorScaleUtils.startScale(callback = { weight ->
// _weightInfo.value = weight
// handleSensorScale(weight)
// })
// }
//
// fun stopSensorScale() {
// Timber.d("关闭称重")
// SensorScaleUtils.stopContinuousRead()
// }
abstract fun handleSensorScale(weight: Double)
fun updateCanLoadMore(canLoad: Boolean) {
_canLoadMore.value = canLoad
}
fun updateLastPhotoUri(photoUri: Uri?) {
_lastPhotoUri.value = photoUri
}
// fun updateReceiptList(list: List<GoodsInfo>) {
// _receiptList.value = list.map { goods ->
// SearchGoodsInfo.Record(
// goodsId = goods.goodId,
// goodsName = goods.goodName
// )
// }
// }
//
// fun updateIdentityList(list: List<SearchGoodsInfo.Record>) {
// _identityListItems.value = list
// }
/**
* 获取识别列表
*/
// fun getIdentityList(photoUri: Uri) {
// Timber.d("getIdentityList")
// launchWithLoading {
// _searchListItems.value = emptyList<SearchGoodsInfo.Record>()
// // 有收货列表,则返回收货列表
// if (_receiptList.value.isNotEmpty()) {
// _identityListItems.value = _receiptList.value
// if (_identityListItems.value.isNotEmpty()) {
// handleIdentityItem(_identityListItems.value[0])
// }
// } else {
// val response = repository.searchGoodsInfoList("", 1, 10)
// if (parseResponse(response)) {
// _identityListItems.value = response.result?.records ?: emptyList()
// if (_identityListItems.value.isNotEmpty()) {
// handleIdentityItem(_identityListItems.value[0])
// }
// }
// }
// }
// }
/**
* 处理识别后要选中的值
*/
open fun handleIdentityItem(goodsInfo: SearchGoodsInfo.Record) {}
fun updateMoreLoading(moreLoading: Boolean) {
_isMoreLoading.value = moreLoading
}
/**
* 搜索物品
*/
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 ?: listOf()
} else {
listOf()
}
}
fun recognizeGoodsList(
nameList: List<String>?=null,
scoreList: List<FoodModule.IdNameScore>?=null,
callback: (List<SearchGoodsInfo.Record>) -> Unit
) {
launch {
if (nameList.isNullOrEmpty() && scoreList.isNullOrEmpty()) return@launch
val paramList = if (nameList.isNullOrEmpty()) scoreList!!.map { it.name } else nameList
val response = repository.recognizeGoodsList(paramList)
val list = if (parseResponse(response)) response.data?:listOf() else listOf()
if (scoreList.isNullOrEmpty().not()) {
list.forEach { record ->
val item = scoreList.firstOrNull { it.name == record.goodsName }
record.score = ((1 - (item?.score?:0.0)) * 10000).roundToInt()
}
}
callback(list)
}
}
// fun searchGoodsInfoList(
// goodsName: String,
// pageNo: Int = 1,
// pageSize: Int = 10,
// searchCallback: ((pageNo: Int, List<SearchGoodsInfo.Record>) -> Unit)? = null
// ) {
// launch {
// if (pageNo > 1) {
// _isMoreLoading.value = true
// }
// _identityListItems.value = emptyList<SearchGoodsInfo.Record>()
// val response = repository.searchGoodsInfoList(goodsName, pageNo, pageSize)
// _isMoreLoading.value = false
// if (parseResponse(response)) {
// val data = response.result
// data?.records?.let {
// _canLoadMore.value = data.records.size >= pageSize
// if (pageNo > 1) {
// _searchListItems.value = _searchListItems.value + data.records
// } else {
// _searchListItems.value = data.records
// }
// searchCallback?.invoke(pageNo, _searchListItems.value)
// }
// } else {
// _searchListItems.value = emptyList<SearchGoodsInfo.Record>()
// searchCallback?.invoke(pageNo, _searchListItems.value)
// }
// }
// }
fun getDictType() {
Timber.d("获取所有字典列表")
launchWithLoading {
val response = repository.getGoodsStorageType()
if (parseResponse(response)) {
Timber.d("getGoodsStorageType data = ${response.result}")
response.result?.let {
val list: MutableList<DictType> = mutableListOf()
response.result
?.filter { it.id.isNullOrBlank().not() && it.title.isNullOrBlank().not() }
?.forEach {
list.add(DictType(id = it.value, value = it.title))
}
GlobalData.storageTypeList = list
}
} else {
Timber.e("getGoodsStorageType msg = ${response.message}, code = ${response.code}")
}
val response1 = repository.getGoodsType()
if (parseResponse(response1)) {
Timber.d("getGoodsType data = ${response1.result?.allType}")
val list = mutableListOf<DictType>()
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}")
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}")
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}")
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}")
}
}
}
fun parseEquipmentInfo(equipmentInfo: EquipmentInfo) {
GlobalData.appBaseUrl = equipmentInfo.appPackageUrl!!
GlobalData.sdkKey = equipmentInfo.arcsoftSdkKey!!
GlobalData.appId = equipmentInfo.arcsoftAppId!!
// GlobalData.activeKey = equipmentInfo.arcsoftActiveKey!!
GlobalData.restId = equipmentInfo.canteenId!!
}
}
@@ -0,0 +1,81 @@
package com.sw.inbound.viewmodel
import com.sw.inbound.GlobalData
import com.sw.inbound.GlobalKey
import com.sw.inbound.model.response.EquipmentInfo
import com.sw.inbound.repository.RemoteRepository
import com.sw.inbound.utils.GsonUtils
import com.sw.inbound.utils.SPUtil
import com.sw.inbound.utils.ToastUtils
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import timber.log.Timber
import javax.inject.Inject
import kotlin.jvm.java
/**
* 初始化的viewmodel
*/
@HiltViewModel
class DeviceViewModel @Inject constructor(
private val repository: RemoteRepository
) : BaseViewModel(repository) {
private val _deviceInfoResult = MutableStateFlow<Boolean?>(null)
val deviceInfoResult: StateFlow<Boolean?> = _deviceInfoResult
/**
* 获取token
*/
fun getDeviceToken(deviceId: String = GlobalData.deviceId) {
launchWithLoading {
val response = repository.getDeviceToken(deviceId)
if (parseResponse(response)) {
val response1 = repository.getDeviceInfo(deviceId, response.result!!)
if (parseResponse(response1)) {
val equipmentInfo = response1.result
if (equipmentInfo == null) return@launchWithLoading
try {
parseEquipmentInfo(equipmentInfo)
SPUtil.getInstance()
.put(GlobalKey.KEY_EQUIPMENT_INFO, GsonUtils.toJson(equipmentInfo))
_deviceInfoResult.value = true
} catch (e: Exception) {
Timber.e(e)
}
} else {
ToastUtils.showToast("获取设备信息失败")
}
}
}
}
/**
* 检查缓存数据
*/
fun checkEquipmentInfo(): Boolean {
val equipmentInfoStr = SPUtil.getInstance().get(GlobalKey.KEY_EQUIPMENT_INFO, "")
if (equipmentInfoStr == null) {
Timber.e("获取缓存设备信息失败")
return false
}
val equipmentInfo =
GsonUtils.fromJson<EquipmentInfo>(equipmentInfoStr, EquipmentInfo::class.java)
if (equipmentInfo == null) {
Timber.e("解析缓存设备信息失败")
return false
}
try {
parseEquipmentInfo(equipmentInfo)
return true
} catch (e: Exception) {
Timber.e(e)
return false
}
}
override fun handleSensorScale(weight: Double) {
TODO("Not yet implemented")
}
}
@@ -0,0 +1,57 @@
package com.sw.inbound.viewmodel
import com.sw.inbound.model.response.SupplierInfo
import com.sw.inbound.repository.RemoteRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import timber.log.Timber
import javax.inject.Inject
/**
* 采购订单
*/
@HiltViewModel
class PurchaseOrderViewModel @Inject constructor(
private val repository: RemoteRepository
) : BaseViewModel(repository) {
/**
* 采购订单-供应商列表
*/
private val _supplierList = MutableStateFlow<List<SupplierInfo?>>(emptyList())
val supplierList: StateFlow<List<SupplierInfo?>> = _supplierList
/**
* 获取采购订单-供应商列表
*/
fun getOrderList(pageNum: Int = 1, pageSize: Int = 5) {
if (pageNum != 1) {
launch {
updateMoreLoading(true)
val response = repository.getReceiveList(pageNum, pageSize)
updateMoreLoading(false)
if (parseResponse(response)) {
response.result?.let {
updateCanLoadMore(it.size >= pageSize)
Timber.d("加载更多 canLoadMore =${it.size >= pageSize}")
_supplierList.value = _supplierList.value + it
}
}
}
} else {
launchWithLoading {
val response = repository.getReceiveList(pageNum, pageSize)
if (parseResponse(response)) {
response.result?.let {
_supplierList.value = it
}
}
}
}
}
override fun handleSensorScale(weight: Double) {
}
}
@@ -0,0 +1,419 @@
package com.sw.inbound.viewmodel
import android.net.Uri
import com.sw.inbound.model.request.GoodsAddParam
import com.sw.inbound.model.request.PurchaseWarehouseParam
import com.sw.inbound.model.request.UploadInfo
import com.sw.inbound.model.response.PurchaseInfo
import com.sw.inbound.model.response.SearchGoodsInfo
import com.sw.inbound.repository.RemoteRepository
import com.sw.inbound.utils.ext.toJsonString
import dagger.hilt.android.lifecycle.HiltViewModel
import okhttp3.RequestBody
import timber.log.Timber
import java.io.File
import javax.inject.Inject
/**
* 收货
*/
@HiltViewModel
class ReceiptViewModel @Inject constructor(
private val repository: RemoteRepository
) : BaseViewModel(repository) {
// 调整状态
// private val _adjustState = MutableStateFlow<Boolean>(true)
// val adjustState: StateFlow<Boolean> = _adjustState
//
// private val _showReceiptDialog = MutableStateFlow(false)
// val showReceiptDialog: StateFlow<Boolean> = _showReceiptDialog
//
// // 当前要收货的供应商
// private val _currentPurchaseInfo = MutableStateFlow<PurchaseInfo?>(null)
// val currentPurchaseInfo: StateFlow<PurchaseInfo?> = _currentPurchaseInfo
//
// private val _orders = MutableStateFlow<List<GoodsInfo>>(emptyList())
// val orders: StateFlow<List<GoodsInfo>> = _orders.asStateFlow()
// fun initOrders() {
// _orders.value = _currentPurchaseInfo.value?.receiveGoodsInfoList ?: emptyList()
// }
//
// // 已调整列表
// val adjustedOrders: StateFlow<List<GoodsInfo>> = _orders
// .map { orders -> orders.filter { it.isAdjusted } }
// .stateIn(viewModelScope, SharingStarted.Lazily, emptyList())
//
// // 未调整列表
// val unadjustedOrders: StateFlow<List<GoodsInfo>> = _orders
// .map { orders -> orders.filter { !it.isAdjusted } }
// .stateIn(viewModelScope, SharingStarted.Lazily, emptyList())
//
// // 选中的商品
// private val _selectedItem = MutableStateFlow<GoodsInfo?>(null)
// val selectedItem: StateFlow<GoodsInfo?> = _selectedItem
//
// // 收货请求结果
// private val _receiptResult = MutableStateFlow<Boolean>(false)
// val receiptResult: StateFlow<Boolean> = _receiptResult
//
// // 物品数量 是否由用户输入
// private val _countUserInput = MutableStateFlow<Boolean>(false)
// private val _priceUserInput = MutableStateFlow<Boolean>(false)
// private val _amountUserInput = MutableStateFlow<Boolean>(false)
// /**
// * 更新调整状态
// * @param isAdjustState true 已调整 false 未调整
// */
// fun updateAdjustState(isAdjustState: Boolean) {
// _adjustState.value = isAdjustState
// }
//
// fun StateFlow<List<GoodsInfo>>.getValidOrders(): List<GoodsInfo> {
// return this.value.filter { it.goodId != null }
// }
//
// /**
// * 更新收货提示弹窗
// */
// fun updateReceiptDialog(showDialog: Boolean) {
// if (_orders.getValidOrders().isEmpty()) {
// ToastUtils.showToast("订单为空或包含异常数据")
// return
// }
//// if (!unadjustedOrders.value.isEmpty()) {
//// ToastUtils.showToast("请先确认物品信息")
//// return
//// }
// _showReceiptDialog.value = showDialog
// }
// fun updateSelectedItemWithSwitch(purchaseOrder: GoodsInfo?) {
// viewModelScope.launch {
// updateSelectedItem(purchaseOrder)
// }
// }
override fun handleIdentityItem(goodsInfo: SearchGoodsInfo.Record) {
// val firstItem = unadjustedOrders.value.find { order ->
// order.goodId == goodsInfo.goodsId
// }
// updateLastPhotoUri(null)
// updateIdentityList(emptyList())
// _selectedItem.value = firstItem
//// updateSelectedItemWithSwitch(firstItem)
}
/**
* 更新选中的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 getReceiveDetail(id: String, action: (PurchaseInfo?) -> Unit = {}) {
launchWithLoading {
val response = repository.getReceiveDetail(id)
if (parseResponse(response)) {
action(response.result)
// _currentPurchaseInfo.value = response.result
// initOrders()
}
}
}
// /**
// * 更新当前供应商信息
// */
// fun updateCurrentPurchaseInfo(purchaseInfo: PurchaseInfo?) {
// _currentPurchaseInfo.value = purchaseInfo
// }
//
// // 添加订单
// fun addPurchaseItem(purchaseOrder: GoodsInfo) {
// _orders.update { currentList ->
// // 当已经添加过则忽略
// if (currentList.any { it.goodId == purchaseOrder.goodId }) {
// currentList
// } else {
// currentList + purchaseOrder
// }
// }
// }
//
// // 更新订单
// fun updatePurchaseItem(purchaseOrder: GoodsInfo) {
// _orders.update { currentList ->
// currentList.map { order ->
// if (order.id == purchaseOrder.id) purchaseOrder else order
// }
// }
// }
//
// /**
// * 有异常的订单数量
// */
// fun hasWrongCount(): Boolean {
// return _orders.value.any {
// it.receiveCount != it.receivedNum
// }
// }
/**
* 更新所有商品仓库
*/
// 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 clearPurchaseOrders() {
// _orders.value = emptyList()
// }
//
// /**
// * 更新数量输入状态
// */
// fun updateCountInputState(boolean: Boolean) {
// _countUserInput.value = boolean
// }
//
// /**
// * 更新单价输入状态
// */
// fun updatePriceInputState(boolean: Boolean) {
// _priceUserInput.value = boolean
// }
//
// /**
// * 更新金额输入状态
// */
// fun updateAmountInputState(boolean: Boolean) {
// _amountUserInput.value = boolean
// }
//private var weightCallback: ((Int) -> Unit)? = null
//fun readWeight(callback: (Int) -> Unit) {
// weightCallback = callback
//}
override fun handleSensorScale(weight: Double) {
// 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) {
// launchWithLoading {
// val response = repository.partialReceipt(uploadInfo)
// if (parseResponse(response)) {
// ToastUtils.showToast("部分收货成功")
// _receiptResult.value = true
// }
// }
// }
//
// fun confirmReceipt(uploadInfo: UploadInfo) {
// launchWithLoading {
// val response = repository.confirmReceipt(uploadInfo)
// if (parseResponse(response)) {
// ToastUtils.showToast("收货成功")
// _receiptResult.value = true
// }
// }
// }
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)
}
}
// fun uploadImage(imageUri: Uri, callback: (String?) -> Unit) {
// launchWithLoading {
// val resp = repository.uploadImage(imageUri)
// if (!parseResponse(resp)) {
// callback(null)
// return@launchWithLoading
// }
// callback(resp.data)
// }
// }
fun uploadImage(file: File, callback: (String?) -> Unit) {
launchWithLoading {
val resp = repository.uploadImage(file)
if (!parseResponse(resp)) {
callback(null)
return@launchWithLoading
}
callback(resp.data)
}
}
fun createNewGoods(imageUri: Uri? = null, param: GoodsAddParam, callback: (Boolean) -> Unit) {
launchWithLoading {
if (imageUri != null) {
val resp = repository.uploadImage(imageUri)
if (!parseResponse(resp)) {
callback(false)
return@launchWithLoading
}
param.relativeUrl = resp.data
}
Timber.tag("ReceiptViewModel").d("createNewGoods入参:${param.toJsonString()}")
val response = repository.selfPurchaseGoodsAdd(param)
if (!parseResponse(response)) {
callback(false)
return@launchWithLoading
}
callback(true)
}
}
// fun uploadMultipleImages(goodsId:String, goodsName:String, files:List<File?>, callback: (Boolean) -> Unit) {
// launchWithLoading {
// val map = mutableMapOf<String, String>()
// map["goodsId"] = goodsId
// map["goodsName"] = goodsName
// val fileList = files.filterNotNull()
// if (fileList.isEmpty()) {
// callback(false)
// return@launchWithLoading
// }
// val resp = repository.uploadMultipleImages(fileList = fileList, param = map)
// if (!parseResponse(resp)) {
// callback(false)
// return@launchWithLoading
// }
// callback(resp.code == "00000")
// }
// }
suspend fun uploadMultipleImages(
files: List<File?>,
params: HashMap<String, RequestBody>
): Boolean {
// val map = mutableMapOf<String, String>()
// map["goodsId"] = goodsId
// map["goodsName"] = goodsName
val fileList = files.filterNotNull()
if (fileList.isEmpty()) {
return true
}
val resp = repository.uploadMultipleImages(fileList = fileList, params = params)
// if (!parseResponse(resp)) {
// callback(false)
// return@launchWithLoading
// }
return resp.code == "00000"
}
}
@@ -0,0 +1,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("", "选择仓库"))
// 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
// }
//
// 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
// }
//
//// 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)
// }
// }
//}
@@ -0,0 +1,73 @@
package com.sw.inbound.viewmodel
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import com.sw.inbound.GlobalData
import com.sw.inbound.GlobalKey
import com.sw.inbound.model.request.LoginParam
import com.sw.inbound.model.response.User
import com.sw.inbound.repository.RemoteRepository
import com.sw.inbound.utils.GsonUtils
import com.sw.inbound.utils.SPUtil
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import timber.log.Timber
import javax.inject.Inject
@HiltViewModel
class UserViewModel @Inject constructor(
private val repo: RemoteRepository
) : BaseViewModel(repo) {
private var isFirstLaunch by mutableStateOf(true)
private val _user = MutableStateFlow<User?>(null)
val user = _user.asStateFlow()
fun getInitInfo() {
Timber.d("getInitInfo isFirstLaunch = $isFirstLaunch")
//if (isFirstLaunch) {
getUserInfo()
getDictType()
isFirstLaunch = false
//}
}
fun login(userName: String, password: String) = launchWithLoading {
val loginParam = LoginParam(userName = userName, password = password)
val response = repo.login(loginParam)
if (parseResponse(response)) {
SPUtil.getInstance().put(GlobalKey.KEY_USER_NAME, userName)
_user.value = response.result
saveToken(response.result)
response.result?.token
}
}
fun getUserInfo() {
val userInfo = SPUtil.getInstance().get(GlobalKey.KEY_USER_INFO, "")
if (userInfo != null) {
_user.value = GsonUtils.fromJson(userInfo, User::class.java)
}
}
private fun saveToken(user: User?) {
user?.let {
SPUtil.getInstance().put(GlobalKey.KEY_USER_INFO, GsonUtils.toJson(it))
SPUtil.getInstance().put(GlobalKey.KEY_TOKEN, it.token)
GlobalData.appToken = it.token?:""
}
}
fun logout() {
SPUtil.getInstance().remove(GlobalKey.KEY_USER_INFO)
SPUtil.getInstance().remove(GlobalKey.KEY_TOKEN)
}
override fun handleSensorScale(weight: Double) {
}
}