feat(inspection): 添加质检任务完整流程功能

- 在HeaderInterceptor中添加新的token请求头
- 新增InspectionValidateState枚举状态管理质检验证状态
- 实现InspectionActivity中的任务信息获取和显示逻辑
- 添加拍照路径管理和质检结果验证功能
- 新增InspectionCompleteActivity的任务提交状态管理
- 实现InspectionResultActivity的结果展示和重新验证流程
- 添加TaskListActivity中检验任务的跳转处理
- 新增InspectionResultVM、InspectionVM和InspectionCompleteVM视图模型
- 创建InspectionApiData数据类定义API响应结构
- 实现Service3接口支持玻璃任务查询和文档验证API
- 添加质检任务完整的工作流程状态管理
这个提交包含在:
徐勤民 2026-04-21 16:11:12 +08:00
父节点 1dd3477810
当前提交 0398ad4600
共有 10 个文件被更改,包括 457 次插入59 次删除

查看文件

@ -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<GlassTaskItem>? = 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<ValidateResultItem>? = 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
)

查看文件

@ -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")

查看文件

@ -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<QueryGlassTaskResponse>
@Multipart
@POST("/api/admin/bom/ocr/glass/validateTaskDocument")
fun validateTaskDocument(
@Part("taskNo") taskNo: RequestBody,
@Part file: MultipartBody.Part
): Observable<ValidateTaskDocumentResponse>
@Multipart
@POST("/api/admin/bom/ocr/glass/checkTaskQualified")
fun checkTaskQualified(
@Part("taskNo") taskNo: RequestBody
): Observable<CheckTaskQualifiedResponse>
}

查看文件

@ -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)
}
}
}

查看文件

@ -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<ActivityInspectionCompleteBinding>() {
@ -13,13 +17,19 @@ class InspectionCompleteActivity : BaseActivity<ActivityInspectionCompleteBindin
companion object {
const val EXTRA_PHOTO_COUNT = "extra_photo_count"
const val EXTRA_TASK_NO = "extra_task_no"
}
private val viewModel: InspectionCompleteVM by lazy {
ViewModelProvider(this)[InspectionCompleteVM::class.java]
}
private val taskNo: String by lazy { intent.getStringExtra(EXTRA_TASK_NO).orEmpty() }
private val listener = object : OfflineCmdListener {
override fun onOfflineCmd(cmd: String) {
runOnUiThread {
when (cmd) {
"退出", "返回", "退回", "完成任务" -> finishTask()
"退出", "返回", "退回", "完成任务" -> triggerFinish()
}
}
}
@ -29,10 +39,33 @@ class InspectionCompleteActivity : BaseActivity<ActivityInspectionCompleteBindin
super.initData()
val count = intent.getIntExtra(EXTRA_PHOTO_COUNT, 0)
binding.subtitle.text = "本次成功提交并归档${count}张单证!"
binding.btnFinish.setOnClickListener { finishTask() }
binding.btnFinish.setOnClickListener { triggerFinish() }
viewModel.submitState.observe(this) { state ->
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)
})

查看文件

@ -2,7 +2,6 @@ package com.nova.brain.glass.ui
import android.app.Activity
import android.content.Intent
import android.os.CountDownTimer
import android.os.Environment
import android.view.WindowManager
import androidx.activity.result.contract.ActivityResultContracts
@ -16,6 +15,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.InspectionResultAction
import com.nova.brain.glass.viewmodel.InspectionResultVM
import com.rokid.security.glass3.sdk.base.data.media.PhotoResolution
import com.rokid.security.system.server.media.callback.PhotoFileCallback
@ -28,7 +28,6 @@ import com.xuqm.base.ui.BaseListFormLayoutNormalActivity
import java.io.File
import java.util.UUID
import java.util.concurrent.Executors
import kotlin.random.Random
class InspectionResultActivity :
BaseListFormLayoutNormalActivity<ItemItem, InspectionResultVM, ActivityInspectionResultBinding>() {
@ -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)
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 -> {}
}
}
// 拍完照等待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() }
}
}.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<ItemItem>(R.layout.item_manual_result_action) {
override fun convert(holder: ViewHolder, item: ItemItem, position: Int) {
holder.setText(R.id.text, item.text)

查看文件

@ -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}")
}
}

查看文件

@ -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<String>()
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()
}
}

查看文件

@ -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<ItemItem>() {
val action = MutableLiveData(InspectionResultAction.IDLE)
val validateResult = MutableLiveData<ValidateResultItem?>()
val errorMsg = MutableLiveData<String>()
override fun loadData(page: Int, onResponse: Response<ItemItem>) {
onResponse.onResponse(arrayListOf<ItemItem>().apply {
add(ItemItem("重拍照"))
@ -12,4 +31,78 @@ class InspectionResultVM : BaseListViewModel<ItemItem>() {
add(ItemItem("继续任务"))
})
}
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)
}
}

查看文件

@ -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<ItemItem>() {
override fun loadData(
page: Int,
onResponse: Response<ItemItem>
) {
val taskInfo = MutableLiveData<GlassTaskItem?>()
val taskInfoError = MutableLiveData<String>()
val validateState = MutableLiveData(InspectionValidateState.IDLE)
val validateResult = MutableLiveData<ValidateResultItem?>()
var taskNo: String = ""
override fun loadData(page: Int, onResponse: Response<ItemItem>) {
onResponse.onResponse(arrayListOf<ItemItem>().apply {
add(ItemItem("开始任务"))
})
}
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)
}
}