feat(inspection): 添加质检任务完整流程功能
- 在HeaderInterceptor中添加新的token请求头 - 新增InspectionValidateState枚举状态管理质检验证状态 - 实现InspectionActivity中的任务信息获取和显示逻辑 - 添加拍照路径管理和质检结果验证功能 - 新增InspectionCompleteActivity的任务提交状态管理 - 实现InspectionResultActivity的结果展示和重新验证流程 - 添加TaskListActivity中检验任务的跳转处理 - 新增InspectionResultVM、InspectionVM和InspectionCompleteVM视图模型 - 创建InspectionApiData数据类定义API响应结构 - 实现Service3接口支持玻璃任务查询和文档验证API - 添加质检任务完整的工作流程状态管理
这个提交包含在:
父节点
1dd3477810
当前提交
0398ad4600
@ -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)
|
||||
})
|
||||
@ -50,4 +83,4 @@ class InspectionCompleteActivity : BaseActivity<ActivityInspectionCompleteBindin
|
||||
OfflineCmdServiceHelper.removeListenerInspectionComplete()
|
||||
OfflineCmdServiceHelper.removeOnLineListener(listener)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
// 拍完照等待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<ItemItem>(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<ItemItem> = adapter
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户