feat(servicing): 优化订单详情页面布局和功能
-调整订单信息显示布局,增加订单来源显示 - 优化地图标记添加逻辑,提高地图展示效果 - 改进路径规划功能,优化预计到达时间计算方式- 更新车辆损伤照片加载逻辑,提高数据展示效率 - 修复部分页面样式问题,提升用户体验
This commit is contained in:
@ -33,15 +33,8 @@ android {
|
||||
]
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
config {
|
||||
storeFile file('E:\\workspace\\study\\zd_sdk_demo\\zd_sdk_demo.jks')
|
||||
storePassword '123456'
|
||||
keyAlias 'key0'
|
||||
@ -49,6 +42,18 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.config
|
||||
}
|
||||
debug {
|
||||
minifyEnabled false // 开启混淆
|
||||
signingConfig signingConfigs.config
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
|
@ -44,6 +44,10 @@
|
||||
android:name="android.app.lib_name"
|
||||
android:value="" />
|
||||
</activity>
|
||||
|
||||
<meta-data
|
||||
android:name="com.amap.api.v2.apikey"
|
||||
android:value="ca9429157ac6a0fb3f331b95817b3ca6" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -27,7 +27,7 @@ class MainActivity : ComponentActivity() {
|
||||
.fillMaxSize()
|
||||
.clickable {
|
||||
val uri =
|
||||
"zd.assist://app?taskCode=ZD250422100056&driverName=宋志领&driverPhone=17630035658&rescueVehicle=沪88888".toUri()
|
||||
"zd.assist://app?taskCode=ZD250425100361&driverName=宋志领&driverPhone=17630035658&rescueVehicle=沪88888".toUri()
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ publishing {
|
||||
release(MavenPublication) {
|
||||
groupId = 'io.github.szl9'
|
||||
artifactId = 'zd_servicing'
|
||||
version = "1.0.1.9"
|
||||
version = "1.0.1.9.9.4"
|
||||
|
||||
pom {
|
||||
packaging = "aar"
|
||||
|
@ -9,6 +9,7 @@
|
||||
android:protectionLevel="signature" /> <!-- 位置相关权限 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <!-- 存储相关权限 -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
@ -75,7 +76,10 @@
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application>
|
||||
<application
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="24">
|
||||
<activity
|
||||
android:name="com.za.ui.main.ServiceLauncherActivity"
|
||||
android:exported="true"
|
||||
@ -115,16 +119,19 @@
|
||||
<service
|
||||
android:name="com.za.ui.order_report.ReportFloatingManager"
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="location" />
|
||||
|
||||
<activity
|
||||
android:name="com.za.ui.order_report.HistoryReportActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.Dealer" />
|
||||
<activity
|
||||
android:name="com.za.ui.order_report.OrderReportActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.Dealer" />
|
||||
<activity
|
||||
android:name="com.za.ui.h5.CommonH5Activity"
|
||||
android:exported="false"
|
||||
@ -152,7 +159,8 @@
|
||||
android:theme="@style/Theme.Dealer" />
|
||||
<activity
|
||||
android:name="com.za.signature.GridPaintActivity"
|
||||
android:exported="false" />
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.Dealer" />
|
||||
<activity
|
||||
android:name="com.za.ui.servicing.operation.InOperationActivity"
|
||||
android:exported="false"
|
||||
@ -161,8 +169,8 @@
|
||||
<activity
|
||||
android:name="com.za.ui.camera.ZdCameraXActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.Dealer"
|
||||
android:screenOrientation="portrait">
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.Dealer">
|
||||
<meta-data
|
||||
android:name="android.app.lib_name"
|
||||
android:value="" />
|
||||
|
@ -35,6 +35,8 @@ data class JpushBean(
|
||||
val distLng: Double? = null,
|
||||
val importantTip: String? = null,
|
||||
val tipContent: String? = null,
|
||||
val settleType: Int?=null,//结算类型 1 月结 2 现金
|
||||
var orderSource: String? = null, // "orderSource":"中道救援-比亚迪道路救援项目"
|
||||
val hasReplaceBatteryCapable: Int? = null ,//是否有更换电瓶的能力 1 搭电可以更换电瓶 2搭电不可以更换电瓶 其他的不展示
|
||||
var voiceType : Int?=null //语音提示类型 1小修单 2拖车单 3困境单
|
||||
) : Serializable {
|
||||
|
@ -2,6 +2,7 @@ package com.za.net
|
||||
|
||||
import android.net.ParseException
|
||||
import com.blankj.utilcode.util.ActivityUtils
|
||||
import com.blankj.utilcode.util.ThreadUtils
|
||||
import com.blankj.utilcode.util.ToastUtils
|
||||
import com.google.gson.JsonParseException
|
||||
import com.za.base.Const
|
||||
@ -22,32 +23,34 @@ import javax.net.ssl.SSLHandshakeException
|
||||
* Created by DoggieX on 2017/7/26.
|
||||
*/
|
||||
abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
// if (!NetworkUtils.isAvailable()) {
|
||||
// doFailure(999, "网络无法使用")
|
||||
// d.dispose()
|
||||
// }
|
||||
override fun onSubscribe(d : Disposable) { // if (!NetworkUtils.isAvailable()) {
|
||||
// doFailure(999, "网络无法使用")
|
||||
// d.dispose()
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onNext(tBaseResponse: BaseResponse<T>) {
|
||||
override fun onNext(tBaseResponse : BaseResponse<T>) {
|
||||
if (tBaseResponse.isOk) {
|
||||
doSuccess(tBaseResponse.result)
|
||||
} else {
|
||||
when (tBaseResponse.code) {
|
||||
3, 401 -> handlerTokenExpired()
|
||||
// 4 -> RsaRouter.navigate(context, "/page/Standby")
|
||||
}
|
||||
if (null != tBaseResponse.msg) {
|
||||
doFailure(tBaseResponse.code, tBaseResponse.msg)
|
||||
val errMsg = if (null != tBaseResponse.msg) {
|
||||
tBaseResponse.msg
|
||||
} else if (null != tBaseResponse.message) {
|
||||
doFailure(tBaseResponse.code, tBaseResponse.message)
|
||||
tBaseResponse.message
|
||||
} else {
|
||||
doFailure(tBaseResponse.code, "error")
|
||||
"error"
|
||||
}
|
||||
doFailure(tBaseResponse.code, errMsg)
|
||||
if (errMsg?.contains("请下载新版本app!") == true) {
|
||||
handlerTokenExpired()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
override fun onError(e : Throwable) {
|
||||
LogUtil.print("net error", e)
|
||||
when (e) {
|
||||
is JsonParseException -> {
|
||||
@ -84,6 +87,7 @@ abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
|
||||
doFailure(Const.NetWorkException, "网络连接超时2")
|
||||
LogUtil.print("SocketTimeoutException2", e)
|
||||
}
|
||||
|
||||
else -> {
|
||||
doFailure(1, "error:" + e.message)
|
||||
LogUtil.print("other error", e)
|
||||
@ -94,18 +98,20 @@ abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
|
||||
override fun onComplete() {
|
||||
}
|
||||
|
||||
abstract fun doSuccess(it: T?)
|
||||
abstract fun doSuccess(it : T?)
|
||||
|
||||
abstract fun doFailure(code: Int, msg: String?)
|
||||
abstract fun doFailure(code : Int, msg : String?)
|
||||
|
||||
private fun handlerTokenExpired() {
|
||||
ToastUtils.showShort("登陆信息已过期,请重新登录")
|
||||
ThreadUtils.runOnUiThread {
|
||||
try {
|
||||
ToastUtils.showShort("登陆信息已过期,请重新登录")
|
||||
GlobalData.clearUserCache()
|
||||
ZdLocationManager.stopContinuousLocation()
|
||||
ActivityUtils.finishAllActivities()
|
||||
} catch (e: Exception) {
|
||||
ActivityUtils.startLauncherActivity()
|
||||
} catch (e : Exception) {
|
||||
LogUtil.print("handlerTokenExpired", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import com.za.common.log.LogUtil
|
||||
import com.za.common.util.DeviceUtil
|
||||
import com.za.service.mqtt.MyMqttClient
|
||||
import com.za.servicing.R
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
interface PushListener {
|
||||
fun newOrderMsg(jpushBean : JpushBean)
|
||||
@ -30,7 +29,7 @@ interface PushListener {
|
||||
data class LastJPushBean(val msg : Int, val time : Long = System.nanoTime())
|
||||
|
||||
object ServiceManager {
|
||||
private val pushListener = AtomicReference<PushListener>()
|
||||
private var pushListener : PushListener? = null
|
||||
private var lastJPushBean : LastJPushBean? = null
|
||||
private const val DUPLICATE_MSG_THRESHOLD = 3000L // 3秒
|
||||
|
||||
@ -56,16 +55,15 @@ object ServiceManager {
|
||||
|
||||
// Register push listener
|
||||
fun registerPushListener(listener : PushListener?) {
|
||||
listener?.let {
|
||||
pushListener.set(it)
|
||||
LogUtil.print("ServiceManager", "Registered push listener: ${it.javaClass.simpleName}")
|
||||
}
|
||||
this.pushListener = listener
|
||||
LogUtil.print("ServiceManager",
|
||||
"Registered push listener: ${pushListener?.javaClass?.simpleName}")
|
||||
}
|
||||
|
||||
// Handle incoming push messages
|
||||
@Synchronized
|
||||
fun handlerPushMsg(msg : String) {
|
||||
LogUtil.print("JpushMessage", "Received push message: $msg")
|
||||
LogUtil.print("handlerPushMsg", "Received push message: $msg")
|
||||
|
||||
// 优化后的重复消息判断
|
||||
lastJPushBean?.let {
|
||||
@ -76,12 +74,12 @@ object ServiceManager {
|
||||
}
|
||||
|
||||
if (msg.startsWith("broadcast:")) {
|
||||
lastJPushBean = LastJPushBean(msg.hashCode())
|
||||
lastJPushBean = LastJPushBean(msg = msg.hashCode())
|
||||
handleBroadcast(msg)
|
||||
return
|
||||
}
|
||||
try {
|
||||
lastJPushBean = LastJPushBean(msg.hashCode())
|
||||
lastJPushBean = LastJPushBean(msg = msg.hashCode())
|
||||
val jpushOrderInfoBean = Gson().fromJson(msg, JpushBean::class.java)
|
||||
sendSystemNotificationFromMessage(jpushOrderInfoBean)
|
||||
when (jpushOrderInfoBean.pushType) {
|
||||
@ -103,7 +101,7 @@ object ServiceManager {
|
||||
private fun handleBroadcast(msg : String) {
|
||||
try {
|
||||
val content = msg.substring(10)
|
||||
pushListener.get()?.broadcast(content)
|
||||
pushListener?.broadcast(content)
|
||||
sendNotification(GlobalData.application, content)
|
||||
LogUtil.print("JpushMessage", "Broadcast content: $content")
|
||||
} catch (e : Exception) {
|
||||
@ -124,7 +122,9 @@ object ServiceManager {
|
||||
// Handle new order messages
|
||||
private fun newOrderMsg(jpushOrderBean : JpushBean) {
|
||||
try {
|
||||
pushListener.get()?.newOrderMsg(jpushOrderBean)
|
||||
LogUtil.print("JpushMessage",
|
||||
"Handling new order message: $pushListener ${pushListener?.javaClass?.simpleName}")
|
||||
pushListener?.newOrderMsg(jpushOrderBean)
|
||||
} catch (e : Exception) {
|
||||
LogUtil.print("JpushMessage", "Failed to handle new order message: ${e.message}")
|
||||
}
|
||||
@ -132,22 +132,22 @@ object ServiceManager {
|
||||
|
||||
// Handle give up order messages
|
||||
private fun giveUpOrder(jpushOrderBean : JpushBean) {
|
||||
pushListener.get()?.giveUpOrder(jpushOrderBean)
|
||||
pushListener?.giveUpOrder(jpushOrderBean)
|
||||
}
|
||||
|
||||
// Handle revoke order messages
|
||||
private fun revokeOrder(jpushOrderBean : JpushBean) {
|
||||
pushListener.get()?.revokeOrder(jpushOrderBean)
|
||||
pushListener?.revokeOrder(jpushOrderBean)
|
||||
}
|
||||
|
||||
// Handle re-dispatch order messages
|
||||
private fun reDispatchOrder(jpushOrderBean : JpushBean) {
|
||||
pushListener.get()?.reDispatchOrder(jpushOrderBean)
|
||||
pushListener?.reDispatchOrder(jpushOrderBean)
|
||||
}
|
||||
|
||||
// Handle important tip messages
|
||||
private fun importantTip(jpushOrderBean : JpushBean) {
|
||||
pushListener.get()?.importantTip(jpushOrderBean)
|
||||
pushListener?.importantTip(jpushOrderBean)
|
||||
}
|
||||
|
||||
// Disconnect from JPush and MQTT
|
||||
|
@ -20,7 +20,6 @@ import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Done
|
||||
import androidx.compose.material.icons.filled.Menu
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
@ -50,7 +49,9 @@ import com.blankj.utilcode.util.ActivityUtils
|
||||
import com.za.base.BaseActivity
|
||||
import com.za.base.theme.bgColor
|
||||
import com.za.base.view.CommonButton
|
||||
import com.za.base.view.EmptyView
|
||||
import com.za.base.view.HeadView
|
||||
import com.za.base.view.LoadError
|
||||
import com.za.bean.db.order.OrderInfo
|
||||
import com.za.common.GlobalData
|
||||
import com.za.common.util.DeviceUtil
|
||||
@ -129,23 +130,35 @@ private fun ServicingMainScreen(jobCode : String? = null,
|
||||
.fillMaxSize()
|
||||
.background(bgColor)
|
||||
.padding(it)) {
|
||||
if (uiState.value.state == 2) {
|
||||
when (uiState.value.state) {
|
||||
1 -> {
|
||||
Box(modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(top = 10.dp),
|
||||
contentAlignment = Alignment.TopCenter) {
|
||||
OrderItemView(GlobalData.currentOrder)
|
||||
}
|
||||
}
|
||||
|
||||
2 -> {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
CommonButton(text = "订单获取异常,点击重新获取") {
|
||||
LoadError(message = "订单获取异常", onRetry = {
|
||||
vm.dispatch(ServicingMainVm.Action.Init(jobCode,
|
||||
phone,
|
||||
taskCode,
|
||||
vehicleId,
|
||||
deviceId,
|
||||
rescueVehicle))
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Box(modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(top = 10.dp),
|
||||
contentAlignment = Alignment.TopCenter) {
|
||||
OrderItemView(GlobalData.currentOrder)
|
||||
|
||||
3 -> { //
|
||||
EmptyView()
|
||||
}
|
||||
|
||||
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,11 +46,14 @@ class ServicingMainVm : BaseVm<ServicingMainVm.Action, ServicingMainVm.UiState>(
|
||||
CommonMethod.queryOrderList(context = ActivityUtils.getTopActivity(),
|
||||
success = { orderInfo : OrderInfo?, orderInfos : List<OrderInfo>? ->
|
||||
LoadingManager.hideLoading()
|
||||
if (orderInfo == null) {
|
||||
ToastUtils.showShort("未查询到订单")
|
||||
GlobalData.clearAllOrderCache()
|
||||
updateState(uiState.value.copy(state = 3))
|
||||
return@queryOrderList
|
||||
}
|
||||
GlobalData.currentOrder = orderInfo
|
||||
updateState(uiState.value.copy(state = 1))
|
||||
if (orderInfos.isNullOrEmpty()) {
|
||||
ToastUtils.showShort("未查询到订单")
|
||||
}
|
||||
},
|
||||
failed = {
|
||||
updateState(uiState.value.copy(state = 2))
|
||||
@ -106,6 +109,6 @@ class ServicingMainVm : BaseVm<ServicingMainVm.Action, ServicingMainVm.UiState>(
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
val state : Int? = null, //1 成功 2 失败
|
||||
val state : Int? = null, //1 成功 2 失败 3:订单为空
|
||||
)
|
||||
}
|
@ -57,6 +57,7 @@ import coil.compose.AsyncImage
|
||||
import com.amap.api.location.AMapLocationClient
|
||||
import com.amap.api.maps.CameraUpdateFactory
|
||||
import com.amap.api.maps.MapView
|
||||
import com.amap.api.maps.model.BitmapDescriptorFactory
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.amap.api.maps.model.LatLngBounds
|
||||
import com.amap.api.maps.model.MarkerOptions
|
||||
@ -234,18 +235,18 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
|
||||
}
|
||||
|
||||
// 添加距离和时间信息
|
||||
// 距离和时间信息
|
||||
Row(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(text = "预计到达: ${uiState.value.estimatedArrivalTime}",
|
||||
color = Color(0xFF666666),
|
||||
fontSize = 14.sp)
|
||||
Text(text = if (uiState.value.estimatedArrivalTime.isNotEmpty()) "预计到达: ${uiState.value.estimatedArrivalTime}"
|
||||
else "计算中...", color = Color(0xFF666666), fontSize = 14.sp)
|
||||
|
||||
Text(text = "总里程: %.1fkm".format(uiState.value.remainingDistance / 1000f),
|
||||
color = Color(0xFFFF4D4F),
|
||||
fontSize = 14.sp)
|
||||
Text(text = if (uiState.value.remainingDistance > 0) "距离救援地: %.1fkm".format(
|
||||
uiState.value.remainingDistance / 1000f)
|
||||
else "计算中...", color = Color(0xFFFF4D4F), fontSize = 14.sp)
|
||||
}
|
||||
|
||||
HorizontalDivider(modifier = Modifier
|
||||
@ -256,8 +257,26 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
|
||||
Column(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)) { // 订单标签
|
||||
Text(text = uiState.value.jpushBean?.serviceTypeName ?: "",
|
||||
fontSize = 18.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Color.Black)
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// 订单标签
|
||||
Row(verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Box(modifier = Modifier
|
||||
.background(Color(0xFF9BA1B2), RoundedCornerShape(4.dp))
|
||||
.padding(horizontal = 6.dp, vertical = 2.dp)) {
|
||||
Text(text = "月结".takeIf { uiState.value.jpushBean?.settleType == 1 }
|
||||
?: "现金", color = Color.White, fontSize = 12.sp)
|
||||
}
|
||||
|
||||
Text(text = uiState.value.jpushBean?.orderSource ?: "",
|
||||
color = Color.Black,
|
||||
fontSize = 12.sp)
|
||||
|
||||
Text(text = uiState.value.jpushBean?.addressProperty ?: "",
|
||||
color = Color(0xFFFD8205),
|
||||
@ -416,10 +435,9 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
|
||||
|
||||
// 绘制路线
|
||||
uiState.value.routePoints?.let { points ->
|
||||
if (points.isNotEmpty()) {
|
||||
mapView.map.addPolyline(PolylineOptions().addAll(points).width(15f)
|
||||
.color(Color(0xFF3D4B7C).toArgb()).zIndex(1f))
|
||||
}
|
||||
.setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.icon_road_green_arrow))
|
||||
.zIndex(1f))
|
||||
}
|
||||
|
||||
// 添加标记点
|
||||
|
@ -157,7 +157,7 @@ class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
|
||||
val photoList = RoomHelper.db?.eleCarDamagePhotoDao()?.getEleCarDamagePhotos(getCurrentOrder()?.taskId
|
||||
?: 0)
|
||||
updateState(uiState.value.copy(eleWorkOrderBean = it, damagePhoto = photoList, orderInfo = getCurrentOrder()))
|
||||
LogUtil.print("电子表单更新车辆损伤照片", "eleWorkOrderBean==${photoList.toJson()}")
|
||||
LogUtil.print("电子表单更新车辆损伤照片", "eleWorkOrderBean==${it.toJson()}")
|
||||
},
|
||||
failed = {
|
||||
LoadingManager.hideLoading()
|
||||
|
@ -170,16 +170,17 @@ fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
|
||||
Column(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)) {
|
||||
Row(modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically) {
|
||||
|
||||
Text(text = uiState.value.orderInfo?.serviceTypeName ?: "",
|
||||
fontSize = 18.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Color.Black)
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// 订单标签
|
||||
Row(verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Box(modifier = Modifier
|
||||
.background(Color(0xFF9BA1B2), RoundedCornerShape(4.dp))
|
||||
.padding(horizontal = 6.dp, vertical = 2.dp)) {
|
||||
@ -187,13 +188,15 @@ fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
|
||||
?: "现金", color = Color.White, fontSize = 12.sp)
|
||||
}
|
||||
|
||||
Text(text = uiState.value.orderInfo?.orderSource ?: "",
|
||||
color = Color.Black,
|
||||
fontSize = 12.sp)
|
||||
|
||||
Text(text = uiState.value.orderInfo?.addressProperty ?: "",
|
||||
color = Color(0xFFFD8205),
|
||||
fontSize = 12.sp,
|
||||
fontWeight = FontWeight.Medium)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically,
|
||||
|
@ -34,6 +34,7 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.UiState>() {
|
||||
@ -136,7 +137,7 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
|
||||
updateState(uiState = uiState.value.copy(orderInfo = getCurrentOrder()))
|
||||
buildMarkers(getCurrentOrder())
|
||||
searchDrivingRoute(getCurrentOrder())
|
||||
// dispatch(Action.StartTimer)
|
||||
startTimer()
|
||||
}
|
||||
|
||||
private fun buildMarkers(orderInfo : OrderInfo?) {
|
||||
@ -182,14 +183,13 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
|
||||
val points = path.steps.flatMap { step ->
|
||||
step.polyline.map { LatLng(it.latitude, it.longitude) }
|
||||
}
|
||||
val durationInSeconds = path.duration
|
||||
val arrivalTime = SimpleDateFormat("HH:mm:ss",
|
||||
Locale.getDefault()).format(System.currentTimeMillis() + durationInSeconds * 1000)
|
||||
|
||||
|
||||
LogUtil.print("arrivalTime", "arrivalTime: arrivalTime=$arrivalTime")
|
||||
LogUtil.print("distance", "distance: distance=${path.distance.div(1000)}km")
|
||||
updateState(uiState.value.copy(routePoints = points, estimatedArrivalTime = arrivalTime, remainingDistance = path.distance))
|
||||
val duration = path.duration
|
||||
val arrivalTime = System.currentTimeMillis() + duration * 1000
|
||||
val dateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val estimatedTime = dateFormat.format(Date(arrivalTime))
|
||||
updateState(uiState.value.copy(routePoints = points,
|
||||
estimatedArrivalTime = estimatedTime,
|
||||
remainingDistance = path.distance))
|
||||
} else {
|
||||
LogUtil.print("searchDrivingRoute", "路径规划失败: errorCode=$errorCode")
|
||||
}
|
||||
@ -233,16 +233,16 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
|
||||
private var timerJob : Job? = null
|
||||
|
||||
private fun startTimer() {
|
||||
timerJob?.cancel()
|
||||
timerJob = viewModelScope.launch {
|
||||
while (isActive) {
|
||||
val (distance, arrivalTime) = calculateRemainingDistance()
|
||||
_uiState.update {
|
||||
it.copy(remainingDistance = distance, estimatedArrivalTime = arrivalTime)
|
||||
}
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
// timerJob?.cancel()
|
||||
// timerJob = viewModelScope.launch {
|
||||
// while (isActive) {
|
||||
// val (distance, arrivalTime) = calculateRemainingDistance()
|
||||
// _uiState.update {
|
||||
// it.copy(remainingDistance = distance, estimatedArrivalTime = arrivalTime)
|
||||
// }
|
||||
// delay(1000)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
@ -78,7 +78,7 @@ class GoToDestinationActivity : BaseActivity() {
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
|
||||
fun GoToDestinationScreen(vm : GoToDestinationVm = viewModel()) {
|
||||
val uiState = vm.uiState.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
@ -88,13 +88,10 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
// 修改 BottomSheet 状态
|
||||
val bottomSheetState = rememberStandardBottomSheetState(
|
||||
initialValue = SheetValue.PartiallyExpanded,
|
||||
confirmValueChange = { true }
|
||||
)
|
||||
val scaffoldState = rememberBottomSheetScaffoldState(
|
||||
bottomSheetState = bottomSheetState
|
||||
)
|
||||
val bottomSheetState =
|
||||
rememberStandardBottomSheetState(initialValue = SheetValue.PartiallyExpanded,
|
||||
confirmValueChange = { true })
|
||||
val scaffoldState = rememberBottomSheetScaffoldState(bottomSheetState = bottomSheetState)
|
||||
|
||||
// 优化状态管理
|
||||
val isExpanded by remember {
|
||||
@ -103,8 +100,10 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
|
||||
|
||||
// 记忆化常用值,减少重组
|
||||
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 }
|
||||
val estimatedTime =
|
||||
remember(uiState.value.estimatedArrivalTime) { uiState.value.estimatedArrivalTime }
|
||||
val remainingDistance =
|
||||
remember(uiState.value.remainingDistance) { uiState.value.remainingDistance }
|
||||
|
||||
DisposableEffect(key1 = lifecycleOwner) {
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
@ -133,285 +132,210 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
|
||||
}
|
||||
|
||||
if (uiState.value.isGoNextPageDialog == true) {
|
||||
CommonDialog(
|
||||
cancelText = "取消",
|
||||
CommonDialog(cancelText = "取消",
|
||||
confirmText = "前往下一步",
|
||||
title = "是否前往下一步?",
|
||||
cancelEnable = true,
|
||||
cancel = {
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false)))
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(
|
||||
isGoNextPageDialog = false)))
|
||||
},
|
||||
dismiss = {
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(
|
||||
isGoNextPageDialog = false)))
|
||||
},
|
||||
dismiss = { vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false))) },
|
||||
confirm = {
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = false)))
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(
|
||||
isGoNextPageDialog = false)))
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateTask)
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
if (uiState.value.showOfflineDialog == true) {
|
||||
CommonDialog(
|
||||
cancelText = "取消",
|
||||
CommonDialog(cancelText = "取消",
|
||||
confirmText = "离线上传",
|
||||
title = "任务提交失败,是否离线提交?",
|
||||
cancelEnable = true,
|
||||
cancel = {
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false)))
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(
|
||||
showOfflineDialog = false)))
|
||||
},
|
||||
dismiss = {
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(
|
||||
showOfflineDialog = false)))
|
||||
},
|
||||
dismiss = { vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false))) },
|
||||
confirm = {
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(showOfflineDialog = false)))
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(
|
||||
showOfflineDialog = false)))
|
||||
vm.dispatch(GoToDestinationVm.Action.UploadOffline)
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
BottomSheetScaffold(
|
||||
scaffoldState = scaffoldState,
|
||||
BottomSheetScaffold(scaffoldState = scaffoldState,
|
||||
topBar = {
|
||||
InServicingHeadView(
|
||||
title = "作业完成,正在拖往目的地",
|
||||
InServicingHeadView(title = "作业完成,正在拖往目的地",
|
||||
onBack = { context.finish() },
|
||||
orderInfo = orderInfo
|
||||
)
|
||||
orderInfo = orderInfo)
|
||||
},
|
||||
sheetContent = {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
Column(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
// 滑动指示器
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())) { // 滑动指示器
|
||||
Box(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
contentAlignment = Alignment.Center) {
|
||||
Box(modifier = Modifier
|
||||
.width(32.dp)
|
||||
.height(4.dp)
|
||||
.background(
|
||||
color = Color(0xFFE0E0E0),
|
||||
shape = RoundedCornerShape(2.dp)
|
||||
)
|
||||
)
|
||||
.background(color = Color(0xFFE0E0E0), shape = RoundedCornerShape(2.dp)))
|
||||
}
|
||||
|
||||
// 距离和时间信息
|
||||
Row(
|
||||
modifier = Modifier
|
||||
Row(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = if (estimatedTime.isNotEmpty())
|
||||
"预计到达: $estimatedTime"
|
||||
else
|
||||
"计算中...",
|
||||
color = Color(0xFF666666),
|
||||
fontSize = 14.sp
|
||||
)
|
||||
verticalAlignment = Alignment.CenterVertically) {
|
||||
Text(text = if (estimatedTime.isNotEmpty()) "预计到达: $estimatedTime"
|
||||
else "计算中...", color = Color(0xFF666666), fontSize = 14.sp)
|
||||
|
||||
Text(
|
||||
text = if (remainingDistance > 0)
|
||||
"目的地距离: %.1fkm".format(remainingDistance / 1000f)
|
||||
else
|
||||
"计算中...",
|
||||
color = Color(0xFFFF4D4F),
|
||||
fontSize = 14.sp
|
||||
)
|
||||
Text(text = if (remainingDistance > 0) "目的地距离: %.1fkm".format(
|
||||
remainingDistance / 1000f)
|
||||
else "计算中...", color = Color(0xFFFF4D4F), fontSize = 14.sp)
|
||||
}
|
||||
|
||||
// 使用 HorizontalDivider 替代 Box
|
||||
HorizontalDivider(
|
||||
modifier = Modifier
|
||||
HorizontalDivider(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.alpha(0.1f)
|
||||
)
|
||||
.alpha(0.1f))
|
||||
|
||||
// 订单信息
|
||||
Column(
|
||||
modifier = Modifier
|
||||
Column(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = uiState.value.orderInfo?.serviceTypeName ?: "",
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)) {
|
||||
Text(text = uiState.value.orderInfo?.serviceTypeName ?: "",
|
||||
fontSize = 18.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Color.Black
|
||||
)
|
||||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
color = Color.Black)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
// 订单标签
|
||||
Row(verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Box(modifier = Modifier
|
||||
.background(Color(0xFF9BA1B2), RoundedCornerShape(4.dp))
|
||||
.padding(horizontal = 6.dp, vertical = 2.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "月结".takeIf { uiState.value.orderInfo?.settleType == 1 }
|
||||
?: "现金",
|
||||
color = Color.White,
|
||||
fontSize = 12.sp
|
||||
)
|
||||
.padding(horizontal = 6.dp, vertical = 2.dp)) {
|
||||
Text(text = "月结".takeIf { uiState.value.orderInfo?.settleType == 1 }
|
||||
?: "现金", color = Color.White, fontSize = 12.sp)
|
||||
}
|
||||
|
||||
Text(
|
||||
text = uiState.value.orderInfo?.addressProperty ?: "",
|
||||
Text(text = uiState.value.orderInfo?.orderSource ?: "",
|
||||
color = Color.Black,
|
||||
fontSize = 12.sp)
|
||||
|
||||
Text(text = uiState.value.orderInfo?.addressProperty ?: "",
|
||||
color = Color(0xFFFD8205),
|
||||
fontSize = 12.sp,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
}
|
||||
fontWeight = FontWeight.Medium)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
// 订单号
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.clickable { uiState.value.orderInfo?.taskCode?.copy(context) }
|
||||
) {
|
||||
Text(
|
||||
text = "单号",
|
||||
color = Color(0xFF999999),
|
||||
fontSize = 13.sp
|
||||
)
|
||||
Row(verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.clickable {
|
||||
uiState.value.orderInfo?.taskCode?.copy(context)
|
||||
}) {
|
||||
Text(text = "单号", color = Color(0xFF999999), fontSize = 13.sp)
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
|
||||
Text(
|
||||
text = uiState.value.orderInfo?.taskCode ?: "",
|
||||
Text(text = uiState.value.orderInfo?.taskCode ?: "",
|
||||
color = Color(0xFF666666),
|
||||
fontSize = 14.sp
|
||||
)
|
||||
fontSize = 14.sp)
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
|
||||
AsyncImage(
|
||||
model = R.drawable.sv_copy,
|
||||
AsyncImage(model = R.drawable.sv_copy,
|
||||
contentDescription = "copy",
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
modifier = Modifier.size(16.dp))
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
// 地址信息
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
// 救援地
|
||||
Row(
|
||||
verticalAlignment = Alignment.Top,
|
||||
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { // 救援地
|
||||
Row(verticalAlignment = Alignment.Top,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
uiState.value.orderInfo?.let { order ->
|
||||
if (order.lat != null && order.lat != 0.0 &&
|
||||
order.lng != null && order.lng != 0.0
|
||||
) {
|
||||
mapView.map.animateCamera(
|
||||
CameraUpdateFactory.newLatLngZoom(
|
||||
LatLng(order.lat!!, order.lng!!),
|
||||
16f
|
||||
)
|
||||
)
|
||||
if (order.lat != null && order.lat != 0.0 && order.lng != null && order.lng != 0.0) {
|
||||
mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(
|
||||
LatLng(order.lat !!, order.lng !!),
|
||||
16f))
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
AsyncImage(
|
||||
model = R.drawable.sv_rescuing,
|
||||
}) {
|
||||
AsyncImage(model = R.drawable.sv_rescuing,
|
||||
contentDescription = "rescue",
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
modifier = Modifier.size(16.dp))
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
|
||||
Text(
|
||||
text = uiState.value.orderInfo?.address ?: "",
|
||||
Text(text = uiState.value.orderInfo?.address ?: "",
|
||||
color = Color.Black,
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
modifier = Modifier.weight(1f))
|
||||
}
|
||||
|
||||
// 目的地
|
||||
if (!uiState.value.orderInfo?.distAddress.isNullOrBlank()) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.Top,
|
||||
if (! uiState.value.orderInfo?.distAddress.isNullOrBlank()) {
|
||||
Row(verticalAlignment = Alignment.Top,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
uiState.value.orderInfo?.let { order ->
|
||||
if (order.distLat != null && order.distLat != 0.0 &&
|
||||
order.distLng != null && order.distLng != 0.0
|
||||
) {
|
||||
mapView.map.animateCamera(
|
||||
CameraUpdateFactory.newLatLngZoom(
|
||||
LatLng(order.distLat!!, order.distLng!!),
|
||||
16f
|
||||
)
|
||||
)
|
||||
if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0) {
|
||||
mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(
|
||||
LatLng(order.distLat !!, order.distLng !!),
|
||||
16f))
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
AsyncImage(
|
||||
model = R.drawable.sv_dist,
|
||||
}) {
|
||||
AsyncImage(model = R.drawable.sv_dist,
|
||||
contentDescription = "destination",
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
modifier = Modifier.size(16.dp))
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
|
||||
Text(
|
||||
text = uiState.value.orderInfo?.distAddress ?: "",
|
||||
Text(text = uiState.value.orderInfo?.distAddress ?: "",
|
||||
color = Color.Black,
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
modifier = Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 到达按钮 - 移除外层 Column,简化布局
|
||||
Button(
|
||||
onClick = {
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = true)))
|
||||
Button(onClick = {
|
||||
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(
|
||||
isGoNextPageDialog = true)))
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(44.dp)
|
||||
.padding(horizontal = 16.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = headBgColor
|
||||
),
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "到达目的地",
|
||||
colors = ButtonDefaults.buttonColors(containerColor = headBgColor),
|
||||
shape = RoundedCornerShape(8.dp)) {
|
||||
Text(text = "到达目的地",
|
||||
color = Color.White,
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
fontWeight = FontWeight.Medium)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
@ -421,17 +345,11 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
|
||||
sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp),
|
||||
sheetContainerColor = Color.White,
|
||||
sheetDragHandle = null,
|
||||
sheetSwipeEnabled = true
|
||||
) { paddingValues ->
|
||||
Box(
|
||||
modifier = Modifier
|
||||
sheetSwipeEnabled = true) { paddingValues ->
|
||||
Box(modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
) {
|
||||
AndroidView(
|
||||
modifier = Modifier
|
||||
.fillMaxSize(),
|
||||
factory = {
|
||||
.padding(paddingValues)) {
|
||||
AndroidView(modifier = Modifier.fillMaxSize(), factory = {
|
||||
AMapLocationClient.updatePrivacyShow(context, true, true)
|
||||
AMapLocationClient.updatePrivacyAgree(context, true)
|
||||
mapView.apply {
|
||||
@ -439,7 +357,7 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
|
||||
isTrafficEnabled = false
|
||||
isMyLocationEnabled = false
|
||||
uiSettings.isMyLocationButtonEnabled = false
|
||||
uiSettings.setLogoBottomMargin(-100)
|
||||
uiSettings.setLogoBottomMargin(- 100)
|
||||
uiSettings.isZoomControlsEnabled = false
|
||||
|
||||
// 添加标记点点击事件
|
||||
@ -452,106 +370,70 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
update = {
|
||||
// 清除旧标记和路线
|
||||
}, update = { // 清除旧标记和路线
|
||||
mapView.map.clear()
|
||||
|
||||
// 先绘制路线
|
||||
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))
|
||||
.zIndex(1f)
|
||||
)
|
||||
.zIndex(1f))
|
||||
}
|
||||
|
||||
// 再添加标记点,确保标记点在路线上层
|
||||
// 添加当前位置标记
|
||||
if (GlobalData.currentLocation != null) {
|
||||
mapView.map.addMarker(
|
||||
MarkerOptions()
|
||||
.position(LatLng(
|
||||
GlobalData.currentLocation?.latitude!!,
|
||||
GlobalData.currentLocation?.longitude!!
|
||||
))
|
||||
.title("当前位置")
|
||||
.icon(ImageUtil.vectorToBitmap(context,R.drawable.ic_current_location))
|
||||
.anchor(0.5f, 0.5f)
|
||||
.visible(true)
|
||||
)
|
||||
mapView.map.addMarker(MarkerOptions().position(LatLng(GlobalData.currentLocation?.latitude !!,
|
||||
GlobalData.currentLocation?.longitude !!)).title("当前位置")
|
||||
.icon(ImageUtil.vectorToBitmap(context, R.drawable.ic_current_location))
|
||||
.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("救援地点")
|
||||
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)
|
||||
)
|
||||
.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("目的地")
|
||||
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(BitmapDescriptorFactory.fromResource(R.mipmap.sv_dist_map))
|
||||
.anchor(0.5f, 0.5f)
|
||||
)
|
||||
.anchor(0.5f, 0.5f))
|
||||
}
|
||||
}
|
||||
|
||||
// 调整地图显示范围
|
||||
val bounds = LatLngBounds.Builder().apply {
|
||||
// 添加当前位置
|
||||
val bounds = LatLngBounds.Builder().apply { // 添加当前位置
|
||||
GlobalData.currentLocation?.let {
|
||||
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.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!!))
|
||||
if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0) {
|
||||
include(LatLng(order.distLat !!, order.distLng !!))
|
||||
}
|
||||
}
|
||||
}.build()
|
||||
|
||||
try {
|
||||
mapView.map.animateCamera(
|
||||
CameraUpdateFactory.newLatLngBounds(bounds, 100)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
// 如果计算边界失败,则使用默认缩放级别
|
||||
mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100))
|
||||
} catch (e : Exception) { // 如果计算边界失败,则使用默认缩放级别
|
||||
GlobalData.currentLocation?.let {
|
||||
mapView.map.animateCamera(
|
||||
CameraUpdateFactory.newLatLngZoom(
|
||||
LatLng(it.latitude, it.longitude),
|
||||
15f
|
||||
)
|
||||
)
|
||||
mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude,
|
||||
it.longitude), 15f))
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,16 +34,17 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestinationVm.UiState>() {
|
||||
private val _uiState = MutableStateFlow(UiState())
|
||||
val uiState get() = _uiState
|
||||
override fun updateState(uiState: UiState) {
|
||||
override fun updateState(uiState : UiState) {
|
||||
_uiState.value = uiState
|
||||
}
|
||||
|
||||
override fun dispatch(action: Action) {
|
||||
override fun dispatch(action : Action) {
|
||||
when (action) {
|
||||
is Action.Init -> init()
|
||||
is Action.UpdateTask -> updateTask()
|
||||
@ -53,12 +54,11 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateOfflineTask(taskRequest: UpdateTaskRequest? = null) {
|
||||
private fun updateOfflineTask(taskRequest : UpdateTaskRequest? = null) {
|
||||
LoadingManager.showLoading()
|
||||
ZdLocationManager.getSingleLocation(success = {
|
||||
LoadingManager.hideLoading()
|
||||
val temp = taskRequest ?: UpdateTaskRequest(
|
||||
type = "ARRIVE_DEST",
|
||||
val temp = taskRequest ?: UpdateTaskRequest(type = "ARRIVE_DEST",
|
||||
taskId = GlobalData.currentOrder?.taskId,
|
||||
userId = GlobalData.driverInfoBean?.userId,
|
||||
vehicleId = GlobalData.driverInfoBean?.vehicleId,
|
||||
@ -69,8 +69,7 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
lat = it.latitude,
|
||||
lng = it.longitude)
|
||||
|
||||
val offlineUpdateTaskBean = OfflineUpdateTaskBean(
|
||||
type = temp.type,
|
||||
val offlineUpdateTaskBean = OfflineUpdateTaskBean(type = temp.type,
|
||||
taskId = temp.taskId,
|
||||
flowType = temp.flowType,
|
||||
userId = temp.userId,
|
||||
@ -87,7 +86,8 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
insertOfflineTask(offlineUpdateTaskBean)
|
||||
|
||||
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()))
|
||||
}, failed = {
|
||||
LoadingManager.hideLoading()
|
||||
ToastUtils.showShort(it)
|
||||
@ -99,8 +99,7 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
LoadingManager.showLoading()
|
||||
ZdLocationManager.getSingleLocation(success = {
|
||||
LoadingManager.hideLoading()
|
||||
val taskRequest = UpdateTaskRequest(
|
||||
type = "ARRIVE_DEST",
|
||||
val taskRequest = UpdateTaskRequest(type = "ARRIVE_DEST",
|
||||
taskId = GlobalData.currentOrder?.taskId,
|
||||
userId = GlobalData.driverInfoBean?.userId,
|
||||
vehicleId = GlobalData.driverInfoBean?.vehicleId,
|
||||
@ -117,8 +116,8 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
})
|
||||
}
|
||||
|
||||
private fun doUploadTask(request: UpdateTaskRequest) {
|
||||
if (!getCurrentOrderOfflineTask().isNullOrEmpty()) {
|
||||
private fun doUploadTask(request : UpdateTaskRequest) {
|
||||
if (! getCurrentOrderOfflineTask().isNullOrEmpty()) {
|
||||
updateOfflineTask(taskRequest = request)
|
||||
return
|
||||
}
|
||||
@ -140,24 +139,19 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
private fun init() {
|
||||
updateState(uiState = uiState.value.copy(orderInfo = getCurrentOrder()))
|
||||
buildMarkers(getCurrentOrder())
|
||||
searchDrivingRoute(getCurrentOrder())
|
||||
// dispatch(Action.StartTimer)
|
||||
searchDrivingRoute(getCurrentOrder()) // dispatch(Action.StartTimer)
|
||||
}
|
||||
|
||||
private fun searchDrivingRoute(orderInfo: OrderInfo?) {
|
||||
// 如果没有当前位置,则不进行路径规划
|
||||
private fun searchDrivingRoute(orderInfo : OrderInfo?) { // 如果没有当前位置,则不进行路径规划
|
||||
if (GlobalData.currentLocation == null) return
|
||||
|
||||
val currentPoint = LatLonPoint(
|
||||
GlobalData.currentLocation?.latitude ?: 0.0,
|
||||
GlobalData.currentLocation?.longitude ?: 0.0
|
||||
)
|
||||
val currentPoint = LatLonPoint(GlobalData.currentLocation?.latitude ?: 0.0,
|
||||
GlobalData.currentLocation?.longitude ?: 0.0)
|
||||
|
||||
// 获取目的地坐标
|
||||
val destPoint = if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 &&
|
||||
orderInfo.distLng != null && orderInfo.distLng != 0.0
|
||||
) {
|
||||
LatLonPoint(orderInfo.distLat!!, orderInfo.distLng!!)
|
||||
val destPoint =
|
||||
if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) {
|
||||
LatLonPoint(orderInfo.distLat !!, orderInfo.distLng !!)
|
||||
} else null
|
||||
|
||||
// 如果没有目的地,则不进行规划
|
||||
@ -166,43 +160,44 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
// 使用 Application Context 创建路由搜索对象
|
||||
val routeSearch = RouteSearch(GlobalData.application)
|
||||
routeSearch.setRouteSearchListener(object : RouteSearch.OnRouteSearchListener {
|
||||
override fun onDriveRouteSearched(result: DriveRouteResult?, errorCode: Int) {
|
||||
override fun onDriveRouteSearched(result : DriveRouteResult?, errorCode : Int) {
|
||||
if (errorCode == 1000 && result != null && result.paths.isNotEmpty()) {
|
||||
val path = result.paths[0]
|
||||
val points = path.steps.flatMap { step ->
|
||||
step.polyline.map { LatLng(it.latitude, it.longitude) }
|
||||
}
|
||||
val durationInSeconds = path.duration
|
||||
val arrivalTime = SimpleDateFormat("HH:mm:ss",
|
||||
Locale.getDefault()).format(System.currentTimeMillis() + durationInSeconds * 1000)
|
||||
|
||||
updateState(uiState.value.copy(routePoints = points, estimatedArrivalTime =arrivalTime, remainingDistance = path.distance ))
|
||||
val duration = path.duration
|
||||
val arrivalTime = System.currentTimeMillis() + duration * 1000
|
||||
val dateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val estimatedTime = dateFormat.format(Date(arrivalTime))
|
||||
updateState(uiState.value.copy(routePoints = points,
|
||||
estimatedArrivalTime = estimatedTime,
|
||||
remainingDistance = path.distance))
|
||||
} else {
|
||||
LogUtil.print("searchDrivingRoute", "路径规划失败: errorCode=$errorCode")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBusRouteSearched(p0: BusRouteResult?, p1: Int) {}
|
||||
override fun onWalkRouteSearched(p0: WalkRouteResult?, p1: Int) {}
|
||||
override fun onRideRouteSearched(p0: RideRouteResult?, p1: Int) {}
|
||||
override fun onBusRouteSearched(p0 : BusRouteResult?, p1 : Int) {}
|
||||
override fun onWalkRouteSearched(p0 : WalkRouteResult?, p1 : Int) {}
|
||||
override fun onRideRouteSearched(p0 : RideRouteResult?, p1 : Int) {}
|
||||
})
|
||||
|
||||
// 规划当前位置到目的地的路线
|
||||
val query = RouteSearch.FromAndTo(currentPoint, destPoint)
|
||||
val driveQuery = RouteSearch.DriveRouteQuery(query, RouteSearch.DrivingDefault, null, null, "")
|
||||
val driveQuery =
|
||||
RouteSearch.DriveRouteQuery(query, RouteSearch.DrivingDefault, null, null, "")
|
||||
routeSearch.calculateDriveRouteAsyn(driveQuery)
|
||||
}
|
||||
|
||||
private fun calculateRemainingDistance(): Pair<Float, String> {
|
||||
private fun calculateRemainingDistance() : Pair<Float, String> {
|
||||
val currentLocation = GlobalData.currentLocation ?: return Pair(0f, "")
|
||||
val orderInfo = _uiState.value.orderInfo ?: return Pair(0f, "")
|
||||
|
||||
// 计算到目的地的距离
|
||||
val distance = if (orderInfo.distLat != null && orderInfo.distLng != null) {
|
||||
AMapUtils.calculateLineDistance(
|
||||
LatLng(currentLocation.latitude, currentLocation.longitude),
|
||||
LatLng(orderInfo.distLat!!, orderInfo.distLng!!)
|
||||
)
|
||||
AMapUtils.calculateLineDistance(LatLng(currentLocation.latitude,
|
||||
currentLocation.longitude), LatLng(orderInfo.distLat !!, orderInfo.distLng !!))
|
||||
} else 0f
|
||||
|
||||
if (distance <= 0f) {
|
||||
@ -218,7 +213,7 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
return Pair(distance, arrivalTime)
|
||||
}
|
||||
|
||||
private var timerJob: Job? = null
|
||||
private var timerJob : Job? = null
|
||||
|
||||
private fun startTimer() {
|
||||
timerJob?.cancel()
|
||||
@ -226,10 +221,7 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
while (isActive) {
|
||||
val (distance, arrivalTime) = calculateRemainingDistance()
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
remainingDistance = distance,
|
||||
estimatedArrivalTime = arrivalTime
|
||||
)
|
||||
it.copy(remainingDistance = distance, estimatedArrivalTime = arrivalTime)
|
||||
}
|
||||
delay(1000)
|
||||
}
|
||||
@ -241,23 +233,20 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
timerJob?.cancel()
|
||||
}
|
||||
|
||||
private fun buildMarkers(orderInfo: OrderInfo?) {
|
||||
private fun buildMarkers(orderInfo : OrderInfo?) {
|
||||
val markers = arrayListOf<MarkerOptions>()
|
||||
if (orderInfo?.lat != null && orderInfo.lat != 0.0 && orderInfo.lng != null && orderInfo.lng != 0.0) {
|
||||
// 获取矢量图资源文件
|
||||
val startMarkers = MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map))
|
||||
.position(LatLng(orderInfo.lat!!, orderInfo.lng!!))
|
||||
.infoWindowEnable(false)
|
||||
if (orderInfo?.lat != null && orderInfo.lat != 0.0 && orderInfo.lng != null && orderInfo.lng != 0.0) { // 获取矢量图资源文件
|
||||
val startMarkers =
|
||||
MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map))
|
||||
.position(LatLng(orderInfo.lat !!, orderInfo.lng !!)).infoWindowEnable(false)
|
||||
.visible(true)
|
||||
markers.add(startMarkers)
|
||||
}
|
||||
|
||||
if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && orderInfo.distLng != null && orderInfo.distLng != 0.0) {
|
||||
val startMarkers = MarkerOptions()
|
||||
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_dist_map))
|
||||
.position(LatLng(orderInfo.distLat!!, orderInfo.distLng!!))
|
||||
.visible(true)
|
||||
val startMarkers =
|
||||
MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_dist_map))
|
||||
.position(LatLng(orderInfo.distLat !!, orderInfo.distLng !!)).visible(true)
|
||||
markers.add(startMarkers)
|
||||
}
|
||||
updateState(uiState.value.copy(markers = markers))
|
||||
@ -266,20 +255,18 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
|
||||
sealed class Action {
|
||||
data object Init : 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 StartTimer : Action()
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
val orderInfo: OrderInfo? = null,
|
||||
val showCallPhoneDialog: Boolean? = false,
|
||||
val markers: ArrayList<MarkerOptions>? = null,
|
||||
val goNextPage: UpdateTaskBean? = null,
|
||||
val isGoNextPageDialog: Boolean? = null,
|
||||
val showOfflineDialog: Boolean? = null,
|
||||
val routePoints: List<LatLng>? = null,
|
||||
val remainingDistance: Float = 0f,
|
||||
val estimatedArrivalTime: String = ""
|
||||
)
|
||||
data class UiState(val orderInfo : OrderInfo? = null,
|
||||
val showCallPhoneDialog : Boolean? = false,
|
||||
val markers : ArrayList<MarkerOptions>? = null,
|
||||
val goNextPage : UpdateTaskBean? = null,
|
||||
val isGoNextPageDialog : Boolean? = null,
|
||||
val showOfflineDialog : Boolean? = null,
|
||||
val routePoints : List<LatLng>? = null,
|
||||
val remainingDistance : Float = 0f,
|
||||
val estimatedArrivalTime : String = "")
|
||||
}
|
@ -38,6 +38,7 @@ import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>() {
|
||||
@ -155,7 +156,13 @@ class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>(
|
||||
val points = path.steps.flatMap { step ->
|
||||
step.polyline.map { LatLng(it.latitude, it.longitude) }
|
||||
}
|
||||
updateState(uiState.value.copy(routePoints = points))
|
||||
val duration = path.duration
|
||||
val arrivalTime = System.currentTimeMillis() + duration * 1000
|
||||
val dateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
val estimatedTime = dateFormat.format(Date(arrivalTime))
|
||||
updateState(uiState.value.copy(routePoints = points,
|
||||
estimatedArrivalTime = estimatedTime,
|
||||
remainingDistance = path.distance))
|
||||
} else {
|
||||
LogUtil.print("searchDrivingRoute", "路径规划失败: errorCode=$errorCode")
|
||||
}
|
||||
@ -176,16 +183,16 @@ class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>(
|
||||
private var timerJob : Job? = null
|
||||
|
||||
private fun startTimer() {
|
||||
timerJob?.cancel()
|
||||
timerJob = viewModelScope.launch {
|
||||
while (isActive) { // 计算从当前位置到目标点的距离和到达时间
|
||||
val (distance, arrivalTime) = calculateRemainingDistance()
|
||||
_uiState.update {
|
||||
it.copy(remainingDistance = distance, estimatedArrivalTime = arrivalTime)
|
||||
}
|
||||
delay(1000) // 每秒更新一次
|
||||
}
|
||||
}
|
||||
// timerJob?.cancel()
|
||||
// timerJob = viewModelScope.launch {
|
||||
// while (isActive) { // 计算从当前位置到目标点的距离和到达时间
|
||||
// val (distance, arrivalTime) = calculateRemainingDistance()
|
||||
// _uiState.update {
|
||||
// it.copy(remainingDistance = distance, estimatedArrivalTime = arrivalTime)
|
||||
// }
|
||||
// delay(1000) // 每秒更新一次
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private fun calculateRemainingDistance() : Pair<Float, String> {
|
||||
|
@ -5,7 +5,6 @@ import android.content.Intent
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
@ -51,5 +50,5 @@ fun SignatureView(modifier: Modifier = Modifier, success: (String?) -> Unit, ser
|
||||
intent.putExtra("lineLength", 10) //每行显示字数(超出屏幕支持横向滚动)
|
||||
signatureLauncher.launch(intent)
|
||||
},
|
||||
contentScale = ContentScale.FillBounds)
|
||||
contentScale = ContentScale.Inside)
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Theme.Dealer" parent="Theme.AppCompat.Light.NoActionBar" />
|
||||
<style name="Theme.Zd_sdk_demo" parent="Theme.Dealer" />
|
||||
|
||||
<style name="Theme.Zd_sdk_demo" parent="android:Theme.Material.Light.NoActionBar" />
|
||||
<style name="Theme.Dealer" parent="Theme.AppCompat.Light.NoActionBar" />
|
||||
</resources>
|
6
servicing/src/main/res/xml/network_security_config.xml
Normal file
6
servicing/src/main/res/xml/network_security_config.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="true">sino-assist.com</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
Reference in New Issue
Block a user