refactor(servicing): 更新ServicingModule

This commit is contained in:
songzhiling
2025-06-17 11:49:32 +08:00
parent 405f732502
commit ea83fc62a9
75 changed files with 3696 additions and 2558 deletions

View File

@ -4,7 +4,7 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-04-27T03:49:03.966203100Z"> <DropdownSelection timestamp="2025-05-09T04:23:51.991280900Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=4f3d584c" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=4f3d584c" />

View File

@ -80,52 +80,64 @@
<activity <activity
android:name="com.za.base.NetworkRouteSelectionActivity" android:name="com.za.base.NetworkRouteSelectionActivity"
android:exported="true" android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.camera.ServicePeopleRealActivity" android:name="com.za.ui.camera.ServicePeopleRealActivity"
android:exported="true" android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.inservice_people_confirm.ServicePeopleConfirmActivity" android:name="com.za.ui.servicing.inservice_people_confirm.ServicePeopleConfirmActivity"
android:exported="true" android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.main.ServiceLauncherActivity" android:name="com.za.ui.main.ServiceLauncherActivity"
android:exported="true" android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.main.ServicingMainActivity" android:name="com.za.ui.main.ServicingMainActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.departure_photo.DeparturePhotoActivity" android:name="com.za.ui.servicing.departure_photo.DeparturePhotoActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.order_confirm.input_money.InputMoneyActivity" android:name="com.za.ui.servicing.order_confirm.input_money.InputMoneyActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.order_confirm.modify_money.ModifyMoneyActivity" android:name="com.za.ui.servicing.order_confirm.modify_money.ModifyMoneyActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.new_order.NewOrderActivity" android:name="com.za.ui.new_order.NewOrderActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.order_confirm.real_order_confirm.RealOrderConfirmActivity" android:name="com.za.ui.servicing.order_confirm.real_order_confirm.RealOrderConfirmActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.order_confirm.receive_money.ReceiveMoneyActivity" android:name="com.za.ui.servicing.order_confirm.receive_money.ReceiveMoneyActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.map_search.MapSearchActivity" android:name="com.za.ui.map_search.MapSearchActivity"
android:exported="false" /> android:exported="false"
android:screenOrientation="portrait" />
<service <service
android:name="com.za.ui.order_report.ReportFloatingManager" android:name="com.za.ui.order_report.ReportFloatingManager"
@ -147,26 +159,32 @@
android:name="com.za.ui.h5.CommonH5Activity" android:name="com.za.ui.h5.CommonH5Activity"
android:exported="false" android:exported="false"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.order_give_up.OrderGiveUpActivity" android:name="com.za.ui.servicing.order_give_up.OrderGiveUpActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.in_servicing_setting.OrderRequirementsActivity" android:name="com.za.ui.servicing.in_servicing_setting.OrderRequirementsActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.order_confirm.OrderConfirmActivity" android:name="com.za.ui.servicing.order_confirm.OrderConfirmActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.destination_photo.DestinationPhotoActivity" android:name="com.za.ui.servicing.destination_photo.DestinationPhotoActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.go_to_destination.GoToDestinationActivity" android:name="com.za.ui.servicing.go_to_destination.GoToDestinationActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.signature.GridPaintActivity" android:name="com.za.signature.GridPaintActivity"
@ -176,6 +194,7 @@
android:name="com.za.ui.servicing.operation.InOperationActivity" android:name="com.za.ui.servicing.operation.InOperationActivity"
android:exported="false" android:exported="false"
android:label="@string/title_activity_in_operation" android:label="@string/title_activity_in_operation"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.camera.ZdCameraXActivity" android:name="com.za.ui.camera.ZdCameraXActivity"
@ -189,21 +208,24 @@
<activity <activity
android:name="com.za.ui.servicing.check_vehicle.CheckVehicleActivity" android:name="com.za.ui.servicing.check_vehicle.CheckVehicleActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.verify.VerifyOrderActivity" android:name="com.za.ui.servicing.verify.VerifyOrderActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.go_accident.GoAccidentSiteActivity" android:name="com.za.ui.servicing.go_accident.GoAccidentSiteActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.wait_to_start.WaitToStartActivity" android:name="com.za.ui.servicing.wait_to_start.WaitToStartActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<receiver <receiver
android:name="com.za.service.ZdPushServiceReceive" android:name="com.za.service.ZdPushServiceReceive"
android:exported="false"> android:exported="false">

View File

@ -24,12 +24,14 @@ object AppConfig {
when (envType) { when (envType) {
Const.NetEnv.Main -> release() Const.NetEnv.Main -> release()
Const.NetEnv.Review -> review() Const.NetEnv.Review -> review()
else -> release()
} }
} else { } else {
when (envType) { when (envType) {
Const.NetEnv.CRM1 -> crm1() Const.NetEnv.CRM1 -> crm1()
Const.NetEnv.CRM2 -> crm2() Const.NetEnv.CRM2 -> crm2()
Const.NetEnv.UAT -> uat() Const.NetEnv.UAT -> uat()
else -> crm1()
} }
} }
} }

View File

@ -5,9 +5,10 @@ import android.os.Bundle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import com.tencent.smtt.sdk.QbSdk import com.tencent.smtt.sdk.QbSdk
import com.za.base.BaseVm.Companion.showTipDialog
import com.za.base.theme.DealerTheme import com.za.base.theme.DealerTheme
import com.za.base.view.CommonDialog import com.za.base.view.CommonDialog
import com.za.base.view.LoadingManager import com.za.base.view.LoadingManager
@ -21,20 +22,22 @@ abstract class BaseActivity : PushMessageActivity() {
enableEdgeToEdge() // 可选:设置导航栏图标颜色(深色/浅色) enableEdgeToEdge() // 可选:设置导航栏图标颜色(深色/浅色)
setContent { setContent {
DealerTheme { DealerTheme {
val tipDialog by remember { showTipDialog }
val showLoading by remember { LoadingManager.showLoading }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val windowInsetsController = val windowInsetsController =
WindowCompat.getInsetsController(window, this.window.decorView) WindowCompat.getInsetsController(window, this.window.decorView)
windowInsetsController.isAppearanceLightStatusBars = false windowInsetsController.isAppearanceLightStatusBars = false
} }
ContentView() ContentView()
if (LoadingManager.showLoading.value) { if (showLoading) {
LoadingManager.LoadingView() LoadingManager.LoadingView()
} }
if (tipDialog != null) {
if (showTipDialog.value != null) { CommonDialog(message = tipDialog ?: "",
CommonDialog(message = showTipDialog.value ?: "",
title = "提示", title = "提示",
confirmText = "我已了解", confirmText = "我已了解",
cancelText = "",
confirm = { BaseVm.hideTipDialog() }, confirm = { BaseVm.hideTipDialog() },
cancel = { BaseVm.hideTipDialog() }, cancel = { BaseVm.hideTipDialog() },
dismiss = { BaseVm.hideTipDialog() }, dismiss = { BaseVm.hideTipDialog() },

View File

@ -3,14 +3,15 @@ package com.za.base
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
val showTipDialog = mutableStateOf<String?>(null) //提示框
abstract class BaseVm<T, U> : ViewModel() { abstract class BaseVm<T, U> : ViewModel() {
val tag: String = javaClass.simpleName val tag : String = javaClass.simpleName
abstract fun updateState(uiState: U) abstract fun updateState(uiState : U)
abstract fun dispatch(action: T) abstract fun dispatch(action : T)
companion object { companion object {
val showTipDialog = mutableStateOf<String?>(null)//提示框 fun showTipDialog(msg : String) {
fun showTipDialog(msg: String) {
showTipDialog.value = msg showTipDialog.value = msg
} }

View File

@ -50,4 +50,17 @@ object Const {
const val CRM2 = 3 //测试环境 const val CRM2 = 3 //测试环境
const val UAT = 4 //测试环境 const val UAT = 4 //测试环境
} }
object PushMessageType {
const val ACTION_SDK = "com.zd.servicing.PUSH_MESSAGE"
const val ACTION_MAIN = "com.za.rescue.dealer.PUSH_MESSAGE"
const val BROADCAST = "broadcast"
const val GIVE_UP = "giveUp"
const val IMPORTANT_TIP = "importantTip"
const val NEW_ORDER = "newOrder"
const val RE_DISPATCH = "reDispatch"
const val MODIFY = "modify"
const val REVOKE = "revoke"
const val GO_MAIN_PAGE = "goMainPage"
}
} }

View File

@ -1,59 +1,64 @@
package com.za.base package com.za.base
import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.google.gson.Gson import com.google.gson.Gson
import com.za.bean.JpushBean import com.za.bean.JpushBean
import com.za.common.GlobalData
import com.za.common.log.LogUtil import com.za.common.log.LogUtil
import com.za.service.PushListener import com.za.service.PushListener
import com.za.service.ServiceManager import com.za.service.ServiceManager
import com.za.service.ZdPushServiceReceive
open class PushMessageActivity : AppCompatActivity() { open class PushMessageActivity : AppCompatActivity() {
private var currentDialog : AlertDialog? = null private var currentDialog : AlertDialog? = null
override fun onCreate(savedInstanceState : Bundle?) { override fun onCreate(savedInstanceState : Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState) // setupPushMessageReceiver()
// setupPushMessageReceiver()
} }
private fun setupPushMessageReceiver() { // 注册推送消息接收器 private fun setupPushMessageReceiver() { // 注册推送消息接收器
ServiceManager.registerPushListener(object : PushListener { ServiceManager.registerPushListener(object : PushListener {
override fun broadcast(msg : String) { override fun broadcast(msg : String) {
sendMessageToMainProcess("broadcast", msg) sendMessageToMainProcess(type = Const.PushMessageType.BROADCAST,
message = msg,
context = this@PushMessageActivity)
} }
override fun giveUpOrder(jpushBean : JpushBean) { override fun giveUpOrder(jpushBean : JpushBean) {
sendMessageToMainProcess("giveUp", Gson().toJson(jpushBean)) sendMessageToMainProcess(type = Const.PushMessageType.GIVE_UP,
message = Gson().toJson(jpushBean),
context = this@PushMessageActivity)
} }
override fun importantTip(jpushBean : JpushBean) { override fun importantTip(jpushBean : JpushBean) {
sendMessageToMainProcess("importantTip", Gson().toJson(jpushBean)) sendMessageToMainProcess(type = Const.PushMessageType.IMPORTANT_TIP,
message = Gson().toJson(jpushBean),
context = this@PushMessageActivity)
} }
override fun newOrderMsg(jpushBean : JpushBean) { override fun newOrderMsg(jpushBean : JpushBean) {
sendMessageToMainProcess("newOrder", Gson().toJson(jpushBean)) sendMessageToMainProcess(type = Const.PushMessageType.NEW_ORDER,
message = Gson().toJson(jpushBean),
context = this@PushMessageActivity)
} }
override fun reDispatchOrder(jpushBean : JpushBean) { override fun reDispatchOrder(jpushBean : JpushBean) {
sendMessageToMainProcess("reDispatch", Gson().toJson(jpushBean)) sendMessageToMainProcess(type = Const.PushMessageType.RE_DISPATCH,
message = Gson().toJson(jpushBean),
context = this@PushMessageActivity)
} }
override fun revokeOrder(jpushBean : JpushBean) { override fun revokeOrder(jpushBean : JpushBean) {
sendMessageToMainProcess("revoke", Gson().toJson(jpushBean)) sendMessageToMainProcess(type = Const.PushMessageType.REVOKE,
message = Gson().toJson(jpushBean),
context = this@PushMessageActivity)
} }
}) })
} }
private fun sendMessageToMainProcess(type : String, message : String) { // 使用广播将消息发送到主进程
val intent = Intent(ZdPushServiceReceive.RECEIVE_ACTION).setPackage(packageName)
intent.putExtra("type", type)
intent.putExtra("message", message)
sendBroadcast(intent)
LogUtil.print("KeepAliveService", "发送消息到主进程: $type")
}
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
@ -72,5 +77,17 @@ open class PushMessageActivity : AppCompatActivity() {
companion object { companion object {
internal const val GIVE_UP_TYPE_NORMAL = 1 internal const val GIVE_UP_TYPE_NORMAL = 1
internal const val DIALOG_TAG_GIVE_UP = "giveUp" internal const val DIALOG_TAG_GIVE_UP = "giveUp"
private fun sendMessageToMainProcess(context : Context, type : String, message : String) {
// 使用广播将消息发送到主进程
val intent = Intent(Const.PushMessageType.ACTION_MAIN.takeIf { GlobalData.isMaster }
?: Const.PushMessageType.ACTION_SDK)
intent.setPackage(context.packageName)
intent.putExtra("type", type)
intent.putExtra("message", message)
context.sendBroadcast(intent)
LogUtil.print("KeepAliveService", "发送消息到主进程: $type")
}
} }
} }

View File

@ -1,7 +1,6 @@
package com.za.base.view package com.za.base.view
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -11,23 +10,32 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.za.base.theme.buttonBgColor import com.za.base.theme.buttonBgColor
import com.za.base.theme.headBgColor
import com.za.ext.noDoubleClick import com.za.ext.noDoubleClick
@Composable @Composable
fun CommonButton(text: String, onClick: () -> Unit) { fun CommonButton(modifier : Modifier = Modifier, text : String, onClick : () -> Unit) {
Box(modifier = modifier.noDoubleClick { onClick() }, contentAlignment = Alignment.Center) {
Text(text = text,
color = Color.White,
fontSize = 15.sp,
fontWeight = FontWeight.Medium,
style = TextStyle.Default.copy(fontSize = 15.sp, fontWeight = FontWeight.Medium))
}
}
@Composable
fun CommonButton(text : String, onClick : () -> Unit) {
Box(modifier = Modifier Box(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.noDoubleClick { onClick() } .noDoubleClick { onClick() }
.padding(horizontal = 60.dp, vertical = 10.dp) .padding(horizontal = 60.dp, vertical = 10.dp)
.background(color = buttonBgColor, shape = RoundedCornerShape(4.dp)) .background(color = buttonBgColor, shape = RoundedCornerShape(4.dp))
.padding(vertical = 12.dp), contentAlignment = Alignment.Center) { .padding(vertical = 12.dp), contentAlignment = Alignment.Center) {
Text(text = text, color = Color.White, Text(text = text, color = Color.White, fontSize = 15.sp, fontWeight = FontWeight.Medium, style = TextStyle.Default.copy())
fontSize = 15.sp,
fontWeight = FontWeight.Medium)
} }
} }

View File

@ -30,6 +30,7 @@ import androidx.compose.ui.window.DialogProperties
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.za.base.theme.black90 import com.za.base.theme.black90
import com.za.common.util.MapUtil import com.za.common.util.MapUtil
import com.za.ext.noDoubleClick
import com.za.servicing.R import com.za.servicing.R
@Composable @Composable
@ -146,7 +147,7 @@ fun ReTakePhotoDialog(title : String? = null,
Box(modifier = Modifier Box(modifier = Modifier
.width(202.dp) .width(202.dp)
.clickable { confirm() } .noDoubleClick { confirm() }
.background(color = Color(0xFF3A58B1), shape = RoundedCornerShape(23.dp)) .background(color = Color(0xFF3A58B1), shape = RoundedCornerShape(23.dp))
.padding(vertical = 12.dp), contentAlignment = Alignment.Center) { .padding(vertical = 12.dp), contentAlignment = Alignment.Center) {
Text(text = "重拍", Text(text = "重拍",

View File

@ -1,23 +1,27 @@
package com.za.base.view package com.za.base.view
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons
import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material.icons.filled.KeyboardArrowLeft
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import com.za.base.theme.headBgColor import com.za.base.theme.headBgColor
import com.za.servicing.R
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
@ -26,21 +30,34 @@ fun HeadView(title : String,
isCanBack : Boolean = true, isCanBack : Boolean = true,
action : @Composable () -> Unit = {}) { action : @Composable () -> Unit = {}) {
Column { Column {
CenterAlignedTopAppBar(modifier = Modifier.fillMaxWidth(), Box(modifier = Modifier
colors = TopAppBarDefaults.centerAlignedTopAppBarColors() .fillMaxWidth()
.copy(containerColor = headBgColor, titleContentColor = Color.White), .background(color = headBgColor)
title = { Text(text = title, fontSize = 15.sp, fontWeight = FontWeight.Medium) }, .padding(horizontal = 10.dp, vertical = 5.dp), contentAlignment = Alignment.Center) {
navigationIcon = {
Row(modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween) {
if (isCanBack) { if (isCanBack) {
AsyncImage(model = R.drawable.sv_back, Icon(Icons.Default.KeyboardArrowLeft,
contentDescription = "", contentDescription = "",
modifier = Modifier modifier = Modifier
.size(40.dp)
.clickable { onBack() } .clickable { onBack() }
.padding(10.dp)) .padding(5.dp),
tint = Color.White)
}
action()
}
Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
Text(text = title,
fontSize = 16.sp,
color = Color.White.copy(alpha = 0.95f),
fontWeight = FontWeight.Medium,
style = TextStyle.Default.copy())
}
} }
},
actions = { action() })
AppTipsView() AppTipsView()
} }
@ -50,11 +67,18 @@ fun HeadView(title : String,
@Composable @Composable
fun HeadViewNotBack(title : String) { fun HeadViewNotBack(title : String) {
Column { Column {
CenterAlignedTopAppBar(modifier = Modifier.fillMaxWidth(), Box(modifier = Modifier
colors = TopAppBarDefaults.centerAlignedTopAppBarColors() .fillMaxWidth()
.copy(containerColor = headBgColor, titleContentColor = Color.White), .background(color = headBgColor)
title = { Text(text = title, fontSize = 15.sp, fontWeight = FontWeight.Medium) }, .padding(horizontal = 10.dp, vertical = 5.dp), contentAlignment = Alignment.Center) {
navigationIcon = {}) Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
Text(text = title,
fontSize = 16.sp,
color = Color.White.copy(alpha = 0.95f),
fontWeight = FontWeight.Medium,
style = TextStyle.Default.copy())
}
}
AppTipsView() AppTipsView()
} }

View File

@ -7,120 +7,124 @@ import java.io.Serializable
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
data class JpushBean( data class JpushBean(
val pushType: Int? = null, //0 新任务 1 任务取消 2 任务变更 val pushType : Int? = null, //0 新任务 1 任务取消 2 任务变更
val taskId: Int? = null,//订单号 "taskId":5313005 val taskId : Int? = null, //订单号 "taskId":5313005
val taskCode: String? = null, //订单编码 "taskCode":"ZD20190308009965" val taskCode : String? = null, //订单编码 "taskCode":"ZD20190308009965"
val customerName: String? = null, //客户姓名 "customerName":"越继安" val customerName : String? = null, //客户姓名 "customerName":"越继安"
val customerPhone: String? = null, //客户电话 "customerPhone":"18078815268" val customerPhone : String? = null, //客户电话 "customerPhone":"18078815268"
val carBrand: String? = null, //车辆品牌 "carBrand":"" val carBrand : String? = null, //车辆品牌 "carBrand":""
val carModel: String? = null,//车辆型号 "carModel":"秦" val carModel : String? = null, //车辆型号 "carModel":"秦"
val contract: String? = null, //车辆型号 "carModel":"秦" val contract : String? = null, //车辆型号 "carModel":"秦"
val typeDesc: String? = null, //推送的附加消息 revoke 撤回 giveUp放弃 reDispatch改派 val typeDesc : String? = null, //推送的附加消息 revoke 撤回 giveUp放弃 reDispatch改派
val userOrderId: Int? = null, val userOrderId : Int? = null,
val carNo: String? = null, //客户车车牌号 "carNo":"粤AF53918" val carNo : String? = null, //客户车车牌号 "carNo":"粤AF53918"
val taskState: String? = null, //订单状态 "taskState":"GOTO" val taskState : String? = null, //订单状态 "taskState":"GOTO"
val address: String? = null, //任务地址 "address":"广东省广州市白云区107国道石井凰岗路342号(白云黄石、同德围地区近庆丰兴隆公园)美景大酒店" val address : String? = null, //任务地址 "address":"广东省广州市白云区107国道石井凰岗路342号(白云黄石、同德围地区近庆丰兴隆公园)美景大酒店"
val addressProperty: String? = null,//任务地址类型 "addressProperty":"地面" val addressProperty : String? = null, //任务地址类型 "addressProperty":"地面"
val hotline: String? = null, //任务地址类型 "addressProperty":"地面" val hotline : String? = null, //任务地址类型 "addressProperty":"地面"
val schedulingFinalRule: Int? = null, //案件类型 0 传统案件 1 聚合派工 val schedulingFinalRule : Int? = null, //案件类型 0 传统案件 1 聚合派工
val addressRemark: String? = null, val addressRemark : String? = null,
val distAddress: String? = null, //目的地地址 "distAddress":"广东省广州市白云区雅岗南大道" val distAddress : String? = null, //目的地地址 "distAddress":"广东省广州市白云区雅岗南大道"
val distAddressRemark: String? = null, val distAddressRemark : String? = null,
val expectArriveTime: String? = null, //预计到达时间 "expectArriveTime":"2019-03-08 05:11:07" val expectArriveTime : String? = null, //预计到达时间 "expectArriveTime":"2019-03-08 05:11:07"
val serviceTypeName: String? = null,//服务类型 "serviceTypeName":"故障--平板拖车" val serviceTypeName : String? = null, //服务类型 "serviceTypeName":"故障--平板拖车"
val dispatchTime: String? = null, //派单时间 "dispatchTime":"2019-03-08 04:26:07" val dispatchTime : String? = null, //派单时间 "dispatchTime":"2019-03-08 04:26:07"
val lat: Double? = null, val lat : Double? = null,
val lng: Double? = null, val lng : Double? = null,
val distLat: Double? = null, val distLat : Double? = null,
val distLng: Double? = null, val distLng : Double? = null,
val importantTip: String? = null, val importantTip : String? = null,
val tipContent: String? = null, val tipContent : String? = null,
val settleType: Int?=null,//结算类型 1 月结 2 现金 val isAppoint : Int? = null, //是否是预约单 1 预约单
var orderSource: String? = null, // "orderSource":"中道救援-比亚迪道路救援项目" val appointTime : String? = null, //预约时间
val hasReplaceBatteryCapable: Int? = null ,//是否有更换电瓶的能力 1 搭电可以更换电瓶 2搭电不可以更换电瓶 其他的不展示 val settleType : Int? = null, //结算类型 1 月结 2 现金
var voiceType : Int?=null //语音提示类型 1小修单 2拖车单 3困境单 var orderSource : String? = null, // "orderSource":"中道救援-比亚迪道路救援项目"
val hasReplaceBatteryCapable : Int? = null, //是否有更换电瓶的能力 1 搭电可以更换电瓶 2搭电不可以更换电瓶 其他的不展示
var voiceType : Int? = null, //语音提示类型 1小修单 2拖车单 3困境单)
) : Serializable { ) : Serializable {
fun isNeedCallCustomPhone(): Boolean { fun isNeedCallCustomPhone() : Boolean {
return "210" != customerPhone && "230" != customerPhone return "210" != customerPhone && "230" != customerPhone
} }
} }
data class NewOrderRequestBean(val vehicleId: Int? = null) data class NewOrderRequestBean(val vehicleId : Int? = null)
//历史订单状态 //历史订单状态
data class HistoryTaskBean( data class HistoryTaskBean(
val taskId: Int? = null, //订单号 val taskId : Int? = null, //订单号
val taskCode: String? = null, //订单编码 val taskCode : String? = null, //订单编码
val userOrderId: Int? = null, val userOrderId : Int? = null,
val userOrderCode: String? = null, //只有电子工单历史补传才需要传 val userOrderCode : String? = null, //只有电子工单历史补传才需要传
val supplierAudit: Int? = null, //审核状态 0待补充 1 待审核 2审核不通过 3 审核通过 val supplierAudit : Int? = null, //审核状态 0待补充 1 待审核 2审核不通过 3 审核通过
val supplierAuditStr: String? = null, //审核状态描述 val supplierAuditStr : String? = null, //审核状态描述
val missingContent: String? = null, //缺失内容 val missingContent : String? = null, //缺失内容
val auditFailReason: String? = null, //审核失败原因 val auditFailReason : String? = null, //审核失败原因
val customerName: String? = null, //客户姓名 val customerName : String? = null, //客户姓名
val customerPhone: String? = null, //客户电话 val customerPhone : String? = null, //客户电话
val carBrand: String? = null, //车辆品牌 val carBrand : String? = null, //车辆品牌
val carModel: String? = null, //车辆型号 val carModel : String? = null, //车辆型号
val carNo: String? = null, //客户车车牌号 " val carNo : String? = null, //客户车车牌号 "
val carVin: String? = null, //客户车Vin码 val carVin : String? = null, //客户车Vin码
val taskState: String? = null, //订单状态 val taskState : String? = null, //订单状态
val address: String? = null, //任务地址 val address : String? = null, //任务地址
val addressRemark: String? = null, //事发地地址补充 val addressRemark : String? = null, //事发地地址补充
val addressProperty: String? = null, //任务地址类型 val addressProperty : String? = null, //任务地址类型
val lat: Double? = null, val lat : Double? = null,
val lng: Double? = null, val lng : Double? = null,
val distAddress: String? = null, //目的地地址 val distAddress : String? = null, //目的地地址
val distAddressRemark: String? = null, //目的地地址补充 val distAddressRemark : String? = null, //目的地地址补充
val distLat: Double? = null, val distLat : Double? = null,
val distLng: Double? = null, val distLng : Double? = null,
val expectArriveTime: String? = null, //预计到达时间 val expectArriveTime : String? = null, //预计到达时间
val serviceTypeName: String? = null, //服务类型 val serviceTypeName : String? = null, //服务类型
val orderSource: String? = null, // val orderSource : String? = null, //
val flowType: Int? = null, //流程类型 "flowType":2 val flowType : Int? = null, //流程类型 "flowType":2
val settleType: Int? = null, //结算类型 1 月结 2 现金 val settleType : Int? = null, //结算类型 1 月结 2 现金
val supplierId: Int? = null, val supplierId : Int? = null,
val successTime: String? = null, //完成时间 "dispatchTime":"2019-03-08 04:26:07" val successTime : String? = null, //完成时间 "dispatchTime":"2019-03-08 04:26:07"
val verifyType: Int? = null, //验证类型 "verifyType":1 val verifyType : Int? = null, //验证类型 "verifyType":1
val verifyValue: String? = null, //验证内容 val verifyValue : String? = null, //验证内容
val holdon: Boolean? = null, //是否被挂起 "holdon":false val holdon : Boolean? = null, //是否被挂起 "holdon":false
val externalCode: String? = null, //流水号 val externalCode : String? = null, //流水号
val vehicleName: String? = null, val vehicleName : String? = null,
val traceIdAB: Int? = null, val traceIdAB : Int? = null,
val mileageAB: Int? = null, val mileageAB : Int? = null,
val traceABUrl: String? = null, val traceABUrl : String? = null,
val traceIdBC: Int? = null, val traceIdBC : Int? = null,
val mileageBC: Int? = null, val mileageBC : Int? = null,
val mileageCA: Int? = null, val mileageCA : Int? = null,
val traceBCUrl: String? = null, val traceBCUrl : String? = null,
val createTime: String? = null, val createTime : String? = null,
val acceptTime: String? = null, val acceptTime : String? = null,
val arriveTime: String? = null, val arriveTime : String? = null,
val arriveDestTime: String? = null, val arriveDestTime : String? = null,
val giveupTime: String? = null, val giveupTime : String? = null,
val giveupAddress: String? = null, val giveupAddress : String? = null,
val giveupLat: Double? = null, val giveupLat : Double? = null,
val giveupLng: Double? = null, val giveupLng : Double? = null,
val needWaterMarker: Boolean? = null, val needWaterMarker : Boolean? = null,
val needShowPhoneBrand: Boolean? = null, val needShowPhoneBrand : Boolean? = null,
val policyNo: String? = null, // 平安拖车责任险 保单号 val policyNo : String? = null, // 平安拖车责任险 保单号
val electronOrderState: String? = null, //电子工单状态 val electronOrderState : String? = null, //电子工单状态
val hasReplaceBatteryCapable: Int? = null, //是否具有更换电瓶的能力 val hasReplaceBatteryCapable : Int? = null, //是否具有更换电瓶的能力
val hasReplaceBattery: Int = 0 //1已更换过 2有更换能力但没更换过 0无 val hasReplaceBattery : Int = 0, //1已更换过 2有更换能力但没更换过 0无)
) : Serializable { ) : Serializable {
fun getEleOrderH5Url(): String? { fun getEleOrderH5Url() : String? {
if (electronOrderState == null || electronOrderState != "3") { if (electronOrderState == null || electronOrderState != "3") {
return null return null
} }
val paramQuery = (("userOrderId=$userOrderId").toString() + "&userOrderCode=" + taskCode) + "&supplierId=" + userOrderId val paramQuery =
return AppConfig.Resource_URL + "/electronicWorkOrder/index.html?" + EncodeUtils.base64Encode2String(paramQuery.toByteArray(StandardCharsets.UTF_8)) (("userOrderId=$userOrderId").toString() + "&userOrderCode=" + taskCode) + "&supplierId=" + userOrderId
return AppConfig.Resource_URL + "/electronicWorkOrder/index.html?" + EncodeUtils.base64Encode2String(
paramQuery.toByteArray(StandardCharsets.UTF_8))
} }
fun getSettleTypeStr(): String { fun getSettleTypeStr() : String {
return when (settleType) { return when (settleType) {
1 -> { 1 -> {
"月结" "月结"
@ -142,33 +146,35 @@ data class HistoryPhotoTemplates(
/** /**
* 任务节点 * 任务节点
*/ */
val taskStatus: Int? = null, val taskStatus : Int? = null,
/** /**
* 图片节点名称 * 图片节点名称
*/ */
val taskStatusString: String? = null, val taskStatusString : String? = null,
/** /**
* 该节点下的所有历史照片信息 * 该节点下的所有历史照片信息
*/ */
val photoList: List<HistoryPhotoTemplateItem>? = null val photoList : List<HistoryPhotoTemplateItem>? = null)
)
data class HistoryPhotoTemplateItem( data class HistoryPhotoTemplateItem(
val photoUrl: String? = null, val photoUrl : String? = null,
val tag: String? = null, val tag : String? = null,
val imageTitle: String? = null, val imageTitle : String? = null,
val lon: String? = null, val lon : String? = null,
val lat: String? = null, val lat : String? = null,
val templatePhotoType: Int = 0, //1 照片 2 工单照片 val sort : Int? = null,
val takePhotoTime: String? = null, val examplePhotoUrl : String? = null, //示例照片地址
val takeAddress: String? = null, val selectFailReasonList : List<PhotoCheckFailedBean>? = null,
val uploadStatus: String? = null, val templatePhotoType : Int = 0, //1 照片 2 工单照片
val uploadState: Int? = 0, //0 上传中 1 上传成功 2 上传失败 val takePhotoTime : String? = null,
val takeAddress : String? = null,
val uploadStatus : String? = null,
val uploadState : Int? = 0, //0 上传中 1 上传成功 2 上传失败
) { ) {
//获取拍照时间 //获取拍照时间
fun getPhotoTakeTime(taskState: String, historyTaskBean: HistoryTaskBean?): String? { fun getPhotoTakeTime(taskState : String, historyTaskBean : HistoryTaskBean?) : String? {
if (!takePhotoTime.isNullOrBlank()) { if (! takePhotoTime.isNullOrBlank()) {
return takePhotoTime return takePhotoTime
} }
return when (taskState) { return when (taskState) {
@ -190,8 +196,8 @@ data class HistoryPhotoTemplateItem(
} }
} }
fun getPhotoLat(taskState: String, historyTaskBean: HistoryTaskBean?): Double? { fun getPhotoLat(taskState : String, historyTaskBean : HistoryTaskBean?) : Double? {
if (!lat.isNullOrBlank()) { if (! lat.isNullOrBlank()) {
return lat.toDouble() return lat.toDouble()
} }
return when (taskState) { return when (taskState) {
@ -209,8 +215,8 @@ data class HistoryPhotoTemplateItem(
} }
} }
fun getPhotoLng(taskState: String, historyTaskBean: HistoryTaskBean?): Double? { fun getPhotoLng(taskState : String, historyTaskBean : HistoryTaskBean?) : Double? {
if (!lon.isNullOrBlank()) { if (! lon.isNullOrBlank()) {
return lon.toDouble() return lon.toDouble()
} }
return when (taskState) { return when (taskState) {
@ -228,8 +234,8 @@ data class HistoryPhotoTemplateItem(
} }
} }
fun getPhotoAddress(taskState: String, historyTaskBean: HistoryTaskBean?): String? { fun getPhotoAddress(taskState : String, historyTaskBean : HistoryTaskBean?) : String? {
if (!takeAddress?.replace("[", "")?.replace("]", "").isNullOrBlank()) { if (! takeAddress?.replace("[", "")?.replace("]", "").isNullOrBlank()) {
return takeAddress return takeAddress
} }
return when (taskState) { return when (taskState) {
@ -250,39 +256,42 @@ data class HistoryPhotoTemplateItem(
} }
data class TaskSettlementAndTraceBean( data class PhotoCheckFailedBean(
val settleMap: SettleMapBean? = null, val abbr : String? = null, //失败原因简称
val traceIdAB: Int? = null, val failReason : String? = null, //失败原因详情
val mileageAB: Int? = null,
val traceABUrl: String? = null,
val traceIdBC: Int? = null,
val mileageBC: Int? = null,
val mileageCA: Int? = null,
val traceBCUrl: String? = null
) )
data class TaskSettlementAndTraceBean(val settleMap : SettleMapBean? = null,
val traceIdAB : Int? = null,
val mileageAB : Int? = null,
val traceABUrl : String? = null,
val traceIdBC : Int? = null,
val mileageBC : Int? = null,
val mileageCA : Int? = null,
val traceBCUrl : String? = null)
data class SettleMapBean( data class SettleMapBean(
/*————————————子公司——————————*/ /*————————————子公司——————————*/
val startPrice: Int? = null, //起步价 val startPrice : Int? = null, //起步价
val unitPrice: Double? = null, //每公里单价 val unitPrice : Double? = null, //每公里单价
val mileage: Int? = null, //公里数 val mileage : Int? = null, //公里数
val basePrice: Double? = null,//基本费用 val basePrice : Double? = null, //基本费用
val roadFee: Int? = null,//路桥费 val roadFee : Int? = null, //路桥费
val assistFee: Int? = null, //辅助总费用 val assistFee : Int? = null, //辅助总费用
/*———————————————供应商———————————————*/ // public Integer startMileage;//出发段公里数 /*———————————————供应商———————————————*/ // public Integer startMileage;//出发段公里数
// public Integer carryMileage;//背车段公里数 // public Integer carryMileage;//背车段公里数
// public Integer backMileage;//回程段公里数 // public Integer backMileage;//回程段公里数
val startRoadFee: Int? = null, //出发段过境费 val startRoadFee : Int? = null, //出发段过境费
val carryRoadFee: Int? = null, //背车段过境费 val carryRoadFee : Int? = null, //背车段过境费
val backRoadFee: Int? = null, //回程段过境费 val backRoadFee : Int? = null, //回程段过境费
val waitFee: Int? = null,//等候费 val waitFee : Int? = null, //等候费
val wheelFee: Int? = null,//辅助轮费 val wheelFee : Int? = null, //辅助轮费
val wheelNum: Int? = null, //辅助轮个数 val wheelNum : Int? = null, //辅助轮个数
val wheelPrice: Int? = null, //辅助轮单价 val wheelPrice : Int? = null, //辅助轮单价
val dilemmaFee: Int? = null,//困境费 val dilemmaFee : Int? = null, //困境费
val basementFee: Int? = null, //其他费用 val basementFee : Int? = null, //其他费用
val totalFee: Double? = null,//费用总计 val totalFee : Double? = null, //费用总计
) )
@ -290,42 +299,40 @@ data class SettleMapBean(
* Created by zhangj on 2019/12/4. * Created by zhangj on 2019/12/4.
*/ */
class SettleInfoRequest( class SettleInfoRequest(
val orderId: Int? = null, val orderId : Int? = null,
val supplierType: Int? = null, val supplierType : Int? = null,
val startMileage: Int? = null, val startMileage : Int? = null,
val carryMileage: Int? = null, val carryMileage : Int? = null,
val backMileage: Int? = null, val backMileage : Int? = null,
val startRoadFee: Int? = null, val startRoadFee : Int? = null,
val carryRoadFee: Int? = null, val carryRoadFee : Int? = null,
val backRoadFee: Int? = null, val backRoadFee : Int? = null,
val waitFee: Int? = null, val waitFee : Int? = null,
val settleType: Int? = null, val settleType : Int? = null,
val wheelFee: Int? = null, //辅助轮费 val wheelFee : Int? = null, //辅助轮费
val wheelNum: Int? = null, val wheelNum : Int? = null,
val wheelPrice: Int? = null, val wheelPrice : Int? = null,
val dilemmaFee: Int? = null, //困境费 val dilemmaFee : Int? = null, //困境费
val basementFee: Int? = null, //其他费用 val basementFee : Int? = null, //其他费用
val totalFee: Double? = null, // val totalFee : Double? = null, //
val startPrice: Int? = null, val startPrice : Int? = null,
val unitPrice: Double? = null, val unitPrice : Double? = null,
val mileage: Int? = null, val mileage : Int? = null,
val basePrice: Double? = null, val basePrice : Double? = null,
val assistFee: Int? = null, val assistFee : Int? = null,
val imgInfo: String? = null, val imgInfo : String? = null,
val imgPath: String? = null, val imgPath : String? = null,
) )
data class AMapTraceBean( data class AMapTraceBean(val counts : Int? = null,
val counts: Int? = null, val distance : Double? = null,
val distance: Double? = null, val time : Long? = null,
val time: Long? = null, val trid : Int? = null,
val trid: Int? = null, val points : List<PointsBean>? = null)
val points: List<PointsBean>? = null)
data class PointsBean( data class PointsBean(val accuracy : Double? = null,
val accuracy: Double? = null, val direction : Double? = null,
val direction: Double? = null, val height : Double? = null,
val height: Double? = null, val locatetime : Long? = null,
val locatetime: Long? = null, val location : String? = null,
val location: String? = null, val speed : Double? = null)
val speed: Double? = null)

View File

@ -75,7 +75,7 @@ data class OrderInfo(
var importantTip : String? = null, var importantTip : String? = null,
var hasReplaceBatteryCapable : Int? = null, //是否有更换电瓶的能力 1 搭电可以更换电瓶 2搭电不可以更换电瓶 其他的不展示 var hasReplaceBatteryCapable : Int? = null, //是否有更换电瓶的能力 1 搭电可以更换电瓶 2搭电不可以更换电瓶 其他的不展示
var taskSuccessStatus : Int? = null, //作业是否完成 0 完成 1未完成 拖车默认完成 var taskSuccessStatus : Int? = null, //作业是否完成 0 完成 1未完成 拖车默认完成
var tyreNumber : Int? = null, //辅助费用 var tyreNumber : Int? = null, //小轮个数
) : Parcelable { ) : Parcelable {
constructor(parcel : Parcel) : this(parcel.readValue(Int::class.java.classLoader) as? Int, constructor(parcel : Parcel) : this(parcel.readValue(Int::class.java.classLoader) as? Int,
parcel.readValue(Int::class.java.classLoader) as? Int, parcel.readValue(Int::class.java.classLoader) as? Int,

View File

@ -9,6 +9,7 @@ import com.za.base.Const
import com.za.bean.db.order.OrderInfo import com.za.bean.db.order.OrderInfo
import com.za.room.RoomHelper import com.za.room.RoomHelper
import com.za.room.db.user.DriverInfoBean import com.za.room.db.user.DriverInfoBean
import com.za.service.location.ZdLocationManager
object GlobalData : GlobalLocalData() { object GlobalData : GlobalLocalData() {
lateinit var application : Application lateinit var application : Application
@ -94,10 +95,17 @@ object GlobalData : GlobalLocalData() {
var currentLocation : AMapLocation? = null var currentLocation : AMapLocation? = null
get() { get() {
return mmkv.decodeParcelable("currentLocation", AMapLocation::class.java) val location = mmkv.decodeParcelable("currentLocation", AMapLocation::class.java)
if (location != null && (System.currentTimeMillis()
.minus(location.time) < 5 * 60 * 1000)
) {
return location
} else {
ZdLocationManager.init(application)
return null
}
} }
set(value) { set(value) {
value?.time = System.currentTimeMillis()
mmkv.encode("currentLocation", value) mmkv.encode("currentLocation", value)
field = value field = value
} }

View File

@ -0,0 +1,5 @@
package com.za.common
interface IServiceBridge {
fun giveUpOrder(orderId : String)
}

View File

@ -11,14 +11,13 @@ import com.za.service.location.ZdLocationManager
object ZDManager { object ZDManager {
lateinit var application : Application lateinit var application : Application
fun init(application : Application, isRelease : Boolean = false) { fun init(application : Application, isRelease : Boolean = false) {
this.application = application this.application = application
thirdSdkInit(isRelease) thirdSdkInit(isRelease)
} }
private fun thirdSdkInit(isRelease : Boolean = false) { private fun thirdSdkInit(isRelease : Boolean = false) {
GlobalData.application = application // 在 Application 中初始化 MMKV所有进程共享同一存储路径 GlobalData.application = application
MMKV.initialize(application) MMKV.initialize(application)
AppConfig.init(isRelease) AppConfig.init(isRelease)
Bugly.init(application, "6972a6b56d", true) Bugly.init(application, "6972a6b56d", true)

View File

@ -107,6 +107,12 @@ object SpeechManager {
mediaPlayer?.start() mediaPlayer?.start()
} }
// 当前订单被改派
fun playCurrentOrderReDispatch() {
mediaPlayer = MediaPlayer.create(mContext, R.raw.order_redispatch)
mediaPlayer?.start()
}
// 订单被取消 // 订单被取消
fun playOrderCanceled() { fun playOrderCanceled() {
mediaPlayer = MediaPlayer.create(mContext, R.raw.cancel_order) mediaPlayer = MediaPlayer.create(mContext, R.raw.cancel_order)

View File

@ -485,5 +485,22 @@ object ImageUtil {
vectorDrawable.draw(canvas) vectorDrawable.draw(canvas)
return BitmapDescriptorFactory.fromBitmap(bitmap) return BitmapDescriptorFactory.fromBitmap(bitmap)
} }
fun scaleBitmapWithMatrix(originalBitmap : Bitmap, targetWidth : Int) : Bitmap {
val aspectRatio = originalBitmap.height.toFloat() / originalBitmap.width.toFloat()
val targetHeight = (targetWidth * aspectRatio).toInt()
val matrix = Matrix().apply {
postScale(targetWidth.toFloat() / originalBitmap.width,
targetHeight.toFloat() / originalBitmap.height)
}
return Bitmap.createBitmap(originalBitmap,
0,
0,
originalBitmap.width,
originalBitmap.height,
matrix,
true)
}
} }

View File

@ -3,19 +3,28 @@ package com.za.common.util
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.net.Uri import androidx.core.net.toUri
import androidx.exifinterface.media.ExifInterface
import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLng
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeQuery
import com.za.common.log.LogUtil
import com.za.ext.toJson
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Locale
import kotlin.math.atan2 import kotlin.math.atan2
import kotlin.math.cos import kotlin.math.cos
import kotlin.math.ln
import kotlin.math.sin import kotlin.math.sin
import kotlin.math.sqrt import kotlin.math.sqrt
object MapUtil { object MapUtil {
const val PN_GAODE_MAP: String = "com.autonavi.minimap" // 高德地图包名 const val PN_GAODE_MAP : String = "com.autonavi.minimap" // 高德地图包名
const val PN_BAIDU_MAP: String = "com.baidu.BaiduMap" // 百度地图包名 const val PN_BAIDU_MAP : String = "com.baidu.BaiduMap" // 百度地图包名
const val PN_TENCENT_MAP: String = "com.tencent.map" // 百度地图包名 const val PN_TENCENT_MAP : String = "com.tencent.map" // 百度地图包名
/** /**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换 * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
@ -24,10 +33,13 @@ object MapUtil {
* @param latLng * @param latLng
* @returns * @returns
*/ */
fun gcj02ToBD09(latLng: LatLng): LatLng { fun gcj02ToBD09(latLng : LatLng) : LatLng {
val xPI = 3.141592653589793 * 3000.0 / 180.0 val xPI = 3.141592653589793 * 3000.0 / 180.0
val z = sqrt(latLng.longitude * latLng.longitude + latLng.latitude * latLng.latitude) + 0.00002 * sin(latLng.latitude * xPI) val z =
val theta = atan2(latLng.latitude, latLng.longitude) + 0.000003 * cos(latLng.longitude * xPI) sqrt(latLng.longitude * latLng.longitude + latLng.latitude * latLng.latitude) + 0.00002 * sin(
latLng.latitude * xPI)
val theta =
atan2(latLng.latitude, latLng.longitude) + 0.000003 * cos(latLng.longitude * xPI)
val bdLat = z * sin(theta) + 0.006 val bdLat = z * sin(theta) + 0.006
val bdLng = z * cos(theta) + 0.0065 val bdLng = z * cos(theta) + 0.0065
return LatLng(bdLat, bdLng) return LatLng(bdLat, bdLng)
@ -38,64 +50,137 @@ object MapUtil {
* *
* @return * @return
*/ */
fun isGdMapInstalled(context: Context): Boolean { fun isGdMapInstalled(context : Context) : Boolean {
return isInstallPackage(context, PN_GAODE_MAP) return isInstallPackage(context, PN_GAODE_MAP)
} }
fun isBaiduMapInstalled(context: Context): Boolean { fun isBaiduMapInstalled(context : Context) : Boolean {
return isInstallPackage(context, PN_BAIDU_MAP) return isInstallPackage(context, PN_BAIDU_MAP)
} }
fun isTencentInstalled(context: Context): Boolean { fun isTencentInstalled(context : Context) : Boolean {
return isInstallPackage(context, PN_TENCENT_MAP) return isInstallPackage(context, PN_TENCENT_MAP)
} }
private fun isInstallPackage(context: Context, packageName: String): Boolean { private fun isInstallPackage(context : Context, packageName : String) : Boolean {
try { try {
val info = context.packageManager val info = context.packageManager.getApplicationInfo(packageName,
.getApplicationInfo(packageName,
PackageManager.GET_UNINSTALLED_PACKAGES) PackageManager.GET_UNINSTALLED_PACKAGES)
return true return true
} catch (e: PackageManager.NameNotFoundException) { } catch (e : PackageManager.NameNotFoundException) {
return false return false
} }
} }
//开启高德导航 //开启高德导航
fun startNavigationGd(context: Context, lat: Double?, lng: Double?, address: String?) { fun startNavigationGd(context : Context, lat : Double?, lng : Double?, address : String?) {
val stringBuffer = "androidamap://route?sourceApplication=" + "amap" + val stringBuffer =
"&dlat=" + lat + "androidamap://route?sourceApplication=amap&dlat=$lat&dlon=$lng&dname=$address&dev=0&t=0"
"&dlon=" + lng + val intent = Intent("android.intent.action.VIEW", stringBuffer.toUri())
"&dname=" + address +
"&dev=" + 0 +
"&t=" + 0
val intent = Intent("android.intent.action.VIEW", Uri.parse(stringBuffer))
intent.setPackage("com.autonavi.minimap") intent.setPackage("com.autonavi.minimap")
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent) context.startActivity(intent)
} }
//开启高德导航 //开启高德导航
fun startNavigationBd(context: Context, lat: Double?, lng: Double?, address: String?) { fun startNavigationBd(context : Context, lat : Double?, lng : Double?, address : String?) {
val i1 = Intent("android.intent.action.VIEW") val i1 = Intent("android.intent.action.VIEW")
i1.setData(Uri.parse("baidumap://map/navi?query=${address}&mode=driving&location=${lat},${lng}&coord_type=gcj02&src=com.za.servicing")) i1.setData("baidumap://map/navi?query=${address}&mode=driving&location=${lat},${lng}&coord_type=gcj02&src=com.za.servicing".toUri())
context.startActivity(i1) context.startActivity(i1)
} }
//开启高德导航 //开启高德导航
fun startNavigationTencent(context: Context, lat: Double?, lng: Double?, address: String?) { fun startNavigationTencent(context : Context, lat : Double?, lng : Double?, address : String?) {
val stringBuffer = "androidamap://route?sourceApplication=" + "amap" + val stringBuffer =
"&dlat=" + lat + "androidamap://route?sourceApplication=amap&dlat=$lat&dlon=$lng&dname=$address&dev=0&t=0"
"&dlon=" + lng + val intent = Intent("android.intent.action.VIEW", stringBuffer.toUri())
"&dname=" + address +
"&dev=" + 0 +
"&t=" + 0
val intent = Intent("android.intent.action.VIEW", Uri.parse(stringBuffer))
intent.setPackage("com.autonavi.minimap") intent.setPackage("com.autonavi.minimap")
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent) context.startActivity(intent)
} }
fun getAddressFromLocation(context : Context, latLng : LatLng?) : String? {
if (latLng == null) {
return null
}
try {
val geocoderSearch = GeocodeSearch(context)
val point = LatLonPoint(latLng.latitude, latLng.longitude)
val query = RegeocodeQuery(point, 200f, GeocodeSearch.AMAP)
return geocoderSearch.getFromLocation(query).formatAddress
} catch (e : Exception) {
LogUtil.print("geoCoderFromPhoto 获取地址异常", e)
return null
}
}
// fun getAddressFromLocation(context : Context, latLng : LatLng?) : String? {
// if (latLng == null) {
// return null
// }
// val geocoder = Geocoder(context, Locale.getDefault())
// try {
// val addresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1)
// if (addresses != null && ! addresses.isEmpty()) {
// val address = addresses[0]
// val sb = StringBuilder()
// for (i in 0 .. address.maxAddressLineIndex) {
// sb.append(address.getAddressLine(i))
// if (i < address.maxAddressLineIndex) {
// sb.append(", ")
// }
// }
// val addressStr = sb.toString()
// LogUtil.print("获取照片地址", addressStr)
// return addressStr
// }
// } catch (e : IOException) {
// LogUtil.print("获取照片地址异常", e)
// }
// return null
// }
fun getExifLatLng(localPath : String) : LatLng? {
try {
val exif = ExifInterface(localPath)
val latLong = exif.latLong
if (exif.getLatLong() != null) {
val lat = latLong?.get(0)
val lng = latLong?.get(1)
if (lat == 0.0 || lng == 0.0) {
LogUtil.print("获取照片的经纬度为空", "null1")
return null
}
val latlng = LatLng(lat !!, lng !!)
LogUtil.print("获取照片的经纬度", latlng.toJson().toString())
return latlng
} else {
LogUtil.print("获取照片的经纬度为空", "null2")
}
} catch (e : IOException) {
LogUtil.print("获取照片拍摄时间异常", e)
return null
}
return null
}
fun getPhotoTime(localPath : String) : String? {
try {
val exif = ExifInterface(localPath) // 获取拍摄时间格式通常为YYYY:MM:DD HH:MM:SS
val dateTime = exif.getAttribute(ExifInterface.TAG_DATETIME)
if (dateTime != null) { // 转换时间格式(可选)
val srcFormat = SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.getDefault())
val destFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
val date = srcFormat.parse(dateTime)
return destFormat.format(date)
}
} catch (e : IOException) {
LogUtil.print("获取照片拍摄时间异常", e)
}
return null
}
} }

View File

@ -25,3 +25,15 @@ fun String?.copy(context : Context) {
clipboardManager.setPrimaryClip(ClipData.newPlainText("", this)) clipboardManager.setPrimaryClip(ClipData.newPlainText("", this))
ToastUtils.showLong("复制成功") ToastUtils.showLong("复制成功")
} }
//截取字符串后六位进行保存
fun String?.getLastSix() : String {
if (this.isNullOrBlank()) {
return ""
}
return if (this.length > 6) {
this.substring(this.length - 6)
} else {
this
}
}

View File

@ -73,12 +73,12 @@ abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
} }
is ConnectException -> { is ConnectException -> {
doFailure(Const.NetWorkException, "与服务器断开连接") doFailure(Const.NetWorkException, "网络异常")
handlerNetError() handlerNetError()
} }
is UnknownHostException -> { is UnknownHostException -> {
doFailure(Const.NetWorkException, "与服务器断开连接") doFailure(Const.NetWorkException, "网络异常")
handlerNetError() handlerNetError()
} }
@ -89,12 +89,12 @@ abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
} }
is TimeoutException -> { is TimeoutException -> {
doFailure(Const.NetWorkException, "网络连接超时1") doFailure(Const.NetWorkException, "网络异常")
LogUtil.print("TimeoutException", e) LogUtil.print("TimeoutException", e)
} }
is SocketTimeoutException -> { is SocketTimeoutException -> {
doFailure(Const.NetWorkException, "网络连接超时2") doFailure(Const.NetWorkException, "网络异常")
LogUtil.print("SocketTimeoutException2", e) LogUtil.print("SocketTimeoutException2", e)
handlerNetError() handlerNetError()
} }

View File

@ -70,7 +70,7 @@ object CommonMethod {
RetrofitHelper.getDefaultService().uploadImage(body).subscribeOn(Schedulers.io()) RetrofitHelper.getDefaultService().uploadImage(body).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).subscribe(object : Observer<ImageBean> { .observeOn(AndroidSchedulers.mainThread()).subscribe(object : Observer<ImageBean> {
override fun onSubscribe(d : Disposable) { override fun onSubscribe(d : Disposable) {
LogUtil.print("onSubscribe", "onSubscribe")
} }
override fun onError(e : Throwable) { override fun onError(e : Throwable) {
@ -123,6 +123,8 @@ object CommonMethod {
GeneralInfoRequest(vehicleId = vehicleId ?: GlobalData.driverInfoBean?.vehicleId, GeneralInfoRequest(vehicleId = vehicleId ?: GlobalData.driverInfoBean?.vehicleId,
driverId = userId ?: GlobalData.driverInfoBean?.userId, driverId = userId ?: GlobalData.driverInfoBean?.userId,
deviceId = DeviceUtil.getAndroidId(ActivityUtils.getTopActivity())) deviceId = DeviceUtil.getAndroidId(ActivityUtils.getTopActivity()))
LogUtil.print("getGenerateInfo", "request=${generalInfoRequest.toJson()}")
RetrofitHelper.getDefaultService().generalInfo(generalInfoRequest) RetrofitHelper.getDefaultService().generalInfo(generalInfoRequest)
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BaseObserver<DriverInfoBean>() { .subscribe(object : BaseObserver<DriverInfoBean>() {
@ -173,6 +175,8 @@ object CommonMethod {
carNo = order.carNo, carNo = order.carNo,
taskState = order.taskState, taskState = order.taskState,
address = order.address, address = order.address,
settleType = order.settleType,
contract = order.contract,
addressProperty = order.addressProperty, addressProperty = order.addressProperty,
hotline = order.hotline, hotline = order.hotline,
expectArriveTime = order.expectArriveTime, expectArriveTime = order.expectArriveTime,
@ -180,6 +184,8 @@ object CommonMethod {
dispatchTime = order.dispatchTime, dispatchTime = order.dispatchTime,
lat = order.lat, lat = order.lat,
lng = order.lng, lng = order.lng,
isAppoint = order.isAppoint,
appointTime = order.appointTime,
distLat = order.distLat, distLat = order.distLat,
distLng = order.distLng, distLng = order.distLng,
importantTip = order.importantTip, importantTip = order.importantTip,
@ -213,7 +219,7 @@ object CommonMethod {
return return
} }
val inServicingOrder = it.find { it.isCurrent == true } var inServicingOrder = it.find { it.isCurrent == true }
val waitServiceOrders = val waitServiceOrders =
it.filter { it.isCurrent == false && it.taskState != "ACCEPT" } it.filter { it.isCurrent == false && it.taskState != "ACCEPT" }
@ -222,6 +228,75 @@ object CommonMethod {
return return
} }
//如果有离线任务,先走离线任务的逻辑
if (! RoomHelper.db?.offlineTaskDao()
?.getOfflineTaskFromTaskId(inServicingOrder.taskId ?: 0).isNullOrEmpty()
) {
LogUtil.print("queryOrderList", "走离线任务逻辑")
inServicingOrder = inServicingOrder.copy(taskState = RoomHelper.db?.orderDao()
?.getCurrentOrder()?.taskState)
if (GlobalData.currentOrder?.serviceTypeName != inServicingOrder.serviceTypeName) {
LogUtil.print("queryOrderList", "订单类型发生变化")
RoomHelper.db?.photoTemplateDao()
?.deleteOrderPhotoTemplateFromTaskId(taskId = inServicingOrder.taskId
?: 0)
fetchPhotoTemplate(orderInfo = inServicingOrder,
isNeedUpload = true,
success = {
GlobalData.currentOrder = inServicingOrder
OfflineManager.start(GlobalData.currentOrder?.taskId)
context?.let {
ReportFloatingManager.startService(it)
}
success(inServicingOrder, waitServiceOrders)
},
failed = {
GlobalData.currentOrder = inServicingOrder
OfflineManager.start(GlobalData.currentOrder?.taskId)
context?.let {
ReportFloatingManager.startService(it)
}
success(inServicingOrder, waitServiceOrders)
})
}
return
}
if (GlobalData.currentOrder?.serviceTypeName != inServicingOrder.serviceTypeName) {
LogUtil.print("queryOrderList", "订单类型发生变化")
RoomHelper.db?.photoTemplateDao()
?.deleteOrderPhotoTemplateFromTaskId(taskId = inServicingOrder.taskId
?: 0)
fetchPhotoTemplate(orderInfo = inServicingOrder,
isNeedUpload = true,
success = {
GlobalData.currentOrder = inServicingOrder
OfflineManager.start(GlobalData.currentOrder?.taskId)
context?.let {
ReportFloatingManager.startService(it)
}
success(inServicingOrder, waitServiceOrders)
},
failed = {
GlobalData.currentOrder = inServicingOrder
OfflineManager.start(GlobalData.currentOrder?.taskId)
context?.let {
ReportFloatingManager.startService(it)
}
success(inServicingOrder, waitServiceOrders)
})
return
}
GlobalData.currentOrder = inServicingOrder GlobalData.currentOrder = inServicingOrder
it.forEach { it.forEach {
if (RoomHelper.db?.orderDao() if (RoomHelper.db?.orderDao()
@ -259,6 +334,7 @@ object CommonMethod {
} }
fun fetchPhotoTemplate(orderInfo : OrderInfo?, fun fetchPhotoTemplate(orderInfo : OrderInfo?,
isNeedUpload : Boolean? = false,
success : () -> Unit = {}, success : () -> Unit = {},
failed : (String?) -> Unit = {}) { failed : (String?) -> Unit = {}) {
val photoTemplateRequest = PhotoTemplateRequest(orderInfo?.userOrderId) val photoTemplateRequest = PhotoTemplateRequest(orderInfo?.userOrderId)
@ -273,13 +349,16 @@ object CommonMethod {
return return
} }
if (isNeedUpload == false) {
val listData = RoomHelper.db?.photoTemplateDao() val listData = RoomHelper.db?.photoTemplateDao()
?.queryCurrentOrderHasTaskNode(orderInfo?.userOrderId ?: 0) ?.queryCurrentOrderHasTaskNode(orderInfo?.userOrderId ?: 0)
if (! listData.isNullOrEmpty()) { if (! listData.isNullOrEmpty()) {
LogUtil.print("queryPhotoTemplate", "模板已经存在==${listData.toJson()}") LogUtil.print("queryPhotoTemplate",
"模板已经存在==${listData.toJson()}")
success() success()
return return
} }
}
it.forEachIndexed { _, item -> it.forEachIndexed { _, item ->
val photoTemplateInfo = item.copy(userOrderId = orderInfo?.userOrderId, val photoTemplateInfo = item.copy(userOrderId = orderInfo?.userOrderId,

View File

@ -5,6 +5,7 @@ import android.provider.Settings
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.net.toUri import androidx.core.net.toUri
import com.alibaba.fastjson.JSONObject import com.alibaba.fastjson.JSONObject
import com.amap.api.maps.model.LatLng
import com.amap.api.services.core.LatLonPoint import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.GeocodeResult import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch import com.amap.api.services.geocoder.GeocodeSearch
@ -20,6 +21,7 @@ import com.za.bean.request.UpdateTaskBean
import com.za.bean.request.UpdateTaskRequest import com.za.bean.request.UpdateTaskRequest
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.log.LogUtil import com.za.common.log.LogUtil
import com.za.common.util.MapUtil
import com.za.ext.toJson import com.za.ext.toJson
import com.za.net.BaseObserver import com.za.net.BaseObserver
import com.za.net.CommonMethod import com.za.net.CommonMethod
@ -32,6 +34,7 @@ import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.File import java.io.File
import java.util.concurrent.TimeUnit
interface IOfflineListener { interface IOfflineListener {
fun start() fun start()
@ -42,6 +45,7 @@ interface IOfflineListener {
} }
object OfflineManager { object OfflineManager {
private const val TAG = "离线任务"
private var isUploading = false private var isUploading = false
private var uploadDispose : Disposable? = null private var uploadDispose : Disposable? = null
private var offlineListener : IOfflineListener? = null private var offlineListener : IOfflineListener? = null
@ -56,11 +60,14 @@ object OfflineManager {
if (checkOfflineIsComplete(taskId)) { if (checkOfflineIsComplete(taskId)) {
return return
} }
if (currentTaskId != null && taskId == currentTaskId && isUploading) { if (currentTaskId != null && taskId == currentTaskId && isUploading) {
LogUtil.print(TAG, "当前任务正在上传中")
return return
} }
if (! Settings.canDrawOverlays(GlobalData.application)) { if (! Settings.canDrawOverlays(GlobalData.application)) {
LogUtil.print(TAG, "开始失败:悬浮窗权限未开启")
openSystemAlertPermissionDialog() openSystemAlertPermissionDialog()
return return
} }
@ -68,13 +75,13 @@ object OfflineManager {
stop() stop()
OfflineService.addListener() OfflineService.addListener()
offlineListener?.start() offlineListener?.start()
uploadDispose = Observable.interval(0, 5, java.util.concurrent.TimeUnit.SECONDS) uploadDispose = Observable.interval(0, 5, TimeUnit.SECONDS).subscribeOn(Schedulers.io())
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe { .observeOn(AndroidSchedulers.mainThread()).subscribe {
if (! isUploading) { if (! isUploading) {
val list = val list =
RoomHelper.db?.offlineTaskDao()?.getOfflineTaskFromTaskId(taskId ?: 0) RoomHelper.db?.offlineTaskDao()?.getOfflineTaskFromTaskId(taskId ?: 0)
if (list.isNullOrEmpty()) { if (list.isNullOrEmpty()) {
LogUtil.print("离线任务", "离线任务为空!!") LogUtil.print(TAG, "离线任务为空!!")
stop() stop()
ToastUtils.showLong("离线任务上传完成") ToastUtils.showLong("离线任务上传完成")
return@subscribe return@subscribe
@ -117,6 +124,7 @@ object OfflineManager {
private fun uploadTask(offlineUpdateTaskBean : OfflineUpdateTaskBean) { private fun uploadTask(offlineUpdateTaskBean : OfflineUpdateTaskBean) {
isUploading = true isUploading = true
LogUtil.print(TAG, "开始 uploadTask=${offlineUpdateTaskBean.toJson()}")
val updateTaskRequest = UpdateTaskRequest(type = offlineUpdateTaskBean.type, val updateTaskRequest = UpdateTaskRequest(type = offlineUpdateTaskBean.type,
taskId = offlineUpdateTaskBean.taskId, taskId = offlineUpdateTaskBean.taskId,
userId = offlineUpdateTaskBean.userId, userId = offlineUpdateTaskBean.userId,
@ -139,25 +147,24 @@ object OfflineManager {
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
isUploading = false isUploading = false
offlineListener?.uploadSuccess() offlineListener?.uploadSuccess()
LogUtil.print("离线任务", "success=$it request=${updateTaskRequest.toJson()}") LogUtil.print(TAG, "uploadTask 完成")
} }
override fun doFailure(code : Int, msg : String?) { override fun doFailure(code : Int, msg : String?) {
isUploading = false isUploading = false
offlineListener?.uploadFailure(msg) offlineListener?.uploadFailure(msg)
LogUtil.print("离线任务", LogUtil.print(TAG, "uploadTask 失败 $code $msg")
"uploadTask failed==${offlineUpdateTaskBean.toJson()}")
} }
}) })
} }
private fun uploadOrderImage(offlineUpdateTaskBean : OfflineUpdateTaskBean) { private fun uploadOrderImage(offlineUpdateTaskBean : OfflineUpdateTaskBean) {
isUploading = true isUploading = true
LogUtil.print(TAG, "开始 uploadOrderImage=${offlineUpdateTaskBean.toJson()}")
var file = File(offlineUpdateTaskBean.photoLocalWaterMarkerPath ?: "") var file = File(offlineUpdateTaskBean.photoLocalWaterMarkerPath ?: "")
if (! file.exists()) { if (! file.exists()) {
offlineListener?.uploadFailure("图片未找到!") offlineListener?.uploadFailure("图片未找到!")
LogUtil.print("离线任务 uploadOrderImage", LogUtil.print(TAG, "uploadOrderImage 失败,图片未找到")
"uploadTask failed==${offlineUpdateTaskBean.toJson()}")
RoomHelper.db?.offlineTaskDao() RoomHelper.db?.offlineTaskDao()
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
isUploading = false isUploading = false
@ -165,31 +172,33 @@ object OfflineManager {
} }
if (offlineUpdateTaskBean.imageAddress.isNullOrBlank() && (offlineUpdateTaskBean.imageLat != null && offlineUpdateTaskBean.imageLat != 0f && offlineUpdateTaskBean.imageLng != null && offlineUpdateTaskBean.imageLng != 0f)) { if (offlineUpdateTaskBean.imageAddress.isNullOrBlank() && (offlineUpdateTaskBean.imageLat != null && offlineUpdateTaskBean.imageLat != 0f && offlineUpdateTaskBean.imageLng != null && offlineUpdateTaskBean.imageLng != 0f)) {
geoCoder(offlineUpdateTaskBean.imageLat.toDouble(), val address = MapUtil.getAddressFromLocation(context = ActivityUtils.getTopActivity(),
offlineUpdateTaskBean.imageLng.toDouble(), latLng = LatLng(offlineUpdateTaskBean.imageLat.toDouble(),
success = { it -> offlineUpdateTaskBean.imageLng.toDouble()))
val photoMarkerInfo = PhotoMarkerInfo(offlineUpdateTaskBean.needWater, val photoMarkerInfo = PhotoMarkerInfo(offlineUpdateTaskBean.needWater,
needShowPhoneBrand = offlineUpdateTaskBean.needPhoneBrand, needShowPhoneBrand = offlineUpdateTaskBean.needPhoneBrand,
path = offlineUpdateTaskBean.photoLocalWaterMarkerPath, path = offlineUpdateTaskBean.photoLocalWaterMarkerPath,
from = "(离线)", from = "(离线)",
lat = offlineUpdateTaskBean.imageLat.toDouble(), lat = offlineUpdateTaskBean.imageLat.toDouble(),
lng = offlineUpdateTaskBean.imageLng.toDouble(), lng = offlineUpdateTaskBean.imageLng.toDouble(),
address = it, address = address,
time = offlineUpdateTaskBean.time, time = offlineUpdateTaskBean.time,
driverName = GlobalData.driverInfoBean?.userName, driverName = GlobalData.driverInfoBean?.userName,
taskCode = offlineUpdateTaskBean.taskCode) taskCode = offlineUpdateTaskBean.taskCode)
val offlineTemp = offlineUpdateTaskBean.copy(imageAddress = it) val offlineTemp = offlineUpdateTaskBean.copy(imageAddress = address)
file = File(PhotoMarkerManager.addPhotoMarker(ActivityUtils.getTopActivity(), file = File(PhotoMarkerManager.addPhotoMarker(ActivityUtils.getTopActivity(),
photoMarkerInfo)) photoMarkerInfo))
CommonMethod.uploadImage(file = file, success = { CommonMethod.uploadImage(file = file, success = {
val item = RoomHelper.db?.offlineTaskDao() val item =
?.getRecentOfflineTask(offlineTemp.taskId ?: 0)?.get(0) RoomHelper.db?.offlineTaskDao()?.getRecentOfflineTask(offlineTemp.taskId ?: 0)
?.get(0)
if (item == null) { if (item == null) {
offlineListener?.uploadFailure(it) offlineListener?.uploadFailure(it)
isUploading = false isUploading = false
LogUtil.print(TAG, "离线图片要出插入的节点 未找到")
return@uploadImage return@uploadImage
} }
LogUtil.print("离线任务 getRecentOfflineTask", "success=${item.toJson()}") LogUtil.print(TAG, "离线图片要出插入的节点 =${item.toJson()}")
val list = item.templatePhotoInfoList?.toMutableList() val list = item.templatePhotoInfoList?.toMutableList()
val jsonObject = JSONObject() val jsonObject = JSONObject()
jsonObject["realTakePhotoTime"] = offlineTemp.realTakePhotoTime ?: "" jsonObject["realTakePhotoTime"] = offlineTemp.realTakePhotoTime ?: ""
@ -197,26 +206,21 @@ object OfflineManager {
jsonObject["path"] = it jsonObject["path"] = it
jsonObject["time"] = offlineTemp.time jsonObject["time"] = offlineTemp.time
jsonObject["lat"] = offlineTemp.imageLat jsonObject["lat"] = offlineTemp.imageLat
jsonObject["sort"] = offlineTemp.sort
jsonObject["lng"] = offlineTemp.imageLng jsonObject["lng"] = offlineTemp.imageLng
jsonObject["address"] = offlineTemp.imageAddress jsonObject["address"] = offlineTemp.imageAddress
list?.set(offlineTemp.imageIndex ?: 0, jsonObject.toJSONString()) list?.set(offlineTemp.imageIndex ?: 0, jsonObject.toJSONString())
val temp = item.copy(templatePhotoInfoList = list?.toList()) val temp = item.copy(templatePhotoInfoList = list?.toList())
RoomHelper.db?.offlineTaskDao()?.update(temp) RoomHelper.db?.offlineTaskDao()?.update(temp)
RoomHelper.db?.offlineTaskDao() RoomHelper.db?.offlineTaskDao()?.deleteOfflineTaskFromId(offlineTemp.primaryId ?: 0)
?.deleteOfflineTaskFromId(offlineTemp.primaryId ?: 0)
isUploading = false isUploading = false
offlineListener?.uploadSuccess() offlineListener?.uploadSuccess()
LogUtil.print("离线任务 逆地理 uploadOrderImage", LogUtil.print(TAG, "离线 uploadOrderImage 成功")
"success=$it request=${offlineUpdateTaskBean.toJson()}")
}, failed = { }, failed = {
RoomHelper.db?.offlineTaskDao()?.update(offlineTemp) RoomHelper.db?.offlineTaskDao()?.update(offlineTemp)
offlineListener?.uploadFailure(it) offlineListener?.uploadFailure(it)
isUploading = false isUploading = false
}) LogUtil.print(TAG, "uploadOrderImage 失败$it")
},
failed = {
offlineListener?.uploadFailure(it)
isUploading = false
}) })
} else { } else {
CommonMethod.uploadImage(file = file, success = { CommonMethod.uploadImage(file = file, success = {
@ -225,14 +229,16 @@ object OfflineManager {
if (item == null) { if (item == null) {
offlineListener?.uploadFailure(it) offlineListener?.uploadFailure(it)
isUploading = false isUploading = false
LogUtil.print(TAG, "离线图片要出插入的节点 未找到")
return@uploadImage return@uploadImage
} }
LogUtil.print("离线任务 getRecentOfflineTask", "success=${item.toJson()}") LogUtil.print(TAG, "离线图片要出插入的节点 =${item.toJson()}")
val list = item.templatePhotoInfoList?.toMutableList() val list = item.templatePhotoInfoList?.toMutableList()
val jsonObject = JSONObject() val jsonObject = JSONObject()
jsonObject["realTakePhotoTime"] = offlineUpdateTaskBean.realTakePhotoTime ?: "" jsonObject["realTakePhotoTime"] = offlineUpdateTaskBean.realTakePhotoTime ?: ""
jsonObject["photoSource"] = offlineUpdateTaskBean.photoSource jsonObject["photoSource"] = offlineUpdateTaskBean.photoSource
jsonObject["path"] = it jsonObject["path"] = it
jsonObject["sort"] = offlineUpdateTaskBean.sort
jsonObject["time"] = offlineUpdateTaskBean.time jsonObject["time"] = offlineUpdateTaskBean.time
jsonObject["lat"] = offlineUpdateTaskBean.imageLat jsonObject["lat"] = offlineUpdateTaskBean.imageLat
jsonObject["lng"] = offlineUpdateTaskBean.imageLng jsonObject["lng"] = offlineUpdateTaskBean.imageLng
@ -245,22 +251,22 @@ object OfflineManager {
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
isUploading = false isUploading = false
offlineListener?.uploadSuccess() offlineListener?.uploadSuccess()
LogUtil.print("离线任务 uploadOrderImage", LogUtil.print(TAG, "离线 uploadOrderImage 成功")
"success=$it request=${offlineUpdateTaskBean.toJson()}")
}, failed = { }, failed = {
offlineListener?.uploadFailure(it) offlineListener?.uploadFailure(it)
isUploading = false isUploading = false
LogUtil.print(TAG, "uploadOrderImage 图片上传失败$it")
}) })
} }
} }
private fun uploadEleDamageImage(offlineUpdateTaskBean : OfflineUpdateTaskBean) { private fun uploadEleDamageImage(offlineUpdateTaskBean : OfflineUpdateTaskBean) {
isUploading = true isUploading = true
LogUtil.print(TAG, "开始 uploadEleDamageImage${offlineUpdateTaskBean.toJson()}")
val file = File(offlineUpdateTaskBean.imageLocalPath ?: "") val file = File(offlineUpdateTaskBean.imageLocalPath ?: "")
if (! file.exists()) { if (! file.exists()) {
offlineListener?.uploadFailure("图片未找到!") offlineListener?.uploadFailure("图片未找到!")
LogUtil.print("离线任务 uploadEleDamageImage", LogUtil.print(TAG, "uploadEleDamageImage 图片未找到")
"failed==${offlineUpdateTaskBean.toJson()}")
RoomHelper.db?.offlineTaskDao() RoomHelper.db?.offlineTaskDao()
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
isUploading = false isUploading = false
@ -274,7 +280,7 @@ object OfflineManager {
isUploading = false isUploading = false
return@uploadImage return@uploadImage
} }
LogUtil.print("离线任务 getRecentOfflineEle", "success=${item.toJson()}") LogUtil.print(TAG, "最近的节点${item.toJson()}")
val list = item.damageFileList?.toMutableList() val list = item.damageFileList?.toMutableList()
list?.set(offlineUpdateTaskBean.imageIndex ?: 0, it) list?.set(offlineUpdateTaskBean.imageIndex ?: 0, it)
val temp = item.copy(templatePhotoInfoList = list?.toList()) val temp = item.copy(templatePhotoInfoList = list?.toList())
@ -284,15 +290,16 @@ object OfflineManager {
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
isUploading = false isUploading = false
offlineListener?.uploadSuccess() offlineListener?.uploadSuccess()
LogUtil.print("离线任务 uploadEleDamageImage", LogUtil.print(TAG, "uploadEleDamageImage 成功")
"success=$it request=${offlineUpdateTaskBean.toJson()}")
}, failed = { }, failed = {
offlineListener?.uploadFailure(it) offlineListener?.uploadFailure(it)
isUploading = false isUploading = false
LogUtil.print(TAG, "uploadEleDamageImage 失败$it")
}) })
} }
private fun uploadEleWorkOrder(offlineUpdateTaskBean : OfflineUpdateTaskBean) { private fun uploadEleWorkOrder(offlineUpdateTaskBean : OfflineUpdateTaskBean) {
LogUtil.print(TAG, "开始 uploadEleWorkOrder ${offlineUpdateTaskBean.toJson()}")
val saveEleOrderRequest = SaveEleOrderRequest(state = offlineUpdateTaskBean.eleState, val saveEleOrderRequest = SaveEleOrderRequest(state = offlineUpdateTaskBean.eleState,
userOrderId = offlineUpdateTaskBean.userOrderId, userOrderId = offlineUpdateTaskBean.userOrderId,
taskOrderId = offlineUpdateTaskBean.taskId, taskOrderId = offlineUpdateTaskBean.taskId,
@ -308,7 +315,7 @@ object OfflineManager {
lng = offlineUpdateTaskBean.eleLng, lng = offlineUpdateTaskBean.eleLng,
tyreNumber = offlineUpdateTaskBean.tyreNumber, tyreNumber = offlineUpdateTaskBean.tyreNumber,
isFinish = offlineUpdateTaskBean.isFinish) isFinish = offlineUpdateTaskBean.isFinish)
LogUtil.print("离线数据 eleSign_check request", saveEleOrderRequest.toJson() ?: "") LogUtil.print(TAG, "uploadEleWorkOrder request=${saveEleOrderRequest.toJson()}")
RetrofitHelper.getDefaultService().saveElectronOrder(saveEleOrderRequest) RetrofitHelper.getDefaultService().saveElectronOrder(saveEleOrderRequest)
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BaseObserver<String>() { .subscribe(object : BaseObserver<String>() {
@ -317,27 +324,27 @@ object OfflineManager {
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
isUploading = false isUploading = false
offlineListener?.uploadSuccess() offlineListener?.uploadSuccess()
LogUtil.print("离线任务 uploadEleWorkOrder", LogUtil.print(TAG, "uploadEleWorkOrder 成功")
"success=$it request=${offlineUpdateTaskBean.toJson()}")
} }
override fun doFailure(code : Int, msg : String?) { override fun doFailure(code : Int, msg : String?) {
offlineListener?.uploadFailure(msg) offlineListener?.uploadFailure(msg)
isUploading = false isUploading = false
LogUtil.print(TAG, "uploadEleWorkOrder 失败$code $msg")
} }
}) })
} }
private fun uploadCustomerSignImage(offlineUpdateTaskBean : OfflineUpdateTaskBean) { private fun uploadCustomerSignImage(offlineUpdateTaskBean : OfflineUpdateTaskBean) {
isUploading = true isUploading = true
LogUtil.print(TAG, "开始 uploadCustomerSignImage${offlineUpdateTaskBean.toJson()}")
val file = File(offlineUpdateTaskBean.imageLocalPath ?: "") val file = File(offlineUpdateTaskBean.imageLocalPath ?: "")
if (! file.exists()) { if (! file.exists()) {
offlineListener?.uploadFailure("图片未找到!") offlineListener?.uploadFailure("图片未找到!")
LogUtil.print("离线任务 uploadCustomerSignImage",
"failed==${offlineUpdateTaskBean.toJson()}")
RoomHelper.db?.offlineTaskDao() RoomHelper.db?.offlineTaskDao()
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
isUploading = false isUploading = false
LogUtil.print(TAG, "uploadCustomerSignImage 图片未找到")
return return
} }
CommonMethod.uploadImage(file = file, success = { it -> CommonMethod.uploadImage(file = file, success = { it ->
@ -348,8 +355,7 @@ object OfflineManager {
isUploading = false isUploading = false
return@uploadImage return@uploadImage
} }
LogUtil.print("离线任务 uploadCustomerSignImage getRecentOfflineEle", LogUtil.print(TAG, "uploadCustomerSignImage 要插入的接单=${item.toJson()}")
"success=${item.toJson()}")
RoomHelper.db?.offlineTaskDao()?.update(item.copy(customerSignPath = it)) RoomHelper.db?.offlineTaskDao()?.update(item.copy(customerSignPath = it))
RoomHelper.db?.offlineTaskDao() RoomHelper.db?.offlineTaskDao()
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
@ -359,21 +365,21 @@ object OfflineManager {
} }
isUploading = false isUploading = false
offlineListener?.uploadSuccess() offlineListener?.uploadSuccess()
LogUtil.print("离线任务 uploadCustomerSignImage", LogUtil.print(TAG, "uploadCustomerSignImage 成功")
"success=$it request=${offlineUpdateTaskBean.toJson()}")
}, failed = { }, failed = {
offlineListener?.uploadFailure(it) offlineListener?.uploadFailure(it)
isUploading = false isUploading = false
LogUtil.print(TAG, "uploadCustomerSignImage 失败$it")
}) })
} }
private fun uploadAcceptPeopleSignImage(offlineUpdateTaskBean : OfflineUpdateTaskBean) { private fun uploadAcceptPeopleSignImage(offlineUpdateTaskBean : OfflineUpdateTaskBean) {
isUploading = true isUploading = true
LogUtil.print(TAG, "开始 uploadAcceptPeopleSignImage ${offlineUpdateTaskBean.toJson()}")
val file = File(offlineUpdateTaskBean.imageLocalPath ?: "") val file = File(offlineUpdateTaskBean.imageLocalPath ?: "")
if (! file.exists()) { if (! file.exists()) {
offlineListener?.uploadFailure("图片未找到!") offlineListener?.uploadFailure("图片未找到!")
LogUtil.print("离线任务 uploadCustomerSignImage", LogUtil.print(TAG, "uploadAcceptPeopleSignImage 图片未找到")
"failed==${offlineUpdateTaskBean.toJson()}")
RoomHelper.db?.offlineTaskDao() RoomHelper.db?.offlineTaskDao()
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
isUploading = false isUploading = false
@ -387,8 +393,7 @@ object OfflineManager {
isUploading = false isUploading = false
return@uploadImage return@uploadImage
} }
LogUtil.print("离线任务 uploadAcceptPeopleSignImage getRecentOfflineEle", LogUtil.print(TAG, "uploadAcceptPeopleSignImage 要插入的接单=${item.toJson()}")
"success=${item.toJson()}")
RoomHelper.db?.offlineTaskDao()?.update(item.copy(recipientSignPath = it)) RoomHelper.db?.offlineTaskDao()?.update(item.copy(recipientSignPath = it))
RoomHelper.db?.offlineTaskDao() RoomHelper.db?.offlineTaskDao()
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
@ -398,24 +403,24 @@ object OfflineManager {
} }
isUploading = false isUploading = false
offlineListener?.uploadSuccess() offlineListener?.uploadSuccess()
LogUtil.print("离线任务 uploadAcceptPeopleSignImage", LogUtil.print(TAG, "uploadAcceptPeopleSignImage 成功")
"success=$it request=${offlineUpdateTaskBean.toJson()}")
}, failed = { }, failed = {
offlineListener?.uploadFailure(it) offlineListener?.uploadFailure(it)
isUploading = false isUploading = false
LogUtil.print(TAG, "uploadAcceptPeopleSignImage 逆地理失败")
}) })
} }
private fun uploadServicePeopleSignImage(offlineUpdateTaskBean : OfflineUpdateTaskBean) { private fun uploadServicePeopleSignImage(offlineUpdateTaskBean : OfflineUpdateTaskBean) {
isUploading = true isUploading = true
LogUtil.print(TAG, "开始 uploadServicePeopleSignImage${offlineUpdateTaskBean.toJson()}")
val file = File(offlineUpdateTaskBean.imageLocalPath ?: "") val file = File(offlineUpdateTaskBean.imageLocalPath ?: "")
if (! file.exists()) { if (! file.exists()) {
offlineListener?.uploadFailure("图片未找到!") offlineListener?.uploadFailure("图片未找到!")
LogUtil.print("离线任务 uploadCustomerSignImage",
"failed==${offlineUpdateTaskBean.toJson()}")
RoomHelper.db?.offlineTaskDao() RoomHelper.db?.offlineTaskDao()
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
isUploading = false isUploading = false
LogUtil.print(TAG, "uploadServicePeopleSignImage 图片未找到")
return return
} }
CommonMethod.uploadImage(file = file, success = { it -> CommonMethod.uploadImage(file = file, success = { it ->
@ -426,8 +431,7 @@ object OfflineManager {
isUploading = false isUploading = false
return@uploadImage return@uploadImage
} }
LogUtil.print("离线任务 uploadCustomerSignImage getRecentOfflineEle", LogUtil.print(TAG, "uploadServicePeopleSignImage 要插入的接单=${item.toJson()}")
"success=${item.toJson()}")
RoomHelper.db?.offlineTaskDao()?.update(item.copy(waitstaffSignPath = it)) RoomHelper.db?.offlineTaskDao()?.update(item.copy(waitstaffSignPath = it))
RoomHelper.db?.offlineTaskDao() RoomHelper.db?.offlineTaskDao()
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
@ -438,22 +442,24 @@ object OfflineManager {
isUploading = false isUploading = false
offlineListener?.uploadSuccess() offlineListener?.uploadSuccess()
LogUtil.print("离线任务 uploadCustomerSignImage", LogUtil.print(TAG, "uploadServicePeopleSignImage 成功")
"success=$it request=${offlineUpdateTaskBean.toJson()}")
}, failed = { }, failed = {
offlineListener?.uploadFailure(it) offlineListener?.uploadFailure(it)
isUploading = false isUploading = false
LogUtil.print(TAG, "uploadAcceptPeopleSignImage 失败$it")
}) })
} }
private fun taskFinish(offlineUpdateTaskBean : OfflineUpdateTaskBean) { private fun taskFinish(offlineUpdateTaskBean : OfflineUpdateTaskBean) {
isUploading = true isUploading = true
LogUtil.print(TAG, "开始 taskFinish ${offlineUpdateTaskBean.toJson()}")
val taskFinishRequest = TaskFinishRequest( val taskFinishRequest = TaskFinishRequest(
operateTime = offlineUpdateTaskBean.operateTime?.toLong(), operateTime = offlineUpdateTaskBean.operateTime?.toLong(),
lat = offlineUpdateTaskBean.updateTaskLat, lat = offlineUpdateTaskBean.updateTaskLat,
userOrderId = offlineUpdateTaskBean.userOrderId, userOrderId = offlineUpdateTaskBean.userOrderId,
lng = offlineUpdateTaskBean.updateTaskLng, lng = offlineUpdateTaskBean.updateTaskLng,
) )
LogUtil.print(TAG, "taskFinish request ${taskFinishRequest.toJson()}")
RetrofitHelper.getDefaultService().taskFinish(taskFinishRequest) RetrofitHelper.getDefaultService().taskFinish(taskFinishRequest)
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BaseObserver<TaskFinishResponse>() { .subscribe(object : BaseObserver<TaskFinishResponse>() {
@ -462,14 +468,13 @@ object OfflineManager {
?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0) ?.deleteOfflineTaskFromId(offlineUpdateTaskBean.primaryId ?: 0)
isUploading = false isUploading = false
offlineListener?.uploadSuccess() offlineListener?.uploadSuccess()
LogUtil.print("离线任务", "success=$it request=${taskFinishRequest.toJson()}") LogUtil.print(TAG, "taskFinish 成功")
} }
override fun doFailure(code : Int, msg : String?) { override fun doFailure(code : Int, msg : String?) {
isUploading = false isUploading = false
offlineListener?.uploadFailure(msg) offlineListener?.uploadFailure(msg)
LogUtil.print("离线任务", LogUtil.print(TAG, "taskFinish 失败 $code $msg")
"uploadTask failed==${offlineUpdateTaskBean.toJson()}")
} }
}) })
} }
@ -505,7 +510,7 @@ private fun geoCoder(lat : Double,
regeocodeResult.regeocodeAddress.formatAddress) regeocodeResult.regeocodeAddress.formatAddress)
} else { } else {
failed("地址获取失败") failed("地址获取失败")
LogUtil.print("singleLocation 逆地理失败 ", regeocodeResult.toString()) LogUtil.print("离线任务 逆地理失败 ", regeocodeResult.toString())
} }
} }

View File

@ -12,12 +12,13 @@ import android.os.Looper
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import cn.jiguang.api.utils.JCollectionAuth import cn.jiguang.api.utils.JCollectionAuth
import cn.jpush.android.api.JPushInterface import cn.jpush.android.api.JPushInterface
import com.blankj.utilcode.util.ProcessUtils
import com.google.gson.Gson import com.google.gson.Gson
import com.za.base.Const
import com.za.bean.JpushBean import com.za.bean.JpushBean
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.log.LogUtil import com.za.common.log.LogUtil
import com.za.common.util.DeviceUtil import com.za.common.util.DeviceUtil
import com.za.ext.toJson
import com.za.service.mqtt.MyMqttClient import com.za.service.mqtt.MyMqttClient
import com.za.servicing.R import com.za.servicing.R
@ -25,6 +26,7 @@ interface PushListener {
fun newOrderMsg(jpushBean : JpushBean) fun newOrderMsg(jpushBean : JpushBean)
fun giveUpOrder(jpushBean : JpushBean) fun giveUpOrder(jpushBean : JpushBean)
fun revokeOrder(jpushBean : JpushBean) fun revokeOrder(jpushBean : JpushBean)
fun modifyOrder(jpushBean : JpushBean)
fun reDispatchOrder(jpushBean : JpushBean) fun reDispatchOrder(jpushBean : JpushBean)
fun broadcast(string : String) fun broadcast(string : String)
fun importantTip(jpushBean : JpushBean) fun importantTip(jpushBean : JpushBean)
@ -38,15 +40,30 @@ object ServiceManager {
private var lastJPushBean : LastJPushBean? = null private var lastJPushBean : LastJPushBean? = null
private const val DUPLICATE_MSG_THRESHOLD = 3000L // 3秒 private const val DUPLICATE_MSG_THRESHOLD = 3000L // 3秒
private const val TAG = "ServiceManager"
// Initialize SharedPreferences // Initialize SharedPreferences
fun initialize(context : Context) { fun initialize(context : Context) {
LogUtil.print("ServiceManager", "Initializing ServiceManager") LogUtil.print(TAG, "Initializing ServiceManager")
jpushRegister(context) jpushRegister(context)
MyMqttClient.initialize(deviceId = DeviceUtil.getAndroidId(context)) MyMqttClient.initialize(deviceId = DeviceUtil.getAndroidId(context))
setupPushMessageReceiver(context) setupPushMessageReceiver(context)
} }
fun sendMessageToMainProcess(context : Context,
type : String,
message : String) { // 使用广播将消息发送到主进程
val intent = Intent(Const.PushMessageType.ACTION_MAIN.takeIf { GlobalData.isMaster }
?: Const.PushMessageType.ACTION_SDK)
intent.setPackage(context.packageName)
intent.putExtra("type", type)
intent.putExtra("message", message)
context.sendBroadcast(intent)
LogUtil.print(TAG, "发送消息到主进程: $type")
}
private fun setupPushMessageReceiver(context : Context) { // 注册推送消息接收器 private fun setupPushMessageReceiver(context : Context) { // 注册推送消息接收器
registerPushListener(object : PushListener { registerPushListener(object : PushListener {
override fun broadcast(msg : String) { override fun broadcast(msg : String) {
@ -74,30 +91,25 @@ object ServiceManager {
override fun revokeOrder(jpushBean : JpushBean) { override fun revokeOrder(jpushBean : JpushBean) {
sendMessageToMainProcess(context = context, "revoke", Gson().toJson(jpushBean)) sendMessageToMainProcess(context = context, "revoke", Gson().toJson(jpushBean))
} }
override fun modifyOrder(jpushBean : JpushBean) {
sendMessageToMainProcess(context = context, "modify", Gson().toJson(jpushBean))
}
}) })
} }
private fun sendMessageToMainProcess(context : Context,
type : String,
message : String) { // 使用广播将消息发送到主进程
val intent = Intent("com.za.rescue.dealer.PUSH_MESSAGE".takeIf { GlobalData.isMaster }
?: ZdPushServiceReceive.RECEIVE_ACTION)
intent.setPackage(context.packageName)
intent.putExtra("type", type)
intent.putExtra("message", message)
context.sendBroadcast(intent)
LogUtil.print("KeepAliveService", "发送消息到主进程: $type")
}
// Register JPush // Register JPush
private fun jpushRegister(context : Context) { private fun jpushRegister(context : Context) {
try { try {
JCollectionAuth.setAuth(context, true)
JPushInterface.setDebugMode(false) JPushInterface.setDebugMode(false)
JCollectionAuth.setAuth(context, true)
JPushInterface.init(context) JPushInterface.init(context)
LogUtil.print("ServiceManager", "JPush initialized successfully") JCollectionAuth.setAuth(context, true)
JCollectionAuth.enableAutoWakeup(context, true)
LogUtil.print(TAG, "JPush initialized successfully")
} catch (e : Exception) { } catch (e : Exception) {
LogUtil.print("ServiceManager", "JPush initialization failed: ${e.message}") LogUtil.print(TAG, "JPush initialization failed: ${e.message}")
} }
} }
@ -105,18 +117,16 @@ object ServiceManager {
fun registerPushListener(listener : PushListener) { fun registerPushListener(listener : PushListener) {
Handler(Looper.getMainLooper()).post { Handler(Looper.getMainLooper()).post {
this.pushListener = listener this.pushListener = listener
LogUtil.print("ServiceManager", "Registered push listener: ${this.pushListener}") LogUtil.print(TAG, "registerPushListener")
} }
} }
// Handle incoming push messages // Handle incoming push messages
fun handlerPushMsg(msg : String) { fun handlerPushMsg(msg : String) {
LogUtil.print("handlerPushMsg", "Received push message: $msg") LogUtil.print(TAG, "handlerPushMsg Received push message: $msg") // 优化后的重复消息判断
// 优化后的重复消息判断
lastJPushBean?.let { lastJPushBean?.let {
if (System.currentTimeMillis() - it.time < DUPLICATE_MSG_THRESHOLD && it.msg == msg) { if (System.currentTimeMillis() - it.time < DUPLICATE_MSG_THRESHOLD && it.msg == msg) {
LogUtil.print("MessageHandler", "Duplicate message detected (hash: ${msg})") LogUtil.print(TAG, "handlerPushMsg Duplicate message detected (hash: ${msg})")
return return
} }
} }
@ -133,6 +143,7 @@ object ServiceManager {
when (jpushOrderInfoBean.pushType) { when (jpushOrderInfoBean.pushType) {
0 -> newOrderMsg(jpushOrderInfoBean) 0 -> newOrderMsg(jpushOrderInfoBean)
1 -> handleTypeOneMessage(jpushOrderInfoBean) 1 -> handleTypeOneMessage(jpushOrderInfoBean)
2 -> handlerModifyOrderMessage(jpushOrderInfoBean)
3 -> importantTip(jpushOrderInfoBean) 3 -> importantTip(jpushOrderInfoBean)
else -> LogUtil.print("JpushMessage", else -> LogUtil.print("JpushMessage",
"Unknown push type: ${jpushOrderInfoBean.pushType}") "Unknown push type: ${jpushOrderInfoBean.pushType}")
@ -141,7 +152,7 @@ object ServiceManager {
if (msg.startsWith("broadcast:")) { if (msg.startsWith("broadcast:")) {
handleBroadcast(msg) handleBroadcast(msg)
} }
LogUtil.print("JpushMessage", "Error handling message: ${e.message}") LogUtil.print(TAG, "handlerPushMsg Error handling message: ${e.message}")
} }
} }
@ -151,9 +162,9 @@ object ServiceManager {
val content = msg.substring(10) val content = msg.substring(10)
pushListener?.broadcast(content) pushListener?.broadcast(content)
sendNotification(GlobalData.application, content) sendNotification(GlobalData.application, content)
LogUtil.print("JpushMessage", "Broadcast content: $content") LogUtil.print(TAG, "handleBroadcast Broadcast content: $content")
} catch (e : Exception) { } catch (e : Exception) {
LogUtil.print("JpushMessage", "Broadcast failed: ${e.message}") LogUtil.print(TAG, "handleBroadcast Broadcast failed: ${e.message}")
} }
} }
@ -167,15 +178,23 @@ object ServiceManager {
} }
} }
private fun handlerModifyOrderMessage(jpushOrderBean : JpushBean) {
try {
LogUtil.print(TAG, "handlerModifyOrderMessage ${jpushOrderBean.toJson()}")
this.pushListener?.modifyOrder(jpushOrderBean)
} catch (e : Exception) {
LogUtil.print(TAG,
"handlerModifyOrderMessage Failed to handle new order message: ${e.message}")
}
}
// Handle new order messages // Handle new order messages
private fun newOrderMsg(jpushOrderBean : JpushBean) { private fun newOrderMsg(jpushOrderBean : JpushBean) {
try { try {
LogUtil.print("JpushMessage", LogUtil.print(TAG, "newOrderMsg ${jpushOrderBean.toJson()}")
"Handling new order message: ${this.pushListener} ${this.pushListener?.javaClass?.simpleName}")
LogUtil.print("isManThread", " ${ProcessUtils.getCurrentProcessName()}")
this.pushListener?.newOrderMsg(jpushOrderBean) this.pushListener?.newOrderMsg(jpushOrderBean)
} catch (e : Exception) { } catch (e : Exception) {
LogUtil.print("JpushMessage", "Failed to handle new order message: ${e.message}") LogUtil.print(TAG, "newOrderMsg Failed to handle new order message: ${e.message}")
} }
} }
@ -205,9 +224,9 @@ object ServiceManager {
try { try {
JPushInterface.stopPush(context) // Stop JPush JPushInterface.stopPush(context) // Stop JPush
MyMqttClient.disconnect() // Disconnect MQTT MyMqttClient.disconnect() // Disconnect MQTT
LogUtil.print("ServiceManager", "Disconnected from JPush and MQTT successfully") LogUtil.print(TAG, "disconnect")
} catch (e : Exception) { } catch (e : Exception) {
LogUtil.print("ServiceManager", "Error during disconnection: ${e.message}") LogUtil.print(TAG, "disconnect Failed ${e.message}")
} }
} }
} }

View File

@ -17,6 +17,7 @@ import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.AppUtils import com.blankj.utilcode.util.AppUtils
import com.google.gson.Gson import com.google.gson.Gson
import com.za.base.BaseActivityLifecycleCallbacks import com.za.base.BaseActivityLifecycleCallbacks
import com.za.base.Const
import com.za.bean.JpushBean import com.za.bean.JpushBean
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.log.LogUtil import com.za.common.log.LogUtil
@ -27,7 +28,6 @@ import com.za.ui.view.CommonDialogFragment
class ZdPushServiceReceive : BroadcastReceiver() { class ZdPushServiceReceive : BroadcastReceiver() {
companion object { companion object {
const val RECEIVE_ACTION = "com.zd.servicing.PUSH_MESSAGE"
private const val GIVE_UP_TYPE_NORMAL = 1 private const val GIVE_UP_TYPE_NORMAL = 1
private const val DIALOG_TAG_GIVE_UP = "giveUp" private const val DIALOG_TAG_GIVE_UP = "giveUp"
} }
@ -35,7 +35,7 @@ class ZdPushServiceReceive : BroadcastReceiver() {
private fun handlerMessage(context : Context?, intent : Intent?) { private fun handlerMessage(context : Context?, intent : Intent?) {
val activity = context ?: ActivityUtils.getTopActivity() val activity = context ?: ActivityUtils.getTopActivity()
activity as? AppCompatActivity activity as? AppCompatActivity
if (intent?.action == RECEIVE_ACTION) { if (intent?.action == Const.PushMessageType.ACTION_SDK) {
val type = intent.getStringExtra("type") ?: return val type = intent.getStringExtra("type") ?: return
val message = intent.getStringExtra("message") ?: return val message = intent.getStringExtra("message") ?: return
if (ActivityUtils.getTopActivity() == null) { if (ActivityUtils.getTopActivity() == null) {
@ -43,9 +43,9 @@ class ZdPushServiceReceive : BroadcastReceiver() {
} }
LogUtil.print("PushActivityLifecycleCallbacks", "收到来自远程进程的消息: $type") LogUtil.print("PushActivityLifecycleCallbacks", "收到来自远程进程的消息: $type")
when (type) { when (type) {
"broadcast" -> handleBroadcast("broadcast:$message") Const.PushMessageType.BROADCAST -> handleBroadcast("broadcast:$message")
"giveUp" -> { Const.PushMessageType.GIVE_UP -> {
try { try {
val jpushBean = Gson().fromJson(message, JpushBean::class.java) val jpushBean = Gson().fromJson(message, JpushBean::class.java)
val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity() val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()
@ -57,8 +57,9 @@ class ZdPushServiceReceive : BroadcastReceiver() {
LogUtil.print("PushActivityLifecycleCallbacks", LogUtil.print("PushActivityLifecycleCallbacks",
"处理订单放弃消息失败: ${e.message}") "处理订单放弃消息失败: ${e.message}")
} }
} // 处理其他类型的消息... }
"importantTip" -> {
Const.PushMessageType.IMPORTANT_TIP -> {
try { try {
val jpushBean = Gson().fromJson(message, JpushBean::class.java) val jpushBean = Gson().fromJson(message, JpushBean::class.java)
val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity() val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()
@ -72,7 +73,7 @@ class ZdPushServiceReceive : BroadcastReceiver() {
} }
} }
"reDispatch" -> { Const.PushMessageType.RE_DISPATCH -> {
try { try {
val jpushBean = Gson().fromJson(message, JpushBean::class.java) val jpushBean = Gson().fromJson(message, JpushBean::class.java)
val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity() val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()
@ -86,7 +87,20 @@ class ZdPushServiceReceive : BroadcastReceiver() {
} }
} }
"revoke" -> { Const.PushMessageType.MODIFY -> {
try {
val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()
?: ActivityUtils.getTopActivity()
if (activity is AppCompatActivity) {
handlerModifyOrder()
}
} catch (e : Exception) {
LogUtil.print("PushActivityLifecycleCallbacks",
"处理重要提示消息失败: ${e.message}")
}
}
Const.PushMessageType.REVOKE -> {
try { try {
val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity() val activity = BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()
?: ActivityUtils.getTopActivity() ?: ActivityUtils.getTopActivity()
@ -134,7 +148,7 @@ class ZdPushServiceReceive : BroadcastReceiver() {
private fun handleReDispatchOrder(activity : Activity, jpushBean : JpushBean) { private fun handleReDispatchOrder(activity : Activity, jpushBean : JpushBean) {
playNotificationSound(activity) playNotificationSound(activity)
BaseActivityLifecycleCallbacks.Companion.getCurrentActivity()?.let { currentActivity -> BaseActivityLifecycleCallbacks.getCurrentActivity()?.let { currentActivity ->
if (currentActivity is AppCompatActivity) { if (currentActivity is AppCompatActivity) {
AlertDialog.Builder(currentActivity).setTitle("订单重新派发") AlertDialog.Builder(currentActivity).setTitle("订单重新派发")
.setMessage(buildReDispatchMessage(jpushBean)).setCancelable(false) .setMessage(buildReDispatchMessage(jpushBean)).setCancelable(false)
@ -154,6 +168,21 @@ class ZdPushServiceReceive : BroadcastReceiver() {
.show() .show()
} }
private fun handlerModifyOrder() {
SpeechManager.speech("订单信息被修改")
BaseActivityLifecycleCallbacks.getCurrentActivity()?.let { currentActivity ->
if (currentActivity is AppCompatActivity) {
AlertDialog.Builder(currentActivity).setTitle("订单重新派发")
.setMessage("订单信息被修改,请返回首页更新订单信息!")
.setPositiveButton("确定") { dialog, _ ->
dialog.dismiss()
currentActivity.finish()
}.show()
}
}
}
// Handle broadcast messages // Handle broadcast messages
private fun handleBroadcast(msg : String) { private fun handleBroadcast(msg : String) {
try { try {

View File

@ -25,11 +25,6 @@ import com.za.common.log.LogUtil
import com.za.ext.toJson import com.za.ext.toJson
import com.za.net.CommonMethod import com.za.net.CommonMethod
import com.za.service.mqtt.MyMqttClient import com.za.service.mqtt.MyMqttClient
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.Locale import java.util.Locale
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.cos import kotlin.math.cos
@ -44,42 +39,11 @@ object ZdLocationManager : AMapLocationListener {
private var option : AMapLocationClientOption? = null private var option : AMapLocationClientOption? = null
private const val NORMA_INTERVAL_TIME = 20000L // GPS上传时间间隔 private const val NORMA_INTERVAL_TIME = 20000L // GPS上传时间间隔
private const val LOCATION_GET_DURATION = 5 * 1000L private const val LOCATION_GET_DURATION = 10 * 1000L
private const val LOCATION_CACHE_DURATION = 60 * 1000L // 1分钟的缓存时间
private const val LOCATION_SEARCH_RADIUS = 200f private const val LOCATION_SEARCH_RADIUS = 200f
private const val DEFAULT_TIMEOUT = 30000L private const val DEFAULT_TIMEOUT = 30000L
private var globalLocation : AMapLocation? = null var lastSingleLocationTime = System.currentTimeMillis()
private var lastSingleLocationTime = 0L
private var locationUploadJob : Job? = null
private fun startUploadLocationJob() {
stopUploadLocationJob()
locationUploadJob = CoroutineScope(Dispatchers.IO).launch {
while (true) {
delay(NORMA_INTERVAL_TIME)
if (GlobalData.currentLocation == null) {
LogUtil.print(TAG, "定位上传失败: location is null")
continue
}
if (System.currentTimeMillis() - (GlobalData.currentLocation?.time
?: System.currentTimeMillis()) > 1000 * 60 * 2
) {
LogUtil.print(TAG, "定位上传失败: location is old")
continue
}
uploadGpsRequest(GlobalData.currentLocation !!)
}
}
}
private fun stopUploadLocationJob() {
locationUploadJob?.cancel()
locationUploadJob = null
}
fun init(context : Context) { fun init(context : Context) {
this.context = context.applicationContext this.context = context.applicationContext
@ -103,16 +67,17 @@ object ZdLocationManager : AMapLocationListener {
} }
private fun createLocationOption(isOnceLocation : Boolean = false, private fun createLocationOption(isOnceLocation : Boolean = false,
isGpsFirst : Boolean = false, isGpsFirst : Boolean = false) : AMapLocationClientOption =
isNeedAddress : Boolean = false) : AMapLocationClientOption =
AMapLocationClientOption().apply { AMapLocationClientOption().apply {
locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy this.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
interval = LOCATION_GET_DURATION this.interval = NORMA_INTERVAL_TIME
isWifiScan = true this.isWifiScan = true
isLocationCacheEnable = false this.httpTimeOut = DEFAULT_TIMEOUT
httpTimeOut = DEFAULT_TIMEOUT this.isLocationCacheEnable = false
isMockEnable = false this.httpTimeOut = 6000
this.isNeedAddress = isNeedAddress this.gpsFirstTimeout = 6000
this.isMockEnable = false
this.isNeedAddress = false
this.isOnceLocation = isOnceLocation this.isOnceLocation = isOnceLocation
this.isGpsFirst = isGpsFirst this.isGpsFirst = isGpsFirst
} }
@ -124,7 +89,6 @@ object ZdLocationManager : AMapLocationListener {
} }
try { try {
aMapLocationClient?.startLocation() aMapLocationClient?.startLocation()
startUploadLocationJob()
LogUtil.print(TAG, "持续定位开启成功") LogUtil.print(TAG, "持续定位开启成功")
} catch (e : Exception) { } catch (e : Exception) {
LogUtil.print(TAG, "持续定位开启失败: ${e.message}") LogUtil.print(TAG, "持续定位开启失败: ${e.message}")
@ -137,7 +101,6 @@ object ZdLocationManager : AMapLocationListener {
aMapLocationClient?.onDestroy() aMapLocationClient?.onDestroy()
aMapLocationClient?.unRegisterLocationListener(this) aMapLocationClient?.unRegisterLocationListener(this)
aMapLocationClient = null aMapLocationClient = null
stopUploadLocationJob()
LogUtil.print(TAG, "关闭持续定位成功") LogUtil.print(TAG, "关闭持续定位成功")
} catch (e : Exception) { } catch (e : Exception) {
LogUtil.print(TAG, "关闭持续定位失败: ${e.message}") LogUtil.print(TAG, "关闭持续定位失败: ${e.message}")
@ -149,13 +112,13 @@ object ZdLocationManager : AMapLocationListener {
LogUtil.print(TAG, "定位获取失败: location is null") LogUtil.print(TAG, "定位获取失败: location is null")
return return
} }
if (location.errorCode != 0) { if (location.errorCode != 0) {
LogUtil.print(TAG, "定位获取失败: ${location.errorInfo}") LogUtil.print(TAG, "定位获取失败: ${location.errorInfo}")
return return
} }
GlobalData.currentLocation = location GlobalData.currentLocation = location
lastSingleLocationTime = System.currentTimeMillis()
uploadGpsRequest(location)
LogUtil.print(TAG, LogUtil.print(TAG,
"定位获取成功: lat=${location.latitude} lng=${location.longitude} time=${location.time} speed=${location.speed} ") // uploadGpsRequest(location) "定位获取成功: lat=${location.latitude} lng=${location.longitude} time=${location.time} speed=${location.speed} ") // uploadGpsRequest(location)
} }
@ -181,132 +144,151 @@ object ZdLocationManager : AMapLocationListener {
} }
CommonMethod.uploadGps(uploadGpsRequest, success = { CommonMethod.uploadGps(uploadGpsRequest, success = {
LogUtil.print(TAG, "定位上传成功: ${uploadGpsRequest.toJson()}") LogUtil.print(TAG, "定位上传成功: ${uploadGpsRequest.toJson()}")
MyMqttClient.publishMessage() // if (ActivityUtils.getTopActivity()==null) { MyMqttClient.publishMessage()
// AppUtils.launchApp(AppUtils.getAppPackageName())
// }
}, failed = { error -> }, failed = { error ->
LogUtil.print(TAG, "定位上传失败: $error $uploadGpsRequest") LogUtil.print(TAG, "定位上传失败: $error $uploadGpsRequest")
MyMqttClient.publishMessage() MyMqttClient.publishMessage()
}) })
} }
fun getSingleLocation(success : (AMapLocation) -> Unit, fun getSingleLocation(success : (AMapLocation) -> Unit,
failed : (String) -> Unit, failed : (String) -> Unit,
isNeedAddress : Boolean = false) { isNeedAddress : Boolean? = false) {
globalLocation?.let { location -> NetworkUtils.isAvailableByDnsAsync {
if (System.currentTimeMillis() - lastSingleLocationTime < LOCATION_CACHE_DURATION && (! isNeedAddress || ! location.address.isNullOrBlank())) { LogUtil.print(TAG, "getSingleLocation isAvailableByDnsAsync=$it")
LogUtil.print(TAG, "返回缓存位置") if (it) {
success(location) LogUtil.print(TAG, "is NeedAddress=$isNeedAddress")
GlobalData.currentLocation = location doGetSingleLocation(isNeedAddress = isNeedAddress, success = {
success(it)
}, failed = { failed(it) })
return@isAvailableByDnsAsync
}
doGetSingleLocationGps(success = {
success(it)
}, failed = { failed(it) }, isNeedAddress = isNeedAddress)
}
}
fun doGetSingleLocation(success : (AMapLocation) -> Unit,
failed : (String) -> Unit,
isNeedAddress : Boolean? = false) {
LogUtil.print(TAG, "doGetSingleLocation")
if (GlobalData.currentLocation != null && (System.currentTimeMillis()
.minus(GlobalData.currentLocation?.time ?: 0) < 60 * 1000)
) {
if (isNeedAddress == false) {
success(GlobalData.currentLocation !!)
return return
} }
} }
NetworkUtils.isAvailableAsync { isNetworkAvailable -> val option = if (isNeedAddress == true) {
LogUtil.print(TAG, "网络状态: $isNetworkAvailable") AMapLocationClientOption().apply {
if (isNetworkAvailable) { this.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
doGetSingleLocationOnline(isNeedAddress = isNeedAddress, this.isNeedAddress = true
success = success, this.isWifiScan = true
failed = failed) this.isLocationCacheEnable = true
this.httpTimeOut = 5000
this.isMockEnable = false
this.isOnceLocation = true
}
} else { } else {
doGetSingleLocationGpsFromOriginal(success, AMapLocationClientOption().apply {
failed) // doGetSingleLocationGps(success, failed) this.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
} this.isNeedAddress = false
this.isWifiScan = true
this.isLocationCacheEnable = true
this.httpTimeOut = 5000
this.isMockEnable = false
this.isOnceLocation = true
} }
} }
private fun createSingleLocationClient(isNeedAddress : Boolean, AMapLocationClient.updatePrivacyShow(context, true, true)
isGpsFirst : Boolean, AMapLocationClient.updatePrivacyAgree(context, true)
locationCallback : (AMapLocation?) -> Unit) : AMapLocationClient? { val aMapLocationClient = AMapLocationClient(context)
return context?.let { ctx -> aMapLocationClient.setLocationOption(option)
try { aMapLocationClient.setLocationListener {
AMapLocationClient(ctx).apply { if (it != null && it.errorCode == 0) {
setLocationOption(createLocationOption(isOnceLocation = true, LogUtil.print("单次定位结果", "$it")
isGpsFirst = isGpsFirst,
isNeedAddress = isNeedAddress))
setLocationListener { location ->
locationCallback(location)
stopLocation()
onDestroy()
}
}
} catch (e : Exception) {
LogUtil.print(TAG, "创建单次定位客户端失败: ${e.message}")
null
}
}
}
private fun handleLocationResult(location : AMapLocation?, if (it.address.isNullOrBlank() && isNeedAddress == true) {
isNeedAddress : Boolean, geoCoder(it, { aMapLocation ->
success : (AMapLocation) -> Unit, it.time = System.currentTimeMillis()
failed : (String) -> Unit) { GlobalData.currentLocation = it
if (location == null) { success(aMapLocation)
failed("Location is null") }, { error -> failed(error) })
LogUtil.print(TAG, "单次定位失败: location is null")
return
}
if (location.errorCode != 0) {
failed("Error code: ${location.errorCode}, ${location.errorInfo}")
LogUtil.print(TAG,
"单次定位失败: errorCode=${location.errorCode}, errorInfo=${location.locationDetail}")
return
}
if (isNeedAddress && location.address.isNullOrBlank()) {
nativeGeoCoder(location = location, success = { success(it) }, failed = { error ->
LogUtil.print(TAG, "逆地理编码失败: $error")
failed("位置获取失败")
})
} else { } else {
updateGlobalLocation(location) GlobalData.currentLocation = it
success(location) success(it)
} }
} else {
failed(it.errorInfo)
LogUtil.print("单次定位失败",
"errorCode====${it.errorCode} errorInfo==${it.locationDetail}")
}
aMapLocationClient.stopLocation()
aMapLocationClient.onDestroy()
}
aMapLocationClient.startLocation()
} }
private fun updateGlobalLocation(location : AMapLocation) { private fun updateGlobalLocation(location : AMapLocation) {
globalLocation = location
lastSingleLocationTime = System.currentTimeMillis() lastSingleLocationTime = System.currentTimeMillis()
GlobalData.currentLocation = location GlobalData.currentLocation = location
LogUtil.print(TAG, "单次定位结果: $location") LogUtil.print(TAG, "单次定位结果: $location")
} }
private fun doGetSingleLocationOnline(isNeedAddress : Boolean,
success : (AMapLocation) -> Unit,
failed : (String) -> Unit) {
val locationClient = createSingleLocationClient(isNeedAddress = isNeedAddress,
isGpsFirst = false) { location ->
handleLocationResult(location, isNeedAddress, success, failed)
} ?: run {
failed("Failed to create location client")
return
}
try {
locationClient.startLocation()
} catch (e : Exception) {
LogUtil.print(TAG, "启动单次定位失败: ${e.message}")
failed("Failed to start location: ${e.message}")
}
}
private fun doGetSingleLocationGps(success : (AMapLocation) -> Unit, private fun doGetSingleLocationGps(success : (AMapLocation) -> Unit,
failed : (String) -> Unit) { failed : (String) -> Unit,
val locationClient = isNeedAddress : Boolean? = false) {
createSingleLocationClient(isNeedAddress = false, isGpsFirst = true) { location -> LogUtil.print(TAG, "doGetSingleLocationGps")
handleLocationResult(location, false, success, failed) if (GlobalData.currentLocation != null && (System.currentTimeMillis()
} ?: run { .minus(GlobalData.currentLocation?.time ?: 0) < 60 * 1000)
failed("Failed to create location client") ) {
if (isNeedAddress == false) {
success(GlobalData.currentLocation !!)
return return
} }
try {
locationClient.startLocation()
} catch (e : Exception) {
LogUtil.print(TAG, "启动GPS定位失败: ${e.message}")
failed("Failed to start GPS location: ${e.message}")
} }
val option = AMapLocationClientOption().apply {
this.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
this.isWifiScan = true
this.isGpsFirst = true
this.isLocationCacheEnable = true
this.httpTimeOut = 5000
this.gpsFirstTimeout = 5000
this.isMockEnable = false
this.isOnceLocation = true
}
AMapLocationClient.updatePrivacyShow(context, true, true)
AMapLocationClient.updatePrivacyAgree(context, true)
val aMapLocationClient = AMapLocationClient(context)
aMapLocationClient.setLocationOption(option)
aMapLocationClient.setLocationListener {
if (it != null && it.errorCode == 0) {
LogUtil.print("单次定位结果", "$it")
if (it.address.isNullOrBlank() && isNeedAddress == true) {
geoCoder(it, { aMapLocation ->
it.time = System.currentTimeMillis()
GlobalData.currentLocation = it
success(aMapLocation)
}, { error -> failed(error) })
} else {
GlobalData.currentLocation = it
success(it)
}
} else {
failed(it.errorInfo)
LogUtil.print("单次定位失败",
"errorCode====${it.errorCode} errorInfo==${it.locationDetail}")
}
aMapLocationClient.stopLocation()
aMapLocationClient.onDestroy()
}
aMapLocationClient.startLocation()
} }
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
@ -320,10 +302,12 @@ object ZdLocationManager : AMapLocationListener {
locationManager) locationManager)
) { ) {
failed("Location service is disabled") failed("Location service is disabled")
LogUtil.print(TAG, "原生定位 Location service is disabled")
return@let return@let
} }
val lastKnownLocation = val lastKnownLocation =
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
LogUtil.print(TAG, "lastKnownLocation== ${lastKnownLocation?.toJson() ?: "null"}")
if (lastKnownLocation != null) { if (lastKnownLocation != null) {
val gcj02Location = val gcj02Location =
wgs84ToGcj02(lastKnownLocation.latitude, lastKnownLocation.longitude) wgs84ToGcj02(lastKnownLocation.latitude, lastKnownLocation.longitude)
@ -352,8 +336,10 @@ object ZdLocationManager : AMapLocationListener {
private fun requestSingleGpsUpdate(locationManager : LocationManager, private fun requestSingleGpsUpdate(locationManager : LocationManager,
success : (AMapLocation) -> Unit, success : (AMapLocation) -> Unit,
failed : (String) -> Unit) { failed : (String) -> Unit) {
LogUtil.print(TAG, "requestSingleGpsUpdate")
val locationListener = object : android.location.LocationListener { val locationListener = object : android.location.LocationListener {
override fun onLocationChanged(location : Location) { override fun onLocationChanged(location : Location) {
LogUtil.print(TAG, "requestSingleGpsUpdate onLocationChanged==${location.toJson()}")
locationManager.removeUpdates(this) locationManager.removeUpdates(this)
val gcj02 = wgs84ToGcj02(location.latitude, location.longitude) val gcj02 = wgs84ToGcj02(location.latitude, location.longitude)
val aMapLocation = AMapLocation("").apply { val aMapLocation = AMapLocation("").apply {
@ -402,6 +388,7 @@ object ZdLocationManager : AMapLocationListener {
geocoderSearch.setOnGeocodeSearchListener(object : OnGeocodeSearchListener { geocoderSearch.setOnGeocodeSearchListener(object : OnGeocodeSearchListener {
override fun onRegeocodeSearched(result : RegeocodeResult?, rCode : Int) { override fun onRegeocodeSearched(result : RegeocodeResult?, rCode : Int) {
if (result == null || rCode != 1000) { if (result == null || rCode != 1000) {
LogUtil.print(TAG, "Geocoding failed: $rCode")
failed("Geocode search failed: $rCode") failed("Geocode search failed: $rCode")
return return
} }
@ -409,6 +396,7 @@ object ZdLocationManager : AMapLocationListener {
val address = result.regeocodeAddress?.formatAddress val address = result.regeocodeAddress?.formatAddress
if (! address.isNullOrBlank()) { if (! address.isNullOrBlank()) {
aMapLocation.address = address aMapLocation.address = address
LogUtil.print(TAG, "Geocoding success: $address")
success(aMapLocation) success(aMapLocation)
} else { } else {
failed("Empty address returned") failed("Empty address returned")

View File

@ -2,11 +2,13 @@ package com.za.signature;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
@ -16,6 +18,8 @@ import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Toast; import android.widget.Toast;
import androidx.activity.compose.ManagedActivityResultLauncher;
import androidx.activity.result.ActivityResult;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -178,7 +182,9 @@ public class GridPaintActivity extends BaseActivity implements View.OnClickListe
mEditView.setMaxWidth(maxWidth * 2 / 3); mEditView.setMaxWidth(maxWidth * 2 / 3);
} }
mEditView.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize); mEditView.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
mEditView.setLineHeight(DisplayUtil.dip2px(this, fontSize)); mEditView.setLineHeight(DisplayUtil.dip2px(this, fontSize));
}
mEditView.setHorizontallyScrolling(false); mEditView.setHorizontallyScrolling(false);
mEditView.requestFocus(); mEditView.requestFocus();
if (bgColor != Color.TRANSPARENT) { if (bgColor != Color.TRANSPARENT) {
@ -303,7 +309,7 @@ public class GridPaintActivity extends BaseActivity implements View.OnClickListe
mHandler.obtainMessage(MSG_SAVE_FAILED).sendToTarget(); mHandler.obtainMessage(MSG_SAVE_FAILED).sendToTarget();
} }
bm.recycle(); bm.recycle();
bm=null; bm = null;
}).start(); }).start();
} }
@ -439,4 +445,14 @@ public class GridPaintActivity extends BaseActivity implements View.OnClickListe
} }
public static void goGridPaintActivity(ManagedActivityResultLauncher<Intent, ActivityResult> launcher, Context context) {
Intent intent = new Intent(context, GridPaintActivity.class);
intent.putExtra("background", Color.WHITE);
intent.putExtra("crop", false);
intent.putExtra("fontSize", 60); //手写字体大小
intent.putExtra("format", PenConfig.FORMAT_PNG);
intent.putExtra("lineLength", 10); //每行显示字数(超出屏幕支持横向滚动)
launcher.launch(intent);
}
} }

View File

@ -101,7 +101,7 @@ public class HandWriteEditView extends AppCompatEditText {
return null; return null;
} }
SpannableString mSpan = new SpannableString("1"); SpannableString mSpan = new SpannableString("1");
mSpan.setSpan(new ImageSpan(getContext(), srcBitmap, ImageSpan.ALIGN_BASELINE), mSpan.length() - 1, mSpan.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); mSpan.setSpan(new ImageSpan(getContext(), srcBitmap, ImageSpan.ALIGN_BOTTOM), mSpan.length() - 1, mSpan.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Editable editable = getText(); Editable editable = getText();
//获取光标所在位置 //获取光标所在位置

View File

@ -38,6 +38,7 @@ import com.za.bean.request.DriverFaceCompareRequest
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.log.LogUtil import com.za.common.log.LogUtil
import com.za.common.speech.SpeechManager import com.za.common.speech.SpeechManager
import com.za.common.util.ImageUtil
import com.za.net.BaseObserver import com.za.net.BaseObserver
import com.za.net.CommonMethod import com.za.net.CommonMethod
import com.za.net.RetrofitHelper import com.za.net.RetrofitHelper
@ -57,7 +58,7 @@ class ServicePeopleRealActivity : AppCompatActivity() {
private var isActivityActive = true private var isActivityActive = true
private var currentStep = 0 private var currentStep = 0
private val steps = listOf( "请向左转头", "请向右转头", "请保持面部居中") private val steps = listOf("请向左转头", "请向右转头", "请保持面部居中")
private var isStepCompleted = false private var isStepCompleted = false
private lateinit var viewFinder : PreviewView private lateinit var viewFinder : PreviewView
@ -110,10 +111,10 @@ class ServicePeopleRealActivity : AppCompatActivity() {
retryButton = findViewById(R.id.retryButton) retryButton = findViewById(R.id.retryButton)
confirmButton = findViewById(R.id.confirmButton) confirmButton = findViewById(R.id.confirmButton)
// lowLightWarning = findViewById(R.id.lowLightWarning) // 保存原始亮度 // lowLightWarning = findViewById(R.id.lowLightWarning) // 保存原始亮度
// originalBrightness = window.attributes.screenBrightness.let { // originalBrightness = window.attributes.screenBrightness.let {
// if (it != - 1f) it else 0.5f // if (it != - 1f) it else 0.5f
// }.toInt() // }.toInt()
} }
private fun setupClickListeners() { private fun setupClickListeners() {
@ -242,8 +243,7 @@ class ServicePeopleRealActivity : AppCompatActivity() {
lifecycleCameraController.setImageAnalysisAnalyzer(ContextCompat.getMainExecutor(this@ServicePeopleRealActivity), lifecycleCameraController.setImageAnalysisAnalyzer(ContextCompat.getMainExecutor(this@ServicePeopleRealActivity),
FaceAnalyzer(faceListener = { FaceAnalyzer(faceListener = {
handleFaceDetection(it) handleFaceDetection(it)
}, lightListener = { }, lightListener = { // handleLowLightCallback(it)
// handleLowLightCallback(it)
})) }))
} }
@ -343,7 +343,8 @@ class ServicePeopleRealActivity : AppCompatActivity() {
private fun returnPhotoResult() { private fun returnPhotoResult() {
avatarBitmap?.let { bitmap -> // 保存图片到临时文件 avatarBitmap?.let { bitmap -> // 保存图片到临时文件
val file = ImageUtils.save2Album(bitmap, CompressFormat.JPEG, 100) val comprossBitmap = ImageUtil.scaleBitmapWithMatrix(bitmap, 1280)
val file = ImageUtils.save2Album(comprossBitmap, CompressFormat.JPEG, 100)
if (file?.exists() == true) { // 创建返回结果 if (file?.exists() == true) { // 创建返回结果
val resultIntent = Intent() val resultIntent = Intent()
resultIntent.putExtra("path", file.absolutePath) resultIntent.putExtra("path", file.absolutePath)

View File

@ -291,21 +291,7 @@ class ZdCameraXActivity : AppCompatActivity() {
if (imageCapture == null) { if (imageCapture == null) {
ToastUtils.showShort("相机打开失败") ToastUtils.showShort("相机打开失败")
finish() finish()
} // val filename = TimeUtils.date2String(Date(), "yyyyMMddHHmmss") }
// val contentValues = ContentValues()
// contentValues.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, filename)
// contentValues.put(MediaStore.Images.ImageColumns.MIME_TYPE, "image/jpeg")
// contentValues.put(MediaStore.Images.ImageColumns.DATE_TAKEN, System.currentTimeMillis())
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// contentValues.put(MediaStore.Images.ImageColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
// } else {
// ImageUtils.save2Album()
// contentValues.put(MediaStore.Images.ImageColumns.DATA, getTakePictureParentPath() + File.separator + filename + ".jpg")
// }
//
// val outputOptions = ImageCapture.OutputFileOptions.Builder(contentResolver,
// MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues).build()
// Create time stamped name and MediaStore entry. // Create time stamped name and MediaStore entry.
val filename = SimpleDateFormat("yyyyMMddHHmmss", val filename = SimpleDateFormat("yyyyMMddHHmmss",
@ -325,7 +311,6 @@ class ZdCameraXActivity : AppCompatActivity() {
takePhoto?.startAnimation() takePhoto?.startAnimation()
imageCapture?.takePicture(outputOptions, imageCapture?.takePicture(outputOptions,
ContextCompat.getMainExecutor(this), ContextCompat.getMainExecutor(this),
object : ImageCapture.OnImageSavedCallback { object : ImageCapture.OnImageSavedCallback {
@ -347,6 +332,7 @@ class ZdCameraXActivity : AppCompatActivity() {
exifInterface.saveAttributes() exifInterface.saveAttributes()
takePhoto?.cancelAnimation() takePhoto?.cancelAnimation()
groupPreview?.visibility = View.VISIBLE groupPreview?.visibility = View.VISIBLE
if (! this@ZdCameraXActivity.isFinishing) { if (! this@ZdCameraXActivity.isFinishing) {
Glide.with(this@ZdCameraXActivity).load(outputFileResults.savedUri) Glide.with(this@ZdCameraXActivity).load(outputFileResults.savedUri)
.into(ivPreview) .into(ivPreview)
@ -372,6 +358,7 @@ class ZdCameraXActivity : AppCompatActivity() {
imageCapture = imageCapture =
ImageCapture.Builder().setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY) ImageCapture.Builder().setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.build() .build()
val cameraProviderFuture = ProcessCameraProvider.getInstance(this) val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({ cameraProviderFuture.addListener({
try { try {

View File

@ -157,6 +157,7 @@ private fun CommonH5Screen(url : String,
var progress by remember { mutableFloatStateOf(0f) } var progress by remember { mutableFloatStateOf(0f) }
var isError by remember { mutableStateOf(false) } var isError by remember { mutableStateOf(false) }
var webView by remember { mutableStateOf<WebView?>(null) } var webView by remember { mutableStateOf<WebView?>(null) }
var title by remember { mutableStateOf(title) }
BackHandler(enabled = isCanBack || webView?.canGoBack() == true) { BackHandler(enabled = isCanBack || webView?.canGoBack() == true) {
handleBackPress(context, webView) handleBackPress(context, webView)
@ -178,6 +179,9 @@ private fun CommonH5Screen(url : String,
onError = { _, desc -> onError = { _, desc ->
isError = true isError = true
ToastUtils.showLong("加载失败:$desc") ToastUtils.showLong("加载失败:$desc")
},
onReceiveTitle = {
title = it ?: ""
}) })
webView = this webView = this
onWebViewCreated(this) onWebViewCreated(this)
@ -197,11 +201,17 @@ private fun CommonH5Screen(url : String,
private fun setupWebViewClients(webView : WebView, private fun setupWebViewClients(webView : WebView,
onProgressChanged : (Int) -> Unit, onProgressChanged : (Int) -> Unit,
onReceiveTitle : (String?) -> Unit,
onError : (Int, String?) -> Unit) { onError : (Int, String?) -> Unit) {
webView.webChromeClient = object : WebChromeClient() { webView.webChromeClient = object : WebChromeClient() {
override fun onProgressChanged(view : WebView?, newProgress : Int) { override fun onProgressChanged(view : WebView?, newProgress : Int) {
onProgressChanged(newProgress) onProgressChanged(newProgress)
} }
override fun onReceivedTitle(view : WebView?, title : String?) {
onReceiveTitle(title)
LogUtil.print("H5Activity title", "$title")
}
} }
webView.webViewClient = object : WebViewClient() { webView.webViewClient = object : WebViewClient() {

View File

@ -48,6 +48,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.blankj.utilcode.util.ActivityUtils import com.blankj.utilcode.util.ActivityUtils
import com.google.gson.Gson import com.google.gson.Gson
import com.za.base.BaseActivity import com.za.base.BaseActivity
import com.za.base.Const
import com.za.base.theme.bgColor import com.za.base.theme.bgColor
import com.za.base.view.CommonButton import com.za.base.view.CommonButton
import com.za.base.view.EmptyView import com.za.base.view.EmptyView
@ -64,7 +65,7 @@ import com.za.ext.finish
import com.za.ext.goStatusPage import com.za.ext.goStatusPage
import com.za.service.PushListener import com.za.service.PushListener
import com.za.service.ServiceManager import com.za.service.ServiceManager
import com.za.service.ZdPushServiceReceive import com.za.service.ServiceManager.registerPushListener
import com.za.service.location.ZdLocationManager import com.za.service.location.ZdLocationManager
import com.za.servicing.R import com.za.servicing.R
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -84,43 +85,49 @@ class ServicingMainActivity : BaseActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
setupPushMessageReceiver() setupPushMessageReceiver(this)
} }
private fun setupPushMessageReceiver() { // 注册推送消息接收器 private fun setupPushMessageReceiver(context : Context) { // 注册推送消息接收器
ServiceManager.registerPushListener(object : PushListener { registerPushListener(object : PushListener {
override fun broadcast(msg : String) { override fun broadcast(msg : String) {
sendMessageToMainProcess("broadcast", msg) sendMessageToMainProcess(context = context, "broadcast", msg)
} }
override fun giveUpOrder(jpushBean : JpushBean) { override fun giveUpOrder(jpushBean : JpushBean) {
sendMessageToMainProcess("giveUp", Gson().toJson(jpushBean)) sendMessageToMainProcess(context = context, "giveUp", Gson().toJson(jpushBean))
} }
override fun importantTip(jpushBean : JpushBean) { override fun importantTip(jpushBean : JpushBean) {
sendMessageToMainProcess("importantTip", Gson().toJson(jpushBean)) sendMessageToMainProcess(context = context,
"importantTip",
Gson().toJson(jpushBean))
} }
override fun newOrderMsg(jpushBean : JpushBean) { override fun newOrderMsg(jpushBean : JpushBean) {
sendMessageToMainProcess("newOrder", Gson().toJson(jpushBean)) sendMessageToMainProcess(context = context, "newOrder", Gson().toJson(jpushBean))
} }
override fun reDispatchOrder(jpushBean : JpushBean) { override fun reDispatchOrder(jpushBean : JpushBean) {
sendMessageToMainProcess("reDispatch", Gson().toJson(jpushBean)) sendMessageToMainProcess(context = context, "reDispatch", Gson().toJson(jpushBean))
} }
override fun revokeOrder(jpushBean : JpushBean) { override fun revokeOrder(jpushBean : JpushBean) {
sendMessageToMainProcess("revoke", Gson().toJson(jpushBean)) sendMessageToMainProcess(context = context, "revoke", Gson().toJson(jpushBean))
} }
}) })
} }
private fun sendMessageToMainProcess(type : String, message : String) { // 使用广播将消息发送到主进程 fun sendMessageToMainProcess(context : Context,
val intent = Intent(ZdPushServiceReceive.RECEIVE_ACTION).setPackage(packageName) type : String,
message : String) { // 使用广播将消息发送到主进程
val intent = Intent(Const.PushMessageType.ACTION_MAIN.takeIf { GlobalData.isMaster }
?: Const.PushMessageType.ACTION_SDK)
intent.setPackage(context.packageName)
intent.putExtra("type", type) intent.putExtra("type", type)
intent.putExtra("message", message) intent.putExtra("message", message)
sendBroadcast(intent) context.sendBroadcast(intent)
LogUtil.print(TAG, "发送消息到主进程: $type") LogUtil.print("KeepAliveService", "发送消息到主进程: $type")
} }
companion object { companion object {

View File

@ -18,6 +18,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
@ -36,7 +37,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@ -55,6 +58,7 @@ import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.LatLngBounds
import com.amap.api.maps.model.MarkerOptions import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.PolylineOptions import com.amap.api.maps.model.PolylineOptions
import com.blankj.utilcode.util.ConvertUtils
import com.za.base.BaseActivity import com.za.base.BaseActivity
import com.za.base.view.CommonDialog import com.za.base.view.CommonDialog
import com.za.base.view.HeadViewNotBack import com.za.base.view.HeadViewNotBack
@ -104,11 +108,6 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
val uiState = vm.uiState.collectAsStateWithLifecycle() val uiState = vm.uiState.collectAsStateWithLifecycle()
val mapView = remember { MapView(context) } val mapView = remember { MapView(context) }
// 将状态提升到 Composable 层级
val lastRoutePoints = remember { mutableStateOf<List<LatLng>?>(null) }
val lastMarkers = remember { mutableStateOf<ArrayList<MarkerOptions>?>(null) }
val lastCurrentLocation = remember { mutableStateOf<LatLng?>(null) }
val bottomSheetState = rememberStandardBottomSheetState(initialValue = SheetValue.Expanded) val bottomSheetState = rememberStandardBottomSheetState(initialValue = SheetValue.Expanded)
val scaffoldState = rememberBottomSheetScaffoldState(bottomSheetState = bottomSheetState) val scaffoldState = rememberBottomSheetScaffoldState(bottomSheetState = bottomSheetState)
@ -126,7 +125,6 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
Lifecycle.Event.ON_PAUSE -> mapView.onPause() Lifecycle.Event.ON_PAUSE -> mapView.onPause()
Lifecycle.Event.ON_DESTROY -> { Lifecycle.Event.ON_DESTROY -> {
mapView.onDestroy() mapView.onDestroy()
vm.dispatch(NewOrderVm.Action.UpdateState(uiState.value.copy(remainingTime = 0)))
} }
else -> {} else -> {}
@ -140,7 +138,6 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
onDispose { onDispose {
try { try {
lifecycleOwner.lifecycle.removeObserver(observer) lifecycleOwner.lifecycle.removeObserver(observer)
vm.dispatch(NewOrderVm.Action.UpdateState(uiState.value.copy(remainingTime = 0)))
} catch (e : Exception) { } catch (e : Exception) {
LogUtil.print("DisposableEffect", "清理资源异常: ${e.message}") LogUtil.print("DisposableEffect", "清理资源异常: ${e.message}")
} }
@ -171,31 +168,30 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
} }
if (uiState.value.refuseSuccess == true) { if (uiState.value.refuseSuccess == true) {
vm.updateState(uiState.value.copy(refuseSuccess = false))
context.finish() context.finish()
} }
// 添加超时对话框 if (uiState.value.refuelOrderDialog == true) {
if (uiState.value.showTimeoutDialog) { CommonDialog(title = "请确认是否拒绝该任务!",
CommonDialog(cancelText = "关闭", confirmText = "确认拒绝",
confirmText = "确定", cancelText = "再想想",
title = "订单已超时", cancelEnable = true,
message = "当前订单已超时,请等待新的订单",
cancelEnable = false,
dismiss = {
vm.dispatch(NewOrderVm.Action.UpdateState(uiState.value.copy(showTimeoutDialog = false)))
context.finish()
},
confirm = { confirm = {
vm.dispatch(NewOrderVm.Action.UpdateState(uiState.value.copy(showTimeoutDialog = false))) vm.updateState(uiState.value.copy(refuelOrderDialog = false))
context.finish() vm.dispatch(NewOrderVm.Action.RefuseOrder)
}) },
cancel = {
vm.updateState(uiState.value.copy(refuelOrderDialog = false))
},
dismiss = { vm.updateState(uiState.value.copy(refuelOrderDialog = false)) })
} }
if (uiState.value.acceptOrderDialog == true) { if (uiState.value.acceptOrderDialog == true) {
CommonDialog(title = "请确认是否接受该任务!", CommonDialog(title = "请确认是否接受该任务!",
confirmText = "确认接单", confirmText = "确认接单",
cancelText = "再想想", cancelText = "再想想",
cancelEnable = false, cancelEnable = true,
confirm = { confirm = {
vm.updateState(uiState.value.copy(acceptOrderDialog = false)) vm.updateState(uiState.value.copy(acceptOrderDialog = false))
vm.dispatch(NewOrderVm.Action.ShowTaskNotes) vm.dispatch(NewOrderVm.Action.ShowTaskNotes)
@ -206,13 +202,20 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
if (uiState.value.showTaskNotesDialog == true) { if (uiState.value.showTaskNotesDialog == true) {
OrderTaskNotesDialog(uiState.value.taskNotesBean, OrderTaskNotesDialog(uiState.value.taskNotesBean,
uiState.value.jpushBean?.contract,
uiState.value.jpushBean?.hasReplaceBatteryCapable == 2, uiState.value.jpushBean?.hasReplaceBatteryCapable == 2,
dismiss = {}, dismiss = {
vm.updateState(uiState.value.copy(showTaskNotesDialog = false))
},
confirm = { confirm = {
vm.updateState(uiState.value.copy(showTaskNotesDialog = false))
vm.dispatch(NewOrderVm.Action.AcceptOrder) vm.dispatch(NewOrderVm.Action.AcceptOrder)
}) })
} }
var sheetExpandHeight = remember { mutableStateOf(0.dp) }
val localDensity = LocalDensity.current
BottomSheetScaffold(scaffoldState = scaffoldState, BottomSheetScaffold(scaffoldState = scaffoldState,
topBar = { HeadViewNotBack(title = "新订单") }, topBar = { HeadViewNotBack(title = "新订单") },
sheetContent = { sheetContent = {
@ -221,13 +224,24 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
address = uiState.value.jpushBean?.address, address = uiState.value.jpushBean?.address,
distAddress = uiState.value.jpushBean?.distAddress, distAddress = uiState.value.jpushBean?.distAddress,
serviceTypeName = uiState.value.jpushBean?.serviceTypeName, serviceTypeName = uiState.value.jpushBean?.serviceTypeName,
orderSource = uiState.value.jpushBean?.orderSource, orderSource = uiState.value.jpushBean?.contract,
settleType = uiState.value.jpushBean?.settleType, settleType = uiState.value.jpushBean?.settleType,
bottomTextString = "接单", bottomTextString = "接单",
reserveTime = (uiState.value.jpushBean?.appointTime
?: "").takeIf { uiState.value.jpushBean?.isAppoint == 1 } ?: "",
uiType = NewOrderUiType.ACCEPT) uiType = NewOrderUiType.ACCEPT)
Box(modifier = Modifier
.fillMaxWidth()
.onSizeChanged { coordinates ->
sheetExpandHeight.value = with(localDensity) { coordinates.height.toDp() }
}) {
NewOrderItem(uiBean, goAccept = { NewOrderItem(uiBean, goAccept = {
vm.dispatch(NewOrderVm.Action.ShowTaskNotes) vm.dispatch(NewOrderVm.Action.ShowTaskNotes)
}, refuelOrder = {
vm.updateState(uiState.value.copy(refuelOrderDialog = true))
}) })
}
}, },
sheetPeekHeight = 180.dp, sheetPeekHeight = 180.dp,
sheetShape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), sheetShape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
@ -236,8 +250,13 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
sheetDragHandle = null, sheetDragHandle = null,
sheetSwipeEnabled = true) { paddingValues -> sheetSwipeEnabled = true) { paddingValues ->
Box(modifier = Modifier Box(modifier = Modifier
.fillMaxSize() .wrapContentSize()
.padding(paddingValues)) { .padding(top = paddingValues.calculateTopPadding(),
bottom = if (bottomSheetState.currentValue == SheetValue.PartiallyExpanded) {
0.dp
} else {
sheetExpandHeight.value
})) {
AndroidView(modifier = Modifier.fillMaxSize(), factory = { AndroidView(modifier = Modifier.fillMaxSize(), factory = {
AMapLocationClient.updatePrivacyShow(context, true, true) AMapLocationClient.updatePrivacyShow(context, true, true)
AMapLocationClient.updatePrivacyAgree(context, true) AMapLocationClient.updatePrivacyAgree(context, true)
@ -259,15 +278,6 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
} }
} }
}, update = { mapView -> }, update = { mapView ->
val currentLocation = if (GlobalData.currentLocation != null) {
LatLng(GlobalData.currentLocation?.latitude !!,
GlobalData.currentLocation?.longitude !!)
} else null
val needUpdate =
lastRoutePoints.value != uiState.value.routePoints || lastMarkers.value != uiState.value.markers || lastCurrentLocation.value != currentLocation
if (needUpdate) {
mapView.map.clear() mapView.map.clear()
// 绘制路线 // 绘制路线
@ -277,57 +287,34 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
.zIndex(1f)) .zIndex(1f))
} }
// 添加标记点 mapView.map.addMarkers(uiState.value.markers, false)
val allPoints = mutableListOf<LatLng>()
// 添加当前位置标记 // 添加当前位置标记
currentLocation?.let { if (GlobalData.currentLocation != null) {
mapView.map.addMarker(MarkerOptions().position(it).title("当前位置") mapView.map.addMarker(MarkerOptions().position(LatLng(GlobalData.currentLocation?.latitude !!,
GlobalData.currentLocation?.longitude !!)).title("当前位置")
.icon(ImageUtil.vectorToBitmap(context, R.drawable.ic_current_location)) .icon(ImageUtil.vectorToBitmap(context, R.drawable.ic_current_location))
.anchor(0.5f, 0.5f).visible(true)) .anchor(0.5f, 0.5f).visible(true))
allPoints.add(it)
} }
// 添加其他标记点 // 计算地图显示范围
uiState.value.markers?.let { markers -> val bounds = LatLngBounds.Builder().apply {
mapView.map.addMarkers(markers, true) uiState.value.routePoints?.forEach {
markers.forEach { marker -> include(LatLng(it.latitude, it.longitude))
allPoints.add(marker.position)
}
} }
}.build()
// 添加路线点 // 调整地图显示范围,确保所有点都可见
uiState.value.routePoints?.let { points ->
allPoints.addAll(points)
}
// 计算边界
if (allPoints.isNotEmpty()) {
try { try {
val boundsBuilder = LatLngBounds.builder() mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,
allPoints.forEach { point -> ConvertUtils.dp2px(50f)))
boundsBuilder.include(point) } catch (e : Exception) { // 如果计算边界失败,则使用默认缩放级别
} GlobalData.currentLocation?.let {
mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude,
mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds( it.longitude), 15f))
boundsBuilder.build(),
100))
} catch (e : Exception) { // 如果边界计算失败,使用救援点作为中心
jpushBean?.let { bean ->
if (bean.lat != null && bean.lat != 0.0 && bean.lng != null && bean.lng != 0.0) {
mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(
LatLng(bean.lat, bean.lng),
15f))
}
}
} }
} }
// 更新状态
lastRoutePoints.value = uiState.value.routePoints
lastMarkers.value = uiState.value.markers
lastCurrentLocation.value = currentLocation
}
}) })
} }
} }

View File

@ -26,6 +26,12 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.VerticalDivider import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
@ -43,17 +49,24 @@ import coil.compose.AsyncImage
import com.za.base.theme.bgColor import com.za.base.theme.bgColor
import com.za.base.theme.black50 import com.za.base.theme.black50
import com.za.base.theme.black90 import com.za.base.theme.black90
import com.za.base.theme.buttonBgColor
import com.za.base.view.CommonButton import com.za.base.view.CommonButton
import com.za.base.view.CommonDialog
import com.za.common.log.LogUtil
import com.za.ext.copy import com.za.ext.copy
import com.za.ext.finish
import com.za.servicing.R import com.za.servicing.R
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
object NewOrderUiType { object NewOrderUiType {
const val SERVICING = 1 const val SERVICING = 1 //服务中界面
const val HISTORY = 2 const val HISTORY = 2 //历史界面
const val ACCEPT = 3 const val ACCEPT = 3 //接单页
const val PENDING = 4 const val PENDING = 4 //待服务
const val IN_SERVICING_HOME = 5 const val IN_SERVICING_HOME = 5 //首页服务中
} }
data class NewOrderItemUIBean( data class NewOrderItemUIBean(
@ -82,6 +95,7 @@ fun NewOrderItem(uiBean : NewOrderItemUIBean?,
goDetail : () -> Unit = {}, goDetail : () -> Unit = {},
goNextPage : () -> Unit = {}, goNextPage : () -> Unit = {},
goAccept : () -> Unit = {}, goAccept : () -> Unit = {},
refuelOrder : () -> Unit = {},
goOrderPhoto : () -> Unit = {}, goOrderPhoto : () -> Unit = {},
goEle : () -> Unit = {}, goEle : () -> Unit = {},
goChange : () -> Unit = {}) { goChange : () -> Unit = {}) {
@ -157,14 +171,19 @@ fun NewOrderItem(uiBean : NewOrderItemUIBean?,
Spacer(modifier = Modifier.width(10.dp)) Spacer(modifier = Modifier.width(10.dp))
Text(uiBean?.orderSource ?: "", Text(uiBean?.orderSource ?: "",
color = Color.Black, color = Color.Black,
modifier = Modifier.width(140.dp),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
fontSize = 12.sp) fontSize = 12.sp)
Spacer(Modifier.weight(1f)) Spacer(Modifier.weight(1f))
Text(uiBean?.addressProperty ?: "", Text(uiBean?.addressProperty ?: "",
color = Color.Black, color = Color.Black,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.width(100.dp),
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
fontSize = 14.sp, fontSize = 14.sp)
modifier = Modifier.wrapContentSize(align = Alignment.Center))
} }
if (! uiBean?.reserveTime.isNullOrBlank()) { if (! uiBean?.reserveTime.isNullOrBlank()) {
@ -225,7 +244,8 @@ fun NewOrderItem(uiBean : NewOrderItemUIBean?,
modifier = Modifier.size(16.dp)) modifier = Modifier.size(16.dp))
if (! uiBean?.distAddress.isNullOrBlank()) { if (! uiBean?.distAddress.isNullOrBlank()) {
VerticalDivider(modifier = Modifier.weight(1f), color = Color(0xFFC1C1C1)) VerticalDivider(modifier = Modifier.weight(1f),
color = Color(0xFFC1C1C1).copy(0.5f))
AsyncImage(model = R.drawable.sv_dist, AsyncImage(model = R.drawable.sv_dist,
contentDescription = null, contentDescription = null,
@ -315,14 +335,36 @@ fun NewOrderItem(uiBean : NewOrderItemUIBean?,
if (uiBean?.uiType == NewOrderUiType.SERVICING || uiBean?.uiType == NewOrderUiType.ACCEPT) { if (uiBean?.uiType == NewOrderUiType.SERVICING || uiBean?.uiType == NewOrderUiType.ACCEPT) {
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
CommonButton(text = uiBean?.bottomTextString ?: "") {
if (uiBean?.uiType == NewOrderUiType.ACCEPT) { if (uiBean?.uiType == NewOrderUiType.ACCEPT) {
goAccept() Row(modifier = Modifier
return@CommonButton .fillMaxWidth()
.padding(horizontal = 5.dp)) {
CommonButton(text = "拒绝",
modifier = Modifier
.weight(1f)
.padding(vertical = 10.dp, horizontal = 5.dp)
.background(color = buttonBgColor.copy(alpha = 0.5f),
shape = RoundedCornerShape(4.dp))
.padding(vertical = 15.dp)) {
refuelOrder()
} }
CommonButton(text = uiBean?.bottomTextString ?: "",
modifier = Modifier
.weight(2f)
.padding(vertical = 10.dp, horizontal = 5.dp)
.background(color = buttonBgColor, shape = RoundedCornerShape(4.dp))
.padding(vertical = 15.dp)) {
goAccept()
}
}
} else {
CommonButton(text = uiBean?.bottomTextString ?: "") {
goNextPage() goNextPage()
} }
} }
}
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
} }
@ -332,8 +374,14 @@ fun NewOrderItem(uiBean : NewOrderItemUIBean?,
fun NewOrderItemHead(uiBean : NewOrderItemUIBean?, fun NewOrderItemHead(uiBean : NewOrderItemUIBean?,
goInServicing : () -> Unit = {}, goInServicing : () -> Unit = {},
goChange : () -> Unit = {}) { goChange : () -> Unit = {}) {
var timeOut by remember { mutableStateOf<String?>(null) }
if (uiBean?.uiType == NewOrderUiType.ACCEPT) {
NewOrderTimeOut(countValue = { timeOut = it })
}
when (uiBean?.uiType) { when (uiBean?.uiType) {
NewOrderUiType.IN_SERVICING_HOME, NewOrderUiType.PENDING, NewOrderUiType.SERVICING -> { NewOrderUiType.IN_SERVICING_HOME, NewOrderUiType.PENDING, NewOrderUiType.SERVICING, NewOrderUiType.ACCEPT -> {
Row(modifier = Modifier Row(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { .clickable {
@ -356,11 +404,13 @@ fun NewOrderItemHead(uiBean : NewOrderItemUIBean?,
verticalAlignment = Alignment.CenterVertically) { verticalAlignment = Alignment.CenterVertically) {
Text(uiBean.serviceTypeName ?: "", Text(uiBean.serviceTypeName ?: "",
color = black90, color = black90,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
modifier = Modifier.fillMaxWidth(0.5f),
fontSize = 17.sp) fontSize = 17.sp)
Spacer(Modifier.weight(1f)) Spacer(Modifier.weight(1f))
if (uiBean?.uiType == NewOrderUiType.SERVICING) { if (uiBean?.uiType == NewOrderUiType.SERVICING) {
Text("预计到达:", Text("预计到达:",
color = Color(0xFFF19028), color = Color(0xFFF19028),
@ -370,9 +420,22 @@ fun NewOrderItemHead(uiBean : NewOrderItemUIBean?,
Text("${ Text("${
uiBean.expectArriveTime?.split(" ")?.get(1) uiBean.expectArriveTime?.split(" ")?.get(1)
}", color = Color(0xFFF19028), fontWeight = FontWeight.Medium, fontSize = 13.sp) }", color = Color(0xFFF19028), fontWeight = FontWeight.Medium, fontSize = 13.sp)
} else if (uiBean?.uiType == NewOrderUiType.ACCEPT) {
Text("超时剩余:",
color = Color.Red,
fontWeight = FontWeight.Medium,
fontSize = 13.sp)
Spacer(modifier = Modifier.width(8.dp))
Text(timeOut ?: "",
color = Color.Red,
fontWeight = FontWeight.Medium,
fontSize = 13.sp)
} else { } else {
Text(uiBean?.currentOrderState ?: "", Text(uiBean?.currentOrderState ?: "",
color = Color(0xFFF19028), color = Color(0xFFF19028),
modifier = Modifier.fillMaxWidth(0.4f),
overflow = TextOverflow.Ellipsis,
maxLines = 1,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
fontSize = 13.sp) fontSize = 13.sp)
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
@ -428,3 +491,50 @@ fun NewOrderItemHead(uiBean : NewOrderItemUIBean?,
HorizontalDivider(modifier = Modifier.alpha(0.1f)) HorizontalDivider(modifier = Modifier.alpha(0.1f))
} }
@Composable
private fun NewOrderTimeOut(countValue : (String) -> Unit) {
val context = LocalContext.current
var timerJob : Job? = null
val scope = rememberCoroutineScope()
var timeCount by remember { mutableStateOf<String?>(null) }
var showTimeOutDialog by remember { mutableStateOf(false) }
DisposableEffect(timerJob) {
timerJob = scope.launch {
try {
var timeLeft = 120
while (timeLeft > 0) {
delay(1000)
timeLeft --
timeCount = "$timeLeft"
countValue(timeCount ?: "")
}
if (timeLeft == 0) {
showTimeOutDialog = true
}
} catch (e : Exception) {
LogUtil.print("startTimer", "倒计时异常: ${e.message}")
}
}
onDispose {
timerJob?.cancel()
timerJob = null
}
}
if (showTimeOutDialog) {
CommonDialog(cancelText = "关闭",
confirmText = "确定",
title = "订单已超时",
message = "当前订单已超时,请等待新的订单",
cancelEnable = false,
dismiss = {
showTimeOutDialog = false
context.finish()
},
confirm = {
showTimeOutDialog = false
context.finish()
})
}
}

View File

@ -1,6 +1,5 @@
package com.za.ui.new_order package com.za.ui.new_order
import androidx.lifecycle.viewModelScope
import com.amap.api.maps.model.BitmapDescriptorFactory import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.MarkerOptions import com.amap.api.maps.model.MarkerOptions
@ -30,10 +29,7 @@ import com.za.servicing.R
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
@ -49,9 +45,7 @@ class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
is Action.Init -> init(action.jpushBean) is Action.Init -> init(action.jpushBean)
is Action.AcceptOrder -> acceptOrder() is Action.AcceptOrder -> acceptOrder()
is Action.RefuseOrder -> refuseOrder() is Action.RefuseOrder -> refuseOrder()
is Action.StartTimer -> startTimer()
is Action.ShowTaskNotes -> showTaskNotes() is Action.ShowTaskNotes -> showTaskNotes()
is Action.UpdateTimer -> updateTimer(action.remainingTime)
else -> {} else -> {}
} }
} }
@ -64,7 +58,6 @@ class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
updateState(uiState.value.copy(jpushBean = jpushBean)) updateState(uiState.value.copy(jpushBean = jpushBean))
buildMarkers(jpushBean) buildMarkers(jpushBean)
searchDrivingRoute(jpushBean) searchDrivingRoute(jpushBean)
startTimer()
getTaskNote() getTaskNote()
} }
@ -85,20 +78,20 @@ class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
private fun buildMarkers(jpushBean : JpushBean?) { private fun buildMarkers(jpushBean : JpushBean?) {
val markers = arrayListOf<MarkerOptions>() val markers = arrayListOf<MarkerOptions>()
if (jpushBean?.lat != null && jpushBean.lat != 0.0 && jpushBean.lng != null && jpushBean.lng != 0.0) { if (jpushBean?.lat != null && jpushBean.lat != 0.0 && jpushBean.lng != null && jpushBean.lng != 0.0) { // 获取矢量图资源文件
val startMarkers = val startMarkers =
MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map)) MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map))
.position(LatLng(jpushBean.lat, jpushBean.lng)).title(jpushBean.address) .position(LatLng(jpushBean.lat !!, jpushBean.lng !!)).infoWindowEnable(false)
.snippet("救援地点").visible(true) .visible(true)
markers.add(startMarkers) markers.add(startMarkers)
} }
if (jpushBean?.distLat != null && jpushBean.distLat != 0.0 && jpushBean.distLng != null && jpushBean.distLng != 0.0) { if (jpushBean?.distLat != null && jpushBean.distLat != 0.0 && jpushBean.distLng != null && jpushBean.distLng != 0.0) {
val startMarkers = val destMarker =
MarkerOptions().icon(ImageUtil.vectorToBitmap(ActivityUtils.getTopActivity(), MarkerOptions().icon(ImageUtil.vectorToBitmap(ActivityUtils.getTopActivity(),
R.drawable.sv_map_dist)).position(LatLng(jpushBean.distLat, jpushBean.distLng)) R.drawable.sv_map_dist))
.title(jpushBean.distAddress).snippet("目的地").visible(true) .position(LatLng(jpushBean.distLat !!, jpushBean.distLng !!)).visible(true)
markers.add(startMarkers) markers.add(destMarker)
} }
updateState(uiState.value.copy(markers = markers)) updateState(uiState.value.copy(markers = markers))
} }
@ -135,13 +128,43 @@ class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
override fun doFailure(code : Int, msg : String?) { override fun doFailure(code : Int, msg : String?) {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg) showTipDialog(msg ?: "接单失败")
LogUtil.print("接单失败", "request=$acceptOrderRequest msg=$msg") LogUtil.print("接单失败", "request=$acceptOrderRequest msg=$msg")
} }
}) })
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
LogUtil.print("接单时获取定位失败", it) if (GlobalData.currentLocation == null) {
LogUtil.print("接单失败", "定位获取失败$it")
showTipDialog(it)
} else {
val orderInfo = uiState.value.jpushBean
val acceptOrderRequest = AcceptOrderRequest()
acceptOrderRequest.taskId = orderInfo?.taskId
acceptOrderRequest.vehicleId = GlobalData.driverInfoBean?.vehicleId
acceptOrderRequest.userId = GlobalData.driverInfoBean?.userId
acceptOrderRequest.taskCode = orderInfo?.taskCode
acceptOrderRequest.deviceId =
DeviceUtil.getAndroidId(ActivityUtils.getTopActivity())
acceptOrderRequest.lat = GlobalData.currentLocation?.latitude
acceptOrderRequest.lng = GlobalData.currentLocation?.longitude
RetrofitHelper.getDefaultService().acceptOrder(acceptOrderRequest)
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BaseObserver<String>() {
override fun doSuccess(it : String?) {
LoadingManager.hideLoading()
LogUtil.print("接单成功,单次订单获取失败",
"request=$acceptOrderRequest")
updateState(uiState.value.copy(showCallPhoneDialog = orderInfo?.isNeedCallCustomPhone()))
}
override fun doFailure(code : Int, msg : String?) {
LoadingManager.hideLoading()
showTipDialog(msg ?: "接单失败")
LogUtil.print("接单失败", "request=$acceptOrderRequest msg=$msg")
}
})
}
}) })
} }
@ -167,25 +190,6 @@ class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
}) })
} }
private fun startTimer() {
timerJob?.cancel()
timerJob = viewModelScope.launch {
try {
var timeLeft = 120
while (timeLeft > 0 && isActive) {
delay(1000)
timeLeft --
updateState(uiState.value.copy(remainingTime = timeLeft))
}
if (timeLeft == 0 && isActive) { // 倒计时结束,显示订单超时
updateState(uiState.value.copy(isTimeout = true, showTimeoutDialog = true))
}
} catch (e : Exception) {
LogUtil.print("startTimer", "倒计时异常: ${e.message}")
}
}
}
private fun isNeedShowNotes() : Boolean { private fun isNeedShowNotes() : Boolean {
if (! uiState.value.taskNotesBean?.taskNotes.isNullOrBlank()) { if (! uiState.value.taskNotesBean?.taskNotes.isNullOrBlank()) {
return true return true
@ -206,38 +210,23 @@ class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
return false return false
} }
private fun updateTimer(remainingTime : Int) {
updateState(uiState.value.copy(remainingTime = remainingTime))
}
private fun searchDrivingRoute(jpushBean : JpushBean?) { private fun searchDrivingRoute(jpushBean : JpushBean?) {
if (GlobalData.currentLocation == null) { if (GlobalData.currentLocation == null) return
ToastUtils.showShort("获取当前位置失败")
return
}
updateState(uiState.value.copy(isLoading = true))
val startPoint = LatLonPoint(GlobalData.currentLocation?.latitude ?: 0.0, val startPoint = LatLonPoint(GlobalData.currentLocation?.latitude ?: 0.0,
GlobalData.currentLocation?.longitude ?: 0.0) GlobalData.currentLocation?.longitude ?: 0.0) // 获取救援地点坐标
val rescuePoint =
if (jpushBean?.lat != null && jpushBean.lat != 0.0 && jpushBean.lng != null && jpushBean.lng != 0.0) {
LatLonPoint(jpushBean.lat !!, jpushBean.lng !!)
} else null
val endPoint = when { // 获取救援地点坐标
jpushBean?.distLat != null && jpushBean.distLat != 0.0 && jpushBean.distLng != null && jpushBean.distLng != 0.0 -> { val disPoint =
LatLonPoint(jpushBean.distLat, jpushBean.distLng) if (jpushBean?.distLat != null && jpushBean.distLat != 0.0 && jpushBean.distLng != null && jpushBean.distLng != 0.0) {
} LatLonPoint(jpushBean.distLat !!, jpushBean.distLng !!)
} else null
jpushBean?.lat != null && jpushBean.lat != 0.0 && jpushBean.lng != null && jpushBean.lng != 0.0 -> { // 如果没有救援地点,则不进行规划
LatLonPoint(jpushBean.lat, jpushBean.lng) if (rescuePoint == null) return
}
else -> null
}
if (endPoint == null) return
val fromAndTo = RouteSearch.FromAndTo(startPoint, endPoint)
val query =
RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DrivingDefault, null, null, "")
RouteSearch(GlobalData.application).apply { RouteSearch(GlobalData.application).apply {
setRouteSearchListener(object : RouteSearch.OnRouteSearchListener { setRouteSearchListener(object : RouteSearch.OnRouteSearchListener {
@ -268,7 +257,25 @@ class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
override fun onWalkRouteSearched(p0 : WalkRouteResult?, p1 : Int) {} override fun onWalkRouteSearched(p0 : WalkRouteResult?, p1 : Int) {}
override fun onRideRouteSearched(p0 : RideRouteResult?, p1 : Int) {} override fun onRideRouteSearched(p0 : RideRouteResult?, p1 : Int) {}
}) })
if (disPoint != null) {
val fromAndTo = RouteSearch.FromAndTo(startPoint, disPoint)
val wayPoints = listOf(rescuePoint)
val query = RouteSearch.DriveRouteQuery(fromAndTo,
RouteSearch.DRIVING_SINGLE_DEFAULT,
wayPoints,
null,
"")
calculateDriveRouteAsyn(query) calculateDriveRouteAsyn(query)
} else {
val fromAndTo = RouteSearch.FromAndTo(startPoint, rescuePoint)
val query = RouteSearch.DriveRouteQuery(fromAndTo,
RouteSearch.DRIVING_SINGLE_DEFAULT,
null,
null,
"")
calculateDriveRouteAsyn(query)
}
} }
} }
@ -288,8 +295,6 @@ class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
data class UpdateState(val uiState : UiState) : Action() data class UpdateState(val uiState : UiState) : Action()
data object RefuseOrder : Action() data object RefuseOrder : Action()
data object ShowTaskNotes : Action() data object ShowTaskNotes : Action()
data object StartTimer : Action()
data class UpdateTimer(val remainingTime : Int) : Action()
} }
data class UiState(val jpushBean : JpushBean? = null, data class UiState(val jpushBean : JpushBean? = null,
@ -298,14 +303,12 @@ class NewOrderVm : BaseVm<NewOrderVm.Action, NewOrderVm.UiState>() {
val refuseSuccess : Boolean? = false, val refuseSuccess : Boolean? = false,
val taskNotesBean : TaskNotesBean? = null, val taskNotesBean : TaskNotesBean? = null,
val showTaskNotesDialog : Boolean? = false, val showTaskNotesDialog : Boolean? = false,
val refuelOrderDialog : Boolean? = false,
val acceptOrderDialog : Boolean? = null, val acceptOrderDialog : Boolean? = null,
val remainingTime : Int = 50,
val routePoints : List<LatLng>? = null, val routePoints : List<LatLng>? = null,
val remainingDistance : Double = 0.0, val remainingDistance : Double = 0.0,
val estimatedArrivalTime : String = "", val estimatedArrivalTime : String = "",
val isLoading : Boolean = false, val isLoading : Boolean = false,
val isTimeout : Boolean = false, val isTimeout : Boolean = false,
val showTimeoutDialog : Boolean = false) val showTimeoutDialog : Boolean = false)
} }

View File

@ -26,6 +26,7 @@ import android.widget.ImageView
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import com.blankj.utilcode.util.ActivityUtils import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.ServiceUtils import com.blankj.utilcode.util.ServiceUtils
import com.za.common.log.LogUtil
import com.za.servicing.R import com.za.servicing.R
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -65,10 +66,14 @@ class ReportFloatingManager : Service() {
} }
} }
override fun onBind(intent : Intent?) : IBinder? = null override fun onBind(intent : Intent?) : IBinder?{
LogUtil.print("ReportFloatingManager service", "onBind")
return null
}
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
LogUtil.print("ReportFloatingManager service", "onCreate")
lastUpdateTime = System.currentTimeMillis() lastUpdateTime = System.currentTimeMillis()
prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE) prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
initializeFloatingWindow() initializeFloatingWindow()

View File

@ -5,7 +5,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -39,6 +38,7 @@ import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.amap.api.location.AMapLocation import com.amap.api.location.AMapLocation
import com.amap.api.maps.model.LatLng
import com.blankj.utilcode.util.TimeUtils import com.blankj.utilcode.util.TimeUtils
import com.blankj.utilcode.util.ToastUtils import com.blankj.utilcode.util.ToastUtils
import com.permissionx.guolindev.PermissionX import com.permissionx.guolindev.PermissionX
@ -54,6 +54,7 @@ import com.za.bean.db.order.PhotoTemplateInfo
import com.za.bean.request.OrderPhotoOcrRecognizeRequest import com.za.bean.request.OrderPhotoOcrRecognizeRequest
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.log.LogUtil import com.za.common.log.LogUtil
import com.za.common.util.MapUtil
import com.za.ext.getEleOrderH5Url import com.za.ext.getEleOrderH5Url
import com.za.ext.noDoubleClick import com.za.ext.noDoubleClick
import com.za.ext.toJson import com.za.ext.toJson
@ -72,6 +73,21 @@ import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.File import java.io.File
import java.util.concurrent.Executors import java.util.concurrent.Executors
private fun formatLocationAddress(aMapLocation : AMapLocation?, context : Context) : String {
return if (aMapLocation?.address.isNullOrBlank()) {
if (aMapLocation?.latitude != 0.0 && aMapLocation?.longitude != 0.0) {
MapUtil.getAddressFromLocation(context = context,
latLng = LatLng(aMapLocation?.latitude ?: 0.0, aMapLocation?.longitude ?: 0.0))
?: ""
} else {
""
}
} else {
aMapLocation?.address ?: ""
}
}
@Synchronized @Synchronized
private fun handlerInServicingPhoto( private fun handlerInServicingPhoto(
context : Context, context : Context,
@ -82,6 +98,7 @@ private fun handlerInServicingPhoto(
) { ) {
LogUtil.print("handlerPhoto", "photoTemplateInfo==${photoTemplateInfo.toJson()}") LogUtil.print("handlerPhoto", "photoTemplateInfo==${photoTemplateInfo.toJson()}")
val time = System.currentTimeMillis().minus(photoTemplateInfo.advanceTime ?: 0L) val time = System.currentTimeMillis().minus(photoTemplateInfo.advanceTime ?: 0L)
val address = formatLocationAddress(aMapLocation = aMapLocation, context = context)
val photoTemplateInfoTemp = photoTemplateInfo.copy(photoLocalPath = path, val photoTemplateInfoTemp = photoTemplateInfo.copy(photoLocalPath = path,
photoUploadPath = null, photoUploadPath = null,
realTakePhotoTime = TimeUtils.getNowString(), realTakePhotoTime = TimeUtils.getNowString(),
@ -89,7 +106,7 @@ private fun handlerInServicingPhoto(
time = TimeUtils.millis2String(time), time = TimeUtils.millis2String(time),
lat = aMapLocation?.latitude?.toFloat(), lat = aMapLocation?.latitude?.toFloat(),
lng = aMapLocation?.longitude?.toFloat(), lng = aMapLocation?.longitude?.toFloat(),
address = aMapLocation?.address) address = address)
LogUtil.print("本地照片拍好返回结果", LogUtil.print("本地照片拍好返回结果",
photoTemplateInfoTemp.toJson() ?: photoTemplateInfoTemp.toString()) photoTemplateInfoTemp.toJson() ?: photoTemplateInfoTemp.toString())
RoomHelper.db?.photoTemplateDao()?.update(photoTemplateInfo = photoTemplateInfoTemp) RoomHelper.db?.photoTemplateDao()?.update(photoTemplateInfo = photoTemplateInfoTemp)
@ -98,15 +115,14 @@ private fun handlerInServicingPhoto(
var localPhotoTemplateInfo = photoTemplateInfoTemp var localPhotoTemplateInfo = photoTemplateInfoTemp
//当需要添加水印并且地址不为空的情况下,才添加水印 //当需要添加水印并且地址不为空的情况下,才添加水印
val file = val file = if (localPhotoTemplateInfo.needWaterMarker == true) {
if (localPhotoTemplateInfo.needWaterMarker == true && ! aMapLocation?.address.isNullOrBlank()) { val photoMarkerInfo = PhotoMarkerInfo(needMark = true,
val photoMarkerInfo = PhotoMarkerInfo(localPhotoTemplateInfo.needWaterMarker,
needShowPhoneBrand = localPhotoTemplateInfo.needShowPhoneBrand, needShowPhoneBrand = localPhotoTemplateInfo.needShowPhoneBrand,
path = localPhotoTemplateInfo.photoLocalPath, path = localPhotoTemplateInfo.photoLocalPath,
from = "(相机)", from = "(相机)",
lat = localPhotoTemplateInfo.lat?.toDouble(), lat = localPhotoTemplateInfo.lat?.toDouble(),
lng = localPhotoTemplateInfo.lng?.toDouble(), lng = localPhotoTemplateInfo.lng?.toDouble(),
address = localPhotoTemplateInfo.address, address = localPhotoTemplateInfo.address ?: "",
time = localPhotoTemplateInfo.time, time = localPhotoTemplateInfo.time,
driverName = GlobalData.driverInfoBean?.userName, driverName = GlobalData.driverInfoBean?.userName,
taskCode = localPhotoTemplateInfo.taskCode) taskCode = localPhotoTemplateInfo.taskCode)
@ -164,6 +180,7 @@ private fun handlerChangeBatteryPhoto(context : Context,
success : (PhotoTemplateInfo) -> Unit) { success : (PhotoTemplateInfo) -> Unit) {
LogUtil.print("handlerPhoto", "photoTemplateInfo==${photoTemplateInfo.toJson()}") LogUtil.print("handlerPhoto", "photoTemplateInfo==${photoTemplateInfo.toJson()}")
val time = System.currentTimeMillis().minus(photoTemplateInfo.advanceTime ?: 0L) val time = System.currentTimeMillis().minus(photoTemplateInfo.advanceTime ?: 0L)
val address = formatLocationAddress(aMapLocation = aMapLocation, context = context)
val photoTemplateInfoTemp = photoTemplateInfo.copy(photoLocalPath = path, val photoTemplateInfoTemp = photoTemplateInfo.copy(photoLocalPath = path,
photoUploadPath = null, photoUploadPath = null,
realTakePhotoTime = TimeUtils.getNowString(), realTakePhotoTime = TimeUtils.getNowString(),
@ -171,16 +188,15 @@ private fun handlerChangeBatteryPhoto(context : Context,
time = TimeUtils.millis2String(time), time = TimeUtils.millis2String(time),
lat = aMapLocation?.latitude?.toFloat(), lat = aMapLocation?.latitude?.toFloat(),
lng = aMapLocation?.longitude?.toFloat(), lng = aMapLocation?.longitude?.toFloat(),
address = aMapLocation?.address) address = address)
LogUtil.print("本地照片拍好返回结果", LogUtil.print("本地照片拍好返回结果",
photoTemplateInfoTemp.toJson() ?: photoTemplateInfoTemp.toString()) photoTemplateInfoTemp.toJson() ?: photoTemplateInfoTemp.toString())
RoomHelper.db?.changeBatteryDao()?.update(photoTemplateInfo = photoTemplateInfoTemp) RoomHelper.db?.changeBatteryDao()?.update(photoTemplateInfo = photoTemplateInfoTemp)
success(photoTemplateInfoTemp) success(photoTemplateInfoTemp)
var localPhotoTemplateInfo = photoTemplateInfoTemp var localPhotoTemplateInfo = photoTemplateInfoTemp
val file = val file = if (localPhotoTemplateInfo.needWaterMarker == true) {
if (localPhotoTemplateInfo.needWaterMarker == true && ! aMapLocation?.address.isNullOrBlank()) { val photoMarkerInfo = PhotoMarkerInfo(needMark = true,
val photoMarkerInfo = PhotoMarkerInfo(localPhotoTemplateInfo.needWaterMarker,
needShowPhoneBrand = localPhotoTemplateInfo.needShowPhoneBrand, needShowPhoneBrand = localPhotoTemplateInfo.needShowPhoneBrand,
path = localPhotoTemplateInfo.photoLocalPath, path = localPhotoTemplateInfo.photoLocalPath,
from = "(相机)", from = "(相机)",
@ -246,6 +262,7 @@ private fun handlerNormalPhoto(context : Context,
success : (PhotoTemplateInfo) -> Unit) { success : (PhotoTemplateInfo) -> Unit) {
LogUtil.print("handlerNormalPhoto", "photoTemplateInfo==${photoTemplateInfo.toJson()}") LogUtil.print("handlerNormalPhoto", "photoTemplateInfo==${photoTemplateInfo.toJson()}")
val time = System.currentTimeMillis().minus(photoTemplateInfo.advanceTime ?: 0L) val time = System.currentTimeMillis().minus(photoTemplateInfo.advanceTime ?: 0L)
val address = formatLocationAddress(aMapLocation = aMapLocation, context = context)
val photoTemplateInfoTemp = photoTemplateInfo.copy(photoLocalPath = path, val photoTemplateInfoTemp = photoTemplateInfo.copy(photoLocalPath = path,
photoUploadPath = null, photoUploadPath = null,
realTakePhotoTime = TimeUtils.getNowString(), realTakePhotoTime = TimeUtils.getNowString(),
@ -254,7 +271,7 @@ private fun handlerNormalPhoto(context : Context,
time = TimeUtils.millis2String(time), time = TimeUtils.millis2String(time),
lat = aMapLocation?.latitude?.toFloat(), lat = aMapLocation?.latitude?.toFloat(),
lng = aMapLocation?.longitude?.toFloat(), lng = aMapLocation?.longitude?.toFloat(),
address = aMapLocation?.address) address = address)
LogUtil.print("本地照片拍好返回结果", LogUtil.print("本地照片拍好返回结果",
photoTemplateInfoTemp.toJson() ?: photoTemplateInfoTemp.toString()) photoTemplateInfoTemp.toJson() ?: photoTemplateInfoTemp.toString())
success(photoTemplateInfoTemp) success(photoTemplateInfoTemp)
@ -389,6 +406,8 @@ fun InServicingPhotoView(modifier : Modifier = Modifier,
?: 0), ?: 0),
fontSize = 12.sp, fontSize = 12.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = photoTemplateInfo.getPhotoStatusColor()) color = photoTemplateInfo.getPhotoStatusColor())
Spacer(modifier = Modifier.width(10.dp)) Spacer(modifier = Modifier.width(10.dp))
@ -472,6 +491,8 @@ fun InServicingPhotoViewIsCanClick(modifier : Modifier = Modifier,
?: 0), ?: 0),
fontSize = 12.sp, fontSize = 12.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = photoTemplateInfo.getPhotoStatusColor()) color = photoTemplateInfo.getPhotoStatusColor())
Spacer(modifier = Modifier.width(10.dp)) Spacer(modifier = Modifier.width(10.dp))
@ -548,6 +569,8 @@ fun InServicingPhotoWithoutTitleView(modifier : Modifier = Modifier,
?: 0), ?: 0),
fontSize = 12.sp, fontSize = 12.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = photoTemplateInfo.getPhotoStatusColor()) color = photoTemplateInfo.getPhotoStatusColor())
Spacer(modifier = Modifier.width(10.dp)) Spacer(modifier = Modifier.width(10.dp))
@ -647,7 +670,6 @@ fun InServicingPhotoItemView(modifier : Modifier = Modifier,
aMapLocation.value = GlobalData.currentLocation aMapLocation.value = GlobalData.currentLocation
val intent = Intent(context, ZdCameraXActivity::class.java) val intent = Intent(context, ZdCameraXActivity::class.java)
getResult.launch(intent) getResult.launch(intent)
ToastUtils.showShort(it)
LogUtil.print("上传图片定位获取失败", LogUtil.print("上传图片定位获取失败",
"使用全局定位location==${GlobalData.currentLocation.toJson()}") "使用全局定位location==${GlobalData.currentLocation.toJson()}")
}) })
@ -676,7 +698,6 @@ fun InServicingPhotoItemView(modifier : Modifier = Modifier,
aMapLocation.value = GlobalData.currentLocation aMapLocation.value = GlobalData.currentLocation
val intent = Intent(context, ZdCameraXActivity::class.java) val intent = Intent(context, ZdCameraXActivity::class.java)
getResult.launch(intent) getResult.launch(intent)
ToastUtils.showShort(it)
LogUtil.print("上传图片定位获取失败", LogUtil.print("上传图片定位获取失败",
"使用全局定位location==${GlobalData.currentLocation.toJson()}") "使用全局定位location==${GlobalData.currentLocation.toJson()}")
}) })
@ -747,7 +768,6 @@ fun InServicingPhotoItemView(modifier : Modifier = Modifier,
aMapLocation.value = GlobalData.currentLocation aMapLocation.value = GlobalData.currentLocation
val intent = Intent(context, ZdCameraXActivity::class.java) val intent = Intent(context, ZdCameraXActivity::class.java)
getResult.launch(intent) getResult.launch(intent)
ToastUtils.showShort(it)
LogUtil.print("上传图片定位获取失败", LogUtil.print("上传图片定位获取失败",
"使用全局定位location==${GlobalData.currentLocation.toJson()}") "使用全局定位location==${GlobalData.currentLocation.toJson()}")
}) })

View File

@ -88,11 +88,16 @@ class CheckVehicleVm : IServicingVm<CheckVehicleVm.Action, CheckVehicleVm.UiStat
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(isNeedAddress = true, success = { ZdLocationManager.getSingleLocation(isNeedAddress = true, success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
doUploadOfflineTask(it, tempPhotoList = tempPhotoList)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
doUploadOfflineTask(GlobalData.currentLocation, tempPhotoList = tempPhotoList)
} else {
LogUtil.print("$tag updateOffline", "定位获取失败$it") LogUtil.print("$tag updateOffline", "定位获取失败$it")
showTipDialog(it)
}
}) })
} }
@ -141,7 +146,7 @@ class CheckVehicleVm : IServicingVm<CheckVehicleVm.Action, CheckVehicleVm.UiStat
private fun updateTask() { private fun updateTask() {
if (uiState.value.photoTemplateList.isNullOrEmpty()) { if (uiState.value.photoTemplateList.isNullOrEmpty()) {
ToastUtils.showShort("现场照片不能为空") showTipDialog("现场照片不能为空")
return return
} }
@ -151,7 +156,7 @@ class CheckVehicleVm : IServicingVm<CheckVehicleVm.Action, CheckVehicleVm.UiStat
return@forEach return@forEach
} }
if (it.doHaveFilm == 1 && it.photoLocalWaterMarkerPath.isNullOrBlank()) { if (it.doHaveFilm == 1 && it.photoLocalWaterMarkerPath.isNullOrBlank()) {
ToastUtils.showLong("请上传 ${it.imageTitle}") showTipDialog("请上传 ${it.imageTitle}")
return return
} }
} }
@ -168,7 +173,7 @@ class CheckVehicleVm : IServicingVm<CheckVehicleVm.Action, CheckVehicleVm.UiStat
return@forEach return@forEach
} }
if (it.photoUploadStatus == 4) { if (it.photoUploadStatus == 4) {
ToastUtils.showLong("${it.photoName}正在上传,请等待照片上传完成!") showTipDialog("${it.photoName}正在上传,请等待照片上传完成!")
return return
} }
if (! it.photoLocalWaterMarkerPath.isNullOrBlank() && it.photoUploadPath.isNullOrBlank()) { if (! it.photoLocalWaterMarkerPath.isNullOrBlank() && it.photoUploadPath.isNullOrBlank()) {
@ -212,8 +217,25 @@ class CheckVehicleVm : IServicingVm<CheckVehicleVm.Action, CheckVehicleVm.UiStat
doUploadTask(request = taskRequest) doUploadTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateTask", "定位获取失败==$it") LogUtil.print("$tag updateTask",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
val taskRequest = UpdateTaskRequest(type = "CHECK_VEHICLE",
taskId = getCurrentOrder()?.taskId,
userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
currentState = "EXAMINE",
offlineMode = 0,
operateTime = System.currentTimeMillis().toString(),
lat = GlobalData.currentLocation?.latitude,
lng = GlobalData.currentLocation?.longitude,
address = GlobalData.currentLocation?.address,
templatePhotoInfoList = tempPhotoList.toList())
doUploadTask(request = taskRequest)
} else {
LogUtil.print("$tag updateTask", "全局定位获取失败==")
showTipDialog(it)
}
}) })
} }
@ -226,9 +248,10 @@ class CheckVehicleVm : IServicingVm<CheckVehicleVm.Action, CheckVehicleVm.UiStat
LogUtil.print("$tag doUploadTask", "状态更新成功==$request") LogUtil.print("$tag doUploadTask", "状态更新成功==$request")
}, failed = { msg, code -> }, failed = { msg, code ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg)
if (code == Const.NetWorkException) { if (code == Const.NetWorkException) {
updateState(uiState.value.copy(showOfflineDialog = true)) updateState(uiState.value.copy(showOfflineDialog = true))
} else {
showTipDialog(msg ?: "状态更新失败")
} }
LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg") LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg")
}) })

View File

@ -40,7 +40,7 @@ class DeparturePhotoVm : IServicingVm<DeparturePhotoVm.Action, DeparturePhotoVm.
private fun updateTask() { private fun updateTask() {
if (uiState.value.photoTemplateList.isNullOrEmpty()) { if (uiState.value.photoTemplateList.isNullOrEmpty()) {
ToastUtils.showShort("现场照片不能为空") showTipDialog("现场照片不能为空!")
return return
} }
@ -50,7 +50,7 @@ class DeparturePhotoVm : IServicingVm<DeparturePhotoVm.Action, DeparturePhotoVm.
return@forEach return@forEach
} }
if (it.doHaveFilm == 1 && it.photoLocalWaterMarkerPath.isNullOrBlank()) { if (it.doHaveFilm == 1 && it.photoLocalWaterMarkerPath.isNullOrBlank()) {
ToastUtils.showLong("请上传 ${it.imageTitle}") showTipDialog("请上传 ${it.imageTitle}")
return return
} }
} }
@ -60,11 +60,11 @@ class DeparturePhotoVm : IServicingVm<DeparturePhotoVm.Action, DeparturePhotoVm.
return@forEach return@forEach
} }
if (it.photoUploadStatus == 4) { if (it.photoUploadStatus == 4) {
ToastUtils.showLong("${it.photoName}正在上传,请等待照片上传完成!") showTipDialog("${it.photoName}正在上传,请等待照片上传完成!")
return return
} }
if (! it.photoLocalWaterMarkerPath.isNullOrBlank() && it.photoUploadPath.isNullOrBlank()) { if (! it.photoLocalWaterMarkerPath.isNullOrBlank() && it.photoUploadPath.isNullOrBlank()) {
ToastUtils.showLong("请上传 ${it.imageTitle}") showTipDialog("请上传 ${it.imageTitle}")
return return
} }
} }
@ -104,8 +104,25 @@ class DeparturePhotoVm : IServicingVm<DeparturePhotoVm.Action, DeparturePhotoVm.
doUploadTask(request = taskRequest) doUploadTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateTask", "定位获取失败==$it") LogUtil.print("$tag updateTask",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
val taskRequest = UpdateTaskRequest(type = "START",
taskId = getCurrentOrder()?.taskId,
userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
currentState = GlobalData.currentOrder?.taskState,
offlineMode = 0,
operateTime = System.currentTimeMillis().toString(),
lat = GlobalData.currentLocation?.latitude,
lng = GlobalData.currentLocation?.longitude,
address = GlobalData.currentLocation?.address,
templatePhotoInfoList = tempPhotoList.toList())
doUploadTask(request = taskRequest)
} else {
LogUtil.print("$tag updateTask", "全局定位获取失败==$it")
showTipDialog(it)
}
}) })
} }
@ -118,7 +135,7 @@ class DeparturePhotoVm : IServicingVm<DeparturePhotoVm.Action, DeparturePhotoVm.
LogUtil.print("$tag doUploadTask", "状态更新成功==$request") LogUtil.print("$tag doUploadTask", "状态更新成功==$request")
}, failed = { msg, code -> }, failed = { msg, code ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg) showTipDialog(msg ?: "提交失败")
LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg") LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg")
}) })
} }

View File

@ -22,11 +22,11 @@ import kotlinx.coroutines.flow.MutableStateFlow
class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPhotoVm.UiState>() { class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPhotoVm.UiState>() {
private val _uiState = MutableStateFlow(UiState()) private val _uiState = MutableStateFlow(UiState())
val uiState get() = _uiState val uiState get() = _uiState
override fun updateState(uiState: UiState) { override fun updateState(uiState : UiState) {
_uiState.value = uiState _uiState.value = uiState
} }
override fun dispatch(action: Action) { override fun dispatch(action : Action) {
when (action) { when (action) {
is Action.Init -> init() is Action.Init -> init()
is Action.UpdateTask -> updateTask() is Action.UpdateTask -> updateTask()
@ -47,9 +47,9 @@ class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPh
return@forEachIndexed return@forEachIndexed
} }
if (!photoTemplateInfo.photoLocalWaterMarkerPath.isNullOrBlank() && photoTemplateInfo.photoUploadPath.isNullOrBlank()) { if (! photoTemplateInfo.photoLocalWaterMarkerPath.isNullOrBlank() && photoTemplateInfo.photoUploadPath.isNullOrBlank()) {
val offlineUpdateTaskBean = OfflineUpdateTaskBean( val offlineUpdateTaskBean =
realTakePhotoTime = photoTemplateInfo.realTakePhotoTime, OfflineUpdateTaskBean(realTakePhotoTime = photoTemplateInfo.realTakePhotoTime,
photoSource = photoTemplateInfo.photoSource, photoSource = photoTemplateInfo.photoSource,
time = photoTemplateInfo.time, time = photoTemplateInfo.time,
imageLat = photoTemplateInfo.lat, imageLat = photoTemplateInfo.lat,
@ -89,18 +89,22 @@ class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPh
} }
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(isNeedAddress = true, ZdLocationManager.getSingleLocation(isNeedAddress = true, success = {
success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
doUploadOfflineTask(it, tempPhotoList = tempPhotoList) doUploadOfflineTask(it, tempPhotoList = tempPhotoList)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline", "定位获取失败$it") LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
doUploadOfflineTask(GlobalData.currentLocation, tempPhotoList = tempPhotoList)
} else {
showTipDialog(it)
}
}) })
} }
private fun doUploadOfflineTask(it: AMapLocation?, tempPhotoList: ArrayList<String?>) { private fun doUploadOfflineTask(it : AMapLocation?, tempPhotoList : ArrayList<String?>) {
val taskRequest = UpdateTaskRequest(type = "DEST_PHOTO", val taskRequest = UpdateTaskRequest(type = "DEST_PHOTO",
taskId = GlobalData.currentOrder?.taskId, taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId, userId = GlobalData.driverInfoBean?.userId,
@ -114,8 +118,7 @@ class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPh
address = it?.address, address = it?.address,
templatePhotoInfoList = tempPhotoList.toList()) templatePhotoInfoList = tempPhotoList.toList())
val offlineUpdateTaskBean = OfflineUpdateTaskBean( val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = taskRequest.type,
type = taskRequest.type,
taskId = taskRequest.taskId, taskId = taskRequest.taskId,
userId = taskRequest.userId, userId = taskRequest.userId,
vehicleId = taskRequest.vehicleId, vehicleId = taskRequest.vehicleId,
@ -134,7 +137,8 @@ class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPh
offlineType = 1) offlineType = 1)
insertOfflineTask(offlineUpdateTaskBean) insertOfflineTask(offlineUpdateTaskBean)
updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus())) updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus()))
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState), orderInfo = getCurrentOrder())) updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState),
orderInfo = getCurrentOrder()))
} }
private fun updateTask() { private fun updateTask() {
@ -155,7 +159,7 @@ class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPh
} }
//先判断是否有离线任务 //先判断是否有离线任务
if (!getCurrentOrderOfflineTask().isNullOrEmpty()) { if (! getCurrentOrderOfflineTask().isNullOrEmpty()) {
updateOffline() updateOffline()
return return
} }
@ -170,7 +174,7 @@ class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPh
return return
} }
if (!it.photoLocalWaterMarkerPath.isNullOrBlank() && it.photoUploadPath.isNullOrBlank()) { if (! it.photoLocalWaterMarkerPath.isNullOrBlank() && it.photoUploadPath.isNullOrBlank()) {
updateState(uiState.value.copy(showOfflineDialog = true)) updateState(uiState.value.copy(showOfflineDialog = true))
return return
} }
@ -212,11 +216,29 @@ class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPh
doUploadTask(request = taskRequest) doUploadTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateTask",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
val taskRequest = UpdateTaskRequest(type = "DEST_PHOTO",
taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId,
flowType = GlobalData.currentOrder?.flowType,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
currentState = "DESTPHOTO",
offlineMode = 0,
operateTime = System.currentTimeMillis().toString(),
lat = GlobalData.currentLocation?.latitude,
lng = GlobalData.currentLocation?.longitude,
address = GlobalData.currentLocation?.address,
templatePhotoInfoList = tempPhotoList.toList())
doUploadTask(request = taskRequest)
} else {
showTipDialog(it)
}
}) })
} }
private fun doUploadTask(request: UpdateTaskRequest) { private fun doUploadTask(request : UpdateTaskRequest) {
LoadingManager.showLoading() LoadingManager.showLoading()
CommonMethod.updateTask(request, success = { CommonMethod.updateTask(request, success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
@ -243,16 +265,16 @@ class DestinationPhotoVm : IServicingVm<DestinationPhotoVm.Action, DestinationPh
sealed class Action { sealed class Action {
data object Init : Action() data object Init : Action()
data object UpdateTask : Action() data object UpdateTask : Action()
data class UpdatePhotoTemplate(val photoTemplateInfo: PhotoTemplateInfo) : Action() data class UpdatePhotoTemplate(val photoTemplateInfo : PhotoTemplateInfo) : Action()
data class UpdateState(val uiState: UiState) : Action() data class UpdateState(val uiState : UiState) : Action()
data object UpdateOffline : Action() data object UpdateOffline : Action()
} }
data class UiState(val orderInfo: OrderInfo? = null, data class UiState(val orderInfo : OrderInfo? = null,
val verifyValue: String? = null, val verifyValue : String? = null,
val goNextPage: UpdateTaskBean? = null, val goNextPage : UpdateTaskBean? = null,
val isGoNextPageDialog: Boolean? = null, val isGoNextPageDialog : Boolean? = null,
val showCallPhoneDialog: Boolean? = null, val showCallPhoneDialog : Boolean? = null,
val showOfflineDialog: Boolean? = null, val showOfflineDialog : Boolean? = null,
val photoTemplateList: List<PhotoTemplateInfo>? = null) val photoTemplateList : List<PhotoTemplateInfo>? = null)
} }

View File

@ -41,6 +41,7 @@ import com.za.base.view.CommonDialog
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.util.ServicingSpeechManager import com.za.common.util.ServicingSpeechManager
import com.za.ext.finish import com.za.ext.finish
import com.za.ext.getLastSix
import com.za.ext.goStatusPage import com.za.ext.goStatusPage
import com.za.servicing.R import com.za.servicing.R
import com.za.ui.servicing.view.InServicingHeadView import com.za.ui.servicing.view.InServicingHeadView
@ -73,6 +74,23 @@ fun EleSignScreen(vm : EleSignVm = viewModel()) {
}) })
} }
if (uiState.value.signUploadFailedDialog == true) {
CommonDialog(cancelText = "取消",
confirmText = "离线上传",
title = "签名上传失败,是否进行离线上传?",
cancelEnable = true,
cancel = {
vm.dispatch(EleSignVm.Action.UpdateState(uiState.value.copy(signUploadFailedDialog = false)))
},
dismiss = {
vm.dispatch(EleSignVm.Action.UpdateState(uiState.value.copy(signUploadFailedDialog = false)))
},
confirm = {
vm.dispatch(EleSignVm.Action.UpdateState(uiState.value.copy(signUploadFailedDialog = false)))
vm.dispatch(EleSignVm.Action.SignUploadFailed)
})
}
if (uiState.value.goNextPage != null) { if (uiState.value.goNextPage != null) {
uiState.value.orderInfo?.goStatusPage(context) uiState.value.orderInfo?.goStatusPage(context)
context.finish() context.finish()
@ -152,7 +170,8 @@ fun EleSignScreen(vm : EleSignVm = viewModel()) {
Text(text = "车架号后6位", fontSize = 12.sp, color = black65) Text(text = "车架号后6位", fontSize = 12.sp, color = black65)
Spacer(modifier = Modifier.width(5.dp)) Spacer(modifier = Modifier.width(5.dp))
Text(text = uiState.value.eleWorkOrderBean?.carVin ?: "", Text(text = uiState.value.eleWorkOrderBean?.carVin?.getLastSix()
?: GlobalData.currentOrder?.carVin?.getLastSix() ?: "",
textDecoration = TextDecoration.Underline, textDecoration = TextDecoration.Underline,
fontSize = 12.sp, fontSize = 12.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
@ -214,10 +233,6 @@ fun EleSignScreen(vm : EleSignVm = viewModel()) {
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
} }
item {
}
item { item {
Column(modifier = Modifier Column(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()

View File

@ -1,5 +1,7 @@
package com.za.ui.servicing.ele_sign package com.za.ui.servicing.ele_sign
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.NetworkUtils
import com.blankj.utilcode.util.ToastUtils import com.blankj.utilcode.util.ToastUtils
import com.za.base.Const import com.za.base.Const
import com.za.base.IServicingVm import com.za.base.IServicingVm
@ -18,7 +20,10 @@ import com.za.offline.OfflineUpdateTaskBean
import com.za.room.RoomHelper import com.za.room.RoomHelper
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File import java.io.File
class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() { class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
@ -35,10 +40,21 @@ class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
is Action.Upload -> upload() is Action.Upload -> upload()
is Action.UploadSignature -> uploadSignature(action.path) is Action.UploadSignature -> uploadSignature(action.path)
is Action.UploadOffline -> uploadOffline() is Action.UploadOffline -> uploadOffline()
is Action.SignUploadFailed -> uploadOfflineSignPhoto()
} }
} }
private fun uploadOfflineSignPhoto() {
val signOfflineUpdateTaskBean =
OfflineUpdateTaskBean(imageLocalPath = uiState.value.eleWorkOrderBean?.localCustomSignPath,
taskId = getCurrentOrder()?.taskId,
taskCode = getCurrentOrder()?.taskCode,
offlineTitle = "电子工单-客户签名照片",
offlineType = 5)
insertOfflineTask(signOfflineUpdateTaskBean)
}
private fun uploadOffline() { private fun uploadOffline() {
val eleWorkOrderBean = val eleWorkOrderBean =
RoomHelper.db?.eleWorkOrderDao()?.getEleWorkOrder(getCurrentOrder()?.taskId ?: 0) RoomHelper.db?.eleWorkOrderDao()?.getEleWorkOrder(getCurrentOrder()?.taskId ?: 0)
@ -57,7 +73,6 @@ class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
insertOfflineTask(signOfflineUpdateTaskBean) insertOfflineTask(signOfflineUpdateTaskBean)
} }
val offlineUpdateTaskBean = OfflineUpdateTaskBean(taskId = getCurrentOrder()?.taskId, val offlineUpdateTaskBean = OfflineUpdateTaskBean(taskId = getCurrentOrder()?.taskId,
taskCode = getCurrentOrder()?.taskCode, taskCode = getCurrentOrder()?.taskCode,
customerSignPath = uiState.value.eleWorkOrderBean?.serverCustomSignPath, customerSignPath = uiState.value.eleWorkOrderBean?.serverCustomSignPath,
@ -89,6 +104,17 @@ class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
} }
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
viewModelScope.launch(Dispatchers.IO) {
if (! NetworkUtils.isAvailable()) {
withContext(Dispatchers.Main) {
updateState(uiState.value.copy(signUploadFailedDialog = true))
}
} else {
withContext(Dispatchers.Main) {
showTipDialog(msg = "签名上传失败,请重新签名上传!")
}
}
}
LogUtil.print("uploadSignature", "failed==$it") LogUtil.print("uploadSignature", "failed==$it")
}) })
} }
@ -134,9 +160,10 @@ class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
override fun doFailure(code : Int, msg : String?) { override fun doFailure(code : Int, msg : String?) {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg)
if (code == Const.NetWorkException) { if (code == Const.NetWorkException) {
updateState(uiState.value.copy(showOfflineDialog = true)) updateState(uiState.value.copy(showOfflineDialog = true))
} else {
showTipDialog(msg ?: "数据提交异常")
} }
LogUtil.print("eleSign upload failed", msg ?: "") LogUtil.print("eleSign upload failed", msg ?: "")
} }
@ -155,7 +182,7 @@ class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
LogUtil.print("电子表单更新车辆损伤照片", "eleWorkOrderBean==${it.toJson()}") LogUtil.print("电子表单更新车辆损伤照片", "eleWorkOrderBean==${it.toJson()}")
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort("数据加载异常,请返回重试!") showTipDialog(msg = "数据加载异常,请返回重试!")
}) })
} }
@ -164,6 +191,7 @@ class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
data class UpdateState(val uiState : UiState) : Action() data class UpdateState(val uiState : UiState) : Action()
data object Upload : Action() data object Upload : Action()
data object UploadOffline : Action() data object UploadOffline : Action()
data object SignUploadFailed : Action()
data class UploadSignature(val path : String) : Action() data class UploadSignature(val path : String) : Action()
} }
@ -174,6 +202,7 @@ class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
val isGoNextPageDialog : Boolean? = null, val isGoNextPageDialog : Boolean? = null,
val showCallPhoneDialog : Boolean? = null, val showCallPhoneDialog : Boolean? = null,
val showOfflineDialog : Boolean? = null, val showOfflineDialog : Boolean? = null,
val signUploadFailedDialog : Boolean? = null,
val damagePhoto : List<EleCarDamagePhotoBean>? = null, val damagePhoto : List<EleCarDamagePhotoBean>? = null,
) )
} }

View File

@ -5,7 +5,9 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
@ -14,10 +16,13 @@ import androidx.compose.material3.rememberBottomSheetScaffoldState
import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.material3.rememberStandardBottomSheetState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
@ -33,11 +38,11 @@ import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.LatLngBounds
import com.amap.api.maps.model.MarkerOptions import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.PolylineOptions import com.amap.api.maps.model.PolylineOptions
import com.blankj.utilcode.util.ConvertUtils
import com.za.base.BaseActivity import com.za.base.BaseActivity
import com.za.base.view.CommonDialog import com.za.base.view.CommonDialog
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.util.ImageUtil import com.za.common.util.ImageUtil
import com.za.ext.convertToFlowName
import com.za.ext.finish import com.za.ext.finish
import com.za.ext.goNextPage import com.za.ext.goNextPage
import com.za.servicing.R import com.za.servicing.R
@ -110,6 +115,30 @@ fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
}) })
} }
if (uiState.value.showOfflineDialog == true) {
CommonDialog(cancelText = "取消",
confirmText = "离线上传",
title = "任务提交失败,是否离线提交?",
cancelEnable = true,
cancel = {
vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy(
showOfflineDialog = false)))
},
dismiss = {
vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy(
showOfflineDialog = false)))
},
confirm = {
vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy(
showOfflineDialog = false)))
vm.dispatch(GoAccidentSiteVm.Action.UpdateOffline)
})
}
var sheetExpandHeight = remember { mutableStateOf(0.dp) }
val localDensity = LocalDensity.current
BottomSheetScaffold(scaffoldState = scaffoldState, BottomSheetScaffold(scaffoldState = scaffoldState,
topBar = { topBar = {
InServicingHeadView(title = "救援车发车,正在赶往现场", InServicingHeadView(title = "救援车发车,正在赶往现场",
@ -127,10 +156,17 @@ fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
bottomTextString = "到达事发地", bottomTextString = "到达事发地",
expectArriveTime = uiState.value.orderInfo?.expectArriveTime, expectArriveTime = uiState.value.orderInfo?.expectArriveTime,
uiType = NewOrderUiType.SERVICING) uiType = NewOrderUiType.SERVICING)
Box(modifier = Modifier
.fillMaxWidth()
.onSizeChanged { coordinates ->
sheetExpandHeight.value = with(localDensity) { coordinates.height.toDp() }
}) {
NewOrderItem(uiBean, goNextPage = { NewOrderItem(uiBean, goNextPage = {
vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy( vm.dispatch(GoAccidentSiteVm.Action.UpdateState(uiState.value.copy(
isGoNextPageDialog = true))) isGoNextPageDialog = true)))
}) })
}
}, },
sheetPeekHeight = 180.dp, sheetPeekHeight = 180.dp,
sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp), sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp),
@ -138,8 +174,13 @@ fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
sheetDragHandle = null, sheetDragHandle = null,
sheetSwipeEnabled = true) { paddingValues -> sheetSwipeEnabled = true) { paddingValues ->
Box(modifier = Modifier Box(modifier = Modifier
.fillMaxSize() .wrapContentSize()
.padding(paddingValues)) { .padding(top = paddingValues.calculateTopPadding(),
bottom = if (bottomSheetState.currentValue == SheetValue.PartiallyExpanded) {
0.dp
} else {
sheetExpandHeight.value
})) {
AndroidView(modifier = Modifier.fillMaxSize(), factory = { AndroidView(modifier = Modifier.fillMaxSize(), factory = {
AMapLocationClient.updatePrivacyShow(context, true, true) AMapLocationClient.updatePrivacyShow(context, true, true)
AMapLocationClient.updatePrivacyAgree(context, true) AMapLocationClient.updatePrivacyAgree(context, true)
@ -171,6 +212,8 @@ fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
.zIndex(1f)) .zIndex(1f))
} }
mapView.map.addMarkers(uiState.value.markers, false)
// 添加当前位置标记 // 添加当前位置标记
if (GlobalData.currentLocation != null) { if (GlobalData.currentLocation != null) {
mapView.map.addMarker(MarkerOptions().position(LatLng(GlobalData.currentLocation?.latitude !!, mapView.map.addMarker(MarkerOptions().position(LatLng(GlobalData.currentLocation?.latitude !!,
@ -179,43 +222,16 @@ fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
.anchor(0.5f, 0.5f).visible(true)) .anchor(0.5f, 0.5f).visible(true))
} }
// 添加救援地标记 // 计算地图显示范围
uiState.value.orderInfo?.let { order ->
if (order.lat != null && order.lat != 0.0 && order.lng != null && order.lng != 0.0) {
mapView.map.addMarker(MarkerOptions().position(LatLng(order.lat !!,
order.lng !!)).title("救援地点")
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map))
.anchor(0.5f, 0.5f))
}
// 添加目的地标记
if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0) {
mapView.map.addMarker(MarkerOptions().position(LatLng(order.distLat !!,
order.distLng !!)).title("目的地")
.icon(ImageUtil.vectorToBitmap(context, R.drawable.sv_map_dist))
.anchor(0.5f, 0.5f))
}
}
// 调整地图显示范围
val bounds = LatLngBounds.Builder().apply { val bounds = LatLngBounds.Builder().apply {
GlobalData.currentLocation?.let { uiState.value.routePoints?.forEach {
include(LatLng(it.latitude, it.longitude)) include(LatLng(it.latitude, it.longitude))
} }
uiState.value.orderInfo?.let { order ->
if (order.lat != null && order.lat != 0.0 && order.lng != null && order.lng != 0.0) {
include(LatLng(order.lat !!, order.lng !!))
}
if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0) {
include(LatLng(order.distLat !!, order.distLng !!))
}
}
}.build() }.build()
try { try {
mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100)) mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,
ConvertUtils.dp2px(100f)))
} catch (e : Exception) { } catch (e : Exception) {
GlobalData.currentLocation?.let { GlobalData.currentLocation?.let {
mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude, mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude,

View File

@ -1,5 +1,6 @@
package com.za.ui.servicing.go_accident package com.za.ui.servicing.go_accident
import com.amap.api.location.AMapLocation
import com.amap.api.maps.AMapUtils import com.amap.api.maps.AMapUtils
import com.amap.api.maps.model.BitmapDescriptorFactory import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLng
@ -11,7 +12,6 @@ import com.amap.api.services.route.RideRouteResult
import com.amap.api.services.route.RouteSearch import com.amap.api.services.route.RouteSearch
import com.amap.api.services.route.WalkRouteResult import com.amap.api.services.route.WalkRouteResult
import com.blankj.utilcode.util.ActivityUtils import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.ToastUtils
import com.za.base.Const import com.za.base.Const
import com.za.base.IServicingVm import com.za.base.IServicingVm
import com.za.base.view.LoadingManager import com.za.base.view.LoadingManager
@ -55,6 +55,21 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { ZdLocationManager.getSingleLocation(success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
doUploadOfflineTask(taskRequest, it)
}, failed = {
LoadingManager.hideLoading()
if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
doUploadOfflineTask(taskRequest, GlobalData.currentLocation)
} else {
showTipDialog(it)
}
})
}
private fun doUploadOfflineTask(taskRequest : UpdateTaskRequest? = null,
location : AMapLocation? = null) {
val temp = taskRequest ?: UpdateTaskRequest(type = "VERIFY", val temp = taskRequest ?: UpdateTaskRequest(type = "VERIFY",
taskId = GlobalData.currentOrder?.taskId, taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId, userId = GlobalData.driverInfoBean?.userId,
@ -62,8 +77,8 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
currentState = GlobalData.currentOrder?.taskState, currentState = GlobalData.currentOrder?.taskState,
offlineMode = 0, offlineMode = 0,
operateTime = System.currentTimeMillis().toString(), operateTime = System.currentTimeMillis().toString(),
lat = it.latitude, lat = location?.latitude,
lng = it.longitude) lng = location?.longitude)
val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = temp.type, val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = temp.type,
taskId = temp.taskId, taskId = temp.taskId,
@ -83,10 +98,6 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus())) updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus()))
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState), updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState),
orderInfo = getCurrentOrder())) orderInfo = getCurrentOrder()))
}, failed = {
LoadingManager.hideLoading()
ToastUtils.showShort(it)
})
} }
private fun updateTask() { private fun updateTask() {
@ -105,7 +116,23 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
doUploadTask(request = taskRequest) doUploadTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
val taskRequest = UpdateTaskRequest(type = "VERIFY",
taskId = getCurrentOrder()?.taskId,
userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
currentState = getCurrentOrder()?.taskState,
offlineMode = 0,
operateTime = System.currentTimeMillis().toString(),
lat = GlobalData.currentLocation?.latitude,
lng = GlobalData.currentLocation?.longitude)
doUploadTask(request = taskRequest)
} else {
LogUtil.print("$tag updateTask", "全局定位获取失败$it")
showTipDialog(it)
}
}) })
} }
@ -122,11 +149,13 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
updateState(uiState.value.copy(goNextPage = it, orderInfo = getCurrentOrder())) updateState(uiState.value.copy(goNextPage = it, orderInfo = getCurrentOrder()))
}, failed = { msg, code -> }, failed = { msg, code ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg)
if (code == Const.NetWorkException) { if (code == Const.NetWorkException) {
updateState(uiState.value.copy(showOfflineDialog = true)) updateState(uiState.value.copy(showOfflineDialog = true))
} else {
showTipDialog(msg ?: "提交失败")
} }
LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg") LogUtil.print("$tag doUploadTask",
"状态更新失败==${request.toJson()} msg==$msg code==$code")
}) })
} }
@ -148,10 +177,11 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
} }
if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) { if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) {
val startMarkers = val destMarker =
MarkerOptions().icon(ImageUtil.vectorToBitmap(ActivityUtils.getTopActivity(), R.drawable.sv_map_dist)) MarkerOptions().icon(ImageUtil.vectorToBitmap(ActivityUtils.getTopActivity(),
R.drawable.sv_map_dist))
.position(LatLng(orderInfo.distLat !!, orderInfo.distLng !!)).visible(true) .position(LatLng(orderInfo.distLat !!, orderInfo.distLng !!)).visible(true)
markers.add(startMarkers) markers.add(destMarker)
} }
updateState(uiState.value.copy(markers = markers)) updateState(uiState.value.copy(markers = markers))
} }
@ -159,7 +189,7 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
private fun searchDrivingRoute(orderInfo : OrderInfo?) { // 如果没有当前位置,则不进行路径规划 private fun searchDrivingRoute(orderInfo : OrderInfo?) { // 如果没有当前位置,则不进行路径规划
if (GlobalData.currentLocation == null) return if (GlobalData.currentLocation == null) return
val currentPoint = LatLonPoint(GlobalData.currentLocation?.latitude ?: 0.0, val startPoint = LatLonPoint(GlobalData.currentLocation?.latitude ?: 0.0,
GlobalData.currentLocation?.longitude ?: 0.0) GlobalData.currentLocation?.longitude ?: 0.0)
// 获取救援地点坐标 // 获取救援地点坐标
@ -168,6 +198,12 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
LatLonPoint(orderInfo.lat !!, orderInfo.lng !!) LatLonPoint(orderInfo.lat !!, orderInfo.lng !!)
} else null } else null
// 获取救援地点坐标
val disPoint =
if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) {
LatLonPoint(orderInfo.distLat !!, orderInfo.distLng !!)
} else null
// 如果没有救援地点,则不进行规划 // 如果没有救援地点,则不进行规划
if (rescuePoint == null) return if (rescuePoint == null) return
@ -197,11 +233,24 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
override fun onRideRouteSearched(p0 : RideRouteResult?, p1 : Int) {} override fun onRideRouteSearched(p0 : RideRouteResult?, p1 : Int) {}
}) })
// 规划当前位置到救援地的路线 if (disPoint != null) {
val query = RouteSearch.FromAndTo(currentPoint, rescuePoint) val fromAndTo = RouteSearch.FromAndTo(startPoint, disPoint)
val driveQuery = val wayPoints = listOf(rescuePoint)
RouteSearch.DriveRouteQuery(query, RouteSearch.DrivingDefault, null, null, "") val query = RouteSearch.DriveRouteQuery(fromAndTo,
routeSearch.calculateDriveRouteAsyn(driveQuery) RouteSearch.DRIVING_SINGLE_DEFAULT,
wayPoints,
null,
"")
routeSearch.calculateDriveRouteAsyn(query)
} else {
val fromAndTo = RouteSearch.FromAndTo(startPoint, rescuePoint)
val query = RouteSearch.DriveRouteQuery(fromAndTo,
RouteSearch.DRIVING_SINGLE_DEFAULT,
null,
null,
"")
routeSearch.calculateDriveRouteAsyn(query)
}
} }
private fun calculateRemainingDistance() : Pair<Float, String> { private fun calculateRemainingDistance() : Pair<Float, String> {
@ -229,17 +278,16 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
private var timerJob : Job? = null private var timerJob : Job? = null
private fun startTimer() { private fun startTimer() { // timerJob?.cancel()
// timerJob?.cancel() // timerJob = viewModelScope.launch {
// timerJob = viewModelScope.launch { // while (isActive) {
// while (isActive) { // val (distance, arrivalTime) = calculateRemainingDistance()
// val (distance, arrivalTime) = calculateRemainingDistance() // _uiState.update {
// _uiState.update { // it.copy(remainingDistance = distance, estimatedArrivalTime = arrivalTime)
// it.copy(remainingDistance = distance, estimatedArrivalTime = arrivalTime) // }
// } // delay(1000)
// delay(1000) // }
// } // }
// }
} }
override fun onCleared() { override fun onCleared() {

View File

@ -3,53 +3,33 @@ package com.za.ui.servicing.go_to_destination
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.SheetValue import androidx.compose.material3.SheetValue
import androidx.compose.material3.Text
import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberBottomSheetScaffoldState
import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.material3.rememberStandardBottomSheetState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import com.amap.api.location.AMapLocationClient import com.amap.api.location.AMapLocationClient
import com.amap.api.maps.CameraUpdateFactory import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.MapView import com.amap.api.maps.MapView
@ -58,19 +38,17 @@ import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.LatLngBounds
import com.amap.api.maps.model.MarkerOptions import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.PolylineOptions import com.amap.api.maps.model.PolylineOptions
import com.blankj.utilcode.util.ConvertUtils
import com.za.base.BaseActivity import com.za.base.BaseActivity
import com.za.base.theme.headBgColor
import com.za.base.view.CommonDialog import com.za.base.view.CommonDialog
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.util.ImageUtil import com.za.common.util.ImageUtil
import com.za.ext.copy
import com.za.ext.finish import com.za.ext.finish
import com.za.ext.goNextPage import com.za.ext.goNextPage
import com.za.servicing.R import com.za.servicing.R
import com.za.ui.new_order.NewOrderItem import com.za.ui.new_order.NewOrderItem
import com.za.ui.new_order.NewOrderItemUIBean import com.za.ui.new_order.NewOrderItemUIBean
import com.za.ui.new_order.NewOrderUiType import com.za.ui.new_order.NewOrderUiType
import com.za.ui.new_order.NewOrderVm
import com.za.ui.servicing.view.InServicingHeadView import com.za.ui.servicing.view.InServicingHeadView
import com.za.ui.servicing.view.ServiceOperation import com.za.ui.servicing.view.ServiceOperation
@ -89,26 +67,11 @@ fun GoToDestinationScreen(vm : GoToDestinationVm = viewModel()) {
val lifecycleOwner = LocalLifecycleOwner.current val lifecycleOwner = LocalLifecycleOwner.current
val mapView = remember { MapView(context) } val mapView = remember { MapView(context) }
// 添加协程作用域 val bottomSheetState = rememberStandardBottomSheetState(initialValue = SheetValue.Expanded)
val scope = rememberCoroutineScope()
// 修改 BottomSheet 状态
val bottomSheetState =
rememberStandardBottomSheetState(initialValue = SheetValue.PartiallyExpanded,
confirmValueChange = { true })
val scaffoldState = rememberBottomSheetScaffoldState(bottomSheetState = bottomSheetState) val scaffoldState = rememberBottomSheetScaffoldState(bottomSheetState = bottomSheetState)
// 优化状态管理
val isExpanded by remember {
derivedStateOf { bottomSheetState.currentValue == SheetValue.Expanded }
}
// 记忆化常用值,减少重组 // 记忆化常用值,减少重组
val orderInfo = remember(uiState.value.orderInfo) { uiState.value.orderInfo } val orderInfo = remember(uiState.value.orderInfo) { uiState.value.orderInfo }
val estimatedTime =
remember(uiState.value.estimatedArrivalTime) { uiState.value.estimatedArrivalTime }
val remainingDistance =
remember(uiState.value.remainingDistance) { uiState.value.remainingDistance }
DisposableEffect(key1 = lifecycleOwner) { DisposableEffect(key1 = lifecycleOwner) {
val observer = LifecycleEventObserver { _, event -> val observer = LifecycleEventObserver { _, event ->
@ -176,6 +139,9 @@ fun GoToDestinationScreen(vm : GoToDestinationVm = viewModel()) {
}) })
} }
var sheetExpandHeight = remember { mutableStateOf(0.dp) }
val localDensity = LocalDensity.current
BottomSheetScaffold(scaffoldState = scaffoldState, BottomSheetScaffold(scaffoldState = scaffoldState,
topBar = { topBar = {
InServicingHeadView(title = "作业完成,正在拖往目的地", InServicingHeadView(title = "作业完成,正在拖往目的地",
@ -193,11 +159,16 @@ fun GoToDestinationScreen(vm : GoToDestinationVm = viewModel()) {
expectArriveTime = uiState.value.orderInfo?.expectArriveTime, expectArriveTime = uiState.value.orderInfo?.expectArriveTime,
bottomTextString = "到达目的地", bottomTextString = "到达目的地",
uiType = NewOrderUiType.SERVICING) uiType = NewOrderUiType.SERVICING)
Box(modifier = Modifier
.fillMaxWidth()
.onSizeChanged { coordinates ->
sheetExpandHeight.value = with(localDensity) { coordinates.height.toDp() }
}) {
NewOrderItem(uiBean, goNextPage = { NewOrderItem(uiBean, goNextPage = {
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy( vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(
isGoNextPageDialog = true))) isGoNextPageDialog = true)))
}) })
}
}, },
sheetPeekHeight = 180.dp, sheetPeekHeight = 180.dp,
sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp), sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp),
@ -205,8 +176,13 @@ fun GoToDestinationScreen(vm : GoToDestinationVm = viewModel()) {
sheetDragHandle = null, sheetDragHandle = null,
sheetSwipeEnabled = true) { paddingValues -> sheetSwipeEnabled = true) { paddingValues ->
Box(modifier = Modifier Box(modifier = Modifier
.fillMaxSize() .wrapContentSize()
.padding(paddingValues)) { .padding(top = paddingValues.calculateTopPadding(),
bottom = if (bottomSheetState.currentValue == SheetValue.PartiallyExpanded) {
0.dp
} else {
sheetExpandHeight.value
})) {
AndroidView(modifier = Modifier.fillMaxSize(), factory = { AndroidView(modifier = Modifier.fillMaxSize(), factory = {
AMapLocationClient.updatePrivacyShow(context, true, true) AMapLocationClient.updatePrivacyShow(context, true, true)
AMapLocationClient.updatePrivacyAgree(context, true) AMapLocationClient.updatePrivacyAgree(context, true)
@ -231,14 +207,15 @@ fun GoToDestinationScreen(vm : GoToDestinationVm = viewModel()) {
}, update = { // 清除旧标记和路线 }, update = { // 清除旧标记和路线
mapView.map.clear() mapView.map.clear()
// 绘制路线 // 绘制路线
uiState.value.routePoints?.let { points -> uiState.value.routePoints?.let { points ->
mapView.map.addPolyline(PolylineOptions().addAll(points).width(15f) mapView.map.addPolyline(PolylineOptions().addAll(points).width(15f)
.setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.icon_road_green_arrow)) .setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.icon_road_green_arrow))
.zIndex(1f)) .zIndex(1f))
} }
// 再添加标记点,确保标记点在路线上层 mapView.map.addMarkers(uiState.value.markers, false)
// 添加当前位置标记 // 添加当前位置标记
if (GlobalData.currentLocation != null) { if (GlobalData.currentLocation != null) {
mapView.map.addMarker(MarkerOptions().position(LatLng(GlobalData.currentLocation?.latitude !!, mapView.map.addMarker(MarkerOptions().position(LatLng(GlobalData.currentLocation?.latitude !!,
@ -247,44 +224,16 @@ fun GoToDestinationScreen(vm : GoToDestinationVm = viewModel()) {
.anchor(0.5f, 0.5f).visible(true)) .anchor(0.5f, 0.5f).visible(true))
} }
// 添加救援地标记 // 计算地图显示范围
uiState.value.orderInfo?.let { order -> val bounds = LatLngBounds.Builder().apply {
if (order.lat != null && order.lat != 0.0 && order.lng != null && order.lng != 0.0) { uiState.value.routePoints?.forEach {
mapView.map.addMarker(MarkerOptions().position(LatLng(order.lat !!,
order.lng !!)).title("救援地点")
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map))
.anchor(0.5f, 0.5f))
}
// 添加目的地标记
if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0) {
mapView.map.addMarker(MarkerOptions().position(LatLng(order.distLat !!,
order.distLng !!)).title("目的地")
.icon(ImageUtil.vectorToBitmap(context, R.drawable.sv_map_dist))
.anchor(0.5f, 0.5f))
}
}
// 调整地图显示范围
val bounds = LatLngBounds.Builder().apply { // 添加当前位置
GlobalData.currentLocation?.let {
include(LatLng(it.latitude, it.longitude)) include(LatLng(it.latitude, it.longitude))
} }
// 添加救援地点和目的地
uiState.value.orderInfo?.let { order ->
if (order.lat != null && order.lat != 0.0 && order.lng != null && order.lng != 0.0) {
include(LatLng(order.lat !!, order.lng !!))
}
if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0) {
include(LatLng(order.distLat !!, order.distLng !!))
}
}
}.build() }.build()
try { try {
mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100)) mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,
ConvertUtils.dp2px(100f)))
} catch (e : Exception) { // 如果计算边界失败,则使用默认缩放级别 } catch (e : Exception) { // 如果计算边界失败,则使用默认缩放级别
GlobalData.currentLocation?.let { GlobalData.currentLocation?.let {
mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude, mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude,

View File

@ -1,9 +1,18 @@
package com.za.ui.servicing.go_to_destination package com.za.ui.servicing.go_to_destination
import androidx.lifecycle.viewModelScope
import com.amap.api.location.AMapLocation
import com.amap.api.maps.AMapUtils
import com.amap.api.maps.model.BitmapDescriptorFactory import com.amap.api.maps.model.BitmapDescriptorFactory
import com.amap.api.maps.model.LatLng import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.MarkerOptions import com.amap.api.maps.model.MarkerOptions
import com.blankj.utilcode.util.ToastUtils import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.route.BusRouteResult
import com.amap.api.services.route.DriveRouteResult
import com.amap.api.services.route.RideRouteResult
import com.amap.api.services.route.RouteSearch
import com.amap.api.services.route.WalkRouteResult
import com.blankj.utilcode.util.ActivityUtils
import com.za.base.Const import com.za.base.Const
import com.za.base.IServicingVm import com.za.base.IServicingVm
import com.za.base.view.LoadingManager import com.za.base.view.LoadingManager
@ -12,25 +21,16 @@ import com.za.bean.request.UpdateTaskBean
import com.za.bean.request.UpdateTaskRequest import com.za.bean.request.UpdateTaskRequest
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.log.LogUtil import com.za.common.log.LogUtil
import com.za.common.util.ImageUtil
import com.za.ext.getNextStatus import com.za.ext.getNextStatus
import com.za.ext.toJson import com.za.ext.toJson
import com.za.net.CommonMethod import com.za.net.CommonMethod
import com.za.offline.OfflineUpdateTaskBean import com.za.offline.OfflineUpdateTaskBean
import com.za.service.location.ZdLocationManager import com.za.service.location.ZdLocationManager
import com.za.servicing.R import com.za.servicing.R
import kotlinx.coroutines.flow.MutableStateFlow
import androidx.lifecycle.viewModelScope
import com.amap.api.maps.AMapUtils
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.route.BusRouteResult
import com.amap.api.services.route.DriveRouteResult
import com.amap.api.services.route.RideRouteResult
import com.amap.api.services.route.RouteSearch
import com.amap.api.services.route.WalkRouteResult
import com.blankj.utilcode.util.ActivityUtils
import com.za.common.util.ImageUtil
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -60,6 +60,22 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { ZdLocationManager.getSingleLocation(success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
doUploadOffline(taskRequest, it)
}, failed = {
LoadingManager.hideLoading()
if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
doUploadOffline(taskRequest, GlobalData.currentLocation)
} else {
LogUtil.print("$tag updateOfflineTask", "全局定位获取失败$it")
showTipDialog(it)
}
})
}
private fun doUploadOffline(taskRequest : UpdateTaskRequest? = null,
location : AMapLocation? = null) {
val temp = taskRequest ?: UpdateTaskRequest(type = "ARRIVE_DEST", val temp = taskRequest ?: UpdateTaskRequest(type = "ARRIVE_DEST",
taskId = GlobalData.currentOrder?.taskId, taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId, userId = GlobalData.driverInfoBean?.userId,
@ -68,8 +84,8 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
currentState = GlobalData.currentOrder?.taskState, currentState = GlobalData.currentOrder?.taskState,
offlineMode = 0, offlineMode = 0,
operateTime = System.currentTimeMillis().toString(), operateTime = System.currentTimeMillis().toString(),
lat = it.latitude, lat = location?.latitude,
lng = it.longitude) lng = location?.longitude)
val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = temp.type, val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = temp.type,
taskId = temp.taskId, taskId = temp.taskId,
@ -90,13 +106,8 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus())) updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus()))
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState), updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState),
orderInfo = getCurrentOrder())) orderInfo = getCurrentOrder()))
}, failed = {
LoadingManager.hideLoading()
ToastUtils.showShort(it)
})
} }
private fun updateTask() { private fun updateTask() {
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { ZdLocationManager.getSingleLocation(success = {
@ -114,7 +125,24 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
doUploadTask(request = taskRequest) doUploadTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
val taskRequest = UpdateTaskRequest(type = "ARRIVE_DEST",
taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
flowType = GlobalData.currentOrder?.flowType,
currentState = GlobalData.currentOrder?.taskState,
offlineMode = 0,
operateTime = System.currentTimeMillis().toString(),
lat = GlobalData.currentLocation?.latitude,
lng = GlobalData.currentLocation?.longitude)
doUploadTask(request = taskRequest)
} else {
LogUtil.print("$tag updateTask", "全局定位获取失败$it")
showTipDialog(it)
}
}) })
} }
@ -130,9 +158,10 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
updateState(uiState.value.copy(goNextPage = it, orderInfo = getCurrentOrder())) updateState(uiState.value.copy(goNextPage = it, orderInfo = getCurrentOrder()))
}, failed = { msg, code -> }, failed = { msg, code ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg)
if (code == Const.NetWorkException) { if (code == Const.NetWorkException) {
updateState(uiState.value.copy(showOfflineDialog = true)) updateState(uiState.value.copy(showOfflineDialog = true))
} else {
showTipDialog(msg ?: "提交失败")
} }
LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg") LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg")
}) })
@ -141,23 +170,29 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
private fun init() { private fun init() {
updateState(uiState = uiState.value.copy(orderInfo = getCurrentOrder())) updateState(uiState = uiState.value.copy(orderInfo = getCurrentOrder()))
buildMarkers(getCurrentOrder()) buildMarkers(getCurrentOrder())
searchDrivingRoute(getCurrentOrder()) // dispatch(Action.StartTimer) searchDrivingRoute(getCurrentOrder())
} }
private fun searchDrivingRoute(orderInfo : OrderInfo?) { // 如果没有当前位置,则不进行路径规划 private fun searchDrivingRoute(orderInfo : OrderInfo?) { // 如果没有当前位置,则不进行路径规划
if (GlobalData.currentLocation == null) return if (GlobalData.currentLocation == null) return
val currentPoint = LatLonPoint(GlobalData.currentLocation?.latitude ?: 0.0, val startPoint = LatLonPoint(GlobalData.currentLocation?.latitude ?: 0.0,
GlobalData.currentLocation?.longitude ?: 0.0) GlobalData.currentLocation?.longitude ?: 0.0)
// 获取目的地坐标 // 获取救援地点坐标
val destPoint = val rescuePoint =
if (orderInfo?.lat != null && orderInfo.lat != 0.0 && orderInfo.lng != null && orderInfo.lng != 0.0) {
LatLonPoint(orderInfo.lat !!, orderInfo.lng !!)
} else null
// 获取救援地点坐标
val disPoint =
if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) { if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) {
LatLonPoint(orderInfo.distLat !!, orderInfo.distLng !!) LatLonPoint(orderInfo.distLat !!, orderInfo.distLng !!)
} else null } else null
// 如果没有目的地,则不进行规划 // 如果没有救援地点,则不进行规划
if (destPoint == null) return if (rescuePoint == null) return
// 使用 Application Context 创建路由搜索对象 // 使用 Application Context 创建路由搜索对象
val routeSearch = RouteSearch(GlobalData.application) val routeSearch = RouteSearch(GlobalData.application)
@ -185,11 +220,24 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
override fun onRideRouteSearched(p0 : RideRouteResult?, p1 : Int) {} override fun onRideRouteSearched(p0 : RideRouteResult?, p1 : Int) {}
}) })
// 规划当前位置到目的地的路线 if (disPoint != null) {
val query = RouteSearch.FromAndTo(currentPoint, destPoint) val fromAndTo = RouteSearch.FromAndTo(startPoint, disPoint)
val driveQuery = val wayPoints = listOf(rescuePoint)
RouteSearch.DriveRouteQuery(query, RouteSearch.DrivingDefault, null, null, "") val query = RouteSearch.DriveRouteQuery(fromAndTo,
routeSearch.calculateDriveRouteAsyn(driveQuery) RouteSearch.DRIVING_SINGLE_DEFAULT,
wayPoints,
null,
"")
routeSearch.calculateDriveRouteAsyn(query)
} else {
val fromAndTo = RouteSearch.FromAndTo(startPoint, rescuePoint)
val query = RouteSearch.DriveRouteQuery(fromAndTo,
RouteSearch.DRIVING_SINGLE_DEFAULT,
null,
null,
"")
routeSearch.calculateDriveRouteAsyn(query)
}
} }
private fun calculateRemainingDistance() : Pair<Float, String> { private fun calculateRemainingDistance() : Pair<Float, String> {
@ -246,10 +294,11 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
} }
if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) { if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) {
val startMarkers = val destMarker =
MarkerOptions().icon(ImageUtil.vectorToBitmap(ActivityUtils.getTopActivity(), R.drawable.sv_map_dist)) MarkerOptions().icon(ImageUtil.vectorToBitmap(ActivityUtils.getTopActivity(),
R.drawable.sv_map_dist))
.position(LatLng(orderInfo.distLat !!, orderInfo.distLng !!)).visible(true) .position(LatLng(orderInfo.distLat !!, orderInfo.distLng !!)).visible(true)
markers.add(startMarkers) markers.add(destMarker)
} }
updateState(uiState.value.copy(markers = markers)) updateState(uiState.value.copy(markers = markers))
} }

View File

@ -146,6 +146,24 @@ private fun OrderDetailBaseInformationView(orderInfo : OrderInfo?) {
}) })
} }
//拖车责任险
if (! orderInfo?.externalCode.isNullOrBlank()) {
Spacer(modifier = Modifier.height(10.dp))
Row(modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically) {
Text(text = "流水号",
color = titleColor,
fontSize = titleSize,
fontWeight = FontWeight.Medium,
modifier = Modifier.width(75.dp))
Spacer(modifier = Modifier.width(5.dp))
Text(text = "${orderInfo?.externalCode}",
color = contentColor,
fontSize = titleSize,
fontWeight = FontWeight.Medium)
}
}
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
Text(text = "客户姓名", Text(text = "客户姓名",
@ -168,6 +186,25 @@ private fun OrderDetailBaseInformationView(orderInfo : OrderInfo?) {
modifier = Modifier.size(10.dp)) modifier = Modifier.size(10.dp))
} }
Spacer(modifier = Modifier.height(10.dp))
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
Text(text = "是否新车",
color = titleColor,
fontSize = titleSize,
fontWeight = FontWeight.Medium,
modifier = Modifier.width(75.dp))
Spacer(modifier = Modifier.width(5.dp))
Text(text = "".takeIf { orderInfo?.isNewCar == true } ?: "",
color = contentColor,
fontSize = titleSize,
fontWeight = FontWeight.Medium)
Spacer(modifier = Modifier.width(5.dp))
AsyncImage(model = R.drawable.sv_copy,
contentDescription = "",
modifier = Modifier.size(15.dp))
}
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
Text(text = "客户车牌号", Text(text = "客户车牌号",
@ -186,6 +223,24 @@ private fun OrderDetailBaseInformationView(orderInfo : OrderInfo?) {
modifier = Modifier.size(15.dp)) modifier = Modifier.size(15.dp))
} }
Spacer(modifier = Modifier.height(10.dp))
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
Text(text = "客户车架号",
color = titleColor,
fontSize = titleSize,
fontWeight = FontWeight.Medium,
modifier = Modifier.width(75.dp))
Spacer(modifier = Modifier.width(5.dp))
Text(text = "${orderInfo?.carVin}",
color = contentColor,
fontSize = titleSize,
fontWeight = FontWeight.Medium)
Spacer(modifier = Modifier.width(5.dp))
AsyncImage(model = R.drawable.sv_copy,
contentDescription = "",
modifier = Modifier.size(15.dp))
}
if (! orderInfo?.carModel.isNullOrBlank()) { if (! orderInfo?.carModel.isNullOrBlank()) {
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))

View File

@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
@ -25,13 +26,19 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.za.base.theme.buttonBgColor
import com.za.base.theme.headBgColor import com.za.base.theme.headBgColor
import com.za.base.theme.white80 import com.za.base.theme.white80
import com.za.base.view.CommonButton
import com.za.base.view.HeadView import com.za.base.view.HeadView
import com.za.bean.db.order.OrderInfo import com.za.bean.db.order.OrderInfo
import com.za.ext.finish import com.za.ext.finish
import com.za.ext.navigationActivity
import com.za.ext.noDoubleClick
import com.za.ui.order_report.OrderReportActivity
import com.za.ui.servicing.order_give_up.OrderGiveUpActivity import com.za.ui.servicing.order_give_up.OrderGiveUpActivity
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -44,12 +51,49 @@ fun OrderDetailScreen(orderInfo : OrderInfo?) {
Scaffold(topBar = { Scaffold(topBar = {
HeadView(title = "订单信息", onBack = { context.finish() }) HeadView(title = "订单信息", onBack = { context.finish() })
}, bottomBar = { }, bottomBar = {
CommonButton(text = "客户放弃") { Row(modifier = Modifier
.fillMaxWidth()
.height(60.dp)
.padding(vertical = 5.dp, horizontal = 12.dp)) {
Box(modifier = Modifier
.weight(1f)
.height(60.dp)
.noDoubleClick { // val url =
// "${AppConfig.BASE_URL}/h5/supplier/dispatch/reportIndex?userOrderId=${GlobalData.currentOrder?.userOrderId}&type=2&userOrderCode=${GlobalData.currentOrder?.taskCode}&driverId=${GlobalData.driverInfoBean?.userId}"
//
// CommonH5Activity.goH5Activity(context, url, "")
context.navigationActivity(OrderReportActivity::class.java)
}
.background(color = Color.Red.copy(alpha = 0.7f), shape = RoundedCornerShape(4.dp))
.padding(vertical = 8.dp), contentAlignment = Alignment.Center) {
Text(text = "报备",
color = Color.White,
fontSize = 15.sp,
fontWeight = FontWeight.Medium,
style = TextStyle.Default.copy())
}
Spacer(modifier = Modifier.width(10.dp))
Box(modifier = Modifier
.weight(2f)
.height(60.dp)
.noDoubleClick {
OrderGiveUpActivity.goOrderGiveUpActivity(context, OrderGiveUpActivity.goOrderGiveUpActivity(context,
orderInfo = orderInfo, orderInfo = orderInfo,
userOrderId = orderInfo?.userOrderId, userOrderId = orderInfo?.userOrderId,
giveUpType = 0) giveUpType = 0)
} }
.background(color = buttonBgColor, shape = RoundedCornerShape(4.dp))
.padding(vertical = 8.dp), contentAlignment = Alignment.Center) {
Text(text = "客户放弃",
color = Color.White,
fontSize = 15.sp,
fontWeight = FontWeight.Medium,
style = TextStyle.Default.copy())
}
}
}) { }) {
Column(modifier = Modifier Column(modifier = Modifier
.fillMaxSize() .fillMaxSize()

View File

@ -124,6 +124,7 @@ fun CarModeView(orderInfo : OrderInfo?) {
@Composable @Composable
fun OrderTaskNotesDialog(taskNotesBean : TaskNotesBean?, fun OrderTaskNotesDialog(taskNotesBean : TaskNotesBean?,
orderSource : String? = null,
isShowChangeBattery : Boolean? = false, isShowChangeBattery : Boolean? = false,
dismiss : () -> Unit, dismiss : () -> Unit,
confirm : () -> Unit) { confirm : () -> Unit) {
@ -137,7 +138,7 @@ fun OrderTaskNotesDialog(taskNotesBean : TaskNotesBean?,
.fillMaxWidth() .fillMaxWidth()
.wrapContentHeight() .wrapContentHeight()
.verticalScroll(state = rememberScrollState()) .verticalScroll(state = rememberScrollState())
.padding(horizontal = 10.dp), .padding(horizontal = 5.dp),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top) { verticalArrangement = Arrangement.Top) {
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
@ -152,7 +153,7 @@ fun OrderTaskNotesDialog(taskNotesBean : TaskNotesBean?,
Spacer(Modifier.weight(1f)) Spacer(Modifier.weight(1f))
Text("平安保险", Text(orderSource ?: "",
color = Color.Black, color = Color.Black,
fontSize = 15.sp, fontSize = 15.sp,
fontWeight = FontWeight.Bold) fontWeight = FontWeight.Bold)
@ -162,26 +163,27 @@ fun OrderTaskNotesDialog(taskNotesBean : TaskNotesBean?,
if (! taskNotesBean?.otherNotes.isNullOrBlank()) { if (! taskNotesBean?.otherNotes.isNullOrBlank()) {
OrderRequirementsItemView(title = "特殊提醒", OrderRequirementsItemView(title = "特殊提醒",
content = taskNotesBean?.otherNotes) content = taskNotesBean?.otherNotes ?: "")
} }
if (! taskNotesBean?.feeStandard.isNullOrBlank()) { if (! taskNotesBean?.feeStandard.isNullOrBlank()) {
OrderRequirementsItemView(title = "收费标准", OrderRequirementsItemView(title = "收费标准",
content = taskNotesBean?.feeStandard) content = taskNotesBean?.feeStandard ?: "")
} }
if (! taskNotesBean?.modelVinNo.isNullOrBlank()) { if (! taskNotesBean?.modelVinNo.isNullOrBlank()) {
OrderRequirementsItemView(title = "车型", content = taskNotesBean?.modelVinNo) OrderRequirementsItemView(title = "车型",
content = taskNotesBean?.modelVinNo ?: "")
} }
if (! taskNotesBean?.taskNotes.isNullOrBlank()) { if (! taskNotesBean?.taskNotes.isNullOrBlank()) {
OrderRequirementsItemView(title = "救援要求", OrderRequirementsItemView(title = "救援要求",
content = taskNotesBean?.taskNotes) content = taskNotesBean?.taskNotes ?: "")
} }
if (! taskNotesBean?.customerNotes.isNullOrBlank()) { if (! taskNotesBean?.customerNotes.isNullOrBlank()) {
OrderRequirementsItemView(title = "客户要求", OrderRequirementsItemView(title = "客户要求",
content = taskNotesBean?.customerNotes) content = taskNotesBean?.customerNotes ?: "")
} }
if (isShowChangeBattery == true) { if (isShowChangeBattery == true) {

View File

@ -1,6 +1,5 @@
package com.za.ui.servicing.inservice_people_confirm package com.za.ui.servicing.inservice_people_confirm
import com.blankj.utilcode.util.ToastUtils
import com.za.base.IServicingVm import com.za.base.IServicingVm
import com.za.base.view.LoadingManager import com.za.base.view.LoadingManager
import com.za.bean.db.order.OrderInfo import com.za.bean.db.order.OrderInfo
@ -40,7 +39,6 @@ class InServicePeopleConfirmVm : IServicingVm<Action, UiState>() {
} }
} }
private fun updateTask() { private fun updateTask() {
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { ZdLocationManager.getSingleLocation(success = {
@ -57,7 +55,23 @@ class InServicePeopleConfirmVm : IServicingVm<Action, UiState>() {
doUploadTask(request = taskRequest) doUploadTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
val taskRequest = UpdateTaskRequest(type = "START",
taskId = getCurrentOrder()?.taskId,
userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
currentState = getCurrentOrder()?.taskState,
offlineMode = 0,
operateTime = System.currentTimeMillis().toString(),
lat = GlobalData.currentLocation?.latitude,
lng = GlobalData.currentLocation?.longitude)
doUploadTask(request = taskRequest)
} else {
LogUtil.print("$tag updateTask", "使用全局定位失败$it")
showTipDialog(it)
}
}) })
} }
@ -69,7 +83,7 @@ class InServicePeopleConfirmVm : IServicingVm<Action, UiState>() {
updateState(uiState.value.copy(goNextPage = data, orderInfo = getCurrentOrder())) updateState(uiState.value.copy(goNextPage = data, orderInfo = getCurrentOrder()))
}, failed = { msg, _ -> }, failed = { msg, _ ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg) showTipDialog(msg ?: "提交失败")
LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg") LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg")
}) })
} }
@ -77,7 +91,7 @@ class InServicePeopleConfirmVm : IServicingVm<Action, UiState>() {
private fun comparePeople(url : String?) { private fun comparePeople(url : String?) {
if (url.isNullOrBlank()) { if (url.isNullOrBlank()) {
ToastUtils.showLong("图片路径为空!") showTipDialog("图片路径为空!")
return return
} }
LoadingManager.showLoading() LoadingManager.showLoading()

View File

@ -22,11 +22,11 @@ import kotlinx.coroutines.flow.MutableStateFlow
class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>() { class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>() {
private val _uiState = MutableStateFlow(UiState()) private val _uiState = MutableStateFlow(UiState())
val uiState get() = _uiState val uiState get() = _uiState
override fun updateState(uiState: UiState) { override fun updateState(uiState : UiState) {
_uiState.value = uiState _uiState.value = uiState
} }
override fun dispatch(action: Action) { override fun dispatch(action : Action) {
when (action) { when (action) {
is Action.Init -> init() is Action.Init -> init()
is Action.UpdateTask -> updateTask() is Action.UpdateTask -> updateTask()
@ -48,9 +48,9 @@ class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>(
return@forEachIndexed return@forEachIndexed
} }
if (!photoTemplateInfo.photoLocalWaterMarkerPath.isNullOrBlank() && photoTemplateInfo.photoUploadPath.isNullOrBlank()) { if (! photoTemplateInfo.photoLocalWaterMarkerPath.isNullOrBlank() && photoTemplateInfo.photoUploadPath.isNullOrBlank()) {
val offlineUpdateTaskBean = OfflineUpdateTaskBean( val offlineUpdateTaskBean =
realTakePhotoTime = photoTemplateInfo.realTakePhotoTime, OfflineUpdateTaskBean(realTakePhotoTime = photoTemplateInfo.realTakePhotoTime,
photoSource = photoTemplateInfo.photoSource, photoSource = photoTemplateInfo.photoSource,
time = photoTemplateInfo.time, time = photoTemplateInfo.time,
imageLat = photoTemplateInfo.lat, imageLat = photoTemplateInfo.lat,
@ -91,18 +91,23 @@ class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>(
} }
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(isNeedAddress = true, ZdLocationManager.getSingleLocation(isNeedAddress = true, success = {
success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
doUploadOfflineTask(it, tempPhotoList = tempPhotoList) doUploadOfflineTask(it, tempPhotoList = tempPhotoList)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline", "定位获取失败$it") LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
doUploadOfflineTask(GlobalData.currentLocation, tempPhotoList = tempPhotoList)
} else {
LogUtil.print("$tag updateOffline", "全局定位获取失败$it")
showTipDialog(it)
}
}) })
} }
private fun doUploadOfflineTask(it: AMapLocation?, tempPhotoList: ArrayList<String?>) { private fun doUploadOfflineTask(it : AMapLocation?, tempPhotoList : ArrayList<String?>) {
val taskRequest = UpdateTaskRequest(type = "OPERATION", val taskRequest = UpdateTaskRequest(type = "OPERATION",
taskId = GlobalData.currentOrder?.taskId, taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId, userId = GlobalData.driverInfoBean?.userId,
@ -116,9 +121,8 @@ class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>(
address = it?.address, address = it?.address,
templatePhotoInfoList = tempPhotoList.toList()) templatePhotoInfoList = tempPhotoList.toList())
if (!getCurrentOrderOfflineTask().isNullOrEmpty()) { if (! getCurrentOrderOfflineTask().isNullOrEmpty()) {
val offlineUpdateTaskBean = OfflineUpdateTaskBean( val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = taskRequest.type,
type = taskRequest.type,
taskId = taskRequest.taskId, taskId = taskRequest.taskId,
userId = taskRequest.userId, userId = taskRequest.userId,
vehicleId = taskRequest.vehicleId, vehicleId = taskRequest.vehicleId,
@ -138,13 +142,14 @@ class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>(
insertOfflineTask(offlineUpdateTaskBean) insertOfflineTask(offlineUpdateTaskBean)
updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus())) updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus()))
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState), orderInfo = getCurrentOrder())) updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState),
orderInfo = getCurrentOrder()))
} }
} }
private fun updateTask() { private fun updateTask() {
if (uiState.value.photoTemplateList.isNullOrEmpty()) { if (uiState.value.photoTemplateList.isNullOrEmpty()) {
ToastUtils.showShort("作业照片不能为空!") showTipDialog("作业照片不能为空!")
return return
} }
@ -154,13 +159,13 @@ class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>(
return@forEach return@forEach
} }
if (it.doHaveFilm == 1 && it.photoLocalWaterMarkerPath.isNullOrBlank()) { if (it.doHaveFilm == 1 && it.photoLocalWaterMarkerPath.isNullOrBlank()) {
ToastUtils.showLong("请上传 ${it.imageTitle}") showTipDialog("请上传 ${it.imageTitle}")
return return
} }
} }
//先判断是否有离线任务 //先判断是否有离线任务
if (!getCurrentOrderOfflineTask().isNullOrEmpty()) { if (! getCurrentOrderOfflineTask().isNullOrEmpty()) {
updateOffline() updateOffline()
return return
} }
@ -171,11 +176,11 @@ class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>(
} }
if (it.photoUploadStatus == 4) { if (it.photoUploadStatus == 4) {
ToastUtils.showLong("${it.photoName}正在上传,请等待照片上传完成!") showTipDialog("${it.photoName}正在上传,请等待照片上传完成!")
return return
} }
if (!it.photoLocalWaterMarkerPath.isNullOrBlank() && it.photoUploadPath.isNullOrBlank()) { if (! it.photoLocalWaterMarkerPath.isNullOrBlank() && it.photoUploadPath.isNullOrBlank()) {
updateState(uiState.value.copy(showOfflineDialog = true)) updateState(uiState.value.copy(showOfflineDialog = true))
return return
} }
@ -217,22 +222,42 @@ class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>(
doUploadTask(request = taskRequest) doUploadTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it)
if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
val taskRequest = UpdateTaskRequest(type = "OPERATION",
taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId,
flowType = GlobalData.currentOrder?.flowType,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
currentState = "OPERATION",
offlineMode = 0,
operateTime = System.currentTimeMillis().toString(),
lat = GlobalData.currentLocation?.latitude,
lng = GlobalData.currentLocation?.longitude,
address = GlobalData.currentLocation?.address,
templatePhotoInfoList = tempPhotoList.toList())
doUploadTask(request = taskRequest)
} else {
LogUtil.print("$tag updateOffline", "全局定位获取失败$it")
showTipDialog(it)
}
}) })
} }
private fun doUploadTask(request: UpdateTaskRequest) { private fun doUploadTask(request : UpdateTaskRequest) {
LoadingManager.showLoading() LoadingManager.showLoading()
CommonMethod.updateTask(request, success = { CommonMethod.updateTask(request, success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
updateOrder(getCurrentOrder()?.copy(taskState = it?.nextState)) updateOrder(getCurrentOrder()?.copy(taskState = it?.nextState))
updateState(uiState.value.copy(goNextPage = it, orderInfo = getCurrentOrder())) updateState(uiState.value.copy(goNextPage = it, orderInfo = getCurrentOrder()))
}, failed = { msg, code -> }, failed = { msg, code ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg)
if (code == Const.NetWorkException) { if (code == Const.NetWorkException) {
updateState(uiState.value.copy(showOfflineDialog = true)) updateState(uiState.value.copy(showOfflineDialog = true))
} else {
showTipDialog(msg ?: "提交失败")
} }
LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg") LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg")
}) })
@ -250,16 +275,16 @@ class InOperationVm : IServicingVm<InOperationVm.Action, InOperationVm.UiState>(
sealed class Action { sealed class Action {
data object Init : Action() data object Init : Action()
data object UpdateTask : Action() data object UpdateTask : Action()
data class UpdatePhotoTemplate(val photoTemplateInfo: PhotoTemplateInfo) : Action() data class UpdatePhotoTemplate(val photoTemplateInfo : PhotoTemplateInfo) : Action()
data class UpdateState(val uiState: UiState) : Action() data class UpdateState(val uiState : UiState) : Action()
data object UpdateOffline : Action() data object UpdateOffline : Action()
} }
data class UiState(val orderInfo: OrderInfo? = null, data class UiState(val orderInfo : OrderInfo? = null,
val verifyValue: String? = null, val verifyValue : String? = null,
val goNextPage: UpdateTaskBean? = null, val goNextPage : UpdateTaskBean? = null,
val isGoNextPageDialog: Boolean? = null, val isGoNextPageDialog : Boolean? = null,
val showCallPhoneDialog: Boolean? = null, val showCallPhoneDialog : Boolean? = null,
val showOfflineDialog: Boolean? = null, val showOfflineDialog : Boolean? = null,
val photoTemplateList: List<PhotoTemplateInfo>? = null) val photoTemplateList : List<PhotoTemplateInfo>? = null)
} }

View File

@ -33,7 +33,7 @@ import com.za.ext.goStatusPage
import com.za.ui.servicing.InServicingPhotoView import com.za.ui.servicing.InServicingPhotoView
@Composable @Composable
fun ChangeBatteryScreen(vm: ChangeBatteryVm = viewModel()) { fun ChangeBatteryScreen(vm : ChangeBatteryVm = viewModel()) {
val uiState = vm.uiState.collectAsStateWithLifecycle() val uiState = vm.uiState.collectAsStateWithLifecycle()
val context = LocalContext.current val context = LocalContext.current
LaunchedEffect(key1 = Unit) { LaunchedEffect(key1 = Unit) {
@ -57,7 +57,8 @@ fun ChangeBatteryScreen(vm: ChangeBatteryVm = viewModel()) {
contentPadding = PaddingValues(10.dp)) { contentPadding = PaddingValues(10.dp)) {
item { item {
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier Row(verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(10.dp) .padding(10.dp)
.background(color = Color.White, shape = RoundedCornerShape(4.dp)) .background(color = Color.White, shape = RoundedCornerShape(4.dp))
@ -66,11 +67,13 @@ fun ChangeBatteryScreen(vm: ChangeBatteryVm = viewModel()) {
Spacer(modifier = Modifier.width(10.dp)) Spacer(modifier = Modifier.width(10.dp))
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
Text(text = "更换", color = Color.Black) Text(text = "更换", color = Color.Black)
Checkbox(checked = uiState.value.eleWorkOrderBean?.changeBattery == true, onCheckedChange = { Checkbox(checked = uiState.value.eleWorkOrderBean?.changeBattery == true,
onCheckedChange = {
val eleWorkOrderBean = uiState.value.eleWorkOrderBean val eleWorkOrderBean = uiState.value.eleWorkOrderBean
vm.dispatch(ChangeBatteryVm.Action.UpdateState(uiState.value.copy(eleWorkOrderBean = eleWorkOrderBean?.copy(changeBattery = true)))) vm.dispatch(ChangeBatteryVm.Action.UpdateState(uiState.value.copy(
}, colors = CheckboxDefaults.colors() eleWorkOrderBean = eleWorkOrderBean?.copy(changeBattery = true))))
.copy(uncheckedBoxColor = Color.Gray, },
colors = CheckboxDefaults.colors().copy(uncheckedBoxColor = Color.Gray,
checkedBorderColor = Color.Transparent, checkedBorderColor = Color.Transparent,
uncheckedBorderColor = Color.Transparent, uncheckedBorderColor = Color.Transparent,
checkedBoxColor = Color.Red)) checkedBoxColor = Color.Red))
@ -83,9 +86,10 @@ fun ChangeBatteryScreen(vm: ChangeBatteryVm = viewModel()) {
Checkbox(checked = uiState.value.eleWorkOrderBean?.changeBattery == false, Checkbox(checked = uiState.value.eleWorkOrderBean?.changeBattery == false,
onCheckedChange = { onCheckedChange = {
val eleWorkOrderBean = uiState.value.eleWorkOrderBean val eleWorkOrderBean = uiState.value.eleWorkOrderBean
vm.dispatch(ChangeBatteryVm.Action.UpdateState(uiState.value.copy(eleWorkOrderBean = eleWorkOrderBean?.copy(changeBattery = false)))) vm.dispatch(ChangeBatteryVm.Action.UpdateState(uiState.value.copy(
}, colors = CheckboxDefaults.colors() eleWorkOrderBean = eleWorkOrderBean?.copy(changeBattery = false))))
.copy(uncheckedBoxColor = Color.Gray, },
colors = CheckboxDefaults.colors().copy(uncheckedBoxColor = Color.Gray,
checkedBorderColor = Color.Transparent, checkedBorderColor = Color.Transparent,
uncheckedBorderColor = Color.Transparent, uncheckedBorderColor = Color.Transparent,
checkedBoxColor = Color.Red)) checkedBoxColor = Color.Red))
@ -93,9 +97,9 @@ fun ChangeBatteryScreen(vm: ChangeBatteryVm = viewModel()) {
} }
} }
itemsIndexed(items = uiState.value.changeBatteryPhoto itemsIndexed(items = uiState.value.changeBatteryPhoto ?: arrayListOf(),
?: arrayListOf(), key = { _, item -> item.hashCode() }) { index: Int, item: PhotoTemplateInfo -> key = { _, item -> item.hashCode() }) { index : Int, item : PhotoTemplateInfo ->
InServicingPhotoView(photoTemplateInfo = item, index = index, success = { InServicingPhotoView(photoTemplateInfo = item, index = index + 1, success = {
vm.dispatch(ChangeBatteryVm.Action.UpdatePhotoTemplate(it)) vm.dispatch(ChangeBatteryVm.Action.UpdatePhotoTemplate(it))
}) })
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))

View File

@ -67,6 +67,7 @@ import com.za.common.GlobalData
import com.za.common.util.AppFileManager import com.za.common.util.AppFileManager
import com.za.common.util.ServicingSpeechManager import com.za.common.util.ServicingSpeechManager
import com.za.ext.finish import com.za.ext.finish
import com.za.ext.getLastSix
import com.za.ext.goNextPage import com.za.ext.goNextPage
import com.za.servicing.R import com.za.servicing.R
import com.za.ui.view.SignatureView import com.za.ui.view.SignatureView
@ -153,6 +154,46 @@ fun ConfirmEleScreen(vm : ConfirmEleVm = viewModel()) {
}) })
} }
if (uiState.value.showServiceSignatureUploadFailedDialog == true) {
CommonDialog(cancelText = "取消",
confirmText = "离线上传",
title = "服务人员签名上传失败,是否进行离线上传?",
cancelEnable = true,
cancel = {
vm.dispatch(ConfirmEleVm.Action.UpdateState(uiState.value.copy(
showServiceSignatureUploadFailedDialog = false)))
},
dismiss = {
vm.dispatch(ConfirmEleVm.Action.UpdateState(uiState.value.copy(
showServiceSignatureUploadFailedDialog = false)))
},
confirm = {
vm.dispatch(ConfirmEleVm.Action.UpdateState(uiState.value.copy(
showServiceSignatureUploadFailedDialog = false)))
vm.dispatch(ConfirmEleVm.Action.UploadOfflineServicePeopleSignature)
})
}
if (uiState.value.showAcceptCarSignUploadFailedDialog == true) {
CommonDialog(cancelText = "取消",
confirmText = "离线上传",
title = "接车人员签名上传失败,是否进行离线上传?",
cancelEnable = true,
cancel = {
vm.dispatch(ConfirmEleVm.Action.UpdateState(uiState.value.copy(
showAcceptCarSignUploadFailedDialog = false)))
},
dismiss = {
vm.dispatch(ConfirmEleVm.Action.UpdateState(uiState.value.copy(
showAcceptCarSignUploadFailedDialog = false)))
},
confirm = {
vm.dispatch(ConfirmEleVm.Action.UpdateState(uiState.value.copy(
showAcceptCarSignUploadFailedDialog = false)))
vm.dispatch(ConfirmEleVm.Action.UploadOfflineAcceptCarSignature)
})
}
Scaffold(topBar = { Scaffold(topBar = {
HeadView(title = "客户签字", onBack = { context.finish() }) HeadView(title = "客户签字", onBack = { context.finish() })
@ -249,7 +290,9 @@ fun ConfirmEleScreen(vm : ConfirmEleVm = viewModel()) {
.padding(horizontal = 16.dp)) { .padding(horizontal = 16.dp)) {
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
Row(verticalAlignment = Alignment.CenterVertically, Row(verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxHeight().fillMaxWidth()) { modifier = Modifier
.fillMaxHeight()
.fillMaxWidth()) {
Text(text = "*", Text(text = "*",
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = Color.Red, color = Color.Red,
@ -403,8 +446,7 @@ fun ConfirmEleScreen(vm : ConfirmEleVm = viewModel()) {
if (! FileUtils.isFileExists(File(AppFileManager.getDriverSignPath( if (! FileUtils.isFileExists(File(AppFileManager.getDriverSignPath(
context))) context)))
) { ) {
vm.updateState(uiState.value.copy( vm.updateState(uiState.value.copy(showServicePeopleSignDialog = true))
showServicePeopleSignDialog = true))
} }
}, },
serverPath = uiState.value.eleWorkOrderBean?.serverServicePeopleSignPath serverPath = uiState.value.eleWorkOrderBean?.serverServicePeopleSignPath
@ -487,9 +529,11 @@ private fun EleWorkOrderDetailView(eleWorkOrderBean : EleWorkOrderBean?,
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
Text(text = "车架号后6位", fontSize = 12.sp, color = black65) Text(text = "车架号后6位", fontSize = 12.sp, color = black65)
Spacer(modifier = Modifier.width(5.dp)) Spacer(modifier = Modifier.width(5.dp))
Text(text = eleWorkOrderBean?.carVin ?: "", Text(text = eleWorkOrderBean?.carVin?.getLastSix()
?: GlobalData.currentOrder?.carNo?.getLastSix() ?: "",
textDecoration = TextDecoration.Underline, textDecoration = TextDecoration.Underline,
fontSize = 12.sp, fontSize = 12.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,

View File

@ -1,8 +1,11 @@
package com.za.ui.servicing.order_confirm package com.za.ui.servicing.order_confirm
import androidx.lifecycle.viewModelScope
import com.amap.api.location.AMapLocation
import com.blankj.utilcode.util.ActivityUtils import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.FileUtils import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.NetworkUtils
import com.blankj.utilcode.util.ToastUtils import com.blankj.utilcode.util.ToastUtils
import com.za.base.Const import com.za.base.Const
import com.za.base.IServicingVm import com.za.base.IServicingVm
@ -24,7 +27,10 @@ import com.za.room.RoomHelper
import com.za.service.location.ZdLocationManager import com.za.service.location.ZdLocationManager
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File import java.io.File
class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() { class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
@ -45,9 +51,30 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
is Action.UploadServiceSignature -> updateServiceSignature(action.path) is Action.UploadServiceSignature -> updateServiceSignature(action.path)
is Action.IsChangeBattery -> updateIsChangeBattery(action.isChange) is Action.IsChangeBattery -> updateIsChangeBattery(action.isChange)
is Action.UploadOffline -> uploadOffline() is Action.UploadOffline -> uploadOffline()
is Action.UploadOfflineAcceptCarSignature -> uploadOfflineAcceptCarSignature()
is Action.UploadOfflineServicePeopleSignature -> uploadOfflineServicePeopleSignature()
} }
} }
private fun uploadOfflineAcceptCarSignature() {
val signOfflineUpdateTaskBean =
OfflineUpdateTaskBean(imageLocalPath = uiState.value.eleWorkOrderBean?.localAcceptCarSignPath,
taskId = getCurrentOrder()?.taskId,
taskCode = getCurrentOrder()?.taskCode,
offlineTitle = "电子工单-接车人签字",
offlineType = 6)
insertOfflineTask(signOfflineUpdateTaskBean)
}
private fun uploadOfflineServicePeopleSignature() {
val signOfflineUpdateTaskBean =
OfflineUpdateTaskBean(imageLocalPath = uiState.value.eleWorkOrderBean?.localServicePeopleSignPath,
taskId = getCurrentOrder()?.taskId,
taskCode = getCurrentOrder()?.taskCode,
offlineTitle = "电子工单-服务人员签字",
offlineType = 7)
insertOfflineTask(signOfflineUpdateTaskBean)
}
private fun updateIsChangeBattery(isChange : Boolean) { private fun updateIsChangeBattery(isChange : Boolean) {
updateState(uiState.value.copy(eleWorkOrderBean = uiState.value.eleWorkOrderBean?.copy( updateState(uiState.value.copy(eleWorkOrderBean = uiState.value.eleWorkOrderBean?.copy(
@ -85,6 +112,17 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
} }
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
viewModelScope.launch(Dispatchers.IO) {
if (! NetworkUtils.isAvailable()) {
withContext(Dispatchers.Main) {
updateState(uiState.value.copy(showServiceSignatureUploadFailedDialog = true))
}
} else {
withContext(Dispatchers.Main) {
showTipDialog("服务人员签名上传失败,请重新签名上传")
}
}
}
LogUtil.print("updateServiceSignature", "failed==$it") LogUtil.print("updateServiceSignature", "failed==$it")
}) })
} }
@ -97,6 +135,7 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
updateState(uiState.value.copy(eleWorkOrderBean = eleWorkOrderBean)) updateState(uiState.value.copy(eleWorkOrderBean = eleWorkOrderBean))
LogUtil.print("updateServiceSignature success", eleWorkOrderBean.toJson() ?: "") LogUtil.print("updateServiceSignature success", eleWorkOrderBean.toJson() ?: "")
} }
CommonMethod.uploadImage(File(path), success = { CommonMethod.uploadImage(File(path), success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
if (eleWorkOrderBean != null) { if (eleWorkOrderBean != null) {
@ -107,39 +146,30 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
} }
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
viewModelScope.launch(Dispatchers.IO) {
if (! NetworkUtils.isAvailable()) {
withContext(Dispatchers.Main) {
updateState(uiState.value.copy(showAcceptCarSignUploadFailedDialog = true))
}
} else {
withContext(Dispatchers.Main) {
showTipDialog("接车人签字上传失败,请重新签名上传")
}
}
}
LogUtil.print("uploadAcceptSignature", "failed==$it") LogUtil.print("uploadAcceptSignature", "failed==$it")
}) })
} }
private fun uploadOffline() { private fun uploadOffline() {
val eleWorkOrderBean = val eleWorkOrderBean =
RoomHelper.db?.eleWorkOrderDao()?.getEleWorkOrder(getCurrentOrder()?.taskId ?: 0) RoomHelper.db?.eleWorkOrderDao()?.getEleWorkOrder(getCurrentOrder()?.taskId ?: 0)
if (eleWorkOrderBean == null) { if (eleWorkOrderBean == null) {
ToastUtils.showLong("数据获取失败,请返回首页重试!") showTipDialog("数据获取失败,请返回首页重试!")
return return
} }
if (uiState.value.eleWorkOrderBean?.serverAcceptCarSignPath.isNullOrBlank()) {
val signOfflineUpdateTaskBean =
OfflineUpdateTaskBean(imageLocalPath = uiState.value.eleWorkOrderBean?.localAcceptCarSignPath,
taskId = getCurrentOrder()?.taskId,
taskCode = getCurrentOrder()?.taskCode,
offlineTitle = "电子工单-接车人签字",
offlineType = 6)
insertOfflineTask(signOfflineUpdateTaskBean)
}
if (uiState.value.eleWorkOrderBean?.serverServicePeopleSignPath.isNullOrBlank()) {
val signOfflineUpdateTaskBean =
OfflineUpdateTaskBean(imageLocalPath = uiState.value.eleWorkOrderBean?.localServicePeopleSignPath,
taskId = getCurrentOrder()?.taskId,
taskCode = getCurrentOrder()?.taskCode,
offlineTitle = "电子工单-服务人员签字",
offlineType = 7)
insertOfflineTask(signOfflineUpdateTaskBean)
}
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { ZdLocationManager.getSingleLocation(success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
@ -189,7 +219,7 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
private fun upload() { private fun upload() {
val eleWorkOrderBean = uiState.value.eleWorkOrderBean val eleWorkOrderBean = uiState.value.eleWorkOrderBean
if (eleWorkOrderBean == null) { if (eleWorkOrderBean == null) {
ToastUtils.showLong("数据获取失败,请返回首页重试!") showTipDialog("数据获取失败,请返回首页重试!")
return return
} }
@ -221,11 +251,26 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { ZdLocationManager.getSingleLocation(success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
doUpload(eleWorkOrderBean, it)
}, failed = {
LoadingManager.hideLoading()
if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
doUpload(eleWorkOrderBean, GlobalData.currentLocation)
} else {
LogUtil.print("$tag Upload", "全局定位获取失败$it")
showTipDialog(it)
}
})
}
private fun doUpload(eleWorkOrderBean : EleWorkOrderBean, location : AMapLocation? = null) {
val saveEleOrderRequest = SaveEleOrderRequest(state = 3, val saveEleOrderRequest = SaveEleOrderRequest(state = 3,
userOrderId = GlobalData.currentOrder?.userOrderId, userOrderId = GlobalData.currentOrder?.userOrderId,
taskOrderId = GlobalData.currentOrder?.taskId, taskOrderId = GlobalData.currentOrder?.taskId,
lat = it.latitude, lat = location?.latitude,
lng = it.longitude, lng = location?.longitude,
offlineMode = 0, offlineMode = 0,
isFinish = true, isFinish = true,
tyreNumber = if (uiState.value.isAddSmallWheel == true) { tyreNumber = if (uiState.value.isAddSmallWheel == true) {
@ -243,21 +288,19 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
updateCurrentEleWorkOrder(eleWorkOrderBean.copy(orderWorkStatus = 3)) updateCurrentEleWorkOrder(eleWorkOrderBean.copy(orderWorkStatus = 3))
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(getCurrentOrder()?.taskState), updateState(uiState.value.copy(goNextPage = UpdateTaskBean(getCurrentOrder()?.taskState),
orderInfo = getCurrentOrder())) orderInfo = getCurrentOrder()))
updateOrder(orderInfo = getCurrentOrder()?.copy(tyreNumber = uiState.value.wheelNum))
} }
override fun doFailure(code : Int, msg : String?) { override fun doFailure(code : Int, msg : String?) {
LoadingManager.hideLoading() LoadingManager.hideLoading()
if (code == Const.NetWorkException) { if (code == Const.NetWorkException) {
updateState(uiState.value.copy(showOfflineDialog = true)) updateState(uiState.value.copy(showOfflineDialog = true))
} else {
showTipDialog(msg ?: "数据提交异常")
} }
LogUtil.print("eleSign upload failed", msg ?: "") LogUtil.print("eleSign upload failed", msg ?: "")
} }
}) })
}, failed = {
LoadingManager.hideLoading()
ToastUtils.showShort(it)
})
} }
private fun init() { private fun init() {
@ -295,6 +338,8 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
data class IsChangeBattery(val isChange : Boolean) : Action() data class IsChangeBattery(val isChange : Boolean) : Action()
data class UpdateAcceptSignature(val path : String) : Action() data class UpdateAcceptSignature(val path : String) : Action()
data class UploadServiceSignature(val path : String) : Action() data class UploadServiceSignature(val path : String) : Action()
data object UploadOfflineServicePeopleSignature : Action()
data object UploadOfflineAcceptCarSignature : Action()
} }
data class UiState( data class UiState(
@ -307,6 +352,8 @@ class ConfirmEleVm : IServicingVm<ConfirmEleVm.Action, ConfirmEleVm.UiState>() {
val isAddSmallWheel : Boolean? = null, val isAddSmallWheel : Boolean? = null,
val wheelNum : Int? = null, val wheelNum : Int? = null,
val showOfflineDialog : Boolean? = null, val showOfflineDialog : Boolean? = null,
val showAcceptCarSignUploadFailedDialog : Boolean? = null,
val showServiceSignatureUploadFailedDialog : Boolean? = null,
val showServicePeopleSignDialog : Boolean? = null, //服务人员签名弹窗 val showServicePeopleSignDialog : Boolean? = null, //服务人员签名弹窗
) )
} }

View File

@ -127,23 +127,17 @@ fun ConfirmH5SuccessScreen(vm : ConfirmH5SuccessVm = viewModel()) {
vm.updateState(uiState.value.copy(showSignDialog = null)) vm.updateState(uiState.value.copy(showSignDialog = null))
}, cancelEnable = false, confirm = { }, cancelEnable = false, confirm = {
vm.updateState(uiState.value.copy(showSignDialog = null)) vm.updateState(uiState.value.copy(showSignDialog = null))
val intent = Intent(context, GridPaintActivity::class.java)
intent.putExtra("background", android.graphics.Color.WHITE)
intent.putExtra("crop", true)
intent.putExtra("fontSize", 50) //手写字体大小
intent.putExtra("format", PenConfig.FORMAT_PNG)
intent.putExtra("lineLength", 10) //每行显示字数(超出屏幕支持横向滚动)
when (uiState.value.showSignDialog) { when (uiState.value.showSignDialog) {
1 -> { 1 -> {
customerSignatureLauncher.launch(intent) GridPaintActivity.goGridPaintActivity(customerSignatureLauncher, context)
} }
2 -> { 2 -> {
receivePeopleSignatureLauncher.launch(intent) GridPaintActivity.goGridPaintActivity(receivePeopleSignatureLauncher, context)
} }
3 -> { 3 -> {
servicePeopleSignatureLauncher.launch(intent) GridPaintActivity.goGridPaintActivity(servicePeopleSignatureLauncher, context)
} }
} }
}, cancelText = "取消", dismiss = { }, cancelText = "取消", dismiss = {

View File

@ -1,5 +1,6 @@
package com.za.ui.servicing.order_confirm package com.za.ui.servicing.order_confirm
import com.amap.api.location.AMapLocation
import com.blankj.utilcode.util.ToastUtils import com.blankj.utilcode.util.ToastUtils
import com.za.base.Const import com.za.base.Const
import com.za.base.IServicingVm import com.za.base.IServicingVm
@ -11,6 +12,7 @@ import com.za.bean.request.QueryEleOrderRequest
import com.za.bean.request.SaveEleOrderRequest import com.za.bean.request.SaveEleOrderRequest
import com.za.bean.request.TaskFinishRequest import com.za.bean.request.TaskFinishRequest
import com.za.bean.request.TaskFinishResponse import com.za.bean.request.TaskFinishResponse
import com.za.common.GlobalData
import com.za.common.log.LogUtil import com.za.common.log.LogUtil
import com.za.ext.toJson import com.za.ext.toJson
import com.za.net.BaseObserver import com.za.net.BaseObserver
@ -174,7 +176,6 @@ class ConfirmH5SuccessVm : IServicingVm<ConfirmH5SuccessVm.Action, ConfirmH5Succ
updateState(uiState.value.copy(showOfflineTaskDialog = true)) updateState(uiState.value.copy(showOfflineTaskDialog = true))
return return
} }
queryEleWorkOrder(success = { queryEleWorkOrder(success = {
doTaskFinish() doTaskFinish()
}, failed = { }, failed = {
@ -186,9 +187,23 @@ class ConfirmH5SuccessVm : IServicingVm<ConfirmH5SuccessVm.Action, ConfirmH5Succ
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { it -> ZdLocationManager.getSingleLocation(success = { it ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
taskFinishImpl()
}, failed = {
LoadingManager.hideLoading()
if (GlobalData.currentLocation != null) {
LogUtil.print("taskFinish", "使用全局定位${GlobalData.currentLocation?.toJson()}")
taskFinishImpl(GlobalData.currentLocation)
} else {
LogUtil.print("taskFinish", "定位获取失败$it")
updateState(uiState.value.copy(loadingState = LoadingState.LoadingFailed(it)))
}
})
}
private fun taskFinishImpl(location : AMapLocation? = null) {
val taskFinishRequest = TaskFinishRequest(uiState.value.orderInfo?.userOrderId, val taskFinishRequest = TaskFinishRequest(uiState.value.orderInfo?.userOrderId,
it.latitude, location?.latitude,
it.longitude, location?.longitude,
System.currentTimeMillis()) System.currentTimeMillis())
LoadingManager.showLoading() LoadingManager.showLoading()
RetrofitHelper.getDefaultService().taskFinish(taskFinishRequest) RetrofitHelper.getDefaultService().taskFinish(taskFinishRequest)
@ -219,11 +234,6 @@ class ConfirmH5SuccessVm : IServicingVm<ConfirmH5SuccessVm.Action, ConfirmH5Succ
LogUtil.print("任务失败", "code==$code msg==$msg") LogUtil.print("任务失败", "code==$code msg==$msg")
} }
}) })
}, failed = {
LoadingManager.hideLoading()
ToastUtils.showLong(it)
updateState(uiState.value.copy(loadingState = LoadingState.LoadingFailed(it)))
})
} }
sealed class Action { sealed class Action {

View File

@ -1,3 +1,5 @@
package com.za.ui.servicing.order_confirm.modify_money
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row

View File

@ -45,9 +45,8 @@ class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
userOrderId = userOrderId, userOrderId = userOrderId,
taskId = taskId, taskId = taskId,
unitPrice = it?.unitPrice, unitPrice = it?.unitPrice,
mileage = it?.mileage?.plus(uiState.value.paymentInfoBean?.limitedMileage mileage = it?.mileage?.plus(it.limitedMileage ?: 0),
?: 0), mileageText = "${it?.mileage?.plus(it.limitedMileage ?: 0)}",
mileageText = "${it?.mileage?.plus(uiState.value.paymentInfoBean?.limitedMileage ?: 0)}",
calculateAmount = it?.calculateAmount, calculateAmount = it?.calculateAmount,
adjustAmount = it?.adjustAmount?.toFloat(), adjustAmount = it?.adjustAmount?.toFloat(),
adjustAmountText = "${it?.adjustAmount ?: ""}", adjustAmountText = "${it?.adjustAmount ?: ""}",

View File

@ -293,6 +293,12 @@ private fun OrderConfirmEditView(value : String? = null,
placeholder = { placeholder = {
Text(text = title, fontSize = 14.sp, color = black65) Text(text = title, fontSize = 14.sp, color = black65)
}, },
label = {
Text(text = title,
fontSize = 10.sp,
color = black65,
style = TextStyle.Default.copy())
},
trailingIcon = { trailingIcon = {
Text(text = unit, Text(text = unit,
fontSize = 14.sp, fontSize = 14.sp,

View File

@ -2,7 +2,7 @@ package com.za.ui.servicing.order_confirm.real_order_confirm
import com.alibaba.fastjson.JSONObject import com.alibaba.fastjson.JSONObject
import com.blankj.utilcode.util.ToastUtils import com.amap.api.location.AMapLocation
import com.za.base.Const import com.za.base.Const
import com.za.base.IServicingVm import com.za.base.IServicingVm
import com.za.base.view.LoadingManager import com.za.base.view.LoadingManager
@ -65,19 +65,19 @@ class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiStat
if ((uiState.value.abRoadFee if ((uiState.value.abRoadFee
?: 0) > 0 && uiState.value.aBAndBCPhotos?.find { it.numbering == "P.1" }?.photoUploadPath.isNullOrBlank() ?: 0) > 0 && uiState.value.aBAndBCPhotos?.find { it.numbering == "P.1" }?.photoUploadPath.isNullOrBlank()
) { ) {
ToastUtils.showShort("请在出发段路桥费下方,拍摄发车段路桥费照片") showTipDialog("请在出发段路桥费下方,拍摄发车段路桥费照片")
return return
} }
if ((uiState.value.bcRoadFee if ((uiState.value.bcRoadFee
?: 0) > 0 && uiState.value.aBAndBCPhotos?.find { it.numbering == "P.2" }?.photoUploadPath.isNullOrBlank() ?: 0) > 0 && uiState.value.aBAndBCPhotos?.find { it.numbering == "P.2" }?.photoUploadPath.isNullOrBlank()
) { ) {
ToastUtils.showShort("请在背车段路桥费下方,拍摄背车段路桥费照片") showTipDialog("请在背车段路桥费下方,拍摄背车段路桥费照片")
return return
} }
uiState.value.photoTemplateList?.forEach { uiState.value.photoTemplateList?.forEach {
if (it.doHaveFilm == 1 && it.photoUploadPath.isNullOrBlank()) { if (it.doHaveFilm == 1 && it.photoUploadPath.isNullOrBlank()) {
ToastUtils.showShort("请拍摄${it.imageTitle}照片") showTipDialog("请拍摄${it.imageTitle}照片")
return return
} }
} }
@ -86,11 +86,11 @@ class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiStat
// AB段不为0 BC段拖车流程不为0 // AB段不为0 BC段拖车流程不为0
if (uiState.value.abKm == null || uiState.value.abKm == 0) { if (uiState.value.abKm == null || uiState.value.abKm == 0) {
ToastUtils.showShort("出发地-事发地距离不可为0") showTipDialog("出发地-事发地距离不可为0")
return return
} }
if (uiState.value.orderInfo?.flowType == Const.TUO_CHE && (uiState.value.bcKm == null || uiState.value.bcKm == 0)) { if (uiState.value.orderInfo?.flowType == Const.TUO_CHE && (uiState.value.bcKm == null || uiState.value.bcKm == 0)) {
ToastUtils.showShort("事发地-目的地距离不可为0") showTipDialog("事发地-目的地距离不可为0")
return return
} }
} }
@ -117,6 +117,21 @@ class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiStat
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { it -> ZdLocationManager.getSingleLocation(success = { it ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
doSubmit(tempPhotoList,it)
}, failed = {
LoadingManager.hideLoading()
if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
doSubmit(tempPhotoList, GlobalData.currentLocation)
} else {
LogUtil.print("$tag updateOffline", "全局定位获取失败$it")
showTipDialog(it)
}
})
}
private fun doSubmit(tempPhotoList : List<String?>? = null, location : AMapLocation? = null) {
val orderConfirmTaskRequest = UpdateOrderConfirmTaskRequest(type = "SETTLEMENT", val orderConfirmTaskRequest = UpdateOrderConfirmTaskRequest(type = "SETTLEMENT",
taskId = GlobalData.currentOrder?.taskId, taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId, userId = GlobalData.driverInfoBean?.userId,
@ -126,11 +141,16 @@ class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiStat
supplierType = GlobalData.driverInfoBean?.supplierType, supplierType = GlobalData.driverInfoBean?.supplierType,
settleType = GlobalData.currentOrder?.settleType, settleType = GlobalData.currentOrder?.settleType,
carryMileage = uiState.value.bcKm, carryMileage = uiState.value.bcKm,
mileage = uiState.value.overKm,
unitPrice = uiState.value.unitKmPrice?.toDouble(),
startPrice = uiState.value.startPrice,
startMileage = uiState.value.abKm, startMileage = uiState.value.abKm,
startRoadFee = uiState.value.abRoadFee, startRoadFee = uiState.value.abRoadFee,
carryRoadFee = uiState.value.bcRoadFee, carryRoadFee = uiState.value.bcRoadFee,
dilemmaFee = uiState.value.dilemmaFee, dilemmaFee = uiState.value.dilemmaFee,
basementFee = uiState.value.basementFee, basementFee = uiState.value.basementFee,
wheelNum = GlobalData.currentOrder?.tyreNumber ?: 0,
wheelPrice = 25,
basePrice = if (GlobalData.driverInfoBean?.supplierType == Const.CHILD_COMPANY) { basePrice = if (GlobalData.driverInfoBean?.supplierType == Const.CHILD_COMPANY) {
computerBaseFee() computerBaseFee()
} else null, } else null,
@ -139,9 +159,10 @@ class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiStat
} else null, } else null,
totalFee = computerTotalFee(), totalFee = computerTotalFee(),
offlineMode = 0, offlineMode = 0,
lat = it.latitude, lat = location?.latitude,
lng = it.longitude, lng = location?.longitude,
templatePhotoInfoList = tempPhotoList.toList()) templatePhotoInfoList = tempPhotoList?.toList())
LogUtil.print("$tag updateRequest", orderConfirmTaskRequest.toJson() ?: "")
LoadingManager.showLoading() LoadingManager.showLoading()
RetrofitHelper.getDefaultService().submitOrderConfirmTask(orderConfirmTaskRequest) RetrofitHelper.getDefaultService().submitOrderConfirmTask(orderConfirmTaskRequest)
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
@ -149,20 +170,14 @@ class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiStat
override fun doSuccess(it : UpdateTaskBean?) { override fun doSuccess(it : UpdateTaskBean?) {
LoadingManager.hideLoading() LoadingManager.hideLoading()
updateOrder(getCurrentOrder()?.copy(taskState = it?.nextState)) updateOrder(getCurrentOrder()?.copy(taskState = it?.nextState))
updateState(uiState.value.copy(goNextPage = it, updateState(uiState.value.copy(goNextPage = it, orderInfo = getCurrentOrder()))
orderInfo = getCurrentOrder()))
} }
override fun doFailure(code : Int, msg : String?) { override fun doFailure(code : Int, msg : String?) {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg) showTipDialog(msg ?: "提交失败")
} }
}) })
}, failed = {
LoadingManager.hideLoading()
ToastUtils.showShort(it)
})
} }
private fun computerBaseFee() : Double { private fun computerBaseFee() : Double {
@ -172,7 +187,8 @@ class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiStat
private fun computerAssistantsFee() : Double { private fun computerAssistantsFee() : Double {
return (uiState.value.abRoadFee ?: 0) + (uiState.value.bcRoadFee return (uiState.value.abRoadFee ?: 0) + (uiState.value.bcRoadFee
?: 0) + (uiState.value.dilemmaFee ?: 0) + (uiState.value.basementFee ?: 0).toDouble() ?: 0) + (uiState.value.dilemmaFee ?: 0) + (uiState.value.basementFee
?: 0).toDouble() + (uiState.value.orderInfo?.tyreNumber ?: 0) * 25
} }
private fun computerTotalFee() : Double { private fun computerTotalFee() : Double {
@ -220,6 +236,7 @@ class OrderConfirmVm : IServicingVm<OrderConfirmVm.Action, OrderConfirmVm.UiStat
val isGoNextPageDialog : Boolean? = null, val isGoNextPageDialog : Boolean? = null,
val aBAndBCPhotos : List<PhotoTemplateInfo>? = null, val aBAndBCPhotos : List<PhotoTemplateInfo>? = null,
val photoTemplateList : List<PhotoTemplateInfo>? = null, val photoTemplateList : List<PhotoTemplateInfo>? = null,
val updateFailedMessage : String? = null,
val startPrice : Int? = null, //起步价 val startPrice : Int? = null, //起步价
val unitKmPrice : Int? = null, //每公里价格 val unitKmPrice : Int? = null, //每公里价格
val overKm : Int? = null, //超出公里数 val overKm : Int? = null, //超出公里数

View File

@ -31,12 +31,14 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.za.base.BaseActivity import com.za.base.BaseActivity
import com.za.base.Const
import com.za.base.view.CommonButton import com.za.base.view.CommonButton
import com.za.base.view.CommonDialog import com.za.base.view.CommonDialog
import com.za.base.view.HeadView import com.za.base.view.HeadView
import com.za.bean.db.order.OrderInfo import com.za.bean.db.order.OrderInfo
import com.za.bean.db.order.PhotoTemplateInfo import com.za.bean.db.order.PhotoTemplateInfo
import com.za.ext.finish import com.za.ext.finish
import com.za.service.ServiceManager
import com.za.servicing.R import com.za.servicing.R
import com.za.ui.servicing.InServicingPhotoView import com.za.ui.servicing.InServicingPhotoView
import com.za.ui.view.SignatureView import com.za.ui.view.SignatureView
@ -53,8 +55,7 @@ class OrderGiveUpActivity : BaseActivity() {
OrderGiveUpScreen(orderInfo = orderInfo, OrderGiveUpScreen(orderInfo = orderInfo,
taskId = intent.getIntExtra("taskId", 0), taskId = intent.getIntExtra("taskId", 0),
giveUpType = intent.getIntExtra("giveUpType", 0)) { giveUpType = intent.getIntExtra("giveUpType", 0)) { }
}
} }
companion object { companion object {
@ -93,14 +94,17 @@ fun OrderGiveUpScreen(vm : OrderGiveUpVm = viewModel(),
} }
if (uiState.value.orderGiveUpSuccess == true) { if (uiState.value.orderGiveUpSuccess == true) {
ServiceManager.sendMessageToMainProcess(type = Const.PushMessageType.GO_MAIN_PAGE,
message = "goMain",
context = context)
context.finish() context.finish()
onBack() onBack()
} }
if (uiState.value.isGoNextPageDialog == true) { if (uiState.value.isGoNextPageDialog == true) {
CommonDialog(cancelText = "取消", CommonDialog(cancelText = "取消",
confirmText = "是否确认放弃订单", confirmText = "放弃订单",
title = "放弃订单", title = "是否确认放弃订单",
cancelEnable = true, cancelEnable = true,
cancel = { cancel = {
vm.dispatch(OrderGiveUpVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false))) vm.dispatch(OrderGiveUpVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false)))

View File

@ -178,7 +178,21 @@ class OrderGiveUpVm : BaseVm<OrderGiveUpVm.Action, OrderGiveUpVm.UiState>() {
doGiveUpTask(request = taskRequest) doGiveUpTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
val taskRequest = GiveUpTaskRequest(taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
lat = GlobalData.currentLocation?.latitude,
address = GlobalData.currentLocation?.address,
pushGiveUpFlag = 1,
lng = GlobalData.currentLocation?.longitude,
templatePhotoInfoList = tempPhotoList.toList())
doGiveUpTask(request = taskRequest)
} else {
showTipDialog(it)
}
}) })
} }
@ -228,7 +242,21 @@ class OrderGiveUpVm : BaseVm<OrderGiveUpVm.Action, OrderGiveUpVm.UiState>() {
doGiveUpTask(request = taskRequest) doGiveUpTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it)
if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
val taskRequest = GiveUpTaskRequest(taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
lat = GlobalData.currentLocation?.latitude,
address = GlobalData.currentLocation?.address,
lng = GlobalData.currentLocation?.longitude,
templatePhotoInfoList = tempPhotoList.toList())
doGiveUpTask(request = taskRequest)
} else {
showTipDialog(it)
}
}) })
} }
} }

View File

@ -1,5 +1,9 @@
package com.za.ui.servicing.verify package com.za.ui.servicing.verify
import android.app.Activity
import android.content.Intent
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -22,6 +26,10 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
@ -34,16 +42,19 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage import coil.compose.AsyncImage
import com.blankj.utilcode.util.ConvertUtils import com.blankj.utilcode.util.ConvertUtils
import com.blankj.utilcode.util.ToastUtils
import com.za.base.BaseActivity import com.za.base.BaseActivity
import com.za.base.theme.black65 import com.za.base.theme.black65
import com.za.base.theme.buttonBgColor import com.za.base.theme.buttonBgColor
import com.za.base.view.CommonDialog import com.za.base.view.CommonDialog
import com.za.bean.db.order.OrderInfo import com.za.bean.db.order.OrderInfo
import com.za.common.log.LogUtil
import com.za.common.util.QRCodeUtil import com.za.common.util.QRCodeUtil
import com.za.ext.callPhone import com.za.ext.callPhone
import com.za.ext.finish import com.za.ext.finish
import com.za.ext.goNextPage import com.za.ext.goNextPage
import com.za.servicing.R import com.za.servicing.R
import com.za.ui.camera.ZdCameraXActivity
import com.za.ui.servicing.view.InServicingHeadView import com.za.ui.servicing.view.InServicingHeadView
class VerifyOrderActivity : BaseActivity() { class VerifyOrderActivity : BaseActivity() {
@ -53,9 +64,8 @@ class VerifyOrderActivity : BaseActivity() {
} }
} }
@Composable @Composable
fun VerifyOrderScreen(vm: VerifyOrderVm = viewModel()) { fun VerifyOrderScreen(vm : VerifyOrderVm = viewModel()) {
val uiState = vm.uiState.collectAsStateWithLifecycle() val uiState = vm.uiState.collectAsStateWithLifecycle()
val context = LocalContext.current val context = LocalContext.current
LaunchedEffect(key1 = Unit) { LaunchedEffect(key1 = Unit) {
@ -63,15 +73,16 @@ fun VerifyOrderScreen(vm: VerifyOrderVm = viewModel()) {
} }
if (uiState.value.isGoNextPageDialog == true) { if (uiState.value.isGoNextPageDialog == true) {
CommonDialog( CommonDialog(cancelText = "取消",
cancelText = "取消",
confirmText = "前往下一步", confirmText = "前往下一步",
title = "是否前往下一步?", title = "是否前往下一步?",
cancelEnable = true, cancelEnable = true,
cancel = { cancel = {
vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false))) vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false)))
}, },
dismiss = { vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false))) }, dismiss = {
vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false)))
},
confirm = { confirm = {
vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false))) vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false)))
vm.dispatch(VerifyOrderVm.Action.UpdateTask) vm.dispatch(VerifyOrderVm.Action.UpdateTask)
@ -83,15 +94,16 @@ fun VerifyOrderScreen(vm: VerifyOrderVm = viewModel()) {
} }
if (uiState.value.showCallPhoneDialog == true) { if (uiState.value.showCallPhoneDialog == true) {
CommonDialog( CommonDialog(cancelText = "取消",
cancelText = "取消",
confirmText = "确定", confirmText = "确定",
title = "是否联系中道客服?", title = "是否联系中道客服?",
cancelEnable = true, cancelEnable = true,
cancel = { cancel = {
vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showCallPhoneDialog = false))) vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showCallPhoneDialog = false)))
}, },
dismiss = { vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showCallPhoneDialog = false))) }, dismiss = {
vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showCallPhoneDialog = false)))
},
confirm = { confirm = {
vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showCallPhoneDialog = false))) vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showCallPhoneDialog = false)))
context.callPhone(uiState.value.orderInfo?.hotline) context.callPhone(uiState.value.orderInfo?.hotline)
@ -100,22 +112,26 @@ fun VerifyOrderScreen(vm: VerifyOrderVm = viewModel()) {
//离线操作框 //离线操作框
if (uiState.value.showOfflineDialog == true) { if (uiState.value.showOfflineDialog == true) {
CommonDialog( CommonDialog(cancelText = "取消",
cancelText = "取消",
confirmText = "离线上传", confirmText = "离线上传",
title = "是否进行离线提交?", title = "是否进行离线提交?",
cancelEnable = true, cancelEnable = true,
cancel = { cancel = {
vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false))) vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false)))
}, },
dismiss = { vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false))) }, dismiss = {
vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false)))
},
confirm = { confirm = {
vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false))) vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false)))
vm.dispatch(VerifyOrderVm.Action.UploadOffline) vm.dispatch(VerifyOrderVm.Action.UploadOffline)
}) })
} }
Scaffold(topBar = {
Scaffold(topBar = { InServicingHeadView(title = "验证资格", orderInfo = uiState.value.orderInfo, onBack = { context.finish() }) }, bottomBar = { InServicingHeadView(title = "验证资格",
orderInfo = uiState.value.orderInfo,
onBack = { context.finish() })
}, bottomBar = {
Row(modifier = Modifier Row(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background(Color.White, shape = RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp)) .background(Color.White, shape = RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp))
@ -125,10 +141,19 @@ fun VerifyOrderScreen(vm: VerifyOrderVm = viewModel()) {
if (uiState.value.orderInfo?.verifyType != 5) { if (uiState.value.orderInfo?.verifyType != 5) {
Box(modifier = Modifier Box(modifier = Modifier
.weight(1f) .weight(1f)
.clickable { vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(showCallPhoneDialog = true))) } .clickable {
.border(width = 0.8.dp, color = Color(0xFFDDDDDD), shape = RoundedCornerShape(4.dp)) vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(
.padding(vertical = 10.dp), contentAlignment = Alignment.Center) { showCallPhoneDialog = true)))
Text(text = "不符合,联系客服", fontSize = 14.sp, fontWeight = FontWeight.Medium, color = black65) }
.border(width = 0.8.dp,
color = Color(0xFFDDDDDD),
shape = RoundedCornerShape(4.dp))
.padding(vertical = 10.dp),
contentAlignment = Alignment.Center) {
Text(text = "不符合,联系客服",
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = black65)
} }
Spacer(modifier = Modifier.width(5.dp)) Spacer(modifier = Modifier.width(5.dp))
} }
@ -147,41 +172,59 @@ fun VerifyOrderScreen(vm: VerifyOrderVm = viewModel()) {
} }
Box(modifier = Modifier Box(modifier = Modifier
.weight(1f) .weight(1f)
.clickable { vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = true))) } .clickable {
vm.dispatch(VerifyOrderVm.Action.UpdateState(uiState.value.copy(
isGoNextPageDialog = true)))
}
.background(color = buttonBgColor, shape = RoundedCornerShape(4.dp)) .background(color = buttonBgColor, shape = RoundedCornerShape(4.dp))
.padding(vertical = 10.dp), contentAlignment = Alignment.Center) { .padding(vertical = 10.dp), contentAlignment = Alignment.Center) {
Text(text = buttonText, fontSize = 14.sp, fontWeight = FontWeight.Medium, color = Color.White) Text(text = buttonText,
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = Color.White)
} }
} }
}) { }) {
LazyColumn(modifier = Modifier LazyColumn(modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(it), contentPadding = PaddingValues(vertical = 5.dp)) { .padding(it),
contentPadding = PaddingValues(vertical = 5.dp)) {
if (uiState.value.orderInfo?.verifyType != null && uiState.value.orderInfo?.verifyType != 0) { if (uiState.value.orderInfo?.verifyType != null && uiState.value.orderInfo?.verifyType != 0) {
item { item {
VerifyCarView(orderInfo = uiState.value.orderInfo) VerifyCarView(orderInfo = uiState.value.orderInfo,
newCarVin = uiState.value.newCarVin,
newCarVinPath = uiState.value.newCarPhotoPath,
recognize = {
vm.dispatch(VerifyOrderVm.Action.Recognize(it))
})
} }
} }
if (!uiState.value.orderInfo?.arriveRemindLink.isNullOrBlank()) { if (! uiState.value.orderInfo?.arriveRemindLink.isNullOrBlank()) {
item { item {
VerifyTipView(arriveRemind = uiState.value.orderInfo?.arriveRemind VerifyTipView(arriveRemind = uiState.value.orderInfo?.arriveRemind ?: "",
?: "", uiState.value.orderInfo?.arriveRemindLink ?: "") uiState.value.orderInfo?.arriveRemindLink ?: "")
} }
} }
//重要提示 //重要提示
if (!uiState.value.orderInfo?.importantTip.isNullOrBlank()) { if (! uiState.value.orderInfo?.importantTip.isNullOrBlank()) {
item { item {
Row(modifier = Modifier Row(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.background(color = Color(0xFFFFF7EE), shape = RoundedCornerShape(4.dp)) .background(color = Color(0xFFFFF7EE), shape = RoundedCornerShape(4.dp))
.padding(vertical = 5.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) { .padding(vertical = 5.dp),
AsyncImage(model = R.drawable.sv_warn_yellow, contentDescription = "", modifier = Modifier.size(12.5.dp, 12.5.dp)) horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically) {
AsyncImage(model = R.drawable.sv_warn_yellow,
contentDescription = "",
modifier = Modifier.size(12.5.dp, 12.5.dp))
Spacer(modifier = Modifier.width(5.dp)) Spacer(modifier = Modifier.width(5.dp))
Text(text = uiState.value.orderInfo?.importantTip Text(text = uiState.value.orderInfo?.importantTip ?: "",
?: "", fontSize = 12.sp, fontWeight = FontWeight.Medium, color = Color.Red) fontSize = 12.sp,
fontWeight = FontWeight.Medium,
color = Color.Red)
} }
} }
} }
@ -191,7 +234,27 @@ fun VerifyOrderScreen(vm: VerifyOrderVm = viewModel()) {
} }
@Composable @Composable
private fun VerifyCarView(orderInfo: OrderInfo?) { private fun VerifyCarView(
orderInfo : OrderInfo?,
newCarVin : String? = null,
newCarVinPath : String? = null,
recognize : (String) -> Unit,
) {
val context = LocalContext.current
var localCarVinPath by remember { mutableStateOf<String?>(null) }
val getResult =
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) { it ->
if (it.resultCode == Activity.RESULT_OK) {
val value = it.data?.getStringExtra("path")
LogUtil.print("takePhoto", "path==$value")
if (value.isNullOrBlank()) {
ToastUtils.showLong("照片路径为空,请重新拍摄!")
return@rememberLauncherForActivityResult
}
localCarVinPath = value
recognize(value)
}
}
Column(modifier = Modifier Column(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -200,10 +263,13 @@ private fun VerifyCarView(orderInfo: OrderInfo?) {
.padding(10.dp)) { .padding(10.dp)) {
Box(modifier = Modifier Box(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(vertical = 10.dp), contentAlignment = Alignment.CenterStart) { .padding(vertical = 10.dp),
contentAlignment = Alignment.CenterStart) {
Text(text = "请确认本次服务车辆信息".takeIf { orderInfo?.verifyType != 5 } Text(text = "请确认本次服务车辆信息".takeIf { orderInfo?.verifyType != 5 }
?: ("本次服务车辆为新车\n" + ?: ("本次服务车辆为新车\n" + "需要填写车架号 "),
"需要填写车架号 "), color = Color(0xFF323643), fontWeight = FontWeight.Medium, fontSize = 14.sp) color = Color(0xFF323643),
fontWeight = FontWeight.Medium,
fontSize = 14.sp)
} }
HorizontalDivider(modifier = Modifier.alpha(0.2f)) HorizontalDivider(modifier = Modifier.alpha(0.2f))
@ -211,37 +277,61 @@ private fun VerifyCarView(orderInfo: OrderInfo?) {
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
Text(text = "车牌号:", color = black65, fontSize = 13.sp, fontWeight = FontWeight.Medium) Text(text = "车牌号:",
color = black65,
fontSize = 13.sp,
fontWeight = FontWeight.Medium)
Spacer(modifier = Modifier.width(10.dp)) Spacer(modifier = Modifier.width(10.dp))
Text(text = orderInfo?.carNo Text(text = orderInfo?.carNo ?: "",
?: "", fontWeight = FontWeight.Medium, fontSize = 16.sp, color = Color.Black) fontWeight = FontWeight.Medium,
fontSize = 16.sp,
color = Color.Black)
} }
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
if (orderInfo?.verifyType == 5) { if (orderInfo?.verifyType == 5) {
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { Row(modifier = Modifier.fillMaxWidth(),
Text(text = "车架号:", color = black65, fontSize = 13.sp, fontWeight = FontWeight.Medium) verticalAlignment = Alignment.CenterVertically) {
Text(text = "车架号:",
color = black65,
fontSize = 13.sp,
fontWeight = FontWeight.Medium)
Spacer(modifier = Modifier.width(10.dp)) Spacer(modifier = Modifier.width(10.dp))
Text(text = orderInfo.carVin Text(text = newCarVin ?: "",
?: "", fontWeight = FontWeight.Medium, fontSize = 16.sp, color = Color.Black) fontWeight = FontWeight.Medium,
fontSize = 16.sp,
color = Color.Black)
} }
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { Box(modifier = Modifier
AsyncImage(model = R.drawable.sv_verify_vin, contentDescription = "", modifier = Modifier.size(220.dp, 123.dp)) .fillMaxWidth()
.clickable {
val intent = Intent(context, ZdCameraXActivity::class.java)
getResult.launch(intent)
}, contentAlignment = Alignment.Center) {
AsyncImage(model = newCarVinPath ?: R.drawable.sv_verify_vin,
contentDescription = "",
modifier = Modifier.size(220.dp, 123.dp))
} }
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
} else if (orderInfo?.verifyType == 1 || orderInfo?.verifyType == 2) { } else if (orderInfo?.verifyType == 1 || orderInfo?.verifyType == 2) {
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { Row(modifier = Modifier.fillMaxWidth(),
Text(text = "车架号:", color = black65, fontSize = 13.sp, fontWeight = FontWeight.Medium) verticalAlignment = Alignment.CenterVertically) {
Text(text = "车架号:",
color = black65,
fontSize = 13.sp,
fontWeight = FontWeight.Medium)
Spacer(modifier = Modifier.width(10.dp)) Spacer(modifier = Modifier.width(10.dp))
Text(text = orderInfo.carVin Text(text = orderInfo.carVin ?: "",
?: "", fontWeight = FontWeight.Medium, fontSize = 16.sp, color = Color.Black) fontWeight = FontWeight.Medium,
fontSize = 16.sp,
color = Color.Black)
} }
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
@ -258,30 +348,36 @@ private fun VerifyCarView(orderInfo: OrderInfo?) {
contentDescription = "", contentDescription = "",
modifier = Modifier.size(12.5.dp, 12.5.dp)) modifier = Modifier.size(12.5.dp, 12.5.dp))
Spacer(modifier = Modifier.width(5.dp)) Spacer(modifier = Modifier.width(5.dp))
Text(text = "请确认以上信息至少一项符合否则将无法结算", fontSize = 12.sp, fontWeight = FontWeight.Medium, color = Color(0xFFFF8F37)) Text(text = "请确认以上信息至少一项符合否则将无法结算",
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
color = Color(0xFFFF8F37))
} }
} }
} }
@Composable @Composable
private fun VerifyTipView(arriveRemind: String, arriveRemindUrl: String) { private fun VerifyTipView(arriveRemind : String, arriveRemindUrl : String) {
Column(modifier = Modifier Column(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(10.dp) .padding(10.dp)
.background(color = Color.White, shape = RoundedCornerShape(6.dp)) .background(color = Color.White, shape = RoundedCornerShape(6.dp))
.padding(10.dp), horizontalAlignment = Alignment.CenterHorizontally) { .padding(10.dp),
horizontalAlignment = Alignment.CenterHorizontally) {
Box(modifier = Modifier Box(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(vertical = 10.dp), contentAlignment = Alignment.CenterStart) { .padding(vertical = 10.dp),
Text(text = arriveRemind, color = Color(0xFF323643), fontWeight = FontWeight.Medium, fontSize = 14.sp) contentAlignment = Alignment.CenterStart) {
Text(text = arriveRemind,
color = Color(0xFF323643),
fontWeight = FontWeight.Medium,
fontSize = 14.sp)
} }
HorizontalDivider(modifier = Modifier.alpha(0.2f)) HorizontalDivider(modifier = Modifier.alpha(0.2f))
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
if (arriveRemindUrl.endsWith("png") if (arriveRemindUrl.endsWith("png") || arriveRemindUrl.endsWith("jpg") || arriveRemindUrl.endsWith(
|| arriveRemindUrl.endsWith("jpg") "jpeg") || arriveRemindUrl.endsWith("WebP")
|| arriveRemindUrl.endsWith("jpeg")
|| arriveRemindUrl.endsWith("WebP")
) { ) {
AsyncImage(model = arriveRemindUrl, contentDescription = "") AsyncImage(model = arriveRemindUrl, contentDescription = "")
} else { } else {

View File

@ -1,41 +1,91 @@
package com.za.ui.servicing.verify package com.za.ui.servicing.verify
import com.amap.api.location.AMapLocation
import com.blankj.utilcode.util.ToastUtils import com.blankj.utilcode.util.ToastUtils
import com.za.base.Const import com.za.base.Const
import com.za.base.IServicingVm import com.za.base.IServicingVm
import com.za.base.view.LoadingManager import com.za.base.view.LoadingManager
import com.za.bean.db.order.OrderInfo import com.za.bean.db.order.OrderInfo
import com.za.bean.request.OrderPhotoOcrRecognizeRequest
import com.za.bean.request.UpdateTaskBean import com.za.bean.request.UpdateTaskBean
import com.za.bean.request.UpdateTaskRequest import com.za.bean.request.UpdateTaskRequest
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.log.LogUtil import com.za.common.log.LogUtil
import com.za.ext.getNextStatus import com.za.ext.getNextStatus
import com.za.ext.toJson import com.za.ext.toJson
import com.za.net.BaseObserver
import com.za.net.CommonMethod import com.za.net.CommonMethod
import com.za.net.RetrofitHelper
import com.za.offline.OfflineUpdateTaskBean import com.za.offline.OfflineUpdateTaskBean
import com.za.service.location.ZdLocationManager import com.za.service.location.ZdLocationManager
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import java.io.File
class VerifyOrderVm : IServicingVm<VerifyOrderVm.Action, VerifyOrderVm.UiState>() { class VerifyOrderVm : IServicingVm<VerifyOrderVm.Action, VerifyOrderVm.UiState>() {
private val _uiState = MutableStateFlow(UiState()) private val _uiState = MutableStateFlow(UiState())
val uiState get() = _uiState val uiState get() = _uiState
override fun updateState(uiState: UiState) { override fun updateState(uiState : UiState) {
_uiState.value = uiState _uiState.value = uiState
} }
override fun dispatch(action: Action) { override fun dispatch(action : Action) {
when (action) { when (action) {
is Action.Init -> init() is Action.Init -> init()
is Action.UpdateTask -> updateTask() is Action.UpdateTask -> updateTask()
is Action.UpdateState -> updateState(action.uiState) is Action.UpdateState -> updateState(action.uiState)
is Action.UploadOffline -> uploadOffline() is Action.UploadOffline -> uploadOffline()
is Action.Recognize -> recognize(action.localPath)
} }
} }
private fun uploadOffline(taskRequest: UpdateTaskRequest? = null) {
private fun recognize(localPath : String) {
LoadingManager.showLoading()
CommonMethod.uploadImage(file = File(localPath), success = {
LoadingManager.hideLoading()
if (it.isNullOrBlank() == true) {
return@uploadImage
}
doRecognize(it)
}, failed = {
LoadingManager.hideLoading()
ToastUtils.showShort(it)
})
}
private fun doRecognize(uploadPath : String) {
LoadingManager.showLoading()
val orderPhotoOcrRecognizeRequest =
OrderPhotoOcrRecognizeRequest(GlobalData.currentOrder?.userOrderId, 2, uploadPath)
LogUtil.print("$tag doRecognize", "请求参数==${orderPhotoOcrRecognizeRequest.toJson()}")
RetrofitHelper.getDefaultService().orderPhotoOcrRecognize(orderPhotoOcrRecognizeRequest)
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BaseObserver<String>() {
override fun doSuccess(it : String?) {
LoadingManager.hideLoading()
if (it.isNullOrBlank()) {
showTipDialog("识别失败")
return
}
if (it.contains("失败")) {
showTipDialog(it)
return
}
updateState(uiState.value.copy(newCarVin = it, newCarPhotoPath = uploadPath))
}
override fun doFailure(code : Int, msg : String?) {
LoadingManager.hideLoading()
showTipDialog(msg ?: "识别失败")
}
})
}
private fun uploadOffline(taskRequest : UpdateTaskRequest? = null) {
if (taskRequest != null) { if (taskRequest != null) {
val offlineUpdateTaskBean = OfflineUpdateTaskBean( val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = taskRequest.type,
type = taskRequest.type,
taskId = taskRequest.taskId, taskId = taskRequest.taskId,
userId = taskRequest.userId, userId = taskRequest.userId,
vehicleId = taskRequest.vehicleId, vehicleId = taskRequest.vehicleId,
@ -51,34 +101,45 @@ class VerifyOrderVm : IServicingVm<VerifyOrderVm.Action, VerifyOrderVm.UiState>(
offlineType = 1) offlineType = 1)
insertOfflineTask(offlineUpdateTaskBean) insertOfflineTask(offlineUpdateTaskBean)
updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus())) updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus()))
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState), orderInfo = getCurrentOrder())) updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState),
orderInfo = getCurrentOrder()))
return return
} }
ZdLocationManager.getSingleLocation(isNeedAddress = false, ZdLocationManager.getSingleLocation(isNeedAddress = false, success = { it ->
success = { it -> doUploadOfflineTask(it)
val temp = UpdateTaskRequest( }, failed = {
type = "VERIFY", if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
doUploadOfflineTask(GlobalData.currentLocation)
} else {
showTipDialog(it)
}
})
}
private fun doUploadOfflineTask(it : AMapLocation?) {
val temp = UpdateTaskRequest(type = "VERIFY",
taskId = GlobalData.currentOrder?.taskId, taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId, userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId, vehicleId = GlobalData.driverInfoBean?.vehicleId,
currentState = GlobalData.currentOrder?.taskState, currentState = GlobalData.currentOrder?.taskState,
offlineMode = 0, offlineMode = 0,
newCarCode = if (uiState.value.orderInfo?.verifyType == 5) { newCarCode = if (uiState.value.orderInfo?.verifyType == 5) {
uiState.value.verifyValue uiState.value.newCarVin
} else { } else {
"" ""
}, },
content = if (uiState.value.orderInfo?.verifyType == 5) { content = if (uiState.value.orderInfo?.verifyType == 5) {
uiState.value.verifyValue uiState.value.newCarVin
} else { } else {
uiState.value.orderInfo?.verifyValue uiState.value.orderInfo?.verifyValue
}, },
operateTime = System.currentTimeMillis().toString(), operateTime = System.currentTimeMillis().toString(),
lat = it.latitude, lat = it?.latitude,
lng = it.longitude) lng = it?.longitude)
val offlineUpdateTaskBean = OfflineUpdateTaskBean( val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = temp.type,
type = temp.type,
taskId = temp.taskId, taskId = temp.taskId,
userId = temp.userId, userId = temp.userId,
vehicleId = temp.vehicleId, vehicleId = temp.vehicleId,
@ -94,36 +155,33 @@ class VerifyOrderVm : IServicingVm<VerifyOrderVm.Action, VerifyOrderVm.UiState>(
offlineType = 1) offlineType = 1)
insertOfflineTask(offlineUpdateTaskBean) insertOfflineTask(offlineUpdateTaskBean)
updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus())) updateOrder(getCurrentOrder()?.copy(taskState = getCurrentOrder()?.getNextStatus()))
updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState), orderInfo = getCurrentOrder())) updateState(uiState.value.copy(goNextPage = UpdateTaskBean(nextState = getCurrentOrder()?.taskState),
}, failed = { orderInfo = getCurrentOrder()))
ToastUtils.showShort(it)
})
} }
private fun updateTask() { private fun updateTask() {
if (uiState.value.orderInfo?.verifyType == 5 && uiState.value.verifyValue.isNullOrBlank()) { if (uiState.value.orderInfo?.verifyType == 5 && uiState.value.newCarVin.isNullOrBlank()) {
ToastUtils.showShort("验证信息不能为空") showTipDialog(msg = "验证信息不能为空!")
return return
} }
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { ZdLocationManager.getSingleLocation(success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
val taskRequest = UpdateTaskRequest( val taskRequest = UpdateTaskRequest(type = "VERIFY",
type = "VERIFY",
taskId = GlobalData.currentOrder?.taskId, taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId, userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId, vehicleId = GlobalData.driverInfoBean?.vehicleId,
currentState = GlobalData.currentOrder?.taskState, currentState = GlobalData.currentOrder?.taskState,
offlineMode = 0, offlineMode = 0,
newCarCode = if (uiState.value.orderInfo?.verifyType == 5) { newCarCode = if (uiState.value.orderInfo?.verifyType == 5) {
uiState.value.verifyValue uiState.value.newCarVin
} else { } else {
"" ""
}, },
content = if (uiState.value.orderInfo?.verifyType == 5) { content = if (uiState.value.orderInfo?.verifyType == 5) {
uiState.value.verifyValue uiState.value.newCarVin
} else { } else {
uiState.value.orderInfo?.verifyValue uiState.value.orderInfo?.verifyValue
}, },
@ -131,18 +189,46 @@ class VerifyOrderVm : IServicingVm<VerifyOrderVm.Action, VerifyOrderVm.UiState>(
lat = it.latitude, lat = it.latitude,
lng = it.longitude) lng = it.longitude)
if (!getCurrentOrderOfflineTask().isNullOrEmpty()) { if (! getCurrentOrderOfflineTask().isNullOrEmpty()) {
uploadOffline(taskRequest) uploadOffline(taskRequest)
return@getSingleLocation return@getSingleLocation
} }
doUploadTask(request = taskRequest) doUploadTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
val taskRequest = UpdateTaskRequest(type = "VERIFY",
taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
currentState = GlobalData.currentOrder?.taskState,
offlineMode = 0,
newCarCode = if (uiState.value.orderInfo?.verifyType == 5) {
uiState.value.newCarVin
} else {
""
},
content = if (uiState.value.orderInfo?.verifyType == 5) {
uiState.value.newCarVin
} else {
uiState.value.orderInfo?.verifyValue
},
operateTime = System.currentTimeMillis().toString(),
lat = GlobalData.currentLocation?.latitude,
lng = GlobalData.currentLocation?.longitude)
if (! getCurrentOrderOfflineTask().isNullOrEmpty()) {
uploadOffline(taskRequest)
return@getSingleLocation
}
doUploadTask(request = taskRequest)
} else {
showTipDialog(msg = it)
}
}) })
} }
private fun doUploadTask(request: UpdateTaskRequest) { private fun doUploadTask(request : UpdateTaskRequest) {
LoadingManager.showLoading() LoadingManager.showLoading()
CommonMethod.updateTask(request, success = { CommonMethod.updateTask(request, success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
@ -150,9 +236,10 @@ class VerifyOrderVm : IServicingVm<VerifyOrderVm.Action, VerifyOrderVm.UiState>(
updateState(uiState.value.copy(goNextPage = it, orderInfo = getCurrentOrder())) updateState(uiState.value.copy(goNextPage = it, orderInfo = getCurrentOrder()))
}, failed = { msg, code -> }, failed = { msg, code ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg)
if (code == Const.NetWorkException) { if (code == Const.NetWorkException) {
updateState(uiState.value.copy(showOfflineDialog = true)) updateState(uiState.value.copy(showOfflineDialog = true))
} else {
showTipDialog(msg = msg ?: "提交失败")
} }
LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg") LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg")
}) })
@ -165,16 +252,19 @@ class VerifyOrderVm : IServicingVm<VerifyOrderVm.Action, VerifyOrderVm.UiState>(
sealed class Action { sealed class Action {
data object Init : Action() data object Init : Action()
data object UpdateTask : Action() data object UpdateTask : Action()
data class UpdateState(val uiState: UiState) : Action() data class UpdateState(val uiState : UiState) : Action()
data object UploadOffline : Action() data object UploadOffline : Action()
data class Recognize(val localPath : String) : Action()
} }
data class UiState( data class UiState(
val orderInfo: OrderInfo? = null, val orderInfo : OrderInfo? = null,
val verifyValue: String? = null, val verifyValue : String? = null,
val goNextPage: UpdateTaskBean? = null, val newCarPhotoPath : String? = null,
val isGoNextPageDialog: Boolean? = null, val newCarVin : String? = null,
val showCallPhoneDialog: Boolean? = null, val goNextPage : UpdateTaskBean? = null,
val showOfflineDialog: Boolean? = null, val isGoNextPageDialog : Boolean? = null,
val showCallPhoneDialog : Boolean? = null,
val showOfflineDialog : Boolean? = null,
) )
} }

View File

@ -73,7 +73,6 @@ fun InServicingHeadView(title : String,
confirm = { confirm = {
showCallPhoneDialog.value = false showCallPhoneDialog.value = false
context.callPhone(orderInfo?.customerPhone) context.callPhone(orderInfo?.customerPhone)
context.finish()
}) })
} }
@ -89,7 +88,6 @@ fun InServicingHeadView(title : String,
confirm = { confirm = {
showCallServicePhoneDialog.value = false showCallServicePhoneDialog.value = false
context.callPhone(orderInfo?.hotline) context.callPhone(orderInfo?.hotline)
context.finish()
}) })
} }
@ -227,13 +225,13 @@ fun InServicingHeadView(title : String,
}, },
actions = { actions = {
Box(modifier = Modifier Box(modifier = Modifier
.size(39.dp) .size(46.dp)
.clickable { .clickable {
OrderRequirementsActivity.goOrderRequirementsActivity(context, OrderRequirementsActivity.goOrderRequirementsActivity(context,
orderInfo, orderInfo,
type = Const.InServiceSettingType.ORDER_DETAIL) type = Const.InServiceSettingType.ORDER_DETAIL)
} }
.padding(10.dp), contentAlignment = Alignment.Center) { .padding(15.dp), contentAlignment = Alignment.Center) {
AsyncImage(model = R.drawable.sv_setting, AsyncImage(model = R.drawable.sv_setting,
contentDescription = "", contentDescription = "",
modifier = Modifier.fillMaxSize()) modifier = Modifier.fillMaxSize())
@ -267,7 +265,6 @@ fun ServiceOperation(orderInfo : OrderInfo?) {
confirm = { confirm = {
showCallPhoneDialog.value = false showCallPhoneDialog.value = false
context.callPhone(orderInfo?.customerPhone) context.callPhone(orderInfo?.customerPhone)
context.finish()
}) })
} }
@ -283,7 +280,6 @@ fun ServiceOperation(orderInfo : OrderInfo?) {
confirm = { confirm = {
showCallServicePhoneDialog.value = false showCallServicePhoneDialog.value = false
context.callPhone(orderInfo?.hotline) context.callPhone(orderInfo?.hotline)
context.finish()
}) })
} }

View File

@ -3,51 +3,32 @@ package com.za.ui.servicing.wait_to_start
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.SheetValue import androidx.compose.material3.SheetValue
import androidx.compose.material3.Text
import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.material3.rememberBottomSheetScaffoldState
import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.material3.rememberStandardBottomSheetState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.AbsoluteAlignment
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import com.amap.api.location.AMapLocationClient import com.amap.api.location.AMapLocationClient
import com.amap.api.maps.CameraUpdateFactory import com.amap.api.maps.CameraUpdateFactory
import com.amap.api.maps.MapView import com.amap.api.maps.MapView
@ -58,12 +39,10 @@ import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.PolylineOptions import com.amap.api.maps.model.PolylineOptions
import com.blankj.utilcode.util.ConvertUtils import com.blankj.utilcode.util.ConvertUtils
import com.za.base.BaseActivity import com.za.base.BaseActivity
import com.za.base.theme.headBgColor
import com.za.base.view.CommonDialog import com.za.base.view.CommonDialog
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.util.ImageUtil import com.za.common.util.ImageUtil
import com.za.common.util.ServicingSpeechManager import com.za.common.util.ServicingSpeechManager
import com.za.ext.copy
import com.za.ext.finish import com.za.ext.finish
import com.za.ext.goNextPage import com.za.ext.goNextPage
import com.za.ext.navigationActivity import com.za.ext.navigationActivity
@ -71,7 +50,6 @@ import com.za.servicing.R
import com.za.ui.new_order.NewOrderItem import com.za.ui.new_order.NewOrderItem
import com.za.ui.new_order.NewOrderItemUIBean import com.za.ui.new_order.NewOrderItemUIBean
import com.za.ui.new_order.NewOrderUiType import com.za.ui.new_order.NewOrderUiType
import com.za.ui.servicing.go_to_destination.GoToDestinationVm
import com.za.ui.servicing.inservice_people_confirm.ServicePeopleConfirmActivity import com.za.ui.servicing.inservice_people_confirm.ServicePeopleConfirmActivity
import com.za.ui.servicing.view.InServicingHeadView import com.za.ui.servicing.view.InServicingHeadView
import com.za.ui.servicing.view.ServiceOperation import com.za.ui.servicing.view.ServiceOperation
@ -160,6 +138,10 @@ fun WaitToStartScreen(vm : WaitToStartVm = viewModel()) {
}) })
} }
var sheetExpandHeight = remember { mutableStateOf(0.dp) }
val localDensity = LocalDensity.current
BottomSheetScaffold(scaffoldState = scaffoldState, BottomSheetScaffold(scaffoldState = scaffoldState,
topBar = { topBar = {
InServicingHeadView(title = "调度成功,等待发车", InServicingHeadView(title = "调度成功,等待发车",
@ -167,7 +149,6 @@ fun WaitToStartScreen(vm : WaitToStartVm = viewModel()) {
orderInfo = uiState.value.orderInfo) orderInfo = uiState.value.orderInfo)
}, },
sheetContent = { sheetContent = {
val uiBean = NewOrderItemUIBean(taskCode = uiState.value.orderInfo?.taskCode, val uiBean = NewOrderItemUIBean(taskCode = uiState.value.orderInfo?.taskCode,
addressProperty = uiState.value.orderInfo?.addressProperty, addressProperty = uiState.value.orderInfo?.addressProperty,
address = uiState.value.orderInfo?.address, address = uiState.value.orderInfo?.address,
@ -178,14 +159,21 @@ fun WaitToStartScreen(vm : WaitToStartVm = viewModel()) {
expectArriveTime = uiState.value.orderInfo?.expectArriveTime, expectArriveTime = uiState.value.orderInfo?.expectArriveTime,
bottomTextString = "发车", bottomTextString = "发车",
uiType = NewOrderUiType.SERVICING) uiType = NewOrderUiType.SERVICING)
Box(modifier = Modifier
.fillMaxWidth()
.onSizeChanged { coordinates ->
sheetExpandHeight.value = with(localDensity) { coordinates.height.toDp() }
}) {
NewOrderItem(uiBean, goNextPage = { NewOrderItem(uiBean, goNextPage = {
if (! GlobalData.isMaster && GlobalData.driverInfoBean != null && GlobalData.driverInfoBean?.authStatus == 1) { if (! GlobalData.isMaster && GlobalData.driverInfoBean != null && GlobalData.driverInfoBean?.authStatus == 1) {
vm.dispatch(WaitToStartVm.Action.UpdateState(uiState.value.copy( vm.dispatch(WaitToStartVm.Action.UpdateState(uiState.value.copy(
showServicePeopleConfirmDialog = true))) showServicePeopleConfirmDialog = true)))
return@NewOrderItem return@NewOrderItem
} }
vm.dispatch(WaitToStartVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = true))) vm.dispatch(WaitToStartVm.Action.UpdateState(uiState.value.copy(
isGoNextPageDialog = true)))
}) })
}
}, },
sheetPeekHeight = 180.dp, sheetPeekHeight = 180.dp,
sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp), sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp),
@ -193,9 +181,14 @@ fun WaitToStartScreen(vm : WaitToStartVm = viewModel()) {
sheetDragHandle = null, sheetDragHandle = null,
sheetSwipeEnabled = true) { paddingValues -> sheetSwipeEnabled = true) { paddingValues ->
Box(modifier = Modifier Box(modifier = Modifier
.fillMaxSize() .wrapContentSize()
.padding(paddingValues)) { .padding(top = paddingValues.calculateTopPadding(),
AndroidView(modifier = Modifier.fillMaxSize(), factory = { bottom = if (bottomSheetState.currentValue == SheetValue.PartiallyExpanded) {
0.dp
} else {
sheetExpandHeight.value
})) {
AndroidView(modifier = Modifier.wrapContentSize(), factory = {
AMapLocationClient.updatePrivacyShow(context, true, true) AMapLocationClient.updatePrivacyShow(context, true, true)
AMapLocationClient.updatePrivacyAgree(context, true) AMapLocationClient.updatePrivacyAgree(context, true)
mapView.apply { mapView.apply {
@ -226,7 +219,8 @@ fun WaitToStartScreen(vm : WaitToStartVm = viewModel()) {
.zIndex(1f)) .zIndex(1f))
} }
// 再添加标记点,确保标记点在路线上层 mapView.map.addMarkers(uiState.value.markers, false)
// 添加当前位置标记 // 添加当前位置标记
if (GlobalData.currentLocation != null) { if (GlobalData.currentLocation != null) {
mapView.map.addMarker(MarkerOptions().position(LatLng(GlobalData.currentLocation?.latitude !!, mapView.map.addMarker(MarkerOptions().position(LatLng(GlobalData.currentLocation?.latitude !!,
@ -235,49 +229,18 @@ fun WaitToStartScreen(vm : WaitToStartVm = viewModel()) {
.anchor(0.5f, 0.5f).visible(true)) .anchor(0.5f, 0.5f).visible(true))
} }
// 添加救援地标记
uiState.value.orderInfo?.let { order ->
if (order.lat != null && order.lat != 0.0 && order.lng != null && order.lng != 0.0 && GlobalData.currentLocation != null) {
mapView.map.addMarker(MarkerOptions().position(LatLng(order.lat !!,
order.lng !!)).title("救援地点")
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map))
.anchor(0.5f, 0.5f))
}
// 添加目的地标记
if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0 && GlobalData.currentLocation != null) {
mapView.map.addMarker(MarkerOptions().position(LatLng(order.distLat !!,
order.distLng !!)).title("目的地")
.icon(ImageUtil.vectorToBitmap(context, R.drawable.sv_map_dist))
.anchor(0.5f, 0.5f))
}
}
// 最后调整地图显示范围
// 计算地图显示范围 // 计算地图显示范围
val bounds = LatLngBounds.Builder().apply { // 添加当前位置 val bounds = LatLngBounds.Builder().apply {
GlobalData.currentLocation?.let { uiState.value.routePoints?.forEach {
include(LatLng(it.latitude, it.longitude)) include(LatLng(it.latitude, it.longitude))
} }
// 添加救援地点
uiState.value.orderInfo?.let { order ->
if (order.lat != null && order.lat != 0.0 && order.lng != null && order.lng != 0.0) {
include(LatLng(order.lat !!, order.lng !!))
}
// 添加目的地
if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0) {
include(LatLng(order.distLat !!, order.distLng !!))
}
}
}.build() }.build()
// 调整地图显示范围,确保所有点都可见 // 调整地图显示范围,确保所有点都可见
try { try {
mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,
ConvertUtils.dp2px(50f))) ConvertUtils.dp2px(100f)))
} catch (e : Exception) { // 如果计算边界失败,则使用默认缩放级别 } catch (e : Exception) {
GlobalData.currentLocation?.let { GlobalData.currentLocation?.let {
mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude, mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude,
it.longitude), 15f)) it.longitude), 15f))

View File

@ -11,7 +11,6 @@ import com.amap.api.services.route.RideRouteResult
import com.amap.api.services.route.RouteSearch import com.amap.api.services.route.RouteSearch
import com.amap.api.services.route.WalkRouteResult import com.amap.api.services.route.WalkRouteResult
import com.blankj.utilcode.util.ActivityUtils import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.ToastUtils
import com.za.base.IServicingVm import com.za.base.IServicingVm
import com.za.base.view.LoadingManager import com.za.base.view.LoadingManager
import com.za.bean.db.order.OrderInfo import com.za.bean.db.order.OrderInfo
@ -64,7 +63,22 @@ class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>(
doUploadTask(request = taskRequest) doUploadTask(request = taskRequest)
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) if (GlobalData.currentLocation != null) {
LogUtil.print("$tag updateOffline",
"使用全局定位${GlobalData.currentLocation?.toJson()}")
val taskRequest = UpdateTaskRequest(type = "START",
taskId = getCurrentOrder()?.taskId,
userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId,
currentState = getCurrentOrder()?.taskState,
offlineMode = 0,
operateTime = System.currentTimeMillis().toString(),
lat = GlobalData.currentLocation?.latitude,
lng = GlobalData.currentLocation?.longitude)
doUploadTask(request = taskRequest)
} else {
showTipDialog(it)
}
}) })
} }
@ -76,7 +90,7 @@ class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>(
updateState(uiState.value.copy(goNextPage = data, orderInfo = getCurrentOrder())) updateState(uiState.value.copy(goNextPage = data, orderInfo = getCurrentOrder()))
}, failed = { msg, _ -> }, failed = { msg, _ ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(msg) showTipDialog(msg ?: "提交失败")
LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg") LogUtil.print("$tag doUploadTask", "状态更新失败==${request.toJson()} msg==$msg")
}) })
} }
@ -130,6 +144,12 @@ class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>(
LatLonPoint(orderInfo.lat !!, orderInfo.lng !!) LatLonPoint(orderInfo.lat !!, orderInfo.lng !!)
} else null } else null
// 获取救援地点坐标
val disPoint =
if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) {
LatLonPoint(orderInfo.distLat !!, orderInfo.distLng !!)
} else null
// 如果没有救援地点,则不进行规划 // 如果没有救援地点,则不进行规划
if (rescuePoint == null) { if (rescuePoint == null) {
LogUtil.print("searchDrivingRoute", "没有有效的终点") LogUtil.print("searchDrivingRoute", "没有有效的终点")
@ -162,10 +182,24 @@ class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>(
override fun onRideRouteSearched(p0 : RideRouteResult?, p1 : Int) {} override fun onRideRouteSearched(p0 : RideRouteResult?, p1 : Int) {}
}) })
val fromAndTo = RouteSearch.FromAndTo(startPoint, rescuePoint) if (disPoint != null) {
val query = val fromAndTo = RouteSearch.FromAndTo(startPoint, disPoint)
RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DrivingDefault, null, null, "") val wayPoints = listOf(rescuePoint)
val query = RouteSearch.DriveRouteQuery(fromAndTo,
RouteSearch.DRIVING_SINGLE_DEFAULT,
wayPoints,
null,
"")
calculateDriveRouteAsyn(query) calculateDriveRouteAsyn(query)
} else {
val fromAndTo = RouteSearch.FromAndTo(startPoint, rescuePoint)
val query = RouteSearch.DriveRouteQuery(fromAndTo,
RouteSearch.DRIVING_SINGLE_DEFAULT,
null,
null,
"")
calculateDriveRouteAsyn(query)
}
} }
} }

View File

@ -8,16 +8,19 @@ import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import com.za.base.view.CommonDialog import com.za.base.view.CommonDialog
class CommonDialogFragment(val title: String? = null, class CommonDialogFragment(val title : String? = null,
val message: String? = null, val message : String? = null,
val cancelText: String? = null, val cancelText : String? = null,
val confirmText: String = "确定", val confirmText : String = "确定",
val confirm: () -> Unit = {}, val cancelable : Boolean = true,
val cancel: () -> Unit = {}) : DialogFragment() { val confirm : () -> Unit = {},
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val cancel : () -> Unit = {}) : DialogFragment() {
override fun onCreateView(inflater : LayoutInflater,
container : ViewGroup?,
savedInstanceState : Bundle?) : View? {
return ComposeView(requireContext()).apply { return ComposeView(requireContext()).apply {
setContent { setContent {
CommonDialog( CommonDialog(cancelEnable = cancelable,
confirm = { confirm = {
dismiss() dismiss()
confirm() confirm()

View File

@ -1,7 +1,6 @@
package com.za.ui.view package com.za.ui.view
import android.app.Activity import android.app.Activity
import android.content.Intent
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background import androidx.compose.foundation.background
@ -22,9 +21,12 @@ import com.za.signature.GridPaintActivity
import com.za.signature.config.PenConfig import com.za.signature.config.PenConfig
@Composable @Composable
fun SignatureView(modifier: Modifier = Modifier, success: (String?) -> Unit, serverPath: String?) { fun SignatureView(modifier : Modifier = Modifier,
success : (String?) -> Unit,
serverPath : String?) {
val context = LocalContext.current val context = LocalContext.current
val signatureLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) { it -> val signatureLauncher =
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) { it ->
if (it.resultCode == Activity.RESULT_OK) { if (it.resultCode == Activity.RESULT_OK) {
val value = it.data?.getStringExtra(PenConfig.SAVE_PATH) val value = it.data?.getStringExtra(PenConfig.SAVE_PATH)
LogUtil.print("pen save Path", "path==$value") LogUtil.print("pen save Path", "path==$value")
@ -42,13 +44,7 @@ fun SignatureView(modifier: Modifier = Modifier, success: (String?) -> Unit, ser
.size(142.dp, 52.dp) .size(142.dp, 52.dp)
.background(color = Color.White, shape = RoundedCornerShape(4.dp)) .background(color = Color.White, shape = RoundedCornerShape(4.dp))
.noDoubleClick { .noDoubleClick {
val intent = Intent(context, GridPaintActivity::class.java) GridPaintActivity.goGridPaintActivity(signatureLauncher, context)
intent.putExtra("background", android.graphics.Color.WHITE)
intent.putExtra("crop", true)
intent.putExtra("fontSize", 30) //手写字体大小
intent.putExtra("format", PenConfig.FORMAT_PNG)
intent.putExtra("lineLength", 10) //每行显示字数(超出屏幕支持横向滚动)
signatureLauncher.launch(intent)
}, },
contentScale = ContentScale.Inside) contentScale = ContentScale.Inside)
} }

View File

@ -5,14 +5,15 @@ package com.za.water_marker.bean
* @create 2021/5/16 11:19 * @create 2021/5/16 11:19
* @mail coldpuppy@163.com * @mail coldpuppy@163.com
*/ */
data class PhotoMarkerInfo( data class PhotoMarkerInfo(val needMark : Boolean? = null, //是否显示手机型号
val needMark: Boolean? = null, //是否显示手机型号 val needShowPhoneBrand : Boolean? = null,
val needShowPhoneBrand: Boolean? = null, val path : String? = null,
val path: String? = null, val from : String? = null,
val from: String? = null, var lat : Double? = null,
var lat: Double? = null, var lng : Double? = null,
var lng: Double? = null, val address : String? = null,
val address: String? = null, val exifTime : String? = null, //照片中获取到的时间 //服务中照片不需要次字段
val time: String? = null, val time : String? = null,
val driverName: String? = null, val photoSource : Int? = null, //服务中照片不需要
val taskCode: String? = null) val driverName : String? = null,
val taskCode : String? = null)

View File

@ -4,31 +4,31 @@
android:viewportWidth="164" android:viewportWidth="164"
android:viewportHeight="94"> android:viewportHeight="94">
<path <path
android:fillColor="#F8FBFF"
android:fillType="evenOdd"
android:pathData="M3.5,0.5L160.5,0.5A3,3 0,0 1,163.5 3.5L163.5,90.5A3,3 0,0 1,160.5 93.5L3.5,93.5A3,3 0,0 1,0.5 90.5L0.5,3.5A3,3 0,0 1,3.5 0.5z" android:pathData="M3.5,0.5L160.5,0.5A3,3 0,0 1,163.5 3.5L163.5,90.5A3,3 0,0 1,160.5 93.5L3.5,93.5A3,3 0,0 1,0.5 90.5L0.5,3.5A3,3 0,0 1,3.5 0.5z"
android:strokeWidth="1" android:strokeWidth="1"
android:fillColor="#F8FBFF" android:strokeColor="#EDEEF2" />
android:strokeColor="#EDEEF2"
android:fillType="evenOdd"/>
<path <path
android:fillAlpha="0.49723306"
android:fillColor="#0057F5"
android:fillType="nonZero"
android:pathData="M75.33,49a6.4,6.22 0,1 0,12.8 0a6.4,6.22 0,1 0,-12.8 0z" android:pathData="M75.33,49a6.4,6.22 0,1 0,12.8 0a6.4,6.22 0,1 0,-12.8 0z"
android:strokeAlpha="0.49723306"
android:strokeWidth="1" android:strokeWidth="1"
android:strokeAlpha="0.49723306"
android:strokeColor="#00000000" />
<path
android:fillAlpha="0.49723306"
android:fillColor="#0057F5" android:fillColor="#0057F5"
android:fillType="nonZero" android:fillType="nonZero"
android:strokeColor="#00000000"
android:fillAlpha="0.49723306"/>
<path
android:pathData="M75.73,29.57L72.07,33.46L65.73,33.46C63.52,33.46 61.73,35.2 61.73,37.34L61.73,60.65C61.73,62.8 63.52,64.53 65.73,64.53L97.73,64.53C99.94,64.53 101.73,62.8 101.73,60.65L101.73,37.34C101.73,35.2 99.94,33.46 97.73,33.46L91.39,33.46L87.73,29.57L75.73,29.57ZM81.73,58.71C76.21,58.71 71.73,54.36 71.73,49C71.73,43.64 76.21,39.29 81.73,39.29C87.25,39.29 91.73,43.64 91.73,49C91.73,54.36 87.25,58.71 81.73,58.71Z" android:pathData="M75.73,29.57L72.07,33.46L65.73,33.46C63.52,33.46 61.73,35.2 61.73,37.34L61.73,60.65C61.73,62.8 63.52,64.53 65.73,64.53L97.73,64.53C99.94,64.53 101.73,62.8 101.73,60.65L101.73,37.34C101.73,35.2 99.94,33.46 97.73,33.46L91.39,33.46L87.73,29.57L75.73,29.57ZM81.73,58.71C76.21,58.71 71.73,54.36 71.73,49C71.73,43.64 76.21,39.29 81.73,39.29C87.25,39.29 91.73,43.64 91.73,49C91.73,54.36 87.25,58.71 81.73,58.71Z"
android:strokeWidth="1"
android:strokeAlpha="0.49723306" android:strokeAlpha="0.49723306"
android:strokeWidth="1" android:strokeColor="#00000000" />
android:fillColor="#0057F5"
android:fillType="nonZero"
android:strokeColor="#00000000"
android:fillAlpha="0.49723306"/>
<path <path
android:pathData="M7.33,84.32C7.33,85.78 8.52,86.97 9.97,86.97L9.97,86.97L9.97,88.42C7.79,88.42 6,86.69 5.9,84.52L5.89,84.32L7.33,84.32ZM157.65,84.32L159.09,84.32C159.09,86.58 157.26,88.42 155.01,88.42L155.01,86.97C156.47,86.97 157.65,85.78 157.65,84.32L157.65,84.32ZM9.97,6.91L9.97,8.36C8.51,8.36 7.33,9.55 7.33,11.01L5.89,11.01C5.89,8.81 7.61,7.02 9.77,6.92L9.97,6.91ZM155.01,6.91C157.26,6.91 159.09,8.75 159.09,11.01L159.09,11.01L157.65,11.01C157.65,9.6 156.56,8.45 155.17,8.36L155.01,8.36Z"
android:strokeWidth="1"
android:fillColor="#206FFF" android:fillColor="#206FFF"
android:fillType="nonZero" android:fillType="nonZero"
android:strokeColor="#00000000"/> android:pathData="M7.33,84.32C7.33,85.78 8.52,86.97 9.97,86.97L9.97,86.97L9.97,88.42C7.79,88.42 6,86.69 5.9,84.52L5.89,84.32L7.33,84.32ZM157.65,84.32L159.09,84.32C159.09,86.58 157.26,88.42 155.01,88.42L155.01,86.97C156.47,86.97 157.65,85.78 157.65,84.32L157.65,84.32ZM9.97,6.91L9.97,8.36C8.51,8.36 7.33,9.55 7.33,11.01L5.89,11.01C5.89,8.81 7.61,7.02 9.77,6.92L9.97,6.91ZM155.01,6.91C157.26,6.91 159.09,8.75 159.09,11.01L159.09,11.01L157.65,11.01C157.65,9.6 156.56,8.45 155.17,8.36L155.01,8.36Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector> </vector>

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64.3dp" android:width="128.8dp"
android:height="64dp" android:height="128dp"
android:viewportWidth="1028" android:viewportWidth="1030"
android:viewportHeight="1024"> android:viewportHeight="1024">
<path <path
android:pathData="M370,493.1L105.8,493.1c-58.4,0 -105.8,-47.5 -105.8,-105.8L0,105.8C0,47.5 47.5,0 105.8,0h264.1c58.3,0 105.8,47.5 105.8,105.8v281.4c-0,58.4 -47.5,105.8 -105.8,105.8zM94.5,47.9c-25.3,0 -45.9,20.6 -45.9,45.9v305.5c0,25.3 20.6,45.9 45.9,45.9L381.3,445.2c25.3,0 45.9,-20.6 45.9,-45.9L427.1,93.8c0,-25.3 -20.6,-45.9 -45.9,-45.9L94.5,47.9zM790.4,1023.9c-130.8,0 -237.3,-106.4 -237.3,-237.3s106.5,-237.3 237.3,-237.3c130.8,0 237.3,106.4 237.3,237.3s-106.4,237.3 -237.3,237.3zM790.4,595.4c-105.5,0 -191.3,85.8 -191.3,191.3 0,105.5 85.8,191.3 191.3,191.3 105.4,0 191.3,-85.8 191.3,-191.3 0,-105.5 -85.8,-191.3 -191.3,-191.3zM922.5,493.1h-264.1c-58.4,0 -105.8,-47.5 -105.8,-105.9L552.5,105.8C552.5,47.5 600,0 658.3,0h264.1c58.3,0 105.8,47.5 105.8,105.8L1028.3,387.2c-0,58.4 -47.5,105.9 -105.8,105.9zM647,47.9c-25.3,0 -45.9,20.6 -45.9,45.9v305.5c0,25.3 20.6,45.9 45.9,45.9h286.8c25.3,0 45.9,-20.6 45.9,-45.9L979.7,93.8c0,-25.3 -20.6,-45.9 -45.9,-45.9h-286.8zM370,1017L105.8,1017c-58.4,0 -105.8,-47.5 -105.8,-105.9v-281.4c0,-58.4 47.5,-105.8 105.8,-105.8h264.1c58.3,0 105.8,47.5 105.8,105.8v281.4c-0,58.4 -47.5,105.9 -105.8,105.9zM94.5,571.8c-25.3,0 -45.9,20.6 -45.9,45.9v305.5c0,25.3 20.6,45.9 45.9,45.9h286.8c25.3,0 45.9,-20.6 45.9,-45.9v-305.5c0,-25.3 -20.6,-45.9 -45.9,-45.9L94.5,571.8z" android:pathData="M0,132.9c0,52.2 42.3,94.5 94.5,94.5 52.2,0 94.5,-42.3 94.5,-94.5C189,80.7 146.7,38.4 94.5,38.4 42.3,38.4 0,80.7 0,132.9zM0,510.8c0,52.2 42.3,94.5 94.5,94.5 52.2,0 94.5,-42.3 94.5,-94.5s-42.3,-94.5 -94.5,-94.5C42.3,416.3 0,458.6 0,510.8zM0,888.8c0,52.2 42.3,94.5 94.5,94.5 52.2,0 94.5,-42.3 94.5,-94.5 0,-52.2 -42.3,-94.5 -94.5,-94.5C42.3,794.3 0,836.6 0,888.8zM961,69.9a63,63 0,1 1,6 125.7l-6,0.3L340.8,195.9c-34.8,-0 -63,-28.2 -63,-63a63,63 0,0 1,56.9 -62.7l6,-0.3h620.3zM961,447.8a63,63 0,1 1,6 125.7l-6,0.3L340.8,573.8c-34.8,-0 -63,-28.2 -63,-63a63,63 0,0 1,56.9 -62.7l6,-0.3h620.3zM961,825.8a63,63 0,1 1,6 125.7l-6,0.3L340.8,951.8c-34.8,-0 -63,-28.2 -63,-63a63,63 0,0 1,56.9 -62.7l6,-0.3h620.3z"
android:fillColor="#ffffff"/> android:fillColor="#ffffff"/>
</vector> </vector>

View File

@ -80,14 +80,16 @@
android:layout_width="@dimen/sign_tool_icon_size" android:layout_width="@dimen/sign_tool_icon_size"
android:layout_height="@dimen/sign_tool_icon_size" android:layout_height="@dimen/sign_tool_icon_size"
android:layout_weight="1" android:layout_weight="1"
android:src="@mipmap/sign_ic_space" /> android:src="@mipmap/sign_ic_space"
android:visibility="gone" />
<com.za.signature.view.CircleImageView <com.za.signature.view.CircleImageView
android:id="@+id/enter" android:id="@+id/enter"
android:layout_width="@dimen/sign_tool_icon_size" android:layout_width="@dimen/sign_tool_icon_size"
android:layout_height="@dimen/sign_tool_icon_size" android:layout_height="@dimen/sign_tool_icon_size"
android:layout_weight="1" android:layout_weight="1"
android:src="@mipmap/sign_ic_enter" /> android:src="@mipmap/sign_ic_enter"
android:visibility="gone" />
<com.za.signature.view.CircleImageView <com.za.signature.view.CircleImageView
android:id="@+id/delete" android:id="@+id/delete"
@ -114,6 +116,7 @@
android:layout_width="@dimen/sign_tool_icon_size" android:layout_width="@dimen/sign_tool_icon_size"
android:layout_height="@dimen/sign_tool_icon_size" android:layout_height="@dimen/sign_tool_icon_size"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:visibility="gone"
app:showOutBorder="true" app:showOutBorder="true"
app:sizeLevel="2" /> app:sizeLevel="2" />
</RelativeLayout> </RelativeLayout>

View File

@ -151,10 +151,7 @@
<com.za.signature.view.GridPaintView <com.za.signature.view.GridPaintView
android:id="@+id/paint_view" android:id="@+id/paint_view"
android:layout_width="@dimen/sign_grid_size" android:layout_width="@dimen/sign_grid_size"
android:layout_height="@dimen/sign_grid_size" android:layout_height="@dimen/sign_grid_size" />
android:layout_gravity="center"
android:layout_margin="10dp"
android:padding="10dp" />
</LinearLayout> </LinearLayout>

Binary file not shown.

Binary file not shown.