[fix]
[运营统计页面]
This commit is contained in:
yangyakun
2024-10-25 12:28:42 +08:00
parent fb7ef61b3f
commit 9a2e6065c4
4 changed files with 616 additions and 5 deletions

View File

@@ -29,6 +29,7 @@ import com.mogo.och.unmanned.taxi.constant.TaxiDriverEventConst
import com.mogo.och.unmanned.taxi.constant.TaxiUnmannedConst.Companion.START_AUTOPILOT_ANIMATION_INTERVAL
import com.mogo.och.unmanned.taxi.ui.navi.amap.TaxiAmapNaviFragment
import com.mogo.och.unmanned.taxi.ui.navi.auto.TaxiRoutingNaviFragment
import com.mogo.och.unmanned.taxi.ui.operational.OperationalManager
import com.mogo.och.unmanned.taxi.ui.operational.TaxiOperationalDialogFragment
import com.mogo.och.unmanned.taxi.ui.task.TaxiTaskModel
import com.mogo.och.unmanned.taxi.ui.task.itinerarycurrent.ItineraryCurrentView
@@ -58,7 +59,6 @@ class TaxiFragment :MvpFragment<TaxiFragment?, TaxiPresenter?>(),
private val runningTaskGateWay = "RUNNINGTASKGATEWAY"
private val lineView = "LINEVIEW"
private var personalDialogFragment: WeakReference<TaxiOperationalDialogFragment>? = null
private fun updateOperationBtnStatusOnModeChange(isRoutingVerifyMode: Boolean) {
@@ -102,10 +102,11 @@ class TaxiFragment :MvpFragment<TaxiFragment?, TaxiPresenter?>(),
when (toolTag) {
runningTaskGateWay -> {
d(TAG, "runningTaskGateWay:$runningTaskGateWay---toolTag:$toolTag")
personalDialogFragment = WeakReference(TaxiOperationalDialogFragment())
activity?.supportFragmentManager?.let {
d(TAG, "runningTaskGateWay:展示view ${personalDialogFragment!!.get()}")
personalDialogFragment!!.get()?.show(it, "service_data")
if(context==null){
d(TAG, "runningTaskGateWay:没有展示view ")
}else{
d(TAG, "runningTaskGateWay:展示view ")
OperationalManager.showBadCaseConfigWindow(it)
}
}
}

View File

@@ -0,0 +1,145 @@
package com.mogo.och.unmanned.taxi.ui.operational
import android.content.Context
import android.graphics.Color
import android.graphics.Rect
import android.graphics.drawable.ColorDrawable
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.transition.Slide
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.WindowManager
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.PopupWindow
import android.widget.PopupWindow.INPUT_METHOD_NEEDED
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle.Event
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.mogo.eagle.core.utilcode.kotlin.lifeCycleOwner
import com.mogo.eagle.core.utilcode.reminder.Reminder
import com.mogo.eagle.core.utilcode.reminder.api.impl.PopupWindowReminder
import com.mogo.eagle.core.utilcode.util.*
import me.jessyan.autosize.utils.AutoSizeUtils
import kotlin.math.abs
object OperationalManager : LifecycleEventObserver{
const val TAG = "BadCase"
private var hideFloat: (() -> Unit)? = null
fun init(context: Context) {
}
/**
* 展示BadCase配置页面
*/
fun showBadCaseConfigWindow(context: Context) {
val badCaseConfigView = OperationalManagerView(context)
badCaseConfigView.setOnClickListener(object : OperationalManagerView.ClickListener {
override fun onClose() {
hideFloat?.invoke()
hideFloat = null
}
})
enqueuePop(
badCaseConfigView,
AutoSizeUtils.dp2px(context, 1046f),
WindowManager.LayoutParams.MATCH_PARENT,
key = "BadCaseConfigView"
).also {
hideFloat = it
}
}
override fun onStateChanged(source: LifecycleOwner, event: Event) {
}
fun enqueuePop(content: View, width: Int, height: Int, key: String = "", startX: Int = 0, startY: Int = 0, gravity: Int = Gravity.START, onOuterViewClicked:((focus: View) -> Unit)? = null, isOverride: Boolean = false, isFocusable: Boolean = true): () -> Unit {
val topActivity = ActivityUtils.getTopActivity()
val activity = (topActivity as? FragmentActivity) ?: throw IllegalStateException("please use Activity to trigger pop show.")
val isImmersiveMode = BarUtils.isImmersiveMode(activity)
var tempReminder: PopupWindowReminder? = null
activity.lifecycleScope.launchWhenResumed {
val pop = PopupWindow(width, height).also {
it.isOutsideTouchable = true
it.isTouchable = true
it.isFocusable = isFocusable
it.inputMethodMode = INPUT_METHOD_NEEDED
it.isClippingEnabled = false
var x = 0f
var y = 0f
val touchSlop = ViewConfiguration.get(activity).scaledTouchSlop
var isClicked = false
it.setTouchInterceptor { v, event ->
val out = Rect()
v.getGlobalVisibleRect(out)
if (out.contains(event.x.toInt(), event.y.toInt())) {
return@setTouchInterceptor false
}
when(event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
x = event.x
y = event.y
}
MotionEvent.ACTION_MOVE -> {
val deltaX = event.x - x
val deltaY = event.y - y
isClicked = !(abs(deltaX) > touchSlop || abs(deltaY) > touchSlop)
}
MotionEvent.ACTION_UP -> {
if (isClicked) {
isClicked = false
onOuterViewClicked?.invoke(v)
}
}
}
try {
return@setTouchInterceptor true
} finally {
activity.window.decorView.dispatchTouchEvent(event)
}
}
it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}
if (VERSION.SDK_INT >= VERSION_CODES.M) {
val transition = Slide(gravity).also {
it.interpolator = AccelerateDecelerateInterpolator()
it.duration = 200
}
pop.enterTransition = transition
pop.exitTransition = transition
}
pop.contentView = content
val reminder = object : PopupWindowReminder(pop) {
override fun key(): String {
return key + super.key()
}
override fun show() {
pop.showAtLocation(activity.window.decorView, gravity, startX, startY)
}
override fun isOverride(): Boolean = isOverride
}
tempReminder = reminder
Reminder.enqueue(activity.lifeCycleOwner, reminder)
}
return {
tempReminder?.hide()
}
}
}

View File

@@ -0,0 +1,255 @@
package com.mogo.och.unmanned.taxi.ui.operational
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.common.module.wigets.WindowRelativeLayout
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.bean.OrderTaskDetailStationBean
import com.mogo.och.unmanned.taxi.bean.QueryOrdersRespBean
import com.mogo.och.unmanned.taxi.bean.QueryServingDurationRespBean
import com.mogo.och.unmanned.taxi.bean.QueryTaskRespBean
import com.mogo.och.unmanned.taxi.constant.StationTypeEnum
import com.mogo.och.unmanned.taxi.constant.TaskTypeEnum
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.dayTotalOrdersView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.itemDayTv
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.operationDataTitle
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.operationItemRecyclerView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.view.operationalDataView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.view.dayCompletedOrdersView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.view.operationalDataCloseIv
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.view.servingDurationView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.operationalDataView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.operationalDetailView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.scheduledTasksView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.view.dayTotalOrdersView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.view.itemDayTv
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.view.operationDataTitle
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.view.operationItemRecyclerView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.view.operationalDetailView
import kotlinx.android.synthetic.main.unmanned_taxi_operational_data_view.view.scheduledTasksView
class OperationalManagerView: WindowRelativeLayout, OperationalViewModel.RunningTaskViewCallback {
constructor(context: Context?) : super(context)
constructor(context: Context?, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
companion object {
const val TAG = "BadCaseManagerView"
}
private var clickListener:ClickListener?=null
private var viewModel:OperationalViewModel?=null
private var orderListAdapter: OrderListAdapter? = null
init {
LayoutInflater.from(context).inflate(R.layout.unmanned_taxi_operational_data_view, this, true)
initView()
}
private fun initView(){
//关闭BadCase管理窗口
operationalDataCloseIv.onClick {
if (operationalDetailView.visibility == View.GONE){
clickListener?.onClose()
}else{
operationalDetailView.visibility = View.GONE
operationalDataView.visibility = View.VISIBLE
operationDataTitle.text = "网约车运营数据"
}
}
}
fun setOnClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
interface ClickListener {
fun onClose()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewModel = ViewModelProvider(this).get(OperationalViewModel::class.java)
viewModel?.setDistanceCallback(this)
}
override fun onVisibilityAggregated(isVisible: Boolean) {
super.onVisibilityAggregated(isVisible)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
}
override fun updateScheduledTaskList(currentScheduledTaskList: MutableList<QueryTaskRespBean.Result>?) {
var dataContent = "0"
if (currentScheduledTaskList != null){
dataContent = currentScheduledTaskList.size.toString()
}
scheduledTasksView.setOperationDataContentTv(dataContent,"")
scheduledTasksView.setOperationalDataTagTv("今日演练任务量")
scheduledTasksView.setOperationalDataViewClick(View.VISIBLE,
object :OperationalDataItemView.DataViewClickListener{
override fun onClick() {
currentScheduledTaskList?.also {
operationalDataView.visibility = View.INVISIBLE
operationalDetailView.visibility = View.VISIBLE
operationDataTitle.text = "今日演练任务量列表"
itemDayTv.text = DateTimeUtil.getYMDTime(DateTimeUtil.getCurrentTimeStamp())
var taskListAdapter = TaskListAdapter(AbsMogoApplication.getApp().applicationContext, it)
operationItemRecyclerView.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
operationItemRecyclerView.adapter = taskListAdapter
}
}
})
}
override fun updateServingDuration(data: QueryServingDurationRespBean?) {
var duration = DateTimeUtil.second2Time(0)
if (data != null) {
duration = DateTimeUtil.second2Time(data.data)
}
val listSplit = duration.split(":")
servingDurationView.setOperationalDuration(listSplit[0],"",listSplit[1],"")
servingDurationView.setOperationalDataTagTv("今日服务总时长")
servingDurationView.setOperationalDataViewClick(View.GONE,null)
}
override fun setTaskList(currentOrderTaskList: MutableList<QueryTaskRespBean.Result>?) {
if (currentOrderTaskList == null) orderListAdapter?.updateTaskStationView(null)
else{
var orderTaskDetailList = mutableListOf<OrderTaskDetailStationBean>()
for (index in currentOrderTaskList.size -1 downTo 0){ //后台给的数据是倒序
val taskDetail = currentOrderTaskList[index]
when(taskDetail.taskType){
TaskTypeEnum.VirtualTask.code, TaskTypeEnum.ToOrderStartTask.code -> {
if (index != currentOrderTaskList.size-2){
var bean =
OrderTaskDetailStationBean(taskDetail.endSiteName, StationTypeEnum.PathwayStation.code)
orderTaskDetailList.add(bean)
}
}
TaskTypeEnum.ToOrderEndTask.code -> {
if(orderTaskDetailList.size>0){
val last = orderTaskDetailList.last()
if (last.stationType== StationTypeEnum.PathwayStation.code &&
last.stationName==taskDetail.startSiteName) {
last.stationType = StationTypeEnum.OrderStartStation.code
}else{
val beanStart =
OrderTaskDetailStationBean(taskDetail.startSiteName,
StationTypeEnum.OrderStartStation.code)
orderTaskDetailList.add(beanStart)
}
}else{
val beanStart =
OrderTaskDetailStationBean(taskDetail.startSiteName,
StationTypeEnum.OrderStartStation.code)
orderTaskDetailList.add(beanStart)
}
var beanEnd =
OrderTaskDetailStationBean(taskDetail.endSiteName, StationTypeEnum.OrderEndStation.code)
orderTaskDetailList.add(beanEnd)
}
}
}
orderListAdapter?.updateTaskStationView(orderTaskDetailList)
}
}
override fun setCurrentCompleteOrderData(completedOrderList: MutableList<QueryOrdersRespBean.Result>?) {
var dataContent = "0"
if (completedOrderList != null){
dataContent = completedOrderList.size.toString()
}
dayCompletedOrdersView.setOperationDataContentTv(dataContent,"")
dayCompletedOrdersView.setOperationalDataTagTv("今日订单完成量")
dayCompletedOrdersView.setOperationalDataViewClick(View.VISIBLE,
object :OperationalDataItemView.DataViewClickListener{
override fun onClick() {
completedOrderList?.also {
operationalDataView.visibility = View.INVISIBLE
operationalDetailView.visibility = View.VISIBLE
operationDataTitle.text = "今日订单完成量列表"
itemDayTv.text = DateTimeUtil.getYMDTime(DateTimeUtil.getCurrentTimeStamp())
orderListAdapter = OrderListAdapter(
AbsMogoApplication.getApp().applicationContext,
it,
object : OrderListAdapter.ClickViewDetailListener{
override fun clickViewOrderDetail(orderNo: String) {
viewModel?.queryTaskListByOrderNo(orderNo)
}
})
operationItemRecyclerView.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
operationItemRecyclerView.adapter = orderListAdapter
}
}
})
}
override fun setCurrentDayOrders(totalOrderList: MutableList<QueryOrdersRespBean.Result>?) {
var dataContent = "0"
if (totalOrderList != null){
dataContent = totalOrderList.size.toString()
}
dayTotalOrdersView.setOperationDataContentTv(dataContent,"")
dayTotalOrdersView.setOperationalDataTagTv("今日全部订单量")
dayTotalOrdersView.setOperationalDataViewClick(View.VISIBLE,
object :OperationalDataItemView.DataViewClickListener{
override fun onClick() {
totalOrderList?.also {
operationalDataView.visibility = View.INVISIBLE
operationalDetailView.visibility = View.VISIBLE
operationDataTitle.text = "今日全部订单量列表"
itemDayTv.text = DateTimeUtil.getYMDTime(DateTimeUtil.getCurrentTimeStamp())
orderListAdapter = OrderListAdapter(AbsMogoApplication.getApp().applicationContext,
it,
object : OrderListAdapter.ClickViewDetailListener{
override fun clickViewOrderDetail(orderNo: String) {
viewModel?.queryTaskListByOrderNo(orderNo)
}
})
operationItemRecyclerView.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
operationItemRecyclerView.adapter = orderListAdapter
}
}
})
}
}

View File

@@ -0,0 +1,210 @@
package com.mogo.och.unmanned.taxi.ui.operational
import androidx.lifecycle.ViewModel
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.common.module.utils.RxUtils
import com.mogo.och.unmanned.taxi.R
import com.mogo.och.unmanned.taxi.bean.QueryOrdersRespBean
import com.mogo.och.unmanned.taxi.bean.QueryServingDurationRespBean
import com.mogo.och.unmanned.taxi.bean.QueryTaskRespBean
import com.mogo.och.unmanned.taxi.network.TaxiOperationalDataServiceManager
import io.reactivex.disposables.Disposable
/**
* @author XuXinChao
* @description BadCase录包管理页面
* @since: 2022/12/15
*/
class OperationalViewModel : ViewModel() {
private val TAG = OperationalViewModel::class.java.simpleName
private var viewCallback:RunningTaskViewCallback?=null
private var subscribe: Disposable?=null
fun setDistanceCallback(viewCallback:RunningTaskViewCallback){
this.viewCallback = viewCallback
queryServingDuration()
queryCurrentCompleteOrder()
queryCurrentDayOrder()
queryCurrentScheduledTaskList()
}
/**
* 车辆演练任务列表
*/
private fun queryCurrentScheduledTaskList() {
TaxiOperationalDataServiceManager.queryCurrentScheduledTaskList(
AbsMogoApplication.getApp().applicationContext,
object : OchCommonServiceCallback<QueryTaskRespBean> {
override fun onSuccess(data: QueryTaskRespBean?) {
CallerLogger.d(TAG, "queryCurrentScheduledTaskList" + GsonUtils.toJson(data))
data?.also {
viewCallback?.updateScheduledTaskList(data.data)
}
}
override fun onFail(code: Int, msg: String?) {
ToastUtils.showShort(msg)
}
override fun onError() {
val context = AbsMogoApplication.getApp().applicationContext
if (!NetworkUtils.isConnected(context)) {
ToastUtils.showShort(context.getString(R.string.network_error_tip))
} else {
ToastUtils.showShort(context.getString(R.string.request_error_tip))
}
}
})
}
/**
* 车辆服务市场列表
*/
private fun queryServingDuration(){
TaxiOperationalDataServiceManager.queryServingDuration(
AbsMogoApplication.getApp().applicationContext,
object : OchCommonServiceCallback<QueryServingDurationRespBean> {
override fun onSuccess(data: QueryServingDurationRespBean) { //服务时长返回 秒
val toJson = GsonUtils.toJson(data)
CallerLogger.d(TAG, "queryServingDuration$toJson")
OchChainLogManager.writeChainLog("今日服务时长",toJson)
viewCallback?.updateServingDuration(data)
}
override fun onFail(code: Int, msg: String?) {
ToastUtils.showShort(msg)
}
override fun onError() {
val context = AbsMogoApplication.getApp().applicationContext
if (!NetworkUtils.isConnected(context)) {
ToastUtils.showShort(context.getString(R.string.network_error_tip))
} else {
ToastUtils.showShort(context.getString(R.string.request_error_tip))
}
}
})
}
/**
* 根据订单查询任务列表
*/
fun queryTaskListByOrderNo(orderNo: String){
TaxiOperationalDataServiceManager.queryTaskListByOrder(
AbsMogoApplication.getApp().applicationContext,
orderNo,
object : OchCommonServiceCallback<QueryTaskRespBean> {
override fun onSuccess(data: QueryTaskRespBean?) {
CallerLogger.d(TAG, "queryTaskListByOrderNo" + GsonUtils.toJson(data))
data?.also {
viewCallback?.setTaskList(data.data)
}
}
override fun onFail(code: Int, msg: String?) {
ToastUtils.showShort(msg)
}
override fun onError() {
val context = AbsMogoApplication.getApp().applicationContext
if (!NetworkUtils.isConnected(context)) {
ToastUtils.showShort(context.getString(R.string.network_error_tip))
} else {
ToastUtils.showShort(context.getString(R.string.request_error_tip))
}
}
})
}
/**
* 查询车辆当天已完成订单
*/
private fun queryCurrentCompleteOrder(){
TaxiOperationalDataServiceManager.queryCurrentCompleteOrder(
AbsMogoApplication.getApp().applicationContext,
object : OchCommonServiceCallback<QueryOrdersRespBean> {
override fun onSuccess(data: QueryOrdersRespBean?) {
CallerLogger.d(TAG, "queryCurrentCompleteOrder" + GsonUtils.toJson(data))
data?.also {
viewCallback?.setCurrentCompleteOrderData(data.data)
}
}
override fun onFail(code: Int, msg: String?) {
ToastUtils.showShort(msg)
}
override fun onError() {
val context = AbsMogoApplication.getApp().applicationContext
if (!NetworkUtils.isConnected(context)) {
ToastUtils.showShort(context.getString(R.string.network_error_tip))
} else {
ToastUtils.showShort(context.getString(R.string.request_error_tip))
}
}
})
}
/**
* 查询车辆当天所有订单
*/
private fun queryCurrentDayOrder(){
TaxiOperationalDataServiceManager.queryCurrentDayOrder(
AbsMogoApplication.getApp().applicationContext,
object : OchCommonServiceCallback<QueryOrdersRespBean> {
override fun onSuccess(data: QueryOrdersRespBean?) {
CallerLogger.d(TAG, "queryCurrentDayOrder" + GsonUtils.toJson(data))
data?.also {
viewCallback?.setCurrentDayOrders(data.data)
}
}
override fun onFail(code: Int, msg: String?) {
ToastUtils.showShort(msg)
}
override fun onError() {
val context = AbsMogoApplication.getApp().applicationContext
if (!NetworkUtils.isConnected(context)) {
ToastUtils.showShort(context.getString(R.string.network_error_tip))
} else {
ToastUtils.showShort(context.getString(R.string.request_error_tip))
}
}
})
}
override fun onCleared() {
RxUtils.disposeSubscribe(subscribe)
subscribe = null
}
interface RunningTaskViewCallback{
fun updateScheduledTaskList(data: MutableList<QueryTaskRespBean.Result>?)
fun updateServingDuration(data: QueryServingDurationRespBean?)
fun setTaskList(data: MutableList<QueryTaskRespBean.Result>?)
fun setCurrentCompleteOrderData(data: MutableList<QueryOrdersRespBean.Result>?)
fun setCurrentDayOrders(data: MutableList<QueryOrdersRespBean.Result>?)
}
}