diff --git a/app/src/main/java/com/nova/brain/glass/model/data/InspectionApiData.kt b/app/src/main/java/com/nova/brain/glass/model/data/InspectionApiData.kt new file mode 100644 index 0000000..a27d3ae --- /dev/null +++ b/app/src/main/java/com/nova/brain/glass/model/data/InspectionApiData.kt @@ -0,0 +1,46 @@ +package com.nova.brain.glass.model.data + +data class GlassTaskItem( + val id: Int = 0, + val taskNo: String = "", + val supplierName: String = "", + val createdAt: String = "", + val status: String = "", + val resultSummary: String = "", + val isDeleted: Int = 0 +) + +data class QueryGlassTaskResponse( + val code: Int, + val message: String, + val success: Boolean = false, + val data: List? = null +) + +data class ValidateResultItem( + val label: String = "", + val partNo: String = "", + val serialNo: String = "", + val qualified: Boolean = true, + val supplierName: String = "", + val reason: String = "" +) + +data class ValidateTaskDocumentResponse( + val code: Int, + val message: String, + val success: Boolean = false, + val data: List? = null +) + +data class CheckQualifiedData( + val qualified: Boolean = true, + val reason: String = "" +) + +data class CheckTaskQualifiedResponse( + val code: Int, + val message: String, + val success: Boolean = false, + val data: CheckQualifiedData? = null +) diff --git a/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt b/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt index ff60e6e..f2651bc 100644 --- a/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt +++ b/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt @@ -24,6 +24,7 @@ class HeaderInterceptor(val context: Context) : Interceptor { //请求定制:添加请求头 val requestBuilder = original.newBuilder() .header("Authorization", "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJyb2tpZCIsInJuU3RyIjoiQTU3NlV1VVV3V2s5NEpxSjlQcU9keDE1bE1tdU5JYmMiLCJ1c2VySW5mbyI6eyJzdGFmZk5vIjoicm9raWQifX0.qp1zWjYjqtmFS7Udo7Ga-a_XhVNwRUByXYomu6P6yxg") + .addHeader("token", "3760384-DWuKlfwAYwWBsKAprAXF2lEAdKcyz1") .addHeader("Content-Type", "application/json;charset=UTF-8") .addHeader("Cookie", "__itrace_wid=87125211-8742-4f12-b5ca-32b9b6c860e4; locale=zh-Hans; _webtracing_device_id=t_13501877-b9b303fc-d3f52eb530e026b0") .addHeader("Environment", "1") diff --git a/app/src/main/java/com/nova/brain/glass/repository/Service3.kt b/app/src/main/java/com/nova/brain/glass/repository/Service3.kt new file mode 100644 index 0000000..1814359 --- /dev/null +++ b/app/src/main/java/com/nova/brain/glass/repository/Service3.kt @@ -0,0 +1,32 @@ +package com.nova.brain.glass.repository + +import com.nova.brain.glass.model.data.CheckTaskQualifiedResponse +import com.nova.brain.glass.model.data.QueryGlassTaskResponse +import com.nova.brain.glass.model.data.ValidateTaskDocumentResponse +import io.reactivex.Observable +import okhttp3.MultipartBody +import okhttp3.RequestBody +import retrofit2.http.GET +import retrofit2.http.Multipart +import retrofit2.http.Part +import retrofit2.http.POST +import retrofit2.http.Query + +interface Service3 { + + @GET("/api/admin/bom/ocr/glass/queryGlassTask") + fun queryGlassTask(@Query("id") id: String): Observable + + @Multipart + @POST("/api/admin/bom/ocr/glass/validateTaskDocument") + fun validateTaskDocument( + @Part("taskNo") taskNo: RequestBody, + @Part file: MultipartBody.Part + ): Observable + + @Multipart + @POST("/api/admin/bom/ocr/glass/checkTaskQualified") + fun checkTaskQualified( + @Part("taskNo") taskNo: RequestBody + ): Observable +} diff --git a/app/src/main/java/com/nova/brain/glass/ui/InspectionActivity.kt b/app/src/main/java/com/nova/brain/glass/ui/InspectionActivity.kt index 6750cb2..43c6399 100644 --- a/app/src/main/java/com/nova/brain/glass/ui/InspectionActivity.kt +++ b/app/src/main/java/com/nova/brain/glass/ui/InspectionActivity.kt @@ -11,6 +11,7 @@ import com.nova.brain.glass.helper.OfflineCmdListener import com.nova.brain.glass.helper.OfflineCmdServiceHelper import com.nova.brain.glass.helper.SprayingPhotoManager import com.nova.brain.glass.model.ItemItem +import com.nova.brain.glass.viewmodel.InspectionValidateState import com.nova.brain.glass.viewmodel.InspectionVM import com.rokid.security.glass3.sdk.base.data.media.PhotoResolution import com.rokid.security.system.server.media.callback.PhotoFileCallback @@ -30,6 +31,9 @@ class InspectionActivity : override fun fullscreen(): Boolean = true override fun getRecyclerOrientation(): Int = RecyclerView.VERTICAL + private val glassTaskId: String by lazy { intent.getStringExtra("glassTaskId").orEmpty() } + private var pendingPhotoPath: String? = null + private val listener = object : OfflineCmdListener { override fun onOfflineCmd(cmd: String) { runOnUiThread { @@ -45,9 +49,52 @@ class InspectionActivity : super.initData() window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) SprayingPhotoManager.clear() + + viewModel.taskInfo.observe(this) { item -> + if (item != null) { + binding.content1.text = "任务编号:${item.taskNo}" + binding.content2.text = "制造供应商:${item.supplierName}" + binding.content3.text = "任务创建时间:${item.createdAt}" + binding.hint.text = "单击或语音输入\"开始\",进入下一步" + } + } + viewModel.taskInfoError.observe(this) { msg -> + binding.hint.text = msg + msg.showMessage() + } + viewModel.validateState.observe(this) { state -> + when (state) { + InspectionValidateState.LOADING -> binding.hint.text = "识别中,请稍后..." + InspectionValidateState.SUCCESS -> { + val result = viewModel.validateResult.value + val path = pendingPhotoPath ?: return@observe + startActivity(Intent(this, InspectionResultActivity::class.java).apply { + putExtra(InspectionResultActivity.EXTRA_PHOTO_PATH, path) + putExtra(InspectionResultActivity.EXTRA_TASK_NO, viewModel.taskNo) + putExtra(InspectionResultActivity.EXTRA_LABEL, result?.label.orEmpty()) + putExtra(InspectionResultActivity.EXTRA_PART_NO, result?.partNo.orEmpty()) + putExtra(InspectionResultActivity.EXTRA_SERIAL_NO, result?.serialNo.orEmpty()) + putExtra(InspectionResultActivity.EXTRA_QUALIFIED, result?.qualified ?: true) + putExtra(InspectionResultActivity.EXTRA_SUPPLIER_NAME, result?.supplierName.orEmpty()) + putExtra(InspectionResultActivity.EXTRA_REASON, result?.reason.orEmpty()) + }) + binding.hint.text = "单击或语音输入\"开始\",进入下一步" + } + InspectionValidateState.FAILED -> { + binding.hint.text = "识别失败,请重试" + } + else -> {} + } + } + + if (glassTaskId.isNotBlank()) { + binding.hint.text = "加载任务信息中..." + viewModel.fetchGlassTask(glassTaskId) + } } private fun startCapture() { + if (viewModel.validateState.value == InspectionValidateState.LOADING) return binding.hint.text = "拍照中,请稍后..." SprayingPhotoManager.clear() takePhoto() @@ -74,16 +121,15 @@ class InspectionActivity : override fun onTakePhotoV2(path: String?, width: Int, height: Int) { if (path == null) { runOnUiThread { - binding.hint.text = "单击或语音输入“开始”,进入下一步\n滑动切换上/下一个任务" + binding.hint.text = "单击或语音输入\"开始\",进入下一步" } "相机异常".showMessage() return } SprayingPhotoManager.addPhoto(path) + pendingPhotoPath = path runOnUiThread { - startActivity(Intent(this@InspectionActivity, InspectionResultActivity::class.java).apply { - putExtra(InspectionResultActivity.EXTRA_PHOTO_PATH, path) - }) + viewModel.validateDocument(path) } } } diff --git a/app/src/main/java/com/nova/brain/glass/ui/InspectionCompleteActivity.kt b/app/src/main/java/com/nova/brain/glass/ui/InspectionCompleteActivity.kt index 21ba72e..de3a410 100644 --- a/app/src/main/java/com/nova/brain/glass/ui/InspectionCompleteActivity.kt +++ b/app/src/main/java/com/nova/brain/glass/ui/InspectionCompleteActivity.kt @@ -1,10 +1,14 @@ package com.nova.brain.glass.ui import android.content.Intent +import androidx.lifecycle.ViewModelProvider import com.nova.brain.glass.R import com.nova.brain.glass.databinding.ActivityInspectionCompleteBinding import com.nova.brain.glass.helper.OfflineCmdListener import com.nova.brain.glass.helper.OfflineCmdServiceHelper +import com.nova.brain.glass.viewmodel.InspectionCompleteVM +import com.nova.brain.glass.viewmodel.SubmitTaskState +import com.xuqm.base.extensions.showMessage import com.xuqm.base.ui.BaseActivity class InspectionCompleteActivity : BaseActivity() { @@ -13,13 +17,19 @@ class InspectionCompleteActivity : BaseActivity finishTask() + "退出", "返回", "退回", "完成任务" -> triggerFinish() } } } @@ -29,10 +39,33 @@ class InspectionCompleteActivity : BaseActivity + when (state) { + SubmitTaskState.LOADING -> binding.hint.text = "提交中..." + SubmitTaskState.SUCCESS -> goTaskList() + SubmitTaskState.FAILED -> { + val msg = viewModel.errorMsg.value ?: "提交失败" + binding.hint.text = msg + msg.showMessage() + binding.btnFinish.isClickable = true + } + else -> {} + } + } } - private fun finishTask() { + private fun triggerFinish() { + if (taskNo.isBlank()) { + goTaskList() + return + } + binding.btnFinish.isClickable = false + viewModel.submitTask(taskNo) + } + + private fun goTaskList() { startActivity(Intent(this, TaskListActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) }) @@ -50,4 +83,4 @@ class InspectionCompleteActivity : BaseActivity() { @@ -37,25 +36,32 @@ class InspectionResultActivity : override fun fullscreen(): Boolean = true override fun getRecyclerOrientation(): Int = RecyclerView.HORIZONTAL - private val imageDecodeExecutor = Executors.newSingleThreadExecutor() - private var status = true // true=合格, false=不合格 - private var resultCountdown: CountDownTimer? = null - companion object { const val EXTRA_PHOTO_PATH = "extra_photo_path" + const val EXTRA_TASK_NO = "extra_task_no" + const val EXTRA_LABEL = "extra_label" + const val EXTRA_PART_NO = "extra_part_no" + const val EXTRA_SERIAL_NO = "extra_serial_no" + const val EXTRA_QUALIFIED = "extra_qualified" + const val EXTRA_SUPPLIER_NAME = "extra_supplier_name" + const val EXTRA_REASON = "extra_reason" } + private val imageDecodeExecutor = Executors.newSingleThreadExecutor() + private val taskNo: String by lazy { intent.getStringExtra(EXTRA_TASK_NO).orEmpty() } + private var currentPhotoPath: String = "" + private val missingLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode != Activity.RESULT_OK) return@registerForActivityResult when (result.data?.getStringExtra(InspectionMissingActivity.EXTRA_ACTION)) { InspectionMissingActivity.ACTION_SUPPLEMENT -> { - // 补充单证:重新拍照 binding.tvTaskHeader.text = "拍照中,请稍后..." takePhoto() } InspectionMissingActivity.ACTION_SUBMIT -> { - goComplete() + binding.hint.text = "提交中..." + viewModel.submitTask(taskNo) } } } @@ -65,7 +71,7 @@ class InspectionResultActivity : runOnUiThread { when (cmd) { "退出", "返回", "退回" -> finish() - "重拍照","重新拍摄","重新拍照" -> retake() + "重拍照", "重新拍摄", "重新拍照" -> retake() "继续任务" -> continueTask() "结束任务" -> endTask() } @@ -76,30 +82,63 @@ class InspectionResultActivity : override fun initData() { super.initData() window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - val path = intent.getStringExtra(EXTRA_PHOTO_PATH) - if (path != null) { - showPhoto(path) - } - // 拍完照等待5秒后显示结果 - startResultCountdown() - } - /** 等待 5 秒后随机显示合格/不合格结果 */ - private fun startResultCountdown(seconds: Long = 5) { - binding.tvTaskHeader.text = "识别中,请稍后..." - resultCountdown?.cancel() - resultCountdown = object : CountDownTimer(seconds * 1000, 1000) { - override fun onTick(millisUntilFinished: Long) {} - override fun onFinish() { - status = Random.nextBoolean() - runOnUiThread { updateResultDisplay() } + val path = intent.getStringExtra(EXTRA_PHOTO_PATH).orEmpty() + currentPhotoPath = path + if (path.isNotBlank()) showPhoto(path) + + displayResult( + label = intent.getStringExtra(EXTRA_LABEL).orEmpty(), + partNo = intent.getStringExtra(EXTRA_PART_NO).orEmpty(), + serialNo = intent.getStringExtra(EXTRA_SERIAL_NO).orEmpty(), + qualified = intent.getBooleanExtra(EXTRA_QUALIFIED, true), + supplierName = intent.getStringExtra(EXTRA_SUPPLIER_NAME).orEmpty() + ) + + viewModel.action.observe(this) { action -> + when (action) { + InspectionResultAction.RETAKE -> { + val result = viewModel.validateResult.value + displayResult( + label = result?.label.orEmpty(), + partNo = result?.partNo.orEmpty(), + serialNo = result?.serialNo.orEmpty(), + qualified = result?.qualified ?: true, + supplierName = result?.supplierName.orEmpty() + ) + } + InspectionResultAction.CHECK_QUALIFIED_MISSING -> { + missingLauncher.launch(Intent(this, InspectionMissingActivity::class.java)) + } + InspectionResultAction.CHECK_QUALIFIED_COMPLETE -> { + goComplete() + } + InspectionResultAction.SUBMIT_SUCCESS -> { + goComplete() + } + InspectionResultAction.FAILED -> { + val msg = viewModel.errorMsg.value ?: "操作失败" + binding.hint.text = msg + msg.showMessage() + } + else -> {} } - }.start() + } } - private fun updateResultDisplay() { - binding.tvTaskHeader.text = if (status) "检验结果:合格!" else "检验结果:不合格!" - binding.status.setImageResource(if (status) R.mipmap.ocr_true else R.mipmap.ocr_false) + private fun displayResult( + label: String, + partNo: String, + serialNo: String, + qualified: Boolean, + supplierName: String + ) { + binding.tvTaskHeader.text = if (qualified) "检验结果:合格!" else "检验结果:不合格!" + binding.status.setImageResource(if (qualified) R.mipmap.ocr_true else R.mipmap.ocr_false) + binding.value1.text = "单证类型:$label" + binding.value2.text = "件号:$partNo" + binding.value3.text = "序列号:$serialNo" + binding.value4.text = "供应商:$supplierName" } private fun retake() { @@ -113,12 +152,8 @@ class InspectionResultActivity : } private fun endTask() { - // 随机进入单证缺失或单证齐全 - if (Random.nextBoolean()) { - missingLauncher.launch(Intent(this, InspectionMissingActivity::class.java)) - } else { - goComplete() - } + binding.hint.text = "质检中..." + viewModel.checkQualified(taskNo) } private fun goComplete() { @@ -126,12 +161,11 @@ class InspectionResultActivity : SprayingPhotoManager.clear() startActivity(Intent(this, InspectionCompleteActivity::class.java).apply { putExtra(InspectionCompleteActivity.EXTRA_PHOTO_COUNT, photoCount) + putExtra(InspectionCompleteActivity.EXTRA_TASK_NO, taskNo) }) finish() } - // ---- 拍照 ---- - private fun takePhoto() { val fileName = "inspection_${System.currentTimeMillis()}.png" val file = File( @@ -159,10 +193,11 @@ class InspectionResultActivity : return } SprayingPhotoManager.addPhoto(path) + currentPhotoPath = path runOnUiThread { showPhoto(path) - // 重拍/继续任务:等待3秒后刷新结果 - startResultCountdown(3) + binding.tvTaskHeader.text = "识别中,请稍后..." + viewModel.revalidateDocument(taskNo, path) } } } @@ -182,8 +217,6 @@ class InspectionResultActivity : } } - // ---- 生命周期 ---- - override fun onResume() { super.onResume() OfflineCmdServiceHelper.addListenerInspectionResult() @@ -193,7 +226,6 @@ class InspectionResultActivity : override fun onPause() { super.onPause() - resultCountdown?.cancel() OfflineCmdServiceHelper.removeListenerInspectionResult() OfflineCmdServiceHelper.removeOnLineListener(listener) GlassMediaServiceHelper.removePhotoCallback(mPhotoFileCallback) @@ -205,8 +237,6 @@ class InspectionResultActivity : window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) } - // ---- Adapter ---- - private val adapter = object : CommonPagedAdapter(R.layout.item_manual_result_action) { override fun convert(holder: ViewHolder, item: ItemItem, position: Int) { holder.setText(R.id.text, item.text) @@ -221,4 +251,4 @@ class InspectionResultActivity : } override fun adapter(): BasePagedAdapter = adapter -} \ No newline at end of file +} diff --git a/app/src/main/java/com/nova/brain/glass/ui/TaskListActivity.kt b/app/src/main/java/com/nova/brain/glass/ui/TaskListActivity.kt index 46496b6..e4671d0 100644 --- a/app/src/main/java/com/nova/brain/glass/ui/TaskListActivity.kt +++ b/app/src/main/java/com/nova/brain/glass/ui/TaskListActivity.kt @@ -155,6 +155,12 @@ class TaskListActivity : .putExtra("aiDescription", item.displayDesc()) .putExtra("taskType", item.taskType) ) + "检验任务", "产业大脑检验任务" -> startActivity( + Intent(this, InspectionActivity::class.java) + .putExtra("glassTaskId", item.params.firstNotBlank("taskId", "task_id", "id")) + .putExtra("taskName", item.params?.get("taskName").orEmpty()) + .putExtra("taskNumber", item.params?.get("taskNumber").orEmpty()) + ) else -> Log.d("TaskListActivity", "unknown taskType: ${item.taskType}") } } diff --git a/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionCompleteVM.kt b/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionCompleteVM.kt new file mode 100644 index 0000000..cb3fd24 --- /dev/null +++ b/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionCompleteVM.kt @@ -0,0 +1,44 @@ +package com.nova.brain.glass.viewmodel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.nova.brain.glass.MyApplication +import com.nova.brain.glass.repository.Service3 +import com.xuqm.base.di.manager.HttpManager +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.schedulers.Schedulers +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.RequestBody.Companion.toRequestBody + +class InspectionCompleteVM : ViewModel() { + val submitState = MutableLiveData(SubmitTaskState.IDLE) + val errorMsg = MutableLiveData() + private val disposables = CompositeDisposable() + + fun submitTask(taskNo: String) { + submitState.value = SubmitTaskState.LOADING + val taskNoBody = taskNo.toRequestBody("text/plain".toMediaTypeOrNull()) + val disposable = HttpManager.getApi(MyApplication.appComponent3, Service3::class.java) + .checkTaskQualified(taskNoBody) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ response -> + if (response.success) { + submitState.value = SubmitTaskState.SUCCESS + } else { + submitState.value = SubmitTaskState.FAILED + errorMsg.value = response.message.ifBlank { "提交失败" } + } + }, { e -> + submitState.value = SubmitTaskState.FAILED + errorMsg.value = e.message ?: "提交失败" + }) + disposables.add(disposable) + } + + override fun onCleared() { + disposables.clear() + super.onCleared() + } +} diff --git a/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionResultVM.kt b/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionResultVM.kt index b11c915..6163709 100644 --- a/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionResultVM.kt +++ b/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionResultVM.kt @@ -1,10 +1,29 @@ package com.nova.brain.glass.viewmodel +import androidx.lifecycle.MutableLiveData +import com.nova.brain.glass.MyApplication import com.nova.brain.glass.model.ItemItem +import com.nova.brain.glass.model.data.ValidateResultItem +import com.nova.brain.glass.repository.Service3 +import com.xuqm.base.di.manager.HttpManager import com.xuqm.base.viewmodel.BaseListViewModel import com.xuqm.base.viewmodel.callback.Response +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import java.io.File + +enum class InspectionResultAction { IDLE, RETAKE, CHECK_QUALIFIED_MISSING, CHECK_QUALIFIED_COMPLETE, SUBMIT_SUCCESS, FAILED } class InspectionResultVM : BaseListViewModel() { + + val action = MutableLiveData(InspectionResultAction.IDLE) + val validateResult = MutableLiveData() + val errorMsg = MutableLiveData() + override fun loadData(page: Int, onResponse: Response) { onResponse.onResponse(arrayListOf().apply { add(ItemItem("重拍照")) @@ -12,4 +31,78 @@ class InspectionResultVM : BaseListViewModel() { add(ItemItem("继续任务")) }) } -} \ No newline at end of file + + fun revalidateDocument(taskNo: String, photoPath: String) { + val file = File(photoPath) + if (!file.exists()) { + action.value = InspectionResultAction.FAILED + errorMsg.value = "图片文件不存在" + return + } + val taskNoBody = taskNo.toRequestBody("text/plain".toMediaTypeOrNull()) + val requestFile = file.asRequestBody("application/octet-stream".toMediaTypeOrNull()) + val filePart = MultipartBody.Part.createFormData("file", file.name, requestFile) + val disposable = HttpManager.getApi(MyApplication.appComponent3, Service3::class.java) + .validateTaskDocument(taskNoBody, filePart) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ response -> + if (response.success && !response.data.isNullOrEmpty()) { + validateResult.value = response.data[0] + action.value = InspectionResultAction.RETAKE + } else { + action.value = InspectionResultAction.FAILED + errorMsg.value = response.message.ifBlank { "单证识别失败" } + } + }, { e -> + action.value = InspectionResultAction.FAILED + errorMsg.value = e.message ?: "单证识别失败" + }) + add(disposable) + } + + fun checkQualified(taskNo: String) { + val taskNoBody = taskNo.toRequestBody("text/plain".toMediaTypeOrNull()) + val disposable = HttpManager.getApi(MyApplication.appComponent3, Service3::class.java) + .checkTaskQualified(taskNoBody) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ response -> + if (response.success) { + val qualified = response.data?.qualified ?: false + action.value = if (qualified) { + InspectionResultAction.CHECK_QUALIFIED_COMPLETE + } else { + InspectionResultAction.CHECK_QUALIFIED_MISSING + } + } else { + action.value = InspectionResultAction.FAILED + errorMsg.value = response.message.ifBlank { "质检失败" } + } + }, { e -> + action.value = InspectionResultAction.FAILED + errorMsg.value = e.message ?: "质检失败" + }) + add(disposable) + } + + fun submitTask(taskNo: String) { + val taskNoBody = taskNo.toRequestBody("text/plain".toMediaTypeOrNull()) + val disposable = HttpManager.getApi(MyApplication.appComponent3, Service3::class.java) + .checkTaskQualified(taskNoBody) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ response -> + if (response.success) { + action.value = InspectionResultAction.SUBMIT_SUCCESS + } else { + action.value = InspectionResultAction.FAILED + errorMsg.value = response.message.ifBlank { "提交失败" } + } + }, { e -> + action.value = InspectionResultAction.FAILED + errorMsg.value = e.message ?: "提交失败" + }) + add(disposable) + } +} diff --git a/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionVM.kt b/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionVM.kt index e549ed8..3df68b7 100644 --- a/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionVM.kt +++ b/app/src/main/java/com/nova/brain/glass/viewmodel/InspectionVM.kt @@ -1,16 +1,83 @@ package com.nova.brain.glass.viewmodel +import androidx.lifecycle.MutableLiveData +import com.nova.brain.glass.MyApplication import com.nova.brain.glass.model.ItemItem +import com.nova.brain.glass.model.data.GlassTaskItem +import com.nova.brain.glass.model.data.ValidateResultItem +import com.nova.brain.glass.repository.Service3 +import com.xuqm.base.di.manager.HttpManager import com.xuqm.base.viewmodel.BaseListViewModel import com.xuqm.base.viewmodel.callback.Response +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.RequestBody.Companion.asRequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import java.io.File + +enum class InspectionValidateState { IDLE, LOADING, SUCCESS, FAILED } class InspectionVM : BaseListViewModel() { - override fun loadData( - page: Int, - onResponse: Response - ) { + + val taskInfo = MutableLiveData() + val taskInfoError = MutableLiveData() + val validateState = MutableLiveData(InspectionValidateState.IDLE) + val validateResult = MutableLiveData() + var taskNo: String = "" + + override fun loadData(page: Int, onResponse: Response) { onResponse.onResponse(arrayListOf().apply { add(ItemItem("开始任务")) }) } -} \ No newline at end of file + + fun fetchGlassTask(id: String) { + val disposable = HttpManager.getApi(MyApplication.appComponent3, Service3::class.java) + .queryGlassTask(id) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ response -> + if (response.success && !response.data.isNullOrEmpty()) { + val item = response.data[0] + taskNo = item.taskNo + taskInfo.value = item + } else { + taskInfoError.value = response.message.ifBlank { "获取任务信息失败" } + } + }, { e -> + taskInfoError.value = e.message ?: "获取任务信息失败" + }) + add(disposable) + } + + fun validateDocument(photoPath: String) { + val file = File(photoPath) + if (!file.exists()) { + validateState.value = InspectionValidateState.FAILED + return + } + validateState.value = InspectionValidateState.LOADING + val taskNoBody = taskNo.toRequestBody("text/plain".toMediaTypeOrNull()) + val requestFile = file.asRequestBody("application/octet-stream".toMediaTypeOrNull()) + val filePart = MultipartBody.Part.createFormData("file", file.name, requestFile) + val disposable = HttpManager.getApi(MyApplication.appComponent3, Service3::class.java) + .validateTaskDocument(taskNoBody, filePart) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ response -> + if (response.success && !response.data.isNullOrEmpty()) { + validateState.value = InspectionValidateState.SUCCESS + validateResult.value = response.data[0] + } else { + validateState.value = InspectionValidateState.FAILED + taskInfoError.value = response.message.ifBlank { "单证识别失败" } + } + }, { e -> + validateState.value = InspectionValidateState.FAILED + taskInfoError.value = e.message ?: "单证识别失败" + }) + add(disposable) + } +}