feat(servicing): 新增培训提醒功能并优化订单修改页面- 新增 AppTipsView 组件用于展示培训提醒信息

- 在 HeadView 和 InServicingBottomView 中集成培训提醒功能
-重构 ModifyMoneyScreen 和 ModifyMoneyViewModel,优化全程公里数计算逻辑- 更新 PaymentInfoBean,增加 originalMileage 字段
This commit is contained in:
songzhiling
2025-05-09 18:21:21 +08:00
parent b3be0706e5
commit f14cdd27fc
19 changed files with 571 additions and 300 deletions

View File

@ -27,7 +27,7 @@ class MainActivity : ComponentActivity() {
.fillMaxSize() .fillMaxSize()
.clickable { .clickable {
val uri = val uri =
"zd.assist://app?taskCode=ZD250429100116&driverName=宋志领&driverPhone=17630035658&rescueVehicle=沪88888".toUri() "zd.assist://app?taskCode=ZD250429100095&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.9.37" version = "1.0.1.9.9.57"
pom { pom {
packaging = "aar" packaging = "aar"

View File

@ -25,8 +25,7 @@ abstract class BaseActivity : PushMessageActivity() {
} }
if (showTipDialog.value != null) { if (showTipDialog.value != null) {
CommonDialog(message = showTipDialog.value CommonDialog(message = showTipDialog.value ?: "",
?: "",
title = "提示", title = "提示",
confirmText = "我已了解", confirmText = "我已了解",
confirm = { BaseVm.hideTipDialog() }, confirm = { BaseVm.hideTipDialog() },
@ -38,8 +37,7 @@ abstract class BaseActivity : PushMessageActivity() {
} }
QbSdk.initX5Environment(this.application, object : QbSdk.PreInitCallback { QbSdk.initX5Environment(this.application, object : QbSdk.PreInitCallback {
override fun onCoreInitFinished() { override fun onCoreInitFinished() { // 内核初始化完成,可能为系统内核,也可能为系统内核
// 内核初始化完成,可能为系统内核,也可能为系统内核
LogUtil.print("initX5Environment ", "finish") LogUtil.print("initX5Environment ", "finish")
} }
@ -57,6 +55,7 @@ abstract class BaseActivity : PushMessageActivity() {
@Composable @Composable
abstract fun ContentView() abstract fun ContentView()
} }

View File

@ -54,10 +54,9 @@ fun DealerTheme(darkTheme : Boolean = isSystemInDarkTheme(), content : @Composab
rightMargin = insets.right rightMargin = insets.right
topMargin = 0 topMargin = 0
} }
view.updatePadding(top = insets.top,
bottom = insets.bottom, view.updatePadding(top = insets.top)
left = view.paddingLeft,
right = view.paddingRight)
WindowInsetsCompat.CONSUMED WindowInsetsCompat.CONSUMED
} }
} }

View File

@ -0,0 +1,208 @@
package com.za.base.view
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Warning
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.za.base.theme.headBgColor
import com.za.base.theme.white95
import com.za.bean.request.ReadTrainingCountRequest
import com.za.common.GlobalData
import com.za.common.log.LogUtil
import com.za.net.BaseObserver
import com.za.net.RetrofitHelper
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
val warnBean = mutableStateOf<IWarnBean?>(null)
@Composable
fun AppTipsView() {
val warnBean by remember { warnBean }
LaunchedEffect(Unit) {
fetchAppTipsData()
}
when (warnBean) {
is NetWarnBean -> {
// NetTipView(warnBean as NetWarnBean)
}
is ReadTrainingCountBean -> {
// TrainingDocView(warnBean as ReadTrainingCountBean)
}
else -> {}
}
}
@Composable
fun NetTipView(tipsBean : NetWarnBean) {
Row(modifier = Modifier
.fillMaxWidth()
.height(20.dp)
.background(color = Color.Yellow)
.padding(top = 20.dp, start = 20.dp, end = 20.dp, bottom = 5.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center) {
Text(tipsBean.message, color = white95)
}
}
@Composable
fun TrainingDocView(readTrainingCountBean : ReadTrainingCountBean) {
val showTrainingDialog = remember { mutableStateOf(false) }
if (showTrainingDialog.value) {
CommonDialog(title = "培训提醒",
message = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, fontSize = 16.sp)) {
append("重要提示:\n")
}
withStyle(style = SpanStyle(fontSize = 14.sp)) {
append("您有未完成的培训任务,为确保工作顺利开展,请尽快完成培训。\n\n")
}
withStyle(style = SpanStyle(color = Color(0xFFE65100),
fontSize = 15.sp,
fontWeight = FontWeight.Medium)) {
append("剩余培训任务:${readTrainingCountBean.mustReadTrainingCount ?: 0}")
}
}.toString(),
confirmText = "立即前往",
cancelText = "稍后提醒",
cancelEnable = true,
confirm = {
showTrainingDialog.value = false
},
dismiss = { showTrainingDialog.value = false })
}
AnimatedVisibility(visible = true,
modifier = Modifier.background(color = headBgColor),
enter = fadeIn(animationSpec = tween(300)) + expandVertically(animationSpec = tween(300),
expandFrom = Alignment.Top),
exit = fadeOut() + shrinkVertically()) {
Box(modifier = Modifier
.fillMaxWidth()
.background(color = Color(0xFFFFF3E0))
.clickable { }) {
Row(modifier = Modifier
.fillMaxWidth()
.padding(5.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically) {
Row(horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically) {
Box(modifier = Modifier
.size(30.dp)
.background(color = Color(0xFFFFE0B2), shape = CircleShape),
contentAlignment = Alignment.Center) {
Icon(imageVector = Icons.Rounded.Warning,
contentDescription = null,
tint = Color(0xFFFF9800),
modifier = Modifier.size(24.dp))
}
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
Text(text = "培训提醒",
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
color = Color(0xFF424242),
fontSize = 14.sp)
Text(text = "您有 ${readTrainingCountBean.mustReadTrainingCount ?: 0} 个培训任务待完成",
style = MaterialTheme.typography.bodyMedium,
color = Color(0xFF757575),
fontSize = 12.sp)
}
}
Box(modifier = Modifier
.clickable {}
.background(color = Color(0xFFFF9800), shape = RoundedCornerShape(5.dp))
.padding(horizontal = 10.dp, vertical = 5.dp),
contentAlignment = Alignment.Center) {
Text("去完成", color = Color.White, style = MaterialTheme.typography.labelLarge)
}
}
}
}
}
private fun fetchAppTipsData() {
if (GlobalData.currentOrder != null) {
return
}
if (GlobalData.token == null) {
return
}
val request = ReadTrainingCountRequest(driverId = GlobalData.driverInfoBean?.userId?.toInt(),
userId = GlobalData.driverInfoBean?.userId,
supplierId = GlobalData.driverInfoBean?.supplierId.toString())
RetrofitHelper.getDefaultService().getReadTrainingCount(request).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BaseObserver<ReadTrainingCountBean>() {
override fun doSuccess(it : ReadTrainingCountBean?) {
warnBean.value = it
}
override fun doFailure(code : Int, msg : String?) {
LogUtil.print("fetchAppTipsData ", "doFailure==$msg")
}
})
}
abstract class IWarnBean
//网络信号强度
data class NetWarnBean(val message : String = "当前网络信息差") : IWarnBean()
data class ReadTrainingCountBean(val mustReadTrainingCount : Int? = null,
val TrainingCount : Int? = null) : IWarnBean()
//gps掉线
data class GpsOfflineBean(val message : String = "Gps掉线了") : IWarnBean()
//gps信号弱
data class GpsWeakBean(val message : String = "Gps信号弱") : IWarnBean()
sealed class WarnType {
object ALl : WarnType()
object NULL : WarnType()
object NetWarn : WarnType()
object GpsOffline : WarnType()
object GpsWeak : WarnType()
}

View File

@ -1,6 +1,7 @@
package com.za.base.view package com.za.base.view
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
@ -22,8 +23,10 @@ import com.za.servicing.R
@Composable @Composable
fun HeadView(title : String, fun HeadView(title : String,
onBack : () -> Unit = {}, onBack : () -> Unit = {},
warnType : WarnType = WarnType.NULL,
isCanBack : Boolean = true, isCanBack : Boolean = true,
action : @Composable () -> Unit = {}) { action : @Composable () -> Unit = {}) {
Column {
CenterAlignedTopAppBar(modifier = Modifier.fillMaxWidth(), CenterAlignedTopAppBar(modifier = Modifier.fillMaxWidth(),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors() colors = TopAppBarDefaults.centerAlignedTopAppBarColors()
.copy(containerColor = headBgColor, titleContentColor = Color.White), .copy(containerColor = headBgColor, titleContentColor = Color.White),
@ -39,14 +42,23 @@ fun HeadView(title : String,
} }
}, },
actions = { action() }) actions = { action() })
if (warnType != WarnType.NULL) {
AppTipsView()
}
}
} }
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun HeadViewNotBack(title : String) { fun HeadViewNotBack(title : String) {
Column {
CenterAlignedTopAppBar(modifier = Modifier.fillMaxWidth(), CenterAlignedTopAppBar(modifier = Modifier.fillMaxWidth(),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors() colors = TopAppBarDefaults.centerAlignedTopAppBarColors()
.copy(containerColor = headBgColor, titleContentColor = Color.White), .copy(containerColor = headBgColor, titleContentColor = Color.White),
title = { Text(text = title, fontSize = 15.sp, fontWeight = FontWeight.Medium) }, title = { Text(text = title, fontSize = 15.sp, fontWeight = FontWeight.Medium) },
navigationIcon = {}) navigationIcon = {})
AppTipsView()
}
} }

View File

@ -8,6 +8,7 @@ data class PaymentInfoBean(
val limitedMileage : Int? = null, //免托公里数 val limitedMileage : Int? = null, //免托公里数
val amount : Float? = null, //收款金额 val amount : Float? = null, //收款金额
val unitPrice : Float? = null, //单价 //如果单价为 null 并且payItem 为2 则为超限无单价项目 val unitPrice : Float? = null, //单价 //如果单价为 null 并且payItem 为2 则为超限无单价项目
val originalMileage : Float? = null, //原始公里数
val mileage : Float? = null, //公里数 val mileage : Float? = null, //公里数
val settlementRule : String? = null, //结算规则 val settlementRule : String? = null, //结算规则
val userPhone : String? = null, //客户手机号 val userPhone : String? = null, //客户手机号

View File

@ -1,6 +1,7 @@
package com.za.bean package com.za.bean
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.za.base.view.ReadTrainingCountBean
import com.za.bean.db.order.OrderInfo import com.za.bean.db.order.OrderInfo
class OrderInfoPreviewParameters : PreviewParameterProvider<OrderInfo> { class OrderInfoPreviewParameters : PreviewParameterProvider<OrderInfo> {
@ -13,3 +14,9 @@ class OrderInfoPreviewParameters : PreviewParameterProvider<OrderInfo> {
plateNumber = "沪A12345", plateNumber = "沪A12345",
importantTip = "请保持电话畅通,服务人员将尽快联系您。")) importantTip = "请保持电话畅通,服务人员将尽快联系您。"))
} }
class ReadTrainingCountPreviewParameters : PreviewParameterProvider<ReadTrainingCountBean> {
override val values : Sequence<ReadTrainingCountBean>
get() = sequenceOf(ReadTrainingCountBean(mustReadTrainingCount = 1,
TrainingCount = 1))
}

View File

@ -2,8 +2,7 @@ package com.za.bean
//public String reportType;//报备类型名称 //public String reportType;//报备类型名称
// public String reportTemplate;//报备内容模板 // public String reportTemplate;//报备内容模板
data class ReportItem(val reportType: String? = null, data class ReportItem(val reportType : String? = null, val reportTemplate : String? = null)
val reportTemplate: String? = null)
//提交报备内容 //提交报备内容

View File

@ -1,6 +1,7 @@
package com.za.bean.db.order package com.za.bean.db.order
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathHitTester
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
@ -64,4 +65,11 @@ data class PhotoTemplateInfo(
else -> Color(0xFF2DBBF9) else -> Color(0xFF2DBBF9)
} }
} }
fun getFormatPhotoUrl() : String? {
if (this.photoUrl?.startsWith("http://") == true) {
return this.photoUrl.replace("http://", "https://")
}
return this.photoUrl
}
} }

View File

@ -0,0 +1,5 @@
package com.za.bean.request
data class ReadTrainingCountRequest(val driverId : Int? = null,
val userId : Int? = null,
val supplierId : String? = null)

View File

@ -1,5 +1,6 @@
package com.za.net package com.za.net
import com.za.base.view.ReadTrainingCountBean
import com.za.bean.AppNewDriverInfoDTO import com.za.bean.AppNewDriverInfoDTO
import com.za.bean.BaseResponse import com.za.bean.BaseResponse
import com.za.bean.BatteryCostQueryBean import com.za.bean.BatteryCostQueryBean
@ -9,7 +10,6 @@ import com.za.bean.DriverIdentityAuthWebBean
import com.za.bean.DriverIdentityAuthWebRequest import com.za.bean.DriverIdentityAuthWebRequest
import com.za.bean.DriverInfo import com.za.bean.DriverInfo
import com.za.bean.FetchChangeBatteryPhotoRequest import com.za.bean.FetchChangeBatteryPhotoRequest
import com.za.bean.GeneralInfo
import com.za.bean.HistoryPhotoTemplates import com.za.bean.HistoryPhotoTemplates
import com.za.bean.HistoryTaskBean import com.za.bean.HistoryTaskBean
import com.za.bean.ImageBean import com.za.bean.ImageBean
@ -52,6 +52,7 @@ import com.za.bean.request.PaymentInfoRequest
import com.za.bean.request.PaymentUpdateRequest import com.za.bean.request.PaymentUpdateRequest
import com.za.bean.request.PhotoTemplateRequest import com.za.bean.request.PhotoTemplateRequest
import com.za.bean.request.QueryEleOrderRequest import com.za.bean.request.QueryEleOrderRequest
import com.za.bean.request.ReadTrainingCountRequest
import com.za.bean.request.RecognizeRefuelOcrRequestBean import com.za.bean.request.RecognizeRefuelOcrRequestBean
import com.za.bean.request.RecognizeRefuelTicketBean import com.za.bean.request.RecognizeRefuelTicketBean
import com.za.bean.request.RecognizeRefuelTicketRequestBean import com.za.bean.request.RecognizeRefuelTicketRequestBean
@ -126,6 +127,9 @@ interface ApiService {
@POST("/driverApp/supplier/getDriverListInfo") @POST("/driverApp/supplier/getDriverListInfo")
fun getDriverListInfo(@Body info : VerifyCodeRequest) : Observable<BaseResponse<List<AppNewDriverInfoDTO>>> fun getDriverListInfo(@Body info : VerifyCodeRequest) : Observable<BaseResponse<List<AppNewDriverInfoDTO>>>
@POST("/driverApp/supplier/getReadTrainingCount")
fun getReadTrainingCount(@Body params : ReadTrainingCountRequest) : Observable<BaseResponse<ReadTrainingCountBean>>
@POST("/driverApp/task/loginWithTask") @POST("/driverApp/task/loginWithTask")
fun loginWithTask(@Body loginWithTaskRequest : LoginWithTaskRequest) : Observable<BaseResponse<LoginWithTaskBean>> fun loginWithTask(@Body loginWithTaskRequest : LoginWithTaskRequest) : Observable<BaseResponse<LoginWithTaskBean>>

View File

@ -616,7 +616,7 @@ fun InServicingPhotoItemView(modifier : Modifier = Modifier,
.fillMaxWidth() .fillMaxWidth()
.height(300.dp), .height(300.dp),
contentAlignment = Alignment.Center) { contentAlignment = Alignment.Center) {
AsyncImage(model = photoTemplateInfo.photoUrl, AsyncImage(model = photoTemplateInfo.getFormatPhotoUrl(),
contentDescription = "", contentDescription = "",
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
contentScale = ContentScale.FillWidth) contentScale = ContentScale.FillWidth)
@ -693,7 +693,7 @@ fun InServicingPhotoItemView(modifier : Modifier = Modifier,
.weight(1f) .weight(1f)
.height(100.dp)) { .height(100.dp)) {
if (photoTemplateInfo.myCustomPhotoType == Const.PhotoType.ChangeBattery) { if (photoTemplateInfo.myCustomPhotoType == Const.PhotoType.ChangeBattery) {
AsyncImage(model = photoTemplateInfo.photoUrl?.toIntOrNull(), AsyncImage(model = photoTemplateInfo.getFormatPhotoUrl()?.toIntOrNull(),
contentDescription = "", contentDescription = "",
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@ -701,7 +701,7 @@ fun InServicingPhotoItemView(modifier : Modifier = Modifier,
.clip(shape = RoundedCornerShape(3.dp)), .clip(shape = RoundedCornerShape(3.dp)),
contentScale = ContentScale.FillBounds) contentScale = ContentScale.FillBounds)
} else { } else {
AsyncImage(model = photoTemplateInfo.photoUrl, AsyncImage(model = photoTemplateInfo.getFormatPhotoUrl(),
contentDescription = "", contentDescription = "",
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()

View File

@ -16,6 +16,8 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -35,6 +37,7 @@ import com.za.base.view.CommonDialog
import com.za.base.view.HeadView import com.za.base.view.HeadView
import com.za.common.GlobalData import com.za.common.GlobalData
import com.za.common.log.LogUtil import com.za.common.log.LogUtil
import com.za.ext.finish
import com.za.ext.goNextPage import com.za.ext.goNextPage
import com.za.servicing.R import com.za.servicing.R
import com.za.ui.camera.ZdCameraXActivity import com.za.ui.camera.ZdCameraXActivity
@ -90,11 +93,12 @@ fun ServicePeopleConfirmScreen(vm : InServicePeopleConfirmVm = viewModel(),
}) })
} }
Scaffold(topBar = { HeadView(title = "身份验证") }) { Scaffold(topBar = { HeadView(title = "身份验证", onBack = { context.finish() }) }) {
Column(modifier = Modifier Column(modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(color = Color.White) .background(color = Color.White)
.padding(it), .padding(it)
.verticalScroll(state = rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally) { horizontalAlignment = Alignment.CenterHorizontally) {
Spacer(modifier = Modifier.height(60.dp)) Spacer(modifier = Modifier.height(60.dp))
@ -154,7 +158,7 @@ fun ServicePeopleConfirmScreen(vm : InServicePeopleConfirmVm = viewModel(),
} }
} }
Spacer(modifier = Modifier.height(60.dp)) Spacer(modifier = Modifier.height(40.dp))
CommonButton(text = "开始核验", onClick = { CommonButton(text = "开始核验", onClick = {
val intent = Intent(context, ZdCameraXActivity::class.java) val intent = Intent(context, ZdCameraXActivity::class.java)
intent.putExtra("isBack", false) intent.putExtra("isBack", false)

View File

@ -79,8 +79,8 @@ fun ModifyMoneyScreen(userOrderId : Int, taskId : Int, vm : ModifyMoneyViewModel
onValueChange = { onValueChange = {
vm.dispatch(ModifyMoneyViewModel.Action.ChangeMileage((it))) vm.dispatch(ModifyMoneyViewModel.Action.ChangeMileage((it)))
}, },
label = "全程公里数", label = "全程公里数,免拖${uiState.value.paymentInfoBean?.limitedMileage ?: "_"}公里,最低${uiState.value.paymentInfoBean?.originalMileage ?: "_"}公里",
hint = uiState.value.paymentInfoBean?.mileage?.toString() ?: "0", hint = uiState.value.mileageText ?: "0",
suffix = "公里") suffix = "公里")
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
@ -109,10 +109,11 @@ fun ModifyMoneyScreen(userOrderId : Int, taskId : Int, vm : ModifyMoneyViewModel
OutlinedTextField(value = uiState.value.adjustRemark, OutlinedTextField(value = uiState.value.adjustRemark,
onValueChange = { vm.updateState(uiState.value.copy(adjustRemark = it)) }, onValueChange = { vm.updateState(uiState.value.copy(adjustRemark = it)) },
label = { Text("调整原因") }, label = { Text("调整原因") },
placeholder = { Text("请输入调整原因", color = Color(0xFF666666)) },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(80.dp), .height(80.dp),
enabled = uiState.value.paymentInfoBean?.payItem == 1) enabled = true)
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
@ -164,9 +165,10 @@ private fun MoneyInputField(value : String,
keyboardType : KeyboardType = KeyboardType.Decimal, keyboardType : KeyboardType = KeyboardType.Decimal,
enabled : Boolean = true) { enabled : Boolean = true) {
val secondaryTextColor = Color(0xFF666666) val secondaryTextColor = Color(0xFF666666)
OutlinedTextField(value = value, OutlinedTextField(value = value,
placeholder = { Text(hint, color = secondaryTextColor) }, placeholder = { Text(hint, color = secondaryTextColor) },
onValueChange = onValueChange, onValueChange = { onValueChange(it) },
label = { Text(label, color = secondaryTextColor) }, label = { Text(label, color = secondaryTextColor) },
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()

View File

@ -36,10 +36,8 @@ class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
private fun init(userOrderId : Int, taskId : Int) { private fun init(userOrderId : Int, taskId : Int) {
LoadingManager.showLoading() LoadingManager.showLoading()
val paymentInfoRequest = PaymentInfoRequest(userOrderId, taskId) val paymentInfoRequest = PaymentInfoRequest(userOrderId, taskId)
RetrofitHelper.getDefaultService() RetrofitHelper.getDefaultService().paymentInfoQuery(paymentInfoRequest)
.paymentInfoQuery(paymentInfoRequest) .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BaseObserver<PaymentInfoBean>() { .subscribe(object : BaseObserver<PaymentInfoBean>() {
override fun doSuccess(it : PaymentInfoBean?) { override fun doSuccess(it : PaymentInfoBean?) {
LoadingManager.hideLoading() LoadingManager.hideLoading()
@ -47,8 +45,9 @@ class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
userOrderId = userOrderId, userOrderId = userOrderId,
taskId = taskId, taskId = taskId,
unitPrice = it?.unitPrice, unitPrice = it?.unitPrice,
mileage = it?.mileage, mileage = it?.mileage?.plus(uiState.value.paymentInfoBean?.limitedMileage
mileageText = "${it?.mileage ?: ""}", ?: 0),
mileageText = "${it?.mileage?.plus(uiState.value.paymentInfoBean?.limitedMileage ?: 0)}",
calculateAmount = it?.calculateAmount, calculateAmount = it?.calculateAmount,
adjustAmount = it?.adjustAmount?.toFloat(), adjustAmount = it?.adjustAmount?.toFloat(),
adjustAmountText = "${it?.adjustAmount ?: ""}", adjustAmountText = "${it?.adjustAmount ?: ""}",
@ -63,26 +62,25 @@ class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
} }
private fun changeMileage(value : String?) { private fun changeMileage(value : String?) {
val mileage = value?.toFloatOrNull() ?: 0f var mileage = value?.toFloatOrNull() ?: 0f
val calculateAmount = if (mileage <= (uiState.value.paymentInfoBean?.limitedMileage val calculateAmount = if (mileage <= (uiState.value.paymentInfoBean?.limitedMileage ?: 0)) {
?: 0) 0f
) {
uiState.value.paymentInfoBean?.startPrice ?: 0f
} else { } else {
(mileage - (uiState.value.paymentInfoBean?.limitedMileage ?: 0)) (mileage - (uiState.value.paymentInfoBean?.limitedMileage
.times(uiState.value.unitPrice ?: 0f) ?: 0)).times(uiState.value.unitPrice ?: 0f)
.plus(uiState.value.paymentInfoBean?.startPrice ?: 0)
} }
updateState(uiState.value.copy(mileage = mileage, mileageText = value, calculateAmount = calculateAmount.toFloat(),
updateState(uiState.value.copy(mileage = mileage,
mileageText = value,
calculateAmount = calculateAmount.toFloat(),
totalMoney = calculateAmount.toFloat().plus(uiState.value.adjustAmount ?: 0f))) totalMoney = calculateAmount.toFloat().plus(uiState.value.adjustAmount ?: 0f)))
// val calculateAmount = mileage.times(uiState.value.unitPrice ?: 0f)
// val totalMoney = calculateAmount + (uiState.value.paymentInfoBean?.adjustAmount ?: 0)
// updateState(uiState.value.copy(mileage = mileage, mileageText = value, calculateAmount = calculateAmount, totalMoney = totalMoney))
} }
private fun changeAdjustAmount(value : String?) { private fun changeAdjustAmount(value : String?) {
val adjustAmount = value?.toFloatOrNull() ?: 0f val adjustAmount = value?.toFloatOrNull() ?: 0f
updateState(uiState.value.copy(adjustAmountText = value, adjustAmount = adjustAmount, updateState(uiState.value.copy(adjustAmountText = value,
adjustAmount = adjustAmount,
totalMoney = uiState.value.calculateAmount?.plus(adjustAmount))) totalMoney = uiState.value.calculateAmount?.plus(adjustAmount)))
} }
@ -93,11 +91,28 @@ class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
return return
} }
val paymentUpdateRequest = PaymentUpdateRequest(
userOrderId = uiState.value.userOrderId, taskOrderId = uiState.value.taskId, if ((uiState.value.mileage ?: 0f) < (uiState.value.paymentInfoBean?.originalMileage
?: 0f)
) {
ToastUtils.showShort("全程公里数不能小于${uiState.value.paymentInfoBean?.originalMileage}")
return
}
if ((uiState.value.mileage?.minus(uiState.value.paymentInfoBean?.limitedMileage ?: 0)
?: 0f) < (uiState.value.paymentInfoBean?.originalMileage ?: 0f)
) {
ToastUtils.showShort("全程公里数减去免拖公里数不能小于${uiState.value.paymentInfoBean?.originalMileage}")
return
}
val paymentUpdateRequest = PaymentUpdateRequest(userOrderId = uiState.value.userOrderId,
taskOrderId = uiState.value.taskId,
payAmount = uiState.value.totalMoney, payAmount = uiState.value.totalMoney,
unitPrice = uiState.value.unitPrice, unitPrice = uiState.value.unitPrice,
mileage = uiState.value.mileage, mileage = uiState.value.mileage?.minus(uiState.value.paymentInfoBean?.limitedMileage
?: 0),
orderPayDetailId = uiState.value.paymentInfoBean?.orderPayDetailId, orderPayDetailId = uiState.value.paymentInfoBean?.orderPayDetailId,
calculateAmount = uiState.value.calculateAmount, calculateAmount = uiState.value.calculateAmount,
adjustAmount = uiState.value.adjustAmount, adjustAmount = uiState.value.adjustAmount,
@ -107,8 +122,7 @@ class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
LoadingManager.showLoading() LoadingManager.showLoading()
RetrofitHelper.getDefaultService().paymentAmountUpdate(paymentUpdateRequest) RetrofitHelper.getDefaultService().paymentAmountUpdate(paymentUpdateRequest)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BaseObserver<String>() { .subscribe(object : BaseObserver<String>() {
override fun doSuccess(it : String?) { override fun doSuccess(it : String?) {
LoadingManager.hideLoading() LoadingManager.hideLoading()
@ -131,8 +145,7 @@ class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
data object Save : Action() data object Save : Action()
} }
data class UiState( data class UiState(val userOrderId : Int = 0,
val userOrderId: Int = 0,
val taskId : Int = 0, val taskId : Int = 0,
val paymentInfoBean : PaymentInfoBean? = null, val paymentInfoBean : PaymentInfoBean? = null,
val unitPrice : Float? = null, //超限单价 val unitPrice : Float? = null, //超限单价
@ -145,6 +158,5 @@ class ModifyMoneyViewModel : BaseVm<Action, UiState>() {
val mileageText : String? = null, //输入框文本展示 val mileageText : String? = null, //输入框文本展示
val adjustAmountText : String? = null, val adjustAmountText : String? = null,
val saveSuccess: Boolean? = null val saveSuccess : Boolean? = null)
)
} }

View File

@ -80,6 +80,7 @@ import com.za.ext.finish
import com.za.ext.goNextPage import com.za.ext.goNextPage
import com.za.ext.noDoubleClick import com.za.ext.noDoubleClick
import com.za.ui.servicing.order_confirm.input_money.InputMoneyActivity import com.za.ui.servicing.order_confirm.input_money.InputMoneyActivity
import com.za.ui.servicing.order_confirm.modify_money.ModifyMoneyActivity
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
val primaryColor = Color(0xFF2563EB) val primaryColor = Color(0xFF2563EB)
@ -158,7 +159,7 @@ fun ReceiveMoneyScreen(userOrderId: Int,
AmountSection(paymentInfoBean = uiState.value.paymentInfoBean) { AmountSection(paymentInfoBean = uiState.value.paymentInfoBean) {
// ModifyMoneyActivity.goModifyMoney(context, uiState.value.paymentInfoBean?.userOrderId // ModifyMoneyActivity.goModifyMoney(context, uiState.value.paymentInfoBean?.userOrderId
// ?: 0, uiState.value.paymentInfoBean?.taskOrderId ?: 0) // ?: 0, uiState.value.paymentInfoBean?.taskOrderId ?: 0)
InputMoneyActivity.goInputMoney(context, uiState.value.paymentInfoBean?.userOrderId ModifyMoneyActivity.goModifyMoney(context, uiState.value.paymentInfoBean?.userOrderId
?: 0, uiState.value.paymentInfoBean?.taskOrderId ?: 0) ?: 0, uiState.value.paymentInfoBean?.taskOrderId ?: 0)
} }

View File

@ -34,6 +34,7 @@ import coil.compose.AsyncImage
import com.za.base.Const import com.za.base.Const
import com.za.base.theme.black5 import com.za.base.theme.black5
import com.za.base.theme.headBgColor import com.za.base.theme.headBgColor
import com.za.base.view.AppTipsView
import com.za.base.view.CommonDialog import com.za.base.view.CommonDialog
import com.za.bean.db.order.OrderInfo import com.za.bean.db.order.OrderInfo
import com.za.common.util.MapUtil import com.za.common.util.MapUtil
@ -207,6 +208,8 @@ fun InServicingHeadView(title : String,
} }
} }
Column {
CenterAlignedTopAppBar(modifier = Modifier.fillMaxWidth(), CenterAlignedTopAppBar(modifier = Modifier.fillMaxWidth(),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors() colors = TopAppBarDefaults.centerAlignedTopAppBarColors()
.copy(containerColor = headBgColor, titleContentColor = Color.White), .copy(containerColor = headBgColor, titleContentColor = Color.White),
@ -231,6 +234,9 @@ fun InServicingHeadView(title : String,
modifier = Modifier.fillMaxSize()) modifier = Modifier.fillMaxSize())
} }
}) })
AppTipsView()
}
} }
@Composable @Composable

View File

@ -55,6 +55,7 @@ import com.amap.api.maps.model.LatLng
import com.amap.api.maps.model.LatLngBounds import com.amap.api.maps.model.LatLngBounds
import com.amap.api.maps.model.MarkerOptions import com.amap.api.maps.model.MarkerOptions
import com.amap.api.maps.model.PolylineOptions import com.amap.api.maps.model.PolylineOptions
import com.blankj.utilcode.util.ConvertUtils
import com.za.base.BaseActivity import com.za.base.BaseActivity
import com.za.base.theme.headBgColor import com.za.base.theme.headBgColor
import com.za.base.view.CommonDialog import com.za.base.view.CommonDialog
@ -333,7 +334,9 @@ fun WaitToStartScreen(vm : WaitToStartVm = viewModel()) {
Box(modifier = Modifier Box(modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(paddingValues)) { .padding(paddingValues)) {
AndroidView(modifier = Modifier.fillMaxSize(), factory = { AndroidView(modifier = Modifier
.fillMaxSize()
.padding(bottom = 20.dp), factory = {
AMapLocationClient.updatePrivacyShow(context, true, true) AMapLocationClient.updatePrivacyShow(context, true, true)
AMapLocationClient.updatePrivacyAgree(context, true) AMapLocationClient.updatePrivacyAgree(context, true)
mapView.apply { mapView.apply {
@ -413,7 +416,8 @@ fun WaitToStartScreen(vm : WaitToStartVm = viewModel()) {
// 调整地图显示范围,确保所有点都可见 // 调整地图显示范围,确保所有点都可见
try { try {
mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100)) mapView.map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,
ConvertUtils.dp2px(50f)))
} catch (e : Exception) { // 如果计算边界失败,则使用默认缩放级别 } catch (e : Exception) { // 如果计算边界失败,则使用默认缩放级别
GlobalData.currentLocation?.let { GlobalData.currentLocation?.let {
mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude, mapView.map.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude,