feat(servicing): 优化订单详情页面布局和功能

-调整订单信息显示布局,增加订单来源显示
- 优化地图标记添加逻辑,提高地图展示效果
- 改进路径规划功能,优化预计到达时间计算方式- 更新车辆损伤照片加载逻辑,提高数据展示效率
- 修复部分页面样式问题,提升用户体验
This commit is contained in:
songzhiling
2025-04-25 18:01:44 +08:00
parent c606ed95cd
commit b0c2f7352d
20 changed files with 794 additions and 851 deletions

View File

@ -33,15 +33,8 @@ android {
] ]
} }
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
signingConfigs { signingConfigs {
release { config {
storeFile file('E:\\workspace\\study\\zd_sdk_demo\\zd_sdk_demo.jks') storeFile file('E:\\workspace\\study\\zd_sdk_demo\\zd_sdk_demo.jks')
storePassword '123456' storePassword '123456'
keyAlias 'key0' 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 { compileOptions {
sourceCompatibility JavaVersion.VERSION_11 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11

View File

@ -44,6 +44,10 @@
android:name="android.app.lib_name" android:name="android.app.lib_name"
android:value="" /> android:value="" />
</activity> </activity>
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="ca9429157ac6a0fb3f331b95817b3ca6" />
</application> </application>
</manifest> </manifest>

View File

@ -27,7 +27,7 @@ class MainActivity : ComponentActivity() {
.fillMaxSize() .fillMaxSize()
.clickable { .clickable {
val uri = 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) val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent) startActivity(intent)
} }

View File

@ -73,7 +73,7 @@ publishing {
release(MavenPublication) { release(MavenPublication) {
groupId = 'io.github.szl9' groupId = 'io.github.szl9'
artifactId = 'zd_servicing' artifactId = 'zd_servicing'
version = "1.0.1.9" version = "1.0.1.9.9.4"
pom { pom {
packaging = "aar" packaging = "aar"

View File

@ -9,6 +9,7 @@
android:protectionLevel="signature" /> <!-- 位置相关权限 --> android:protectionLevel="signature" /> <!-- 位置相关权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_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_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <!-- 存储相关权限 --> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <!-- 存储相关权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@ -75,7 +76,10 @@
</intent> </intent>
</queries> </queries>
<application> <application
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true"
tools:targetApi="24">
<activity <activity
android:name="com.za.ui.main.ServiceLauncherActivity" android:name="com.za.ui.main.ServiceLauncherActivity"
android:exported="true" android:exported="true"
@ -115,16 +119,19 @@
<service <service
android:name="com.za.ui.order_report.ReportFloatingManager" android:name="com.za.ui.order_report.ReportFloatingManager"
android:enabled="true" android:enabled="true"
android:exported="false" /> android:exported="false"
android:foregroundServiceType="location" />
<activity <activity
android:name="com.za.ui.order_report.HistoryReportActivity" android:name="com.za.ui.order_report.HistoryReportActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait" /> android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.order_report.OrderReportActivity" android:name="com.za.ui.order_report.OrderReportActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait" /> android:screenOrientation="portrait"
android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.h5.CommonH5Activity" android:name="com.za.ui.h5.CommonH5Activity"
android:exported="false" android:exported="false"
@ -152,7 +159,8 @@
android:theme="@style/Theme.Dealer" /> android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.signature.GridPaintActivity" android:name="com.za.signature.GridPaintActivity"
android:exported="false" /> android:exported="false"
android:theme="@style/Theme.Dealer" />
<activity <activity
android:name="com.za.ui.servicing.operation.InOperationActivity" android:name="com.za.ui.servicing.operation.InOperationActivity"
android:exported="false" android:exported="false"
@ -161,8 +169,8 @@
<activity <activity
android:name="com.za.ui.camera.ZdCameraXActivity" android:name="com.za.ui.camera.ZdCameraXActivity"
android:exported="false" android:exported="false"
android:theme="@style/Theme.Dealer" android:screenOrientation="portrait"
android:screenOrientation="portrait"> android:theme="@style/Theme.Dealer">
<meta-data <meta-data
android:name="android.app.lib_name" android:name="android.app.lib_name"
android:value="" /> android:value="" />

View File

@ -35,6 +35,8 @@ data class JpushBean(
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 现金
var orderSource: String? = null, // "orderSource":"中道救援-比亚迪道路救援项目"
val hasReplaceBatteryCapable: Int? = null ,//是否有更换电瓶的能力 1 搭电可以更换电瓶 2搭电不可以更换电瓶 其他的不展示 val hasReplaceBatteryCapable: Int? = null ,//是否有更换电瓶的能力 1 搭电可以更换电瓶 2搭电不可以更换电瓶 其他的不展示
var voiceType : Int?=null //语音提示类型 1小修单 2拖车单 3困境单 var voiceType : Int?=null //语音提示类型 1小修单 2拖车单 3困境单
) : Serializable { ) : Serializable {

View File

@ -2,6 +2,7 @@ package com.za.net
import android.net.ParseException import android.net.ParseException
import com.blankj.utilcode.util.ActivityUtils import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.ThreadUtils
import com.blankj.utilcode.util.ToastUtils import com.blankj.utilcode.util.ToastUtils
import com.google.gson.JsonParseException import com.google.gson.JsonParseException
import com.za.base.Const import com.za.base.Const
@ -22,32 +23,34 @@ import javax.net.ssl.SSLHandshakeException
* Created by DoggieX on 2017/7/26. * Created by DoggieX on 2017/7/26.
*/ */
abstract class BaseObserver<T> : Observer<BaseResponse<T>> { abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
override fun onSubscribe(d: Disposable) { override fun onSubscribe(d : Disposable) { // if (!NetworkUtils.isAvailable()) {
// if (!NetworkUtils.isAvailable()) { // doFailure(999, "网络无法使用")
// doFailure(999, "网络无法使用") // d.dispose()
// d.dispose() // }
// }
} }
override fun onNext(tBaseResponse: BaseResponse<T>) { override fun onNext(tBaseResponse : BaseResponse<T>) {
if (tBaseResponse.isOk) { if (tBaseResponse.isOk) {
doSuccess(tBaseResponse.result) doSuccess(tBaseResponse.result)
} else { } else {
when (tBaseResponse.code) { when (tBaseResponse.code) {
3, 401 -> handlerTokenExpired() 3, 401 -> handlerTokenExpired()
// 4 -> RsaRouter.navigate(context, "/page/Standby")
} }
if (null != tBaseResponse.msg) { val errMsg = if (null != tBaseResponse.msg) {
doFailure(tBaseResponse.code, tBaseResponse.msg) tBaseResponse.msg
} else if (null != tBaseResponse.message) { } else if (null != tBaseResponse.message) {
doFailure(tBaseResponse.code, tBaseResponse.message) tBaseResponse.message
} else { } 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) LogUtil.print("net error", e)
when (e) { when (e) {
is JsonParseException -> { is JsonParseException -> {
@ -84,6 +87,7 @@ abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
doFailure(Const.NetWorkException, "网络连接超时2") doFailure(Const.NetWorkException, "网络连接超时2")
LogUtil.print("SocketTimeoutException2", e) LogUtil.print("SocketTimeoutException2", e)
} }
else -> { else -> {
doFailure(1, "error:" + e.message) doFailure(1, "error:" + e.message)
LogUtil.print("other error", e) LogUtil.print("other error", e)
@ -94,18 +98,20 @@ abstract class BaseObserver<T> : Observer<BaseResponse<T>> {
override fun onComplete() { 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() { private fun handlerTokenExpired() {
ToastUtils.showShort("登陆信息已过期,请重新登录") ThreadUtils.runOnUiThread {
try { try {
ToastUtils.showShort("登陆信息已过期,请重新登录")
GlobalData.clearUserCache() GlobalData.clearUserCache()
ZdLocationManager.stopContinuousLocation() ZdLocationManager.stopContinuousLocation()
ActivityUtils.finishAllActivities() ActivityUtils.startLauncherActivity()
} catch (e: Exception) { } catch (e : Exception) {
LogUtil.print("handlerTokenExpired", e) LogUtil.print("handlerTokenExpired", e)
} }
} }
}
} }

View File

@ -16,7 +16,6 @@ import com.za.common.log.LogUtil
import com.za.common.util.DeviceUtil import com.za.common.util.DeviceUtil
import com.za.service.mqtt.MyMqttClient import com.za.service.mqtt.MyMqttClient
import com.za.servicing.R import com.za.servicing.R
import java.util.concurrent.atomic.AtomicReference
interface PushListener { interface PushListener {
fun newOrderMsg(jpushBean : JpushBean) fun newOrderMsg(jpushBean : JpushBean)
@ -30,7 +29,7 @@ interface PushListener {
data class LastJPushBean(val msg : Int, val time : Long = System.nanoTime()) data class LastJPushBean(val msg : Int, val time : Long = System.nanoTime())
object ServiceManager { object ServiceManager {
private val pushListener = AtomicReference<PushListener>() private var pushListener : PushListener? = null
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秒
@ -56,16 +55,15 @@ object ServiceManager {
// Register push listener // Register push listener
fun registerPushListener(listener : PushListener?) { fun registerPushListener(listener : PushListener?) {
listener?.let { this.pushListener = listener
pushListener.set(it) LogUtil.print("ServiceManager",
LogUtil.print("ServiceManager", "Registered push listener: ${it.javaClass.simpleName}") "Registered push listener: ${pushListener?.javaClass?.simpleName}")
}
} }
// Handle incoming push messages // Handle incoming push messages
@Synchronized @Synchronized
fun handlerPushMsg(msg : String) { fun handlerPushMsg(msg : String) {
LogUtil.print("JpushMessage", "Received push message: $msg") LogUtil.print("handlerPushMsg", "Received push message: $msg")
// 优化后的重复消息判断 // 优化后的重复消息判断
lastJPushBean?.let { lastJPushBean?.let {
@ -76,12 +74,12 @@ object ServiceManager {
} }
if (msg.startsWith("broadcast:")) { if (msg.startsWith("broadcast:")) {
lastJPushBean = LastJPushBean(msg.hashCode()) lastJPushBean = LastJPushBean(msg = msg.hashCode())
handleBroadcast(msg) handleBroadcast(msg)
return return
} }
try { try {
lastJPushBean = LastJPushBean(msg.hashCode()) lastJPushBean = LastJPushBean(msg = msg.hashCode())
val jpushOrderInfoBean = Gson().fromJson(msg, JpushBean::class.java) val jpushOrderInfoBean = Gson().fromJson(msg, JpushBean::class.java)
sendSystemNotificationFromMessage(jpushOrderInfoBean) sendSystemNotificationFromMessage(jpushOrderInfoBean)
when (jpushOrderInfoBean.pushType) { when (jpushOrderInfoBean.pushType) {
@ -103,7 +101,7 @@ object ServiceManager {
private fun handleBroadcast(msg : String) { private fun handleBroadcast(msg : String) {
try { try {
val content = msg.substring(10) val content = msg.substring(10)
pushListener.get()?.broadcast(content) pushListener?.broadcast(content)
sendNotification(GlobalData.application, content) sendNotification(GlobalData.application, content)
LogUtil.print("JpushMessage", "Broadcast content: $content") LogUtil.print("JpushMessage", "Broadcast content: $content")
} catch (e : Exception) { } catch (e : Exception) {
@ -124,7 +122,9 @@ object ServiceManager {
// Handle new order messages // Handle new order messages
private fun newOrderMsg(jpushOrderBean : JpushBean) { private fun newOrderMsg(jpushOrderBean : JpushBean) {
try { try {
pushListener.get()?.newOrderMsg(jpushOrderBean) LogUtil.print("JpushMessage",
"Handling new order message: $pushListener ${pushListener?.javaClass?.simpleName}")
pushListener?.newOrderMsg(jpushOrderBean)
} catch (e : Exception) { } catch (e : Exception) {
LogUtil.print("JpushMessage", "Failed to handle new order message: ${e.message}") LogUtil.print("JpushMessage", "Failed to handle new order message: ${e.message}")
} }
@ -132,22 +132,22 @@ object ServiceManager {
// Handle give up order messages // Handle give up order messages
private fun giveUpOrder(jpushOrderBean : JpushBean) { private fun giveUpOrder(jpushOrderBean : JpushBean) {
pushListener.get()?.giveUpOrder(jpushOrderBean) pushListener?.giveUpOrder(jpushOrderBean)
} }
// Handle revoke order messages // Handle revoke order messages
private fun revokeOrder(jpushOrderBean : JpushBean) { private fun revokeOrder(jpushOrderBean : JpushBean) {
pushListener.get()?.revokeOrder(jpushOrderBean) pushListener?.revokeOrder(jpushOrderBean)
} }
// Handle re-dispatch order messages // Handle re-dispatch order messages
private fun reDispatchOrder(jpushOrderBean : JpushBean) { private fun reDispatchOrder(jpushOrderBean : JpushBean) {
pushListener.get()?.reDispatchOrder(jpushOrderBean) pushListener?.reDispatchOrder(jpushOrderBean)
} }
// Handle important tip messages // Handle important tip messages
private fun importantTip(jpushOrderBean : JpushBean) { private fun importantTip(jpushOrderBean : JpushBean) {
pushListener.get()?.importantTip(jpushOrderBean) pushListener?.importantTip(jpushOrderBean)
} }
// Disconnect from JPush and MQTT // Disconnect from JPush and MQTT

View File

@ -20,7 +20,6 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Done
import androidx.compose.material.icons.filled.Menu import androidx.compose.material.icons.filled.Menu
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
@ -50,7 +49,9 @@ import com.blankj.utilcode.util.ActivityUtils
import com.za.base.BaseActivity import com.za.base.BaseActivity
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.HeadView import com.za.base.view.HeadView
import com.za.base.view.LoadError
import com.za.bean.db.order.OrderInfo import com.za.bean.db.order.OrderInfo
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.util.DeviceUtil import com.za.common.util.DeviceUtil
@ -129,23 +130,35 @@ private fun ServicingMainScreen(jobCode : String? = null,
.fillMaxSize() .fillMaxSize()
.background(bgColor) .background(bgColor)
.padding(it)) { .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) { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CommonButton(text = "订单获取异常,点击重新获取") { LoadError(message = "订单获取异常", onRetry = {
vm.dispatch(ServicingMainVm.Action.Init(jobCode, vm.dispatch(ServicingMainVm.Action.Init(jobCode,
phone, phone,
taskCode, taskCode,
vehicleId, vehicleId,
deviceId, deviceId,
rescueVehicle)) rescueVehicle))
})
} }
} }
} else {
Box(modifier = Modifier 3 -> { //
.fillMaxSize() EmptyView()
.padding(top = 10.dp), }
contentAlignment = Alignment.TopCenter) {
OrderItemView(GlobalData.currentOrder)
else -> {
} }
} }
} }

View File

@ -46,11 +46,14 @@ class ServicingMainVm : BaseVm<ServicingMainVm.Action, ServicingMainVm.UiState>(
CommonMethod.queryOrderList(context = ActivityUtils.getTopActivity(), CommonMethod.queryOrderList(context = ActivityUtils.getTopActivity(),
success = { orderInfo : OrderInfo?, orderInfos : List<OrderInfo>? -> success = { orderInfo : OrderInfo?, orderInfos : List<OrderInfo>? ->
LoadingManager.hideLoading() LoadingManager.hideLoading()
if (orderInfo == null) {
ToastUtils.showShort("未查询到订单")
GlobalData.clearAllOrderCache()
updateState(uiState.value.copy(state = 3))
return@queryOrderList
}
GlobalData.currentOrder = orderInfo GlobalData.currentOrder = orderInfo
updateState(uiState.value.copy(state = 1)) updateState(uiState.value.copy(state = 1))
if (orderInfos.isNullOrEmpty()) {
ToastUtils.showShort("未查询到订单")
}
}, },
failed = { failed = {
updateState(uiState.value.copy(state = 2)) updateState(uiState.value.copy(state = 2))
@ -106,6 +109,6 @@ class ServicingMainVm : BaseVm<ServicingMainVm.Action, ServicingMainVm.UiState>(
} }
data class UiState( data class UiState(
val state : Int? = null, //1 成功 2 失败 val state : Int? = null, //1 成功 2 失败 3:订单为空
) )
} }

View File

@ -57,6 +57,7 @@ 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
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.LatLngBounds import com.amap.api.maps.model.LatLngBounds
import com.amap.api.maps.model.MarkerOptions import com.amap.api.maps.model.MarkerOptions
@ -234,18 +235,18 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
} }
// 添加距离和时间信息 // 添加距离和时间信息
// 距离和时间信息
Row(modifier = Modifier Row(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp), .padding(horizontal = 16.dp, vertical = 12.dp),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically) { verticalAlignment = Alignment.CenterVertically) {
Text(text = "预计到达: ${uiState.value.estimatedArrivalTime}", Text(text = if (uiState.value.estimatedArrivalTime.isNotEmpty()) "预计到达: ${uiState.value.estimatedArrivalTime}"
color = Color(0xFF666666), else "计算中...", color = Color(0xFF666666), fontSize = 14.sp)
fontSize = 14.sp)
Text(text = "总里程: %.1fkm".format(uiState.value.remainingDistance / 1000f), Text(text = if (uiState.value.remainingDistance > 0) "距离救援地: %.1fkm".format(
color = Color(0xFFFF4D4F), uiState.value.remainingDistance / 1000f)
fontSize = 14.sp) else "计算中...", color = Color(0xFFFF4D4F), fontSize = 14.sp)
} }
HorizontalDivider(modifier = Modifier HorizontalDivider(modifier = Modifier
@ -256,8 +257,26 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
Column(modifier = Modifier Column(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp)) { // 订单标签 .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, Row(verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)) { 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 ?: "", Text(text = uiState.value.jpushBean?.addressProperty ?: "",
color = Color(0xFFFD8205), color = Color(0xFFFD8205),
@ -416,10 +435,9 @@ private fun AcceptOrderScreen(jpushBean : JpushBean?, vm : NewOrderVm = viewMode
// 绘制路线 // 绘制路线
uiState.value.routePoints?.let { points -> uiState.value.routePoints?.let { points ->
if (points.isNotEmpty()) {
mapView.map.addPolyline(PolylineOptions().addAll(points).width(15f) 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))
} }
// 添加标记点 // 添加标记点

View File

@ -157,7 +157,7 @@ class EleSignVm : IServicingVm<EleSignVm.Action, EleSignVm.UiState>() {
val photoList = RoomHelper.db?.eleCarDamagePhotoDao()?.getEleCarDamagePhotos(getCurrentOrder()?.taskId val photoList = RoomHelper.db?.eleCarDamagePhotoDao()?.getEleCarDamagePhotos(getCurrentOrder()?.taskId
?: 0) ?: 0)
updateState(uiState.value.copy(eleWorkOrderBean = it, damagePhoto = photoList, orderInfo = getCurrentOrder())) updateState(uiState.value.copy(eleWorkOrderBean = it, damagePhoto = photoList, orderInfo = getCurrentOrder()))
LogUtil.print("电子表单更新车辆损伤照片", "eleWorkOrderBean==${photoList.toJson()}") LogUtil.print("电子表单更新车辆损伤照片", "eleWorkOrderBean==${it.toJson()}")
}, },
failed = { failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()

View File

@ -170,16 +170,17 @@ fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
Column(modifier = Modifier Column(modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp)) { .padding(horizontal = 16.dp, vertical = 12.dp)) {
Row(modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically) {
Text(text = uiState.value.orderInfo?.serviceTypeName ?: "", Text(text = uiState.value.orderInfo?.serviceTypeName ?: "",
fontSize = 18.sp, fontSize = 18.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = Color.Black) color = Color.Black)
Row(horizontalArrangement = Arrangement.spacedBy(8.dp), Spacer(modifier = Modifier.height(8.dp))
verticalAlignment = Alignment.CenterVertically) {
// 订单标签
Row(verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Box(modifier = Modifier Box(modifier = Modifier
.background(Color(0xFF9BA1B2), RoundedCornerShape(4.dp)) .background(Color(0xFF9BA1B2), RoundedCornerShape(4.dp))
.padding(horizontal = 6.dp, vertical = 2.dp)) { .padding(horizontal = 6.dp, vertical = 2.dp)) {
@ -187,13 +188,15 @@ fun GoAccidentSiteScreen(vm : GoAccidentSiteVm = viewModel()) {
?: "现金", color = Color.White, fontSize = 12.sp) ?: "现金", color = Color.White, fontSize = 12.sp)
} }
Text(text = uiState.value.orderInfo?.orderSource ?: "",
color = Color.Black,
fontSize = 12.sp)
Text(text = uiState.value.orderInfo?.addressProperty ?: "", Text(text = uiState.value.orderInfo?.addressProperty ?: "",
color = Color(0xFFFD8205), color = Color(0xFFFD8205),
fontSize = 12.sp, fontSize = 12.sp,
fontWeight = FontWeight.Medium) fontWeight = FontWeight.Medium)
} }
}
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
Row(verticalAlignment = Alignment.CenterVertically, Row(verticalAlignment = Alignment.CenterVertically,

View File

@ -34,6 +34,7 @@ import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date
import java.util.Locale import java.util.Locale
class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.UiState>() { class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.UiState>() {
@ -136,7 +137,7 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
updateState(uiState = uiState.value.copy(orderInfo = getCurrentOrder())) updateState(uiState = uiState.value.copy(orderInfo = getCurrentOrder()))
buildMarkers(getCurrentOrder()) buildMarkers(getCurrentOrder())
searchDrivingRoute(getCurrentOrder()) searchDrivingRoute(getCurrentOrder())
// dispatch(Action.StartTimer) startTimer()
} }
private fun buildMarkers(orderInfo : OrderInfo?) { private fun buildMarkers(orderInfo : OrderInfo?) {
@ -182,14 +183,13 @@ class GoAccidentSiteVm : IServicingVm<GoAccidentSiteVm.Action, GoAccidentSiteVm.
val points = path.steps.flatMap { step -> val points = path.steps.flatMap { step ->
step.polyline.map { LatLng(it.latitude, it.longitude) } step.polyline.map { LatLng(it.latitude, it.longitude) }
} }
val durationInSeconds = path.duration val duration = path.duration
val arrivalTime = SimpleDateFormat("HH:mm:ss", val arrivalTime = System.currentTimeMillis() + duration * 1000
Locale.getDefault()).format(System.currentTimeMillis() + durationInSeconds * 1000) val dateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
val estimatedTime = dateFormat.format(Date(arrivalTime))
updateState(uiState.value.copy(routePoints = points,
LogUtil.print("arrivalTime", "arrivalTime: arrivalTime=$arrivalTime") estimatedArrivalTime = estimatedTime,
LogUtil.print("distance", "distance: distance=${path.distance.div(1000)}km") remainingDistance = path.distance))
updateState(uiState.value.copy(routePoints = points, estimatedArrivalTime = arrivalTime, remainingDistance = path.distance))
} else { } else {
LogUtil.print("searchDrivingRoute", "路径规划失败: errorCode=$errorCode") LogUtil.print("searchDrivingRoute", "路径规划失败: errorCode=$errorCode")
} }
@ -233,16 +233,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

@ -78,7 +78,7 @@ class GoToDestinationActivity : BaseActivity() {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) { fun GoToDestinationScreen(vm : GoToDestinationVm = viewModel()) {
val uiState = vm.uiState.collectAsStateWithLifecycle() val uiState = vm.uiState.collectAsStateWithLifecycle()
val context = LocalContext.current val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current val lifecycleOwner = LocalLifecycleOwner.current
@ -88,13 +88,10 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
// 修改 BottomSheet 状态 // 修改 BottomSheet 状态
val bottomSheetState = rememberStandardBottomSheetState( val bottomSheetState =
initialValue = SheetValue.PartiallyExpanded, rememberStandardBottomSheetState(initialValue = SheetValue.PartiallyExpanded,
confirmValueChange = { true } confirmValueChange = { true })
) val scaffoldState = rememberBottomSheetScaffoldState(bottomSheetState = bottomSheetState)
val scaffoldState = rememberBottomSheetScaffoldState(
bottomSheetState = bottomSheetState
)
// 优化状态管理 // 优化状态管理
val isExpanded by remember { val isExpanded by remember {
@ -103,8 +100,10 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
// 记忆化常用值,减少重组 // 记忆化常用值,减少重组
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 estimatedTime =
val remainingDistance = remember(uiState.value.remainingDistance) { uiState.value.remainingDistance } 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 ->
@ -133,285 +132,210 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = 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(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 = { 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) vm.dispatch(GoToDestinationVm.Action.UpdateTask)
} })
)
} }
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(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 = { 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) vm.dispatch(GoToDestinationVm.Action.UploadOffline)
} })
)
} }
BottomSheetScaffold( BottomSheetScaffold(scaffoldState = scaffoldState,
scaffoldState = scaffoldState,
topBar = { topBar = {
InServicingHeadView( InServicingHeadView(title = "作业完成,正在拖往目的地",
title = "作业完成,正在拖往目的地",
onBack = { context.finish() }, onBack = { context.finish() },
orderInfo = orderInfo orderInfo = orderInfo)
)
}, },
sheetContent = { sheetContent = {
Column( Column(modifier = Modifier
modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.wrapContentHeight() .wrapContentHeight()
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())) { // 滑动指示器
) { Box(modifier = Modifier
// 滑动指示器
Box(
modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(vertical = 8.dp), .padding(vertical = 8.dp),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center) {
) { Box(modifier = Modifier
Box(
modifier = Modifier
.width(32.dp) .width(32.dp)
.height(4.dp) .height(4.dp)
.background( .background(color = Color(0xFFE0E0E0), shape = RoundedCornerShape(2.dp)))
color = Color(0xFFE0E0E0),
shape = RoundedCornerShape(2.dp)
)
)
} }
// 距离和时间信息 // 距离和时间信息
Row( Row(modifier = Modifier
modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp), .padding(horizontal = 16.dp, vertical = 12.dp),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically) {
) { Text(text = if (estimatedTime.isNotEmpty()) "预计到达: $estimatedTime"
Text( else "计算中...", color = Color(0xFF666666), fontSize = 14.sp)
text = if (estimatedTime.isNotEmpty())
"预计到达: $estimatedTime"
else
"计算中...",
color = Color(0xFF666666),
fontSize = 14.sp
)
Text( Text(text = if (remainingDistance > 0) "目的地距离: %.1fkm".format(
text = if (remainingDistance > 0) remainingDistance / 1000f)
"目的地距离: %.1fkm".format(remainingDistance / 1000f) else "计算中...", color = Color(0xFFFF4D4F), fontSize = 14.sp)
else
"计算中...",
color = Color(0xFFFF4D4F),
fontSize = 14.sp
)
} }
// 使用 HorizontalDivider 替代 Box // 使用 HorizontalDivider 替代 Box
HorizontalDivider( HorizontalDivider(modifier = Modifier
modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.alpha(0.1f) .alpha(0.1f))
)
// 订单信息 // 订单信息
Column( Column(modifier = Modifier
modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp) .padding(horizontal = 16.dp, vertical = 12.dp)) {
) { Text(text = uiState.value.orderInfo?.serviceTypeName ?: "",
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = uiState.value.orderInfo?.serviceTypeName ?: "",
fontSize = 18.sp, fontSize = 18.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = Color.Black color = Color.Black)
) Spacer(modifier = Modifier.height(8.dp))
// 订单标签
Row( Row(verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
verticalAlignment = Alignment.CenterVertically Box(modifier = Modifier
) {
Box(
modifier = Modifier
.background(Color(0xFF9BA1B2), RoundedCornerShape(4.dp)) .background(Color(0xFF9BA1B2), RoundedCornerShape(4.dp))
.padding(horizontal = 6.dp, vertical = 2.dp) .padding(horizontal = 6.dp, vertical = 2.dp)) {
) { Text(text = "月结".takeIf { uiState.value.orderInfo?.settleType == 1 }
Text( ?: "现金", color = Color.White, fontSize = 12.sp)
text = "月结".takeIf { uiState.value.orderInfo?.settleType == 1 }
?: "现金",
color = Color.White,
fontSize = 12.sp
)
} }
Text( Text(text = uiState.value.orderInfo?.orderSource ?: "",
text = uiState.value.orderInfo?.addressProperty ?: "", color = Color.Black,
fontSize = 12.sp)
Text(text = uiState.value.orderInfo?.addressProperty ?: "",
color = Color(0xFFFD8205), color = Color(0xFFFD8205),
fontSize = 12.sp, fontSize = 12.sp,
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium)
)
}
} }
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
// 订单号 // 订单号
Row( Row(verticalAlignment = Alignment.CenterVertically,
verticalAlignment = Alignment.CenterVertically, modifier = Modifier.clickable {
modifier = Modifier.clickable { uiState.value.orderInfo?.taskCode?.copy(context) } uiState.value.orderInfo?.taskCode?.copy(context)
) { }) {
Text( Text(text = "单号", color = Color(0xFF999999), fontSize = 13.sp)
text = "单号",
color = Color(0xFF999999),
fontSize = 13.sp
)
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(text = uiState.value.orderInfo?.taskCode ?: "",
text = uiState.value.orderInfo?.taskCode ?: "",
color = Color(0xFF666666), color = Color(0xFF666666),
fontSize = 14.sp fontSize = 14.sp)
)
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
AsyncImage( AsyncImage(model = R.drawable.sv_copy,
model = R.drawable.sv_copy,
contentDescription = "copy", contentDescription = "copy",
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp))
)
} }
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
// 地址信息 // 地址信息
Column( Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { // 救援地
verticalArrangement = Arrangement.spacedBy(12.dp) Row(verticalAlignment = Alignment.Top,
) {
// 救援地
Row(
verticalAlignment = Alignment.Top,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { .clickable {
uiState.value.orderInfo?.let { order -> uiState.value.orderInfo?.let { order ->
if (order.lat != null && order.lat != 0.0 && if (order.lat != null && order.lat != 0.0 && order.lng != null && order.lng != 0.0) {
order.lng != null && order.lng != 0.0 mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(
) { LatLng(order.lat !!, order.lng !!),
mapView.map.animateCamera( 16f))
CameraUpdateFactory.newLatLngZoom(
LatLng(order.lat!!, order.lng!!),
16f
)
)
} }
} }
} }) {
) { AsyncImage(model = R.drawable.sv_rescuing,
AsyncImage(
model = R.drawable.sv_rescuing,
contentDescription = "rescue", contentDescription = "rescue",
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp))
)
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(text = uiState.value.orderInfo?.address ?: "",
text = uiState.value.orderInfo?.address ?: "",
color = Color.Black, color = Color.Black,
fontSize = 15.sp, fontSize = 15.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
modifier = Modifier.weight(1f) modifier = Modifier.weight(1f))
)
} }
// 目的地 // 目的地
if (!uiState.value.orderInfo?.distAddress.isNullOrBlank()) { if (! uiState.value.orderInfo?.distAddress.isNullOrBlank()) {
Row( Row(verticalAlignment = Alignment.Top,
verticalAlignment = Alignment.Top,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { .clickable {
uiState.value.orderInfo?.let { order -> uiState.value.orderInfo?.let { order ->
if (order.distLat != null && order.distLat != 0.0 && if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0) {
order.distLng != null && order.distLng != 0.0 mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(
) { LatLng(order.distLat !!, order.distLng !!),
mapView.map.animateCamera( 16f))
CameraUpdateFactory.newLatLngZoom(
LatLng(order.distLat!!, order.distLng!!),
16f
)
)
} }
} }
} }) {
) { AsyncImage(model = R.drawable.sv_dist,
AsyncImage(
model = R.drawable.sv_dist,
contentDescription = "destination", contentDescription = "destination",
modifier = Modifier.size(16.dp) modifier = Modifier.size(16.dp))
)
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text( Text(text = uiState.value.orderInfo?.distAddress ?: "",
text = uiState.value.orderInfo?.distAddress ?: "",
color = Color.Black, color = Color.Black,
fontSize = 15.sp, fontSize = 15.sp,
fontWeight = FontWeight.Medium, fontWeight = FontWeight.Medium,
modifier = Modifier.weight(1f) modifier = Modifier.weight(1f))
)
} }
} }
} }
} }
// 到达按钮 - 移除外层 Column简化布局 // 到达按钮 - 移除外层 Column简化布局
Button( Button(onClick = {
onClick = { vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(
vm.dispatch(GoToDestinationVm.Action.UpdateState(uiState.value.copy(isGoNextPageDialog = true))) isGoNextPageDialog = true)))
}, },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(44.dp) .height(44.dp)
.padding(horizontal = 16.dp), .padding(horizontal = 16.dp),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(containerColor = headBgColor),
containerColor = headBgColor shape = RoundedCornerShape(8.dp)) {
), Text(text = "到达目的地",
shape = RoundedCornerShape(8.dp)
) {
Text(
text = "到达目的地",
color = Color.White, color = Color.White,
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.Medium fontWeight = FontWeight.Medium)
)
} }
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
@ -421,17 +345,11 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp), sheetShape = RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp),
sheetContainerColor = Color.White, sheetContainerColor = Color.White,
sheetDragHandle = null, sheetDragHandle = null,
sheetSwipeEnabled = true sheetSwipeEnabled = true) { paddingValues ->
) { paddingValues -> Box(modifier = Modifier
Box(
modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(paddingValues) .padding(paddingValues)) {
) { 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)
mapView.apply { mapView.apply {
@ -439,7 +357,7 @@ fun GoToDestinationScreen(vm: GoToDestinationVm = viewModel()) {
isTrafficEnabled = false isTrafficEnabled = false
isMyLocationEnabled = false isMyLocationEnabled = false
uiSettings.isMyLocationButtonEnabled = false uiSettings.isMyLocationButtonEnabled = false
uiSettings.setLogoBottomMargin(-100) uiSettings.setLogoBottomMargin(- 100)
uiSettings.isZoomControlsEnabled = false uiSettings.isZoomControlsEnabled = false
// 添加标记点点击事件 // 添加标记点点击事件
@ -452,106 +370,70 @@ 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( mapView.map.addPolyline(PolylineOptions().addAll(points).width(15f)
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))
)
} }
// 再添加标记点,确保标记点在路线上层 // 再添加标记点,确保标记点在路线上层
// 添加当前位置标记 // 添加当前位置标记
if (GlobalData.currentLocation != null) { if (GlobalData.currentLocation != null) {
mapView.map.addMarker( mapView.map.addMarker(MarkerOptions().position(LatLng(GlobalData.currentLocation?.latitude !!,
MarkerOptions() GlobalData.currentLocation?.longitude !!)).title("当前位置")
.position(LatLng( .icon(ImageUtil.vectorToBitmap(context, R.drawable.ic_current_location))
GlobalData.currentLocation?.latitude!!, .anchor(0.5f, 0.5f).visible(true))
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 -> uiState.value.orderInfo?.let { order ->
if (order.lat != null && order.lat != 0.0 && if (order.lat != null && order.lat != 0.0 && order.lng != null && order.lng != 0.0) {
order.lng != null && order.lng != 0.0 mapView.map.addMarker(MarkerOptions().position(LatLng(order.lat !!,
) { order.lng !!)).title("救援地点")
mapView.map.addMarker(
MarkerOptions()
.position(LatLng(order.lat!!, order.lng!!))
.title("救援地点")
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map)) .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 && if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0) {
order.distLng != null && order.distLng != 0.0 mapView.map.addMarker(MarkerOptions().position(LatLng(order.distLat !!,
) { order.distLng !!)).title("目的地")
mapView.map.addMarker(
MarkerOptions()
.position(LatLng(order.distLat!!, order.distLng!!))
.title("目的地")
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_dist_map)) .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 { GlobalData.currentLocation?.let {
include(LatLng(it.latitude, it.longitude)) include(LatLng(it.latitude, it.longitude))
} }
// 添加救援地点和目的地 // 添加救援地点和目的地
uiState.value.orderInfo?.let { order -> uiState.value.orderInfo?.let { order ->
if (order.lat != null && order.lat != 0.0 && if (order.lat != null && order.lat != 0.0 && order.lng != null && order.lng != 0.0) {
order.lng != null && order.lng != 0.0 include(LatLng(order.lat !!, order.lng !!))
) {
include(LatLng(order.lat!!, order.lng!!))
} }
if (order.distLat != null && order.distLat != 0.0 && if (order.distLat != null && order.distLat != 0.0 && order.distLng != null && order.distLng != 0.0) {
order.distLng != null && order.distLng != 0.0 include(LatLng(order.distLat !!, order.distLng !!))
) {
include(LatLng(order.distLat!!, order.distLng!!))
} }
} }
}.build() }.build()
try { try {
mapView.map.animateCamera( mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100))
CameraUpdateFactory.newLatLngBounds(bounds, 100) } catch (e : Exception) { // 如果计算边界失败,则使用默认缩放级别
)
} catch (e: Exception) {
// 如果计算边界失败,则使用默认缩放级别
GlobalData.currentLocation?.let { GlobalData.currentLocation?.let {
mapView.map.animateCamera( mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude,
CameraUpdateFactory.newLatLngZoom( it.longitude), 15f))
LatLng(it.latitude, it.longitude),
15f
)
)
} }
} }
} })
)
} }
} }
} }

View File

@ -34,16 +34,17 @@ import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date
import java.util.Locale import java.util.Locale
class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestinationVm.UiState>() { class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestinationVm.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()
@ -53,12 +54,11 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
} }
} }
private fun updateOfflineTask(taskRequest: UpdateTaskRequest? = null) { private fun updateOfflineTask(taskRequest : UpdateTaskRequest? = null) {
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { ZdLocationManager.getSingleLocation(success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
val temp = taskRequest ?: UpdateTaskRequest( val temp = taskRequest ?: UpdateTaskRequest(type = "ARRIVE_DEST",
type = "ARRIVE_DEST",
taskId = GlobalData.currentOrder?.taskId, taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId, userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId, vehicleId = GlobalData.driverInfoBean?.vehicleId,
@ -69,8 +69,7 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
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,
flowType = temp.flowType, flowType = temp.flowType,
userId = temp.userId, userId = temp.userId,
@ -87,7 +86,8 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
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()))
}, failed = { }, failed = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
ToastUtils.showShort(it) ToastUtils.showShort(it)
@ -99,8 +99,7 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
LoadingManager.showLoading() LoadingManager.showLoading()
ZdLocationManager.getSingleLocation(success = { ZdLocationManager.getSingleLocation(success = {
LoadingManager.hideLoading() LoadingManager.hideLoading()
val taskRequest = UpdateTaskRequest( val taskRequest = UpdateTaskRequest(type = "ARRIVE_DEST",
type = "ARRIVE_DEST",
taskId = GlobalData.currentOrder?.taskId, taskId = GlobalData.currentOrder?.taskId,
userId = GlobalData.driverInfoBean?.userId, userId = GlobalData.driverInfoBean?.userId,
vehicleId = GlobalData.driverInfoBean?.vehicleId, vehicleId = GlobalData.driverInfoBean?.vehicleId,
@ -117,8 +116,8 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
}) })
} }
private fun doUploadTask(request: UpdateTaskRequest) { private fun doUploadTask(request : UpdateTaskRequest) {
if (!getCurrentOrderOfflineTask().isNullOrEmpty()) { if (! getCurrentOrderOfflineTask().isNullOrEmpty()) {
updateOfflineTask(taskRequest = request) updateOfflineTask(taskRequest = request)
return return
} }
@ -140,24 +139,19 @@ 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()) searchDrivingRoute(getCurrentOrder()) // dispatch(Action.StartTimer)
// dispatch(Action.StartTimer)
} }
private fun searchDrivingRoute(orderInfo: OrderInfo?) { private fun searchDrivingRoute(orderInfo : OrderInfo?) { // 如果没有当前位置,则不进行路径规划
// 如果没有当前位置,则不进行路径规划
if (GlobalData.currentLocation == null) return if (GlobalData.currentLocation == null) return
val currentPoint = LatLonPoint( val currentPoint = LatLonPoint(GlobalData.currentLocation?.latitude ?: 0.0,
GlobalData.currentLocation?.latitude ?: 0.0, GlobalData.currentLocation?.longitude ?: 0.0)
GlobalData.currentLocation?.longitude ?: 0.0
)
// 获取目的地坐标 // 获取目的地坐标
val destPoint = if (orderInfo?.distLat != null && orderInfo.distLat != 0.0 && val destPoint =
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
// 如果没有目的地,则不进行规划 // 如果没有目的地,则不进行规划
@ -166,43 +160,44 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
// 使用 Application Context 创建路由搜索对象 // 使用 Application Context 创建路由搜索对象
val routeSearch = RouteSearch(GlobalData.application) val routeSearch = RouteSearch(GlobalData.application)
routeSearch.setRouteSearchListener(object : RouteSearch.OnRouteSearchListener { 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()) { if (errorCode == 1000 && result != null && result.paths.isNotEmpty()) {
val path = result.paths[0] val path = result.paths[0]
val points = path.steps.flatMap { step -> val points = path.steps.flatMap { step ->
step.polyline.map { LatLng(it.latitude, it.longitude) } step.polyline.map { LatLng(it.latitude, it.longitude) }
} }
val durationInSeconds = path.duration val duration = path.duration
val arrivalTime = SimpleDateFormat("HH:mm:ss", val arrivalTime = System.currentTimeMillis() + duration * 1000
Locale.getDefault()).format(System.currentTimeMillis() + durationInSeconds * 1000) val dateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
val estimatedTime = dateFormat.format(Date(arrivalTime))
updateState(uiState.value.copy(routePoints = points, estimatedArrivalTime =arrivalTime, remainingDistance = path.distance )) updateState(uiState.value.copy(routePoints = points,
estimatedArrivalTime = estimatedTime,
remainingDistance = path.distance))
} else { } else {
LogUtil.print("searchDrivingRoute", "路径规划失败: errorCode=$errorCode") LogUtil.print("searchDrivingRoute", "路径规划失败: errorCode=$errorCode")
} }
} }
override fun onBusRouteSearched(p0: BusRouteResult?, p1: Int) {} override fun onBusRouteSearched(p0 : BusRouteResult?, p1 : Int) {}
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) {}
}) })
// 规划当前位置到目的地的路线 // 规划当前位置到目的地的路线
val query = RouteSearch.FromAndTo(currentPoint, destPoint) 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) routeSearch.calculateDriveRouteAsyn(driveQuery)
} }
private fun calculateRemainingDistance(): Pair<Float, String> { private fun calculateRemainingDistance() : Pair<Float, String> {
val currentLocation = GlobalData.currentLocation ?: return Pair(0f, "") val currentLocation = GlobalData.currentLocation ?: return Pair(0f, "")
val orderInfo = _uiState.value.orderInfo ?: return Pair(0f, "") val orderInfo = _uiState.value.orderInfo ?: return Pair(0f, "")
// 计算到目的地的距离 // 计算到目的地的距离
val distance = if (orderInfo.distLat != null && orderInfo.distLng != null) { val distance = if (orderInfo.distLat != null && orderInfo.distLng != null) {
AMapUtils.calculateLineDistance( AMapUtils.calculateLineDistance(LatLng(currentLocation.latitude,
LatLng(currentLocation.latitude, currentLocation.longitude), currentLocation.longitude), LatLng(orderInfo.distLat !!, orderInfo.distLng !!))
LatLng(orderInfo.distLat!!, orderInfo.distLng!!)
)
} else 0f } else 0f
if (distance <= 0f) { if (distance <= 0f) {
@ -218,7 +213,7 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
return Pair(distance, arrivalTime) return Pair(distance, arrivalTime)
} }
private var timerJob: Job? = null private var timerJob : Job? = null
private fun startTimer() { private fun startTimer() {
timerJob?.cancel() timerJob?.cancel()
@ -226,10 +221,7 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
while (isActive) { while (isActive) {
val (distance, arrivalTime) = calculateRemainingDistance() val (distance, arrivalTime) = calculateRemainingDistance()
_uiState.update { _uiState.update {
it.copy( it.copy(remainingDistance = distance, estimatedArrivalTime = arrivalTime)
remainingDistance = distance,
estimatedArrivalTime = arrivalTime
)
} }
delay(1000) delay(1000)
} }
@ -241,23 +233,20 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
timerJob?.cancel() timerJob?.cancel()
} }
private fun buildMarkers(orderInfo: OrderInfo?) { private fun buildMarkers(orderInfo : OrderInfo?) {
val markers = arrayListOf<MarkerOptions>() val markers = arrayListOf<MarkerOptions>()
if (orderInfo?.lat != null && orderInfo.lat != 0.0 && orderInfo.lng != null && orderInfo.lng != 0.0) { if (orderInfo?.lat != null && orderInfo.lat != 0.0 && orderInfo.lng != null && orderInfo.lng != 0.0) { // 获取矢量图资源文件
// 获取矢量图资源文件 val startMarkers =
val startMarkers = MarkerOptions() MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map))
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_rescuing_map)) .position(LatLng(orderInfo.lat !!, orderInfo.lng !!)).infoWindowEnable(false)
.position(LatLng(orderInfo.lat!!, orderInfo.lng!!))
.infoWindowEnable(false)
.visible(true) .visible(true)
markers.add(startMarkers) markers.add(startMarkers)
} }
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 = MarkerOptions() val startMarkers =
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_dist_map)) MarkerOptions().icon(BitmapDescriptorFactory.fromResource(R.mipmap.sv_dist_map))
.position(LatLng(orderInfo.distLat!!, orderInfo.distLng!!)) .position(LatLng(orderInfo.distLat !!, orderInfo.distLng !!)).visible(true)
.visible(true)
markers.add(startMarkers) markers.add(startMarkers)
} }
updateState(uiState.value.copy(markers = markers)) updateState(uiState.value.copy(markers = markers))
@ -266,20 +255,18 @@ class GoToDestinationVm : IServicingVm<GoToDestinationVm.Action, GoToDestination
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 object StartTimer : Action() data object StartTimer : Action()
} }
data class UiState( data class UiState(val orderInfo : OrderInfo? = null,
val orderInfo: OrderInfo? = null, val showCallPhoneDialog : Boolean? = false,
val showCallPhoneDialog: Boolean? = false, val markers : ArrayList<MarkerOptions>? = null,
val markers: ArrayList<MarkerOptions>? = null, val goNextPage : UpdateTaskBean? = null,
val goNextPage: UpdateTaskBean? = null, val isGoNextPageDialog : Boolean? = null,
val isGoNextPageDialog: Boolean? = null, val showOfflineDialog : Boolean? = null,
val showOfflineDialog: Boolean? = null, val routePoints : List<LatLng>? = null,
val routePoints: List<LatLng>? = null, val remainingDistance : Float = 0f,
val remainingDistance: Float = 0f, val estimatedArrivalTime : String = "")
val estimatedArrivalTime: String = ""
)
} }

View File

@ -38,6 +38,7 @@ import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Date
import java.util.Locale import java.util.Locale
class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>() { class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>() {
@ -155,7 +156,13 @@ class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>(
val points = path.steps.flatMap { step -> val points = path.steps.flatMap { step ->
step.polyline.map { LatLng(it.latitude, it.longitude) } 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 { } else {
LogUtil.print("searchDrivingRoute", "路径规划失败: errorCode=$errorCode") LogUtil.print("searchDrivingRoute", "路径规划失败: errorCode=$errorCode")
} }
@ -176,16 +183,16 @@ class WaitToStartVm : IServicingVm<WaitToStartVm.Action, WaitToStartVm.UiState>(
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) // 每秒更新一次
} // }
} // }
} }
private fun calculateRemainingDistance() : Pair<Float, String> { private fun calculateRemainingDistance() : Pair<Float, String> {

View File

@ -5,7 +5,6 @@ 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
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -51,5 +50,5 @@ fun SignatureView(modifier: Modifier = Modifier, success: (String?) -> Unit, ser
intent.putExtra("lineLength", 10) //每行显示字数(超出屏幕支持横向滚动) intent.putExtra("lineLength", 10) //每行显示字数(超出屏幕支持横向滚动)
signatureLauncher.launch(intent) signatureLauncher.launch(intent)
}, },
contentScale = ContentScale.FillBounds) contentScale = ContentScale.Inside)
} }

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <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> </resources>

View 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>