Merge branch 'dev_robotaxi-d_241112_6.8.0' of gitlab.zhidaoauto.com:SCA/L4HA/AndroidApp/MoGoEagleEye into dev_robotaxi-d_241112_6.8.0

This commit is contained in:
xinfengkun
2024-11-20 17:23:21 +08:00
131 changed files with 3859 additions and 4522 deletions

View File

@@ -15,6 +15,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListener
import com.mogo.eagle.core.function.call.datacenter.CallerDataCenterBizListener
import com.mogo.eagle.core.function.call.map.CallerMapGlobalTrajectoryDrawManager
import com.mogo.eagle.core.function.call.och.CallerEagleBaseFunctionCall4OchManager
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.e
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
@@ -79,13 +80,14 @@ object LineManager : CallerBase<ILineCallback>() {
private var autopilotId: String by Delegates.observable("") { _, oldValue, newValue ->
if (oldValue != newValue) {
CallerEagleBaseFunctionCall4OchManager.setOchAutopilotOrderId(newValue)
val (start, end) = getStations()
if(start!=null&&end!=null){
CallerDataCenterBizListener.invokeOchInfo(OchInfo(0, mutableListOf(start.toMogoLocation(),end.toMogoLocation())))
}else{
CallerDataCenterBizListener.invokeOchInfo(OchInfo(0, mutableListOf()))
if(!AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)&&!AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)){
val (start, end) = getStations()
if(start!=null&&end!=null){
CallerDataCenterBizListener.invokeOchInfo(OchInfo(0, mutableListOf(start.toMogoLocation(),end.toMogoLocation())))
}else{
CallerDataCenterBizListener.invokeOchInfo(OchInfo(0, mutableListOf()))
}
}
}
}

View File

@@ -0,0 +1,55 @@
package com.mogo.och.common.module.manager.bluetooth
import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.app.ActivityCompat
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.function.main.MainPresenter
import com.mogo.eagle.core.utilcode.mogo.permissions.PermissionsDialogUtils
import com.mogo.eagle.core.utilcode.util.ActivityUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.utils.PermissionUtil
open class BaseBluetoothManager {
protected var bluetoothAdapter: BluetoothAdapter? = null
protected var bluetoothManager: BluetoothManager? = null
private val REQUEST_ENABLE_BT = 10001
private val TAG = "OchBluetoothManager"
private var permissionlist = arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_ADVERTISE,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
)
enum class BluetoothState {
NONE, ON, OFF
}
init {
bluetoothManager = AbsMogoApplication.getApp().getSystemService(BluetoothManager::class.java)
bluetoothAdapter = bluetoothManager?.adapter
}
fun isEnable(): BluetoothState {
bluetoothAdapter?.let {
if (it.isEnabled) {
return BluetoothState.ON
} else {
return BluetoothState.OFF
}
}
ToastUtils.showShort("设备无蓝牙硬件")
return BluetoothState.NONE
}
}

View File

@@ -0,0 +1,19 @@
package com.mogo.och.common.module.manager.bluetooth
import android.bluetooth.BluetoothDevice
import android.bluetooth.le.ScanResult
data class BleDevItem(val dev: BluetoothDevice,val scanResult: ScanResult,val gattcallback:OchBluetoothGattCallback){
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as BleDevItem
return dev.address == other.dev.address
}
override fun hashCode(): Int {
return dev.hashCode()
}
}

View File

@@ -0,0 +1,127 @@
package com.mogo.och.common.module.manager.bluetooth
import android.annotation.SuppressLint
import android.bluetooth.le.BluetoothLeScanner
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.mogo.och.common.module.manager.loop.BizLoopManager
import java.util.UUID
object BleManager : BaseBluetoothManager() {
val UUID_SERVICE: UUID = UUID.fromString("000018F0-0000-1000-8000-00805F9BDDFB") //自定义UUID
val UUID_CHAR_READ_NOTIFY: UUID = UUID.fromString("00002AF0-0000-1000-8000-00805F9BEEFB")
val UUID_DESC_NOTITY: UUID = UUID.fromString("00002AF1-0000-1000-8000-00805F9BCCFB")
val UUID_CHAR_WRITE: UUID = UUID.fromString("00002AF1-0000-1000-8000-00805F9BFFFB")
private var scanning = false
private val handler = Handler(Looper.getMainLooper())
private var bluetoothLeScanner: BluetoothLeScanner? = null
private val SCAN_PERIOD = 10000L
private const val TAG = "BleManager"
private val scanList = mutableListOf<BleDevItem>()
var listener: BleDevListener? = null
private val leScanCallback = object : ScanCallback(){
@SuppressLint("MissingPermission")
override fun onScanResult(callbackType: Int, result: ScanResult?) {
result?.let {
val device = it.device
it.rssi// 信号强度
it.scanRecord?.advertiseFlags
it.scanRecord?.serviceUuids
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
it.scanRecord?.serviceSolicitationUuids
}
it.scanRecord?.manufacturerSpecificData
it.scanRecord?.serviceData
it.scanRecord?.txPowerLevel
it.scanRecord?.deviceName
it.scanRecord?.manufacturerSpecificData
it.timestampNanos//
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
it.isLegacy
} else {
TODO("VERSION.SDK_INT < O")
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
it.isLegacy//是否传统蓝牙
} else {
TODO("VERSION.SDK_INT < O")
}
it.primaryPhy
it.secondaryPhy
it.advertisingSid
it.txPower
it.periodicAdvertisingInterval
if(!it.device.name.isNullOrEmpty()){
val bleDevItem = BleDevItem(result.device, result,OchBluetoothGattCallback(result.device))
if(!scanList.contains(bleDevItem)){
scanList.add(bleDevItem)
}
Log.d(TAG, "callbackType:${callbackType}_____result:${result}")
listener?.dataChange(scanList)
}
}
}
override fun onBatchScanResults(results: MutableList<ScanResult>?) {
Log.d(TAG, "results:${results}")
}
override fun onScanFailed(errorCode: Int) {
Log.d(TAG, "errorCode:${errorCode}")
}
}
fun scanLeDevice() {
when (isEnable()) {
BluetoothState.ON -> {}
else -> {
return
}
}
if(bluetoothLeScanner ==null){
bluetoothLeScanner = bluetoothAdapter?.bluetoothLeScanner
}
try {
if (!scanning) { // Stops scanning after a pre-defined scan period.
handler.postDelayed({
scanning = false
bluetoothLeScanner?.stopScan(leScanCallback)
}, SCAN_PERIOD)
scanning = true
bluetoothLeScanner?.startScan(leScanCallback)
scanList.clear()
listener?.dataChange(scanList)
} else {
scanning = false
bluetoothLeScanner?.stopScan(leScanCallback)
}
}catch (e:SecurityException){
e.printStackTrace()
}
}
interface BleDevListener{
fun dataChange(scanList:MutableList<BleDevItem>)
}
}

View File

@@ -0,0 +1,244 @@
package com.mogo.och.common.module.manager.bluetooth
import android.annotation.SuppressLint
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattDescriptor
import android.bluetooth.BluetoothGattService
import android.bluetooth.BluetoothProfile
import android.util.Log
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import java.util.UUID
import kotlin.properties.Delegates
@SuppressLint("MissingPermission")
class OchBluetoothGattCallback(device: BluetoothDevice) : BluetoothGattCallback() {
private val device = device
private var mBluetoothGatt: BluetoothGatt? = null
var connectListener: ConnectListener?=null
private val waitSendData = mutableMapOf<String,UUID>()
private val maxTryCount = 6
private var currentTryCount = 0
var isConnected:Boolean by Delegates.observable(false) { _, oldValue, newValue ->
if (oldValue != newValue) {
Log.i(TAG,"链接状态发生变化${newValue}")
connectListener?.connectChangeListener()
connectListener = null
}
}
private val TAG = "GattCallback"
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
val dev = gatt.device
Log.i(TAG, "onConnectionStateChange:${dev.name},${dev.address},${status},${newState},${dev.type}")
if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
isConnected = true
gatt.discoverServices() //启动服务发现
} else {
isConnected = false
closeConn()
}
if(status==0){
if(newState==2){
Log.i(TAG,"与[${dev}]连接成功")
}else{
Log.i(TAG,"与[${dev}]连接断开")
}
}else{
Log.i(TAG,"与[${dev}]连接出错,错误码:$status")
if(status==133){
connect()
}
}
}
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
Log.i(TAG,"onServicesDiscovered:${gatt.device.name},${gatt.device.address},${status}")
if (status == BluetoothGatt.GATT_SUCCESS) { //BLE服务发现成功
// 遍历获取BLE服务Services/Characteristics/Descriptors的全部UUID
for (service in gatt.services) {
val allUUIDs = StringBuilder(
"UUIDs={\n S=${service.uuid}".trimIndent()
)
for (characteristic in service.characteristics) {
allUUIDs.append(",\nC=").append(characteristic.uuid)
for (descriptor in characteristic.descriptors) {
allUUIDs.append(",\nD=").append(descriptor.uuid)
}
}
allUUIDs.append("}")
Log.i(TAG, "onServicesDiscovered:$allUUIDs")
}
// 链接成功 服务发现也成功后
waitSendData.forEach {
writeData2UUID(it.key,it.value)
}
}
}
override fun onCharacteristicRead(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
status: Int
) {
val uuid = characteristic.uuid
val valueStr = String(characteristic.value)
Log.i(TAG,"onCharacteristicRead:${gatt.device.name},${gatt.device.address},$uuid,$valueStr,$status")
}
override fun onCharacteristicWrite(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
status: Int
) {
val uuid = characteristic.uuid
val valueStr = String(characteristic.value)
Log.i(
TAG,
"onCharacteristicWrite:${gatt.device.name},${gatt.device.address},$uuid,$valueStr,$status"
)
if(status==BluetoothGatt.GATT_SUCCESS){
waitSendData.remove(valueStr)
closeConn()
connectListener?.sendDataSuccessAndCloseListener(device)
}
}
override fun onCharacteristicChanged(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic
) {
val uuid = characteristic.uuid
val valueStr = String(characteristic.value)
Log.i(TAG,"onCharacteristicChanged:${gatt.device.name},${ gatt.device.address},$uuid,$valueStr")
}
override fun onDescriptorRead(
gatt: BluetoothGatt,
descriptor: BluetoothGattDescriptor,
status: Int
) {
val uuid = descriptor.uuid
val valueStr = descriptor.value.contentToString()
Log.i(TAG,"onDescriptorRead:${gatt.device.name},${gatt.device.address},$uuid,$valueStr,$status")
}
override fun onDescriptorWrite(
gatt: BluetoothGatt,
descriptor: BluetoothGattDescriptor,
status: Int
) {
val uuid = descriptor.uuid
val valueStr = descriptor.value.contentToString()
Log.i(TAG,"onDescriptorWrite:${gatt.device.name},${gatt.device.address},$uuid,$valueStr,$status")
}
private fun refreshDeviceCache(mBluetoothGatt: BluetoothGatt?): Boolean {
if (mBluetoothGatt != null) {
try {
val refresh = mBluetoothGatt.javaClass.getMethod("refresh")
if (refresh != null) {
return refresh.invoke(mBluetoothGatt) as Boolean
}
} catch (e: Exception) {
e.printStackTrace()
}
}
return false
}
// BLE中心设备连接外围设备的数量有限(大概2~7个)在建立新连接之前必须释放旧连接资源否则容易出现连接错误133
fun closeConn() {
if (mBluetoothGatt != null) {
mBluetoothGatt!!.disconnect()
mBluetoothGatt!!.close()
refreshDeviceCache(mBluetoothGatt)
mBluetoothGatt = null
isConnected = false
}
}
// 获取Gatt服务
private fun getGattService(uuid: UUID): BluetoothGattService? {
if (!isConnected) {
return null
}
val service = mBluetoothGatt!!.getService(uuid)
if (service == null) ToastUtils.showShort("没有找到服务UUID=$uuid")
return service
}
// 注意连续频繁读写数据容易失败读写操作间隔最好200ms以上或等待上次回调完成后再进行下次读写操作
// 写入数据成功会回调->onCharacteristicWrite()
fun writeData2UUID(text:String,uuid: UUID){
OchChainLogManager.writeChainLogWriteOff("司机端核销成功","发送数据${text}")
val service = getGattService(BleManager.UUID_SERVICE)
if (service != null) {
val characteristic = service.getCharacteristic(uuid) //通过UUID获取可写的Characteristic
characteristic.setValue(text.toByteArray()) //单次最多20个字节
mBluetoothGatt!!.writeCharacteristic(characteristic)
}
}
// 注意连续频繁读写数据容易失败读写操作间隔最好200ms以上或等待上次回调完成后再进行下次读写操作
// 读取数据成功会回调->onCharacteristicChanged()
fun readDataByUUId(uuid: UUID){
val service = getGattService(BleManager.UUID_SERVICE)
if (service != null) {
val characteristic =
service.getCharacteristic(uuid) //通过UUID获取可读的Characteristic
mBluetoothGatt!!.readCharacteristic(characteristic)
}
}
fun notifyByUUID(uuid: UUID,notify:UUID){
// 设置通知Characteristic变化会回调->onCharacteristicChanged()
val service = getGattService(BleManager.UUID_SERVICE)
if (service != null) {
// 设置Characteristic通知
val characteristic =
service.getCharacteristic(BleManager.UUID_CHAR_READ_NOTIFY) //通过UUID获取可通知的Characteristic
mBluetoothGatt!!.setCharacteristicNotification(characteristic, true)
// 向Characteristic的Descriptor属性写入通知开关使蓝牙设备主动向手机发送数据
val descriptor = characteristic.getDescriptor(BleManager.UUID_DESC_NOTITY)
// descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);//和通知类似,但服务端不主动发数据,只指示客户端读取数据
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)
mBluetoothGatt!!.writeDescriptor(descriptor)
}
}
fun connectGatt(code: String, businessTime: Long) {
if(isConnected){
ToastUtils.showShort("已连接成功")
writeData2UUID("$code,$businessTime",BleManager.UUID_CHAR_WRITE)
}else {
connect()
waitSendData["$code,$businessTime"] = BleManager.UUID_CHAR_WRITE
}
}
private fun connect(){
Log.i(TAG,"connect:第${currentTryCount}")
// 重试5次
if(currentTryCount>maxTryCount){
return
}
currentTryCount += 1
mBluetoothGatt = device.connectGatt(AbsMogoApplication.getApp(), false, this)
}
interface ConnectListener{
fun connectChangeListener(){}
fun sendDataSuccessAndCloseListener(device: BluetoothDevice)
}
}

View File

@@ -26,6 +26,14 @@ object CheckVinManager : IMoGoAutopilotCarConfigListener {
checkVin()
}
fun getVin(): String {
var delineVin = CallerAutoPilotControlManager.getVIN()
if(delineVin.isEmpty()){
delineVin = LoginStatusManager.getLoginInfo()?.vin?:""
}
return delineVin
}
private fun checkVin() {
LoginStatusManager.getLoginInfo()?.let {loginInfo ->
val serverVin = loginInfo.vin

View File

@@ -58,10 +58,16 @@ object OchChainLogManager {
const val EVENT_KEY_INFO_DB = "analytics_event_och_db"
const val EVENT_KEY_INFO_WRITEOFF = "analytics_event_och_writeoff"
fun writeChainLogDb(title: String, info: String) {
writeChainLog(title, info, true, EVENT_KEY_INFO_DB)
}
fun writeChainLogWriteOff(title: String, info: String) {
writeChainLog(title, info, true, EVENT_KEY_INFO_WRITEOFF)
}
fun writeChainLogNet(mustUpdate: Boolean, title: String, info: String) {

View File

@@ -0,0 +1,61 @@
package com.mogo.och.common.module.manager.scnner
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.V2XMsg
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDevicesMsg
import com.mogo.och.common.module.manager.socket.lan.ILanMessageListener
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
object ScannerClientManager {
private val TAG = "ScannerClientManager"
private val writeOfDevicefMsg = object : ILanMessageListener<WriteOffDevicesMsg> {
override fun targetLan(): Class<WriteOffDevicesMsg> = WriteOffDevicesMsg::class.java
override fun onLanMsgReceived(writeOffDevicesMsg: WriteOffDevicesMsg?){
writeOffDevicesMsg?.let {
if (it.isConnectScanner != null) {
val reason = it.reason ?: ""
if (it.isConnectScanner==true) { // 链接成功
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X,
V2XMsg(
EventTypeEnumNew.TYPE_DEVICE_STATUS_NORMAL.poiType,
reason,
EventTypeEnumNew.TYPE_DEVICE_STATUS_NORMAL.tts,
""
)
)
)
} else { // 核验失败
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X,
V2XMsg(
EventTypeEnumNew.TYPE_DEVICE_STATUS_ABNORMAL.poiType,
reason,
EventTypeEnumNew.TYPE_DEVICE_STATUS_ABNORMAL.tts,
""
)
)
)
}
}
}
}
}
fun load(){
// 核销设备信息
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_WRITEOFF_DEVICES_INFO.type,writeOfDevicefMsg)
}
fun release(){
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_WRITEOFF_DEVICES_INFO.type,writeOfDevicefMsg)
}
}

View File

@@ -1,6 +1,11 @@
package com.mogo.och.common.module.manager.scnner
import android.net.Uri
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.V2XMsg
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS_P
@@ -8,17 +13,19 @@ import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.StringUtils
import com.mogo.och.common.module.biz.lansocket.IOchLanPassengerStatusListener
import com.mogo.och.common.module.biz.lansocket.LoginLanPassengerSocket
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDevicesMsg
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import com.mogo.och.common.module.manager.socket.lan.ILanMessageListener
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDevicesMsg
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffMsg
import com.mogo.support.device.manager.SerialPortManager
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDetialMsg
import com.mogo.support.device.manager.bean.VerificationData
import com.mogo.support.serialport.common.core.DeviceType
import com.mogo.support.device.DevicesManager
import com.mogo.support.device.IBindStateChangeListener
import com.mogo.support.device.IVerificationAutoListener
import com.mogo.support.device.manager.SerialPortManager
import java.util.concurrent.ConcurrentHashMap
import kotlin.properties.Delegates
@@ -107,7 +114,6 @@ object ScannerManager : IOchLanPassengerStatusListener {
)
data?.let {
if (data.unpackStatus.isNullOrEmpty()) {
"数据类型${it.dataType.name}"
CallerLogger.d(M_BUS_P + TAG, "data $it")
if (!StringUtils.isEmpty(it.payload)) {
parseParams(it.payload)
@@ -161,9 +167,47 @@ object ScannerManager : IOchLanPassengerStatusListener {
}
private val writeOfDevicefMsg = object : ILanMessageListener<WriteOffDevicesMsg> {
override fun targetLan(): Class<WriteOffDevicesMsg> = WriteOffDevicesMsg::class.java
override fun onLanMsgReceived(writeOffDevicesMsg: WriteOffDevicesMsg?){
writeOffDevicesMsg?.let {
if (writeOffDevicesMsg.isConnectScanner != null) {
val reason = if (writeOffDevicesMsg.reason == null) "" else writeOffDevicesMsg.reason!!
if (writeOffDevicesMsg.isConnectScanner==true) { // 链接成功
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X,
V2XMsg(
EventTypeEnumNew.TYPE_DEVICE_STATUS_NORMAL.poiType,
reason,
EventTypeEnumNew.TYPE_DEVICE_STATUS_NORMAL.tts,
""
)
)
)
} else { // 核验失败
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X,
V2XMsg(
EventTypeEnumNew.TYPE_DEVICE_STATUS_ABNORMAL.poiType,
reason,
EventTypeEnumNew.TYPE_DEVICE_STATUS_ABNORMAL.tts,
""
)
)
)
}
}
}
}
}
init {
//监听司机端消息
LoginLanPassengerSocket.addListener(TAG, this)
// 核销设备信息
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_WRITEOFF_DEVICES_INFO.type,writeOfDevicefMsg)
DevicesManager.addBindStateChangeListener(TAG, onSerialPortListener)
DevicesManager.addVerificationListener(TAG, onDeviceVerificationListener)
}
@@ -175,6 +219,10 @@ object ScannerManager : IOchLanPassengerStatusListener {
stateChanageListeners[tag] = listener
}
fun removeListener(tag:String){
stateChanageListeners.remove(tag)
}
override fun onDriverConnectChangeListener(isConnect: Boolean) {
super.onDriverConnectChangeListener(isConnect)
if (isConnect) {
@@ -185,7 +233,7 @@ object ScannerManager : IOchLanPassengerStatusListener {
private fun parseParams(payload: String?) {
val parse = Uri.parse("${OchCommonConst.getShuttleUrl()}?${payload}")
val queryParameterNames = parse.queryParameterNames
val mutableMapOf = mutableMapOf<String, Any>()
val mutableMapOf = mutableMapOf<String, String>()
queryParameterNames.forEach {
val queryParameter = parse.getQueryParameter(it)
if (it != null && queryParameter != null) {
@@ -216,8 +264,8 @@ object ScannerManager : IOchLanPassengerStatusListener {
/**
* 打开设备后数据异常
*/
private fun sendWriteOffMessage2Driver(message: String) {
val msg = WriteOffMsg(false, "", 0, "", message, "")
private fun sendWriteOffMessage2Driver(message:String){
val msg = WriteOffDetialMsg(code = 10001, msg = message)
CallerLogger.d(M_BUS_P + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg))
LanSocketManager.sendMsgToServer(msg)
}

View File

@@ -2,5 +2,5 @@ package com.mogo.och.common.module.manager.scnner
interface StateChangeListener {
fun stateChange(newBindValue: BindStatus, newOpentValue: OpenStatus){}
fun parseData(params: MutableMap<String, Any>, payload: String?){}
fun parseData(params: MutableMap<String, String>, payload: String?){}
}

View File

@@ -19,5 +19,7 @@ enum class DPMsgType(val type: Int) {
TYPE_WRITEOFF_DEVICES_INFO(9), //核销设备信息
TYPE_CHANGE_BUSINESS_TYPE(10), //业务模式切换
TYPE_ENV_CHECK(11), //环境核验
TYPE_WRITEOFF_INFO_DETAIL(13), //核销信息
TYPE_WRITEOFF_INFO_RESULT(14), //核销结果
TYPE_CLIENT_REGISTER(12); //客户端注册 服务端需要
}

View File

@@ -70,6 +70,36 @@ data class WriteOffMsg(
val orderNo: String?
) : BaseDPMsg(DPMsgType.TYPE_WRITEOFF_INFO.type)
data class WriteOffDetialMsg(
val code:Int, // 0 乘客端参加校验成功 给司机屏 3001 乘客屏校验失败
val msg:String?,// code 非0时具体错误信息
val expiryTime: Long?=null, // 二维码有效期
val bookingTime: Long?=null,// 预定时间
val lineId: Long?=null, // 线路id
val availableTimes: Int?=null,//总票数
val orderNo: String?=null, // 订单Id
val uid: String?=null,// 服务器端唯一码
val phone: String?=null,// 手机号码
val ticketSize: Int?=null,// 票上几个人
val ticketName: String?=null,// 票的名称
val typeBiz: String?=null,//bus shuttle
val pipe:String?=null,// 渠道ehsafety mogogosafety
val startStationId:Long?=null,// 开始站点名称
val tenantId:Long?=null// 租户id
) : BaseDPMsg(DPMsgType.TYPE_WRITEOFF_INFO_DETAIL.type)
/**
* code 3001 乘客屏参数校验失败
* code 3002 司机屏校验失败原因未知
* code 99 小程序缓存丢失Android 缓存存在
*/
data class WriteOffResultMsg(
val code:Int,// 1成功 其他失败
val phone:String,// 手机号
val businessTime:Long
) : BaseDPMsg(DPMsgType.TYPE_WRITEOFF_INFO_RESULT.type)
data class WriteOffDevicesMsg(
val isConnectScanner: Boolean?,
val reason: String?

View File

@@ -1,5 +1,6 @@
package com.mogo.och.common.module.manager.transform
import android.view.View
import com.mogo.eagle.core.function.api.och.IOchBizFunctionCall4Eagle
import com.mogo.eagle.core.function.call.base.CallerBase
import com.mogo.eagle.core.function.call.och.CallerOchBizFunctionCall4EagleManager
@@ -15,4 +16,10 @@ object OchTransform : CallerBase<OchTransformDispatch>(), IOchBizFunctionCall4Ea
it.value.logout()
}
}
override fun setVideoView(target: View?) {
M_LISTENERS.forEach {
it.value.setVideoView(target)
}
}
}

View File

@@ -1,6 +1,9 @@
package com.mogo.och.common.module.manager.transform
import android.view.View
interface OchTransformDispatch {
fun logout(){}
fun setVideoView(target: View?){}
}

View File

@@ -13,6 +13,7 @@
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:src="@drawable/common_dialog_close"
android:visibility="gone"
android:layout_marginEnd="@dimen/dp_50"
android:layout_marginTop="@dimen/dp_50"
android:layout_width="@dimen/dp_60"

View File

@@ -33,4 +33,10 @@
<string name="common_biz_loading">加载中……</string>
<string name="common_empty_data">暂无数据</string>
<string name="common_error_data">重新加载</string>
<string name="common_dialog_title">提示</string>
<string name="common_dialog_confirm">确认</string>
<string name="common_dialog_cancel">取消</string>
</resources>

View File

@@ -0,0 +1,3 @@
package com.mogo.och.data.bean
data class WriteOffBean(val orderNo:String,val uid:String,val phone:String)

View File

@@ -0,0 +1,739 @@
{
"formatVersion": 1,
"database": {
"version": 5,
"identityHash": "018ed967c5f335de5d39581e033160ed",
"entities": [
{
"tableName": "contrail_data_table",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `line_id` INTEGER, `csv_file_url` TEXT, `csv_file_md5` TEXT, `txt_file_url` TEXT, `txt_file_md5` TEXT, `contrail_save_time` INTEGER, `md5` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lineId",
"columnName": "line_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "csvFileUrl",
"columnName": "csv_file_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "csvFileMd5",
"columnName": "csv_file_md5",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "txtFileUrl",
"columnName": "txt_file_url",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "txtFileMd5",
"columnName": "txt_file_md5",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "contrailSaveTime",
"columnName": "contrail_save_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "md5",
"columnName": "md5",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_contrail_data_table_line_id",
"unique": false,
"columnNames": [
"line_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_contrail_data_table_line_id` ON `${TABLE_NAME}` (`line_id`)"
},
{
"name": "index_contrail_data_table_md5",
"unique": false,
"columnNames": [
"md5"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_contrail_data_table_md5` ON `${TABLE_NAME}` (`md5`)"
}
],
"foreignKeys": []
},
{
"tableName": "line_data_table",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `line_id` INTEGER, `line_name` TEXT, `end_station_name` TEXT, `line_get_time` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "lineId",
"columnName": "line_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lineName",
"columnName": "line_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "endStationName",
"columnName": "end_station_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "linegetTime",
"columnName": "line_get_time",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_line_data_table_line_id",
"unique": false,
"columnNames": [
"line_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_line_data_table_line_id` ON `${TABLE_NAME}` (`line_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "site_data_table",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `site_id` INTEGER, `line_id` INTEGER, `name` TEXT, `name_kr` TEXT, `seq` INTEGER, `gcj_lon` REAL, `gcj_lat` REAL, `lon` REAL, `lat` REAL, `introduction` TEXT, `is_play_tts` INTEGER, `md5` TEXT, `videoList` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "siteId",
"columnName": "site_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lineId",
"columnName": "line_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "nameKr",
"columnName": "name_kr",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "seq",
"columnName": "seq",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "gcjLon",
"columnName": "gcj_lon",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "gcjLat",
"columnName": "gcj_lat",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "lon",
"columnName": "lon",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "lat",
"columnName": "lat",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "introduction",
"columnName": "introduction",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "isPlayTts",
"columnName": "is_play_tts",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "md5",
"columnName": "md5",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "videoListDB",
"columnName": "videoList",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_site_data_table_site_id",
"unique": false,
"columnNames": [
"site_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_site_data_table_site_id` ON `${TABLE_NAME}` (`site_id`)"
},
{
"name": "index_site_data_table_line_id",
"unique": false,
"columnNames": [
"line_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_site_data_table_line_id` ON `${TABLE_NAME}` (`line_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "task_data_table",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task_id` INTEGER, `line_id` INTEGER, `task_data` INTEGER, `task_start_time` INTEGER, `start_time` INTEGER, `end_time` INTEGER, `task_get_time` INTEGER NOT NULL, `status` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "taskId",
"columnName": "task_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lineId",
"columnName": "line_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "taskDate",
"columnName": "task_data",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "taskStartTime",
"columnName": "task_start_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "startTime",
"columnName": "start_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "endtime",
"columnName": "end_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "taskgetTime",
"columnName": "task_get_time",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "status",
"columnName": "status",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_task_data_table_task_id",
"unique": false,
"columnNames": [
"task_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_task_data_table_task_id` ON `${TABLE_NAME}` (`task_id`)"
},
{
"name": "index_task_data_table_line_id",
"unique": false,
"columnNames": [
"line_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_task_data_table_line_id` ON `${TABLE_NAME}` (`line_id`)"
}
],
"foreignKeys": []
},
{
"tableName": "used_task_data_table",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `task_id` INTEGER, `line_id` INTEGER, `site_id` INTEGER, `line_name` TEXT, `name` TEXT, `name_kr` TEXT, `seq` INTEGER, `gcj_lon` REAL, `gcj_lat` REAL, `lon` REAL, `lat` REAL, `driving_status` INTEGER, `leaving` INTEGER, `arrived_time` INTEGER, `leave_time` INTEGER, `introduction` TEXT, `is_play_tts` INTEGER, `event_save_time` INTEGER NOT NULL, `videoList` TEXT)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "taskId",
"columnName": "task_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lineId",
"columnName": "line_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "siteId",
"columnName": "site_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lineName",
"columnName": "line_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "nameKr",
"columnName": "name_kr",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "seq",
"columnName": "seq",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "gcjLon",
"columnName": "gcj_lon",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "gcjLat",
"columnName": "gcj_lat",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "lon",
"columnName": "lon",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "lat",
"columnName": "lat",
"affinity": "REAL",
"notNull": false
},
{
"fieldPath": "drivingStatus",
"columnName": "driving_status",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "leaving",
"columnName": "leaving",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "arrivedTime",
"columnName": "arrived_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "leaveTime",
"columnName": "leave_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "introduction",
"columnName": "introduction",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "isPlayTts",
"columnName": "is_play_tts",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "eventSaveTime",
"columnName": "event_save_time",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "videoList",
"columnName": "videoList",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "event_data_table",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `event_type` TEXT, `lineId` INTEGER, `lineName` TEXT, `task_id` INTEGER, `task_start_time` INTEGER, `business_time` INTEGER, `write_version` INTEGER, `site_id` INTEGER, `seq` INTEGER, `driver_id` INTEGER, `event_save_time` INTEGER NOT NULL, `update_status` INTEGER NOT NULL, `msg_id` TEXT, `update_time` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "eventType",
"columnName": "event_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "lineId",
"columnName": "lineId",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lineName",
"columnName": "lineName",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "taskId",
"columnName": "task_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "taskStartTime",
"columnName": "task_start_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "businessTime",
"columnName": "business_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "writeVersion",
"columnName": "write_version",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "siteId",
"columnName": "site_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "seq",
"columnName": "seq",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "driverId",
"columnName": "driver_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "eventSaveTime",
"columnName": "event_save_time",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "updateStatus",
"columnName": "update_status",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "msgId",
"columnName": "msg_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "upDateTime",
"columnName": "update_time",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_event_data_table_event_save_time",
"unique": false,
"columnNames": [
"event_save_time"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_event_data_table_event_save_time` ON `${TABLE_NAME}` (`event_save_time`)"
}
],
"foreignKeys": []
},
{
"tableName": "writeoff_data_table",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `msg_id` TEXT, `expiry_time` INTEGER, `booking_time` INTEGER, `type` INTEGER, `task_id` INTEGER, `line_id` INTEGER, `site_id` INTEGER, `driver_id` INTEGER, `available_times` INTEGER, `order_no` TEXT, `uid` TEXT, `seq` TEXT, `business_time` INTEGER, `tick_size` INTEGER, `tick_name` TEXT, `event_save_time` INTEGER NOT NULL, `update_status` INTEGER NOT NULL, `update_time` INTEGER)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "msgId",
"columnName": "msg_id",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "expiryTime",
"columnName": "expiry_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "bookingTime",
"columnName": "booking_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "taskId",
"columnName": "task_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "lineId",
"columnName": "line_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "siteId",
"columnName": "site_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "driverId",
"columnName": "driver_id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "availableTimes",
"columnName": "available_times",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "orderNo",
"columnName": "order_no",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "uid",
"columnName": "uid",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "phone",
"columnName": "seq",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "businessTime",
"columnName": "business_time",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "ticketSize",
"columnName": "tick_size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "ticketName",
"columnName": "tick_name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "eventSaveTime",
"columnName": "event_save_time",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "updateStatus",
"columnName": "update_status",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "upDateTime",
"columnName": "update_time",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_writeoff_data_table_event_save_time",
"unique": false,
"columnNames": [
"event_save_time"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_writeoff_data_table_event_save_time` ON `${TABLE_NAME}` (`event_save_time`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '018ed967c5f335de5d39581e033160ed')"
]
}
}

View File

@@ -11,6 +11,7 @@ import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.biz.provider.CommonServiceImpl
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutopilotAnalytics
import com.mogo.och.common.module.manager.scnner.ScannerClientManager
import com.mogo.och.weaknet.repository.db.repository.EventDb
import com.mogo.och.weaknet.repository.db.repository.LineDb
import com.mogo.och.weaknet.repository.db.repository.TaskDb
@@ -18,6 +19,7 @@ import com.mogo.och.weaknet.repository.db.repository.TaskSiteDb
import com.mogo.och.weaknet.ui.fragment.ShuttleFragment
import com.mogo.och.weaknet.model.LineModel
import com.mogo.och.weaknet.repository.RepositoryManager
import com.mogo.och.weaknet.repository.db.repository.WriteOffDb
import com.mogo.och.weaknet.ui.bizswitch.SwitchBizView
import com.mogo.och.weaknet.ui.qr.QrOpenView
import com.mogo.och.weaknet.util.BusAnalyticsManager
@@ -40,6 +42,7 @@ class ShuttleDriverProvider : CommonServiceImpl() {
TaskDb.deleteObsoleteData()
TaskSiteDb.deleteObsoleteData()
EventDb.deleteObsoleteData()
WriteOffDb.deleteObsoleteData()
}
}
@@ -48,7 +51,8 @@ class ShuttleDriverProvider : CommonServiceImpl() {
busFragment = ShuttleFragment()
}
OchAutopilotAnalytics.ochEventKey = BusAnalyticsManager
LineModel.init();
LineModel.init()
ScannerClientManager.load()
return busFragment!!
}
@@ -56,6 +60,7 @@ class ShuttleDriverProvider : CommonServiceImpl() {
busFragment = null
OchAutopilotAnalytics.ochEventKey = null
LineModel.release()
ScannerClientManager.release()
RepositoryManager.release()
}

View File

@@ -20,7 +20,7 @@ data class WaitUploadLine(var lineName:String ,var lineId:Long,var task:MutableL
}
}
data class WaitUploadTask(val taskStartTime:Long,val taskId:Long){
data class WaitUploadTask(val taskStartTime:Long,val taskId:Long,val waitUploadWriteOff:Int){
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

View File

@@ -3,31 +3,45 @@ package com.mogo.och.weaknet.bean.request
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.network.utils.digest.DigestUtils
import com.mogo.och.common.module.biz.login.LoginStatusManager
import com.mogo.och.common.module.manager.device.checkvin.CheckVinManager
import com.mogo.och.weaknet.repository.db.bean.EventDataBean
import com.mogo.och.weaknet.repository.db.bean.WriteOffDataBean
/**
* 上报事件
*/
data class ShuttleEventRequest(val requestId: String, val sn: String, val businessType: Int,val eventList:MutableList<Event>){
data class ShuttleEventRequest(val requestId: String, val sn: String,val vin:String ,val businessType: Int,val eventList:MutableList<Event>){
companion object{
fun transformDb2Net(waitUpdateEvent: List<EventDataBean>): ShuttleEventRequest {
fun transformDb2Net(
waitUpdateEvent: List<EventDataBean>?,
waitUpdateWriteOffEvent: List<WriteOffDataBean>?
): ShuttleEventRequest {
val businessTypeShuttle = LoginStatusManager.getLoginInfo()?.businessType?:11
val md5Hex = DigestUtils.md5Hex(waitUpdateEvent.toString())
val eventList4Request = mutableListOf<Event>()
var tempEvent: Event?=null
waitUpdateEvent.forEach {
waitUpdateEvent?.forEach {
tempEvent = Event(it.eventType,
EventData(it.taskId,it.businessTime,it.writeVersion,it.siteId,it.seq,it.driverId,it.msgId)
)
eventList4Request.add(tempEvent!!)
}
return ShuttleEventRequest(md5Hex, SharedPrefsMgr.getInstance().sn,
waitUpdateWriteOffEvent?.forEach {
tempEvent = Event("WriteOff",
WriteOffEventData(it.msgId,it.taskId,it.siteId,it.driverId,it.orderNo,it.businessTime,it.businessTime)
)
eventList4Request.add(tempEvent!!)
}
val md5Hex = DigestUtils.md5Hex(eventList4Request.toString())
return ShuttleEventRequest(md5Hex, SharedPrefsMgr.getInstance().sn, CheckVinManager.getVin(),
businessTypeShuttle,eventList4Request)
}
}
}
data class Event(var eventType: String?,val eventData: EventData)
data class Event(var eventType: String?,val eventData: EventDataBase)
open class EventDataBase(val msgtype:String)
data class EventData(
var taskId: Long?,
@@ -37,4 +51,14 @@ data class EventData(
var seq: Int?,
var driverId:Long?,
var msgId:String?
)
):EventDataBase(msgtype = "lineEvent")
data class WriteOffEventData(
var msgId: String?,
var taskId: Long?,
var siteId: Long?,
var driverId: Long?,
var orderNo: String?,
var businessTime: Long?,
var writeVersion: Long?,
):EventDataBase(msgtype = "writeoffEvent")

View File

@@ -9,39 +9,36 @@ import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest
import com.mogo.och.weaknet.bean.WaitUploadLine
import com.mogo.och.weaknet.bean.WaitUploadTask
import com.mogo.och.weaknet.repository.net.weaknet.dali.shuttle.DaliShuttleServiceManager
import com.mogo.och.weaknet.repository.db.bean.EventDataBean
import com.mogo.och.weaknet.repository.db.repository.EventDb
import com.mogo.och.weaknet.repository.RepositoryManager
import com.mogo.och.weaknet.repository.db.repository.SiteDb
import com.mogo.och.weaknet.repository.db.repository.WriteOffDb
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.BehaviorSubject
import java.util.concurrent.atomic.AtomicBoolean
object EventModel : EventDb.EventCallback {
object EventModel {
private val isUpdating by lazy { AtomicBoolean(false) }
private val createDefault = BehaviorSubject.createDefault(isUpdating.get())
fun load(){
if (RepositoryManager.supportDb()) {
EventDb.eventCallback = this
if (RepositoryManager.supportDb() || RepositoryManager.supportWriteOffDb()) {
BizLoopManager.postDelayed(loopUpdateInfo,2*60*1000)
}
}
fun release(){
if (RepositoryManager.supportDb()) {
EventDb.eventCallback = null
}
BizLoopManager.removeCallback(loopUpdateInfo)
}
private val loopUpdateInfo = Runnable { updateEvent() }
override fun notifySyn() {
fun notifySyn() {
BizLoopManager.removeCallback(loopUpdateInfo)
updateEvent()
checkDbData()
@@ -62,8 +59,9 @@ object EventModel : EventDb.EventCallback {
isUpdating.set(true)
createDefault.onNext(isUpdating.get())
ThreadUtils.getSinglePool().submit {
val waitUpdateEvent = EventDb.queryWaitUpdateEvent()
if(waitUpdateEvent.isNullOrEmpty()){
val waitUpdateLineEvent = EventDb.queryWaitUpdateEvent()
val waitUpdateWriteOffEvent = WriteOffDb.queryWaitUpdateEvent()
if (waitUpdateLineEvent.isNullOrEmpty() && waitUpdateWriteOffEvent.isNullOrEmpty()) {
OchChainLogManager.writeChainLogDb("上报event","没有数据需要上报${Thread.currentThread().name}")
isUpdating.set(false)
createDefault.onNext(isUpdating.get())
@@ -71,15 +69,27 @@ object EventModel : EventDb.EventCallback {
return@submit
}
OchChainLogManager.writeChainLogDb("上报event","开始上报:${Thread.currentThread().name}")
val transformDb2Net = ShuttleEventRequest.transformDb2Net(waitUpdateEvent)
val transformDb2Net = ShuttleEventRequest.transformDb2Net(waitUpdateLineEvent,waitUpdateWriteOffEvent)
RepositoryManager.reportCabinEvent(AbsMogoApplication.getApp()!!,transformDb2Net,object :OchCommonServiceCallback<BaseData?>{
override fun onSuccess(data: BaseData?) {
waitUpdateEvent.forEach {
it.updateStatus = EventDataBean.updated
it.upDateTime = System.currentTimeMillis()
}
OchChainLogManager.writeChainLogDb("上报event成功","$transformDb2Net ${Thread.currentThread().name}")
EventDb.saveUpdateSuccess(waitUpdateEvent)
waitUpdateLineEvent?.let {lineEvents->
lineEvents.forEach {
it.updateStatus = EventDataBean.updated
it.upDateTime = System.currentTimeMillis()
}
EventDb.saveUpdateSuccess(lineEvents)
}
waitUpdateWriteOffEvent?.let {writeOffEvents->
writeOffEvents.forEach {
it.updateStatus = EventDataBean.updated
it.upDateTime = System.currentTimeMillis()
}
WriteOffDb.saveUpdateSuccess(writeOffEvents)
}
isUpdating.set(false)
createDefault.onNext(isUpdating.get())
val queryWaitUpdateEventCount = EventDb.queryWaitUpdateEventCount()
@@ -110,26 +120,7 @@ object EventModel : EventDb.EventCallback {
}
fun queryWaitUploadInfo(): Observable<MutableList<WaitUploadLine>>? {
return EventDb.queryWaitUploadData()
?.flatMap { waitUploadList->
val result = mutableListOf<WaitUploadLine>()
waitUploadList.forEach { wait->
if(wait.lineId!=null&&wait.lineName!=null&&wait.taskId!=null&&wait.taskStartTime!=null) {
val tempTask = WaitUploadTask(wait.taskStartTime!!,wait.taskId!!)
val tempLine = WaitUploadLine(wait.lineName!!, wait.lineId!!, mutableListOf(tempTask))
val haveSave = result.filter {
it.lineId==tempLine.lineId
}
if(haveSave.isEmpty()){
result.add(tempLine)
}else{
haveSave.first().task.add(tempTask)
}
}
}
Observable.just(result)
}?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
return RepositoryManager.queryWaitUploadData()
}
fun getUploadTaskObservable():BehaviorSubject<Boolean>{

View File

@@ -5,7 +5,11 @@ import android.content.Context
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.map.SiteMarkerBean
import com.mogo.eagle.core.data.och.OchInfo
import com.mogo.eagle.core.data.v2x.Point
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.function.call.datacenter.CallerDataCenterBizListener
import com.mogo.eagle.core.network.utils.digest.DigestUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
@@ -146,7 +150,9 @@ object LineModel {
"数据发生变化",
"接口信息发生变化 $lastChangeMd5 new md5${currentRequest}"
)
val startTime = System.currentTimeMillis()
CarExecutableTaskResponse.save2Db(data)
CallerLogger.d(TAG,"更新数据耗时${System.currentTimeMillis()-startTime}___${Thread.currentThread().name}")
RxUtils.createSubscribe(800) {
// 等待写入数据库
mBusLinesCallbackMap.forEach { callback ->
@@ -298,75 +304,85 @@ object LineModel {
}
fun endTask() {
currentTask?.let { task ->
RepositoryManager.endTask(task.taskId?:0L)
?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(object : Observer<Boolean> {
override fun onSubscribe(d: Disposable) {
startTaskDisposable
d(TAG, "endTask onSubscribe")
}
override fun onError(e: Throwable) {
d(TAG, "endTask onError${e.printStackTrace()}")
if (e is DataException) {
currentTask?.taskId?.let { taskId ->
if (RepositoryManager.canCanEndTask(taskId)) {
RepositoryManager.endTask(taskId)
?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(object : Observer<Boolean> {
override fun onSubscribe(d: Disposable) {
startTaskDisposable
d(TAG, "endTask onSubscribe")
}
if (RepositoryManager.supportDb()) {
isGoingToNextStation = false
ThirdDeviceData.endTask()
ThirdDeviceData.sendTaskDetailsToClients()
ShuttleVoiceManager.endOrderBus()
// 取消自驾
CallerAutoPilotControlManager.cancelAutoPilot()
currentTask = null
LineManager.setLineInfo(null)
LineManager.setStartAndEndStation(null,null)
stationList = mutableListOf()
startStationIndex = 0
mBusLinesCallbackMap.forEach {
it.value.onCompleteTask()
override fun onError(e: Throwable) {
d(TAG, "endTask onError${e.printStackTrace()}")
if (e is DataException) {
}
val changeInfo = "taskId:${currentTask?.taskId}--lineInfo:${LineManager.lineInfos}"
OchChainLogManager.writeChainLog("结束任务", changeInfo)
}else{
ToastUtils.showShort("结束任务失败请稍后再试")
mBusLinesCallbackMap.forEach {
it.value.onCompleteTaskFail()
if (RepositoryManager.supportDb()) {
isGoingToNextStation = false
ThirdDeviceData.endTask()
ThirdDeviceData.sendTaskDetailsToClients()
ShuttleVoiceManager.endOrderBus()
// 取消自驾
CallerAutoPilotControlManager.cancelAutoPilot()
currentTask = null
LineManager.setLineInfo(null)
LineManager.setStartAndEndStation(null, null)
LineModel.callEyeMap(true)
stationList = mutableListOf()
startStationIndex = 0
mBusLinesCallbackMap.forEach {
it.value.onCompleteTask()
}
val changeInfo =
"taskId:${currentTask?.taskId}--lineInfo:${LineManager.lineInfos}"
OchChainLogManager.writeChainLog("结束任务", changeInfo)
} else {
ToastUtils.showShort("结束任务失败请稍后再试")
mBusLinesCallbackMap.forEach {
it.value.onCompleteTaskFail()
}
}
}
}
override fun onComplete() {
d(TAG, "endTask onComplete")
}
override fun onNext(data: Boolean) {
d(TAG, "endTask onNext ${data}")
if (data) {
isGoingToNextStation = false
ThirdDeviceData.endTask()
ThirdDeviceData.sendTaskDetailsToClients()
ShuttleVoiceManager.endOrderBus()
// 取消自驾
CallerAutoPilotControlManager.cancelAutoPilot()
currentTask = null
LineManager.setLineInfo(null)
LineManager.setStartAndEndStation(null,null)
stationList = mutableListOf()
startStationIndex = 0
mBusLinesCallbackMap.forEach {
it.value.onCompleteTask()
}
val changeInfo = "taskId:${currentTask?.taskId}--lineInfo:${LineManager.lineInfos}"
OchChainLogManager.writeChainLog("结束任务", changeInfo)
override fun onComplete() {
d(TAG, "endTask onComplete")
}
onComplete()
}
})
override fun onNext(data: Boolean) {
d(TAG, "endTask onNext ${data}")
if (data) {
isGoingToNextStation = false
ThirdDeviceData.endTask()
ThirdDeviceData.sendTaskDetailsToClients()
ShuttleVoiceManager.endOrderBus()
// 取消自驾
CallerAutoPilotControlManager.cancelAutoPilot()
currentTask = null
LineManager.setLineInfo(null)
LineManager.setStartAndEndStation(null, null)
LineModel.callEyeMap(true)
stationList = mutableListOf()
startStationIndex = 0
mBusLinesCallbackMap.forEach {
it.value.onCompleteTask()
}
val changeInfo =
"taskId:${currentTask?.taskId}--lineInfo:${LineManager.lineInfos}"
OchChainLogManager.writeChainLog("结束任务", changeInfo)
}
onComplete()
}
})
}else{
ToastUtils.showShort("有待上传核销数据请稍等")
// 主动上报一次
EventModel.notifySyn()
}
}
}
@@ -394,4 +410,45 @@ object LineModel {
}
}
fun callEyeMap(isClear:Boolean){
if(isClear) {
val ochInfo = OchInfo(1, mutableListOf())
ochInfo.siteMarkerList = mutableListOf()
CallerDataCenterBizListener.invokeOchInfo(ochInfo)
}else{
val siteList = mutableListOf<SiteMarkerBean>()
var temp: SiteMarkerBean?=null
stationList?.let {
it.forEachIndexed { index, busStationBean ->
if(index==0){
temp =SiteMarkerBean(Point(busStationBean.gcjLon,busStationBean.gcjLat),R.drawable.bus_station_start,0.5f,0.87f)
}else if(index==it.size-1){
temp =SiteMarkerBean(Point(busStationBean.gcjLon,busStationBean.gcjLat),R.drawable.bus_station_end,0.5f,0.87f)
}else{
if(busStationBean.drivingStatus==1){
temp =SiteMarkerBean(Point(busStationBean.gcjLon,busStationBean.gcjLat),R.drawable.bus_station_pass,0.5f,0.478f)
}else if (busStationBean.drivingStatus==3){
temp =SiteMarkerBean(Point(busStationBean.gcjLon,busStationBean.gcjLat),R.drawable.bus_station_notarrive,0.5f,0.478f)
}else if (busStationBean.drivingStatus==2){
if(busStationBean.isLeaving){
temp =SiteMarkerBean(Point(busStationBean.gcjLon,busStationBean.gcjLat),R.drawable.bus_station_pass,0.5f,0.478f)
}else{
temp =SiteMarkerBean(Point(busStationBean.gcjLon,busStationBean.gcjLat),R.drawable.bus_station_notarrive,0.5f,0.478f)
}
}
}
temp?.let {temp->
siteList.add(temp)
}
}
}
val (start, end) = LineManager.getStations()
if(start!=null&&end!=null){
val ochInfo = OchInfo(1, mutableListOf(start.toMogoLocation(),end.toMogoLocation()))
ochInfo.siteMarkerList = siteList
CallerDataCenterBizListener.invokeOchInfo(ochInfo)
}
}
}
}

View File

@@ -416,6 +416,7 @@ object OrderModel {
if(LineModel.startStationIndex +1< it.size){
val endStation = it[LineModel.startStationIndex +1]
LineManager.setStartAndEndStation(startStation,endStation)
LineModel.callEyeMap(false)
}
}
LineModel.arrivedStationSuccess()
@@ -431,6 +432,7 @@ object OrderModel {
if(LineModel.startStationIndex +1< it.size){
val endStation = it[LineModel.startStationIndex +1]
LineManager.setStartAndEndStation(startStation,endStation)
LineModel.callEyeMap(false)
}
}
LineModel.arrivedStationSuccess()

View File

@@ -2,15 +2,16 @@ package com.mogo.och.weaknet.model
import com.elegant.network.utils.GsonUtil
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.env.ProjectUtils
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
import com.mogo.eagle.core.data.msgbox.MsgBoxType
import com.mogo.eagle.core.data.msgbox.V2XMsg
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxManager.saveMsgBox
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.i
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS_P
import com.mogo.och.common.module.manager.autopilot.line.LineManager
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import com.mogo.och.common.module.manager.loop.BizLoopManager
@@ -20,19 +21,24 @@ import com.mogo.och.common.module.manager.socket.cloud.OCHSocketMessageManager
import com.mogo.och.common.module.manager.socket.lan.ILanMessageListener
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDevicesMsg
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffMsg
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDetialMsg
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffResultMsg
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.bean.WriteOffPassenger
import com.mogo.och.weaknet.repository.RepositoryManager
import com.mogo.och.weaknet.repository.exception.DataException
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse
import com.mogo.och.weaknet.util.ShuttleVoiceManager
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import io.reactivex.ObservableOnSubscribe
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
object TicketModel : IOchOnMessageListener<WriteOffPassenger>{
object TicketModel {
private const val TAG = "TicketModel"
@@ -40,89 +46,106 @@ object TicketModel : IOchOnMessageListener<WriteOffPassenger>{
private var emitterMain: ObservableEmitter<Pair<Int,Int>>?=null
private val observable = Observable.create(ObservableOnSubscribe<Pair<Int,Int>> { emitter -> emitterMain = emitter })
private val writeOffMsg = object : ILanMessageListener<WriteOffMsg> {
override fun targetLan(): Class<WriteOffMsg> = WriteOffMsg::class.java
override fun onLanMsgReceived(obj: WriteOffMsg?) = receiveWrteOffInfo(obj)
/**
* 接受乘客端扫码数据进行云端和本地核销
*/
private val writeOffDetialMsg = object : ILanMessageListener<WriteOffDetialMsg> {
override fun targetLan(): Class<WriteOffDetialMsg> = WriteOffDetialMsg::class.java
override fun onLanMsgReceived(obj: WriteOffDetialMsg?) = receiveWrteOffDefailtInfo(obj)
}
private val writeOfDevicefMsg = object : ILanMessageListener<WriteOffDevicesMsg> {
override fun targetLan(): Class<WriteOffDevicesMsg> = WriteOffDevicesMsg::class.java
override fun onLanMsgReceived(obj: WriteOffDevicesMsg?) = receiveWrteOffDevicesInfo(obj)
/**
* 接受乘客端扫码数据进行云端和本地核销
*/
private val writeOffOnlineMsg = object : IOchOnMessageListener<WriteOffPassenger> {
override fun target(): Class<WriteOffPassenger> {
return WriteOffPassenger::class.java
}
override fun onMsgReceived(passenger: WriteOffPassenger?) {
//进行播报
i(SceneConstant.M_BUS + TAG, "后台socket 核验:passenger = " + GsonUtil.jsonFromObject(passenger))
if(passenger==null||passenger.passengerSize==0){
return
}
RepositoryManager.saveWriteOff4Socket(passenger)
writeOffSuccess(
passenger.passengerSize,
passenger.phone ?: "",
passenger.ticketName?:"",
0
)
}
}
private val observable = Observable.create(ObservableOnSubscribe<Pair<Int,Int>> { emitter -> emitterMain = emitter })
fun getWriteOffCountObservable():Observable<Pair<Int,Int>>{
return observable
}
fun load(){
// 3s轮训站点核销人数
if(RepositoryManager.supportWriteOff()) {
// 3s轮训站点核销人数 人数本地核销 直接计算就好
if (RepositoryManager.supportWriteOff() && RepositoryManager.supportWriteOffDb()) {
BizLoopManager.setLoopFunction(
SELECTWRITEOFFCOUNT,
LoopInfo(3, TicketModel::selectWriteOffCount, scheduler = Schedulers.io())
)
}
// 核销信息
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_WRITEOFF_INFO.type,writeOffMsg)
// 核销设备信息
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_WRITEOFF_DEVICES_INFO.type,writeOfDevicefMsg)
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_WRITEOFF_INFO_DETAIL.type,writeOffDetialMsg)
//监听核销乘客
OCHSocketMessageManager.registerSocketMessageListener(OCHSocketMessageManager.msgWriteOffPassengerType, this)
OCHSocketMessageManager.registerSocketMessageListener(OCHSocketMessageManager.msgWriteOffPassengerType, writeOffOnlineMsg)
}
fun release(){
if(RepositoryManager.supportWriteOff()) {
BizLoopManager.removeLoopFunction(SELECTWRITEOFFCOUNT)
}
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_WRITEOFF_INFO.type,writeOffMsg)
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_WRITEOFF_DEVICES_INFO.type,writeOfDevicefMsg)
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_WRITEOFF_INFO_DETAIL.type,writeOffDetialMsg)
OCHSocketMessageManager.releaseSocketMessageListener(OCHSocketMessageManager.msgWriteOffPassengerType)
}
override fun target(): Class<WriteOffPassenger> {
return WriteOffPassenger::class.java
}
// 收到服务器的核验信息
override fun onMsgReceived(passenger: WriteOffPassenger?) {
//进行播报
i(SceneConstant.M_BUS + TAG, "后台socket 核验:passenger = " + GsonUtil.jsonFromObject(passenger))
if(passenger==null||passenger.passengerSize==0){
return
}
playPassenger(
passenger.passengerSize,
passenger.phone ?: "",
passenger.ticketName?:"",
passenger.orderNo?:""
)
selectWriteOffCount()
}
private fun selectWriteOffCount(){
LineManager.getStations().first?.let { firstStation->
LineModel.currentTask?.let { currentTask->
RepositoryManager.queryWriteoffCount(
val queryWriteoffCount = RepositoryManager.queryWriteoffCount(
AbsMogoApplication.getApp(),
currentTask.taskId?:0L,
firstStation.siteId.toLong(),
object : OchCommonServiceCallback<WriteOffCountResponse> {
override fun onSuccess(data: WriteOffCountResponse?) {
data?.let {
val count = if(it.data==null){
0
}else{
it.data
}
emitterMain?.onNext(Pair<Int,Int>(firstStation.siteId,count))
d(SceneConstant.M_BUS + TAG, "${firstStation.name}核销人数:${count}")
OchChainLogManager.writeChainLog("核销人数","任务:${currentTask.taskId} zhan'dian")
currentTask.taskId ?: 0L,
firstStation.siteId.toLong()
)
if(queryWriteoffCount!=null){
queryWriteoffCount.subscribe(
object : Observer<Int> {
override fun onSubscribe(d: Disposable) {
}
}
override fun onFail(code: Int, msg: String?) {
override fun onError(e: Throwable) {
}
override fun onComplete() {
}
override fun onNext(count: Int) {
emitterMain?.onNext(Pair<Int, Int>(firstStation.siteId, count))
d(
SceneConstant.M_BUS + TAG,
"${firstStation.name}核销人数:${count}"
)
OchChainLogManager.writeChainLog(
"核销人数",
"任务:${currentTask.taskId} zhan'dian"
)
}
}
})
return
)
return
}
}
}
@@ -130,83 +153,129 @@ object TicketModel : IOchOnMessageListener<WriteOffPassenger>{
d(SceneConstant.M_BUS + TAG, "线路或者站点未空")
}
fun getWriteOffCountObservable():Observable<Pair<Int,Int>>{
return observable
}
private fun receiveWrteOffInfo(writeOffMsg: WriteOffMsg?) {
if(writeOffMsg!=null) {
if (writeOffMsg.isScuccess != null) {
if (writeOffMsg.isScuccess == true) { // 核验成功
if(writeOffMsg.ticketSize==null||writeOffMsg.ticketSize==0){
return
}
} else { // 核验失败
ShuttleVoiceManager.writeOffFaile(writeOffMsg.failedReason ?: "")
var tempPhone = writeOffMsg.phone
tempPhone?.let {
if (it.length > 8) {
//截取电话号码前三位
val phoneNumPre = it.substring(0, 3)
//截取电话号码后四位
val phoneNumFix = it.substring(7)
tempPhone = "$phoneNumPre****$phoneNumFix"
private fun receiveWrteOffDefailtInfo(writeOffDetialMsg: WriteOffDetialMsg?) {
writeOffDetialMsg?.let {
if (writeOffDetialMsg.code != 0) {
sendMessage2Driver(
writeOffDetialMsg.msg ?: "",
writeOffDetialMsg.phone ?: "",
writeOffDetialMsg.code
)
} else {
RepositoryManager.writeOff(writeOffDetialMsg)
?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(object : Observer<PassengerWriteOffResponse.Result?> {
override fun onSubscribe(d: Disposable) {
d(TAG, "receiveWrteOffDefailtInfo onSubscribe")
}
}
val reaseonAndPhone = if(tempPhone.isNullOrEmpty()) {
"${writeOffMsg.failedReason}"
}else{
"${writeOffMsg.failedReason};乘客:${tempPhone}"
}
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X, V2XMsg(
EventTypeEnumNew.TYPE_ABNORMAL_VERIFICATION.poiType,
reaseonAndPhone,
EventTypeEnumNew.TYPE_ABNORMAL_VERIFICATION.tts,
""
override fun onError(e: Throwable) {
d(TAG, "receiveWrteOffDefailtInfo onError${e.printStackTrace()}")
if (e is DataException) {
CallerLogger.d(M_BUS_P + TAG, "核销失败 ${e.code}-----${e.msg}")
parseData(e.code,e.msg?:"",writeOffDetialMsg.phone?:"")
}
}
override fun onComplete() {
d(TAG, "receiveWrteOffDefailtInfo onComplete")
}
override fun onNext(data: PassengerWriteOffResponse.Result) {
d(TAG, "queryBusLines onNext ${data}")
writeOffSuccess(
data.ticketSize ?: 0,
data.phone ?: "",
data.ticketName ?: "",
data.businessTime?:System.currentTimeMillis(),
)
)
)
}
})
}
}
}
/**
* 解析错误原因
*/
private fun parseData(code:Int,msg:String,phone: String){
when (code) {
6002 -> sendMessage2Driver("同一订单核销间隔时间需大于2分钟", phone,6002)
1009 -> sendMessage2Driver("车票所选乘车日期非今日", phone,1009)
1005 -> sendMessage2Driver("车辆未登录、或没有任务", phone,1005)
1006 -> sendMessage2Driver("车票路线信息与当前车辆执行任务的路线信息不符合", phone,1006)
1008 -> sendMessage2Driver("车票剩余可用次数为0", phone,99)
6001 -> sendMessage2Driver("二维码已过期", phone,6001)
1012 -> sendMessage2Driver("当前用户下单路线非当前的车辆所属公司", phone,1012)
else -> {
try {
val tempcode=msg.toInt()
parseData(tempcode,msg,phone)
}catch (e:Exception){
sendMessage2Driver(msg, phone,3002)
}
}
}
}
private fun receiveWrteOffDevicesInfo(writeOffMsg: WriteOffDevicesMsg?) {
writeOffMsg?.let {
if (writeOffMsg.isConnectScanner != null) {
val reason = if (writeOffMsg.reason == null) "" else writeOffMsg.reason!!
if (writeOffMsg.isConnectScanner==true) { // 链接成功
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X,
V2XMsg(
EventTypeEnumNew.TYPE_DEVICE_STATUS_NORMAL.poiType,
reason,
EventTypeEnumNew.TYPE_DEVICE_STATUS_NORMAL.tts,
""
)
)
)
} else { // 核验失败
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X,
V2XMsg(
EventTypeEnumNew.TYPE_DEVICE_STATUS_ABNORMAL.poiType,
reason,
EventTypeEnumNew.TYPE_DEVICE_STATUS_ABNORMAL.tts,
""
)
)
)
}
/**
* 验票失败
* code 3001 乘客屏参数校验失败
* code 3002 司机屏校验失败原因未知
* code 99 小程序缓存丢失Android 缓存存在
*/
private fun sendMessage2Driver(message:String,phone:String,code:Int){
// 发送乘客屏 通过蓝牙告知小程序
LanSocketManager.sendMsgToClient(WriteOffResultMsg(code = code, phone = phone, System.currentTimeMillis()))
val failedReason = "验票失败,${message}"
ShuttleVoiceManager.writeOffFaile(failedReason)
var tempPhone = phone
tempPhone.let {
if (it.length > 8) {
//截取电话号码前三位
val phoneNumPre = it.substring(0, 3)
//截取电话号码后四位
val phoneNumFix = it.substring(7)
tempPhone = "$phoneNumPre****$phoneNumFix"
}
}
val reaseonAndPhone = if(tempPhone.isNullOrEmpty()) {
failedReason
}else{
"${failedReason};乘客:${tempPhone}"
}
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X, V2XMsg(
EventTypeEnumNew.TYPE_ABNORMAL_VERIFICATION.poiType,
reaseonAndPhone,
EventTypeEnumNew.TYPE_ABNORMAL_VERIFICATION.tts,
""
)
)
)
}
private fun playPassenger(ticketSize: Int,phone:String,ticketName:String,orderNo:String) {
/**
* 验票成功
* 1、本地核销
* 2、云端核销
*/
private fun writeOffSuccess(ticketSize: Int, phone:String, ticketName:String,businessTime:Long) {
// 发送乘客屏 通过蓝牙告知小程序 为0时是 安全员小程序核销的
if(businessTime>0) {
LanSocketManager.sendMsgToClient(
WriteOffResultMsg(
code = 0,// 00成功
phone = phone,
businessTime = businessTime
)
)
}
BizLoopManager.runInIoThread { selectWriteOffCount() }
ShuttleVoiceManager.writeOffCount(ticketSize)

View File

@@ -7,22 +7,30 @@ import com.mogo.eagle.core.data.BaseData
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDetialMsg
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.weaknet.bean.WaitUploadLine
import com.mogo.och.weaknet.bean.WriteOffPassenger
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.repository.db.MyDataBase
import com.mogo.och.weaknet.repository.db.bean.LineDataBean
import com.mogo.och.weaknet.repository.db.bean.TaskDataBean
import com.mogo.och.weaknet.repository.db.repository.EventDb
import com.mogo.och.weaknet.repository.impl.NormalRepository
import com.mogo.och.weaknet.repository.impl.WeaknetRepository
import com.mogo.och.weaknet.repository.line.ILineRepository
import com.mogo.och.weaknet.repository.line.impl.NormalRepository
import com.mogo.och.weaknet.repository.line.impl.WeaknetRepository
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse
import com.mogo.och.weaknet.repository.writeoff.IWriteOffRepository
import com.mogo.och.weaknet.repository.writeoff.impl.WriteOffCacheRepository
import com.mogo.och.weaknet.repository.writeoff.impl.WriteOffNormallRepository
import io.reactivex.Observable
object RepositoryManager {
private val TAG = "RepositoryManager"
private var repository: IRepository?=null
private var lineRepository: ILineRepository?=null
get() {
if(field==null){
when (ProjectUtils.getProjectType()) {
@@ -59,45 +67,69 @@ object RepositoryManager {
return field
}
private var writeOffRepository: IWriteOffRepository?=null
get() {
if(field==null){
when (ProjectUtils.getProjectType()) {
Project.SAAS -> {
if(AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
field = WriteOffCacheRepository()
CallerLogger.d(TAG,"saas shuttle 核销缓存")
}else if(AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
field = WriteOffCacheRepository()
CallerLogger.d(TAG,"saas bus 核销缓存")
}
}
Project.DALI -> {
if(AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
field = WriteOffNormallRepository()
CallerLogger.d(TAG,"dali shuttle 不支持核销缓存")
}else if(AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
field = WriteOffNormallRepository()
CallerLogger.d(TAG,"dali bus 不支持核销缓存")
}
}
else->{}
}
}
return field
}
fun release(){
closeDb()
}
fun loadCurrentTaskInfo():Observable<Boolean>?{
return repository?.loadCurrentTaskInfo()
return lineRepository?.loadCurrentTaskInfo()
}
fun queryCanUseLine() : Observable<List<LineDataBean>?>? {
return repository?.queryCanUseLine()
return lineRepository?.queryCanUseLine()
}
fun queryCanUserTask(lineId: Long): Observable<List<TaskDataBean>?>? {
return repository?.queryCanUserTask(lineId)
return lineRepository?.queryCanUserTask(lineId)
}
fun startTask(taskId:Long,lineId:Long,taskTime:Long,lineName:String): Observable<Boolean>? {
return repository?.startTask(taskId,lineId,taskTime,lineName)
return lineRepository?.startTask(taskId,lineId,taskTime,lineName)
}
fun leaveStation(seq: Int, siteId: Long, taskId: Long, lineId: Long, taskStartTime:Long
): Observable<Boolean>?{
return repository?.leaveStation(seq,siteId,taskId,lineId,taskStartTime)
return lineRepository?.leaveStation(seq,siteId,taskId,lineId,taskStartTime)
}
fun arriveStation(seq: Int, siteId: Long, taskId: Long): Observable<Boolean>?{
return repository?.arriveStation(seq,siteId,taskId)
return lineRepository?.arriveStation(seq,siteId,taskId)
}
fun endTask(taskId: Long): Observable<Boolean>?{
return repository?.endTask(taskId)
}
fun queryWriteoffCount(context: Context, taskId: Long, siteId: Long, callback: OchCommonServiceCallback<WriteOffCountResponse>?){
repository?.queryWriteoffCount(context,taskId,siteId,callback)
return lineRepository?.endTask(taskId)
}
fun haveRunningTask():Boolean{
return repository?.haveRunningTask()?:false
return lineRepository?.haveRunningTask()?:false
}
@@ -123,12 +155,18 @@ object RepositoryManager {
}
return false
}
fun supportWriteOffDb():Boolean{
if(supportWriteOff()){
return ProjectUtils.isSaas()
}
return false
}
fun queryCarExecutableTaskList(
ochCommonServiceCallback: OchCommonServiceCallback<CarExecutableTaskResponse>
) {
if (repository is WeaknetRepository) {
repository?.queryCarExecutableTaskList(ochCommonServiceCallback)
if (lineRepository is WeaknetRepository) {
lineRepository?.queryCarExecutableTaskList(ochCommonServiceCallback)
}
}
@@ -137,8 +175,34 @@ object RepositoryManager {
data: ShuttleEventRequest?,
callback: OchCommonServiceCallback<BaseData?>?
){
if (repository is WeaknetRepository) {
repository?.reportCabinEvent(context,data,callback)
if (lineRepository is WeaknetRepository) {
lineRepository?.reportCabinEvent(context,data,callback)
}
}
fun queryWriteoffCount(context: Context, taskId: Long, siteId: Long): Observable<Int>? {
return writeOffRepository?.queryWriteoffCount(context,taskId,siteId)
}
fun writeOff(writeOffDetialMsg: WriteOffDetialMsg): Observable<PassengerWriteOffResponse.Result>? {
return writeOffRepository?.writeOffEvent(writeOffDetialMsg)
}
fun queryWaitUploadData(): Observable<MutableList<WaitUploadLine>>? {
return writeOffRepository?.queryWaitUploadData()
}
fun canCanEndTask(taskId: Long): Boolean {
return writeOffRepository?.canCanEndTask(taskId)?:true
}
/**
* 安全员小程序核销成功的用户计数用
*/
fun saveWriteOff4Socket(passenger: WriteOffPassenger) {
BizLoopManager.runInIoThread{
writeOffRepository?.writeOffEvent4Socket(passenger)
}
}
@@ -148,8 +212,10 @@ object RepositoryManager {
CallerLogger.d(TAG,"关闭数据库")
MyDataBase.instance = null
CallerLogger.d(TAG,"重置数据库")
repository?.release()
repository = null
lineRepository?.release()
lineRepository = null
writeOffRepository?.release()
writeOffRepository = null
CallerLogger.d(TAG,"重置 repository")
}
}

View File

@@ -19,19 +19,21 @@ import com.mogo.och.weaknet.repository.db.bean.LineDataBean
import com.mogo.och.weaknet.repository.db.bean.SiteDataBean
import com.mogo.och.weaknet.repository.db.bean.TaskDataBean
import com.mogo.och.weaknet.repository.db.bean.TaskSiteDataBean
import com.mogo.och.weaknet.repository.db.bean.WriteOffDataBean
import com.mogo.och.weaknet.repository.db.dao.ContrailDataDao
import com.mogo.och.weaknet.repository.db.dao.EventDataDao
import com.mogo.och.weaknet.repository.db.dao.LineDataDao
import com.mogo.och.weaknet.repository.db.dao.SiteDataDao
import com.mogo.och.weaknet.repository.db.dao.TaskDataDao
import com.mogo.och.weaknet.repository.db.dao.TaskSiteDataDao
import com.mogo.och.weaknet.repository.db.dao.WriteOffDataDao
import java.io.File
//注解Database告诉系统这是Room数据库对象
//entities指定该数据库有哪些表多张表就逗号分隔
//version指定数据库版本号升级时需要用到
//数据库继承自RoomDatabase
@Database(entities = [ContrailDataBean::class, LineDataBean::class, SiteDataBean::class, TaskDataBean::class, TaskSiteDataBean::class, EventDataBean::class], version = 4)
@Database(entities = [ContrailDataBean::class, LineDataBean::class, SiteDataBean::class, TaskDataBean::class, TaskSiteDataBean::class, EventDataBean::class, WriteOffDataBean::class], version = 5)
abstract class MyDataBase : RoomDatabase() {
override fun getOpenHelper(): SupportSQLiteOpenHelper {
@@ -58,8 +60,33 @@ abstract class MyDataBase : RoomDatabase() {
abstract val siteDataDao: SiteDataDao?
abstract val taskDataDao: TaskDataDao?
abstract val taskSiteDataDao: TaskSiteDataDao?
abstract val writeOffDataDao: WriteOffDataDao?
companion object {
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE ${EventDataBean.evnetDataTable} ADD COLUMN driver_id INTEGER");
}
}
private val MIGRATION_2_3 = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE ${SiteDataBean.siteDataTable} ADD COLUMN videoList TEXT");
database.execSQL("ALTER TABLE ${TaskSiteDataBean.usedTaskDataTable} ADD COLUMN videoList TEXT");
}
}
private val MIGRATION_3_4 = object : Migration(3, 4) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE ${EventDataBean.evnetDataTable} ADD COLUMN msg_id TEXT")
database.execSQL("ALTER TABLE ${EventDataBean.evnetDataTable} ADD COLUMN update_time INTEGER")
}
}
private val MIGRATION_4_5 = object : Migration(4, 5) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `${WriteOffDataBean.writeoffDataTable}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `msg_id` TEXT, `expiry_time` INTEGER, `booking_time` INTEGER, `type` INTEGER, `task_id` INTEGER, `line_id` INTEGER, `site_id` INTEGER, `driver_id` INTEGER, `remaining_times` INTEGER, `order_no` TEXT, `uid` TEXT, `seq` TEXT, `business_time` INTEGER, `tick_size` INTEGER, `tick_name` TEXT, `event_save_time` INTEGER NOT NULL, `update_status` INTEGER NOT NULL, `update_time` INTEGER)")
}
}
fun getDBName():MyDataBase{
val roomName = when (ProjectUtils.getProjectType()) {
Project.SAAS -> {
@@ -88,11 +115,10 @@ abstract class MyDataBase : RoomDatabase() {
return Room.databaseBuilder(
AbsMogoApplication.getApp()!!.applicationContext, MyDataBase::class.java, ROOT_PATH+roomName
)
.addMigrations(Migration1_2(1,2))
.addMigrations(Migration2_3(2,3))
.addMigrations(Migration3_4(3,4))
.addMigrations(Migration2_4(2,4))
.fallbackToDestructiveMigration()
.addMigrations(MIGRATION_1_2)
.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.addMigrations(MIGRATION_4_5)
.build()
}
val ROOT_PATH = Environment.getExternalStorageDirectory().absolutePath + File.separator + "Mogo" + File.separator + "APP_cache" + File.separator //程序外部存储跟目录
@@ -105,32 +131,4 @@ abstract class MyDataBase : RoomDatabase() {
return field
}
}
class Migration1_2(val startVersion:Int,val endVersion:Int): Migration(startVersion,endVersion) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE ${EventDataBean.evnetDataTable} ADD COLUMN driver_id INTEGER");
}
}
class Migration2_3(val startVersion:Int,val endVersion:Int): Migration(startVersion,endVersion) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE ${SiteDataBean.siteDataTable} ADD COLUMN videoList TEXT");
database.execSQL("ALTER TABLE ${TaskSiteDataBean.usedTaskDataTable} ADD COLUMN videoList TEXT");
}
}
class Migration3_4(val startVersion:Int,val endVersion:Int): Migration(startVersion,endVersion) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE ${EventDataBean.evnetDataTable} ADD COLUMN msg_id TEXT")
database.execSQL("ALTER TABLE ${EventDataBean.evnetDataTable} ADD COLUMN update_time INTEGER")
}
}
class Migration2_4(val startVersion:Int,val endVersion:Int): Migration(startVersion,endVersion) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE ${SiteDataBean.siteDataTable} ADD COLUMN videoList TEXT");
database.execSQL("ALTER TABLE ${TaskSiteDataBean.usedTaskDataTable} ADD COLUMN videoList TEXT");
database.execSQL("ALTER TABLE ${EventDataBean.evnetDataTable} ADD COLUMN msg_id TEXT")
database.execSQL("ALTER TABLE ${EventDataBean.evnetDataTable} ADD COLUMN update_time INTEGER")
}
}
}

View File

@@ -0,0 +1,131 @@
package com.mogo.och.weaknet.repository.db.bean
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
/**
* 上报给服务器端的 选择线路、滑动出发、进站 完成线路的对象
*/
@Entity(tableName = WriteOffDataBean.writeoffDataTable)
data class WriteOffDataBean(
@PrimaryKey(autoGenerate = true) var id: Int = 0,
/**
* 二维码有效时间 时间戳 有效时间1分钟
*/
@ColumnInfo(name = "msg_id", typeAffinity = ColumnInfo.TEXT)
var msgId: String? = null,
/**
* 二维码有效时间 时间戳 有效时间1分钟
*/
@ColumnInfo(name = "expiry_time", typeAffinity = ColumnInfo.INTEGER)
var expiryTime: Long? = null,
/**
* 乘车日期
*/
@ColumnInfo(name = "booking_time", typeAffinity = ColumnInfo.INTEGER)
var bookingTime: Long? = null,
/**
* 校验接驳还是公交 shuttle bus
*/
@ColumnInfo(name = "type", typeAffinity = ColumnInfo.INTEGER)
var type: Int? = null,
/**
* 当前的任务id
*/
@ColumnInfo(name = "task_id", typeAffinity = ColumnInfo.INTEGER)
var taskId: Long? = null,
/**
* 校验线路Id
*/
@ColumnInfo(name = "line_id", typeAffinity = ColumnInfo.INTEGER)
var lineId: Long? = null,
/**
* 校验站点Id
*/
@ColumnInfo(name = "site_id", typeAffinity = ColumnInfo.INTEGER)
var siteId: Long? = null,
/**
* 司机id
*/
@ColumnInfo(name = "driver_id", typeAffinity = ColumnInfo.INTEGER)
var driverId: Long? = null,
/**
* 剩余核销次数>0
*/
@ColumnInfo(name = "available_times", typeAffinity = ColumnInfo.INTEGER)
var availableTimes: Int? = null,
/**
* 订单号
*/
@ColumnInfo(name = "order_no", typeAffinity = ColumnInfo.TEXT)
var orderNo: String? = null,
/**
* uid
*/
@ColumnInfo(name = "uid", typeAffinity = ColumnInfo.TEXT)
var uid: String? = null,
/**
* 用户手机号
*/
@ColumnInfo(name = "seq", typeAffinity = ColumnInfo.TEXT)
var phone: String? = null,
/**
* 业务发生的时间
*/
@ColumnInfo(name = "business_time", typeAffinity = ColumnInfo.INTEGER)
var businessTime: Long? = null,
/**
* 票里人数
*/
@ColumnInfo(name = "tick_size", typeAffinity = ColumnInfo.INTEGER)
var ticketSize: Int? = null,
/**
* 票的类型
*/
@ColumnInfo(name = "tick_name", typeAffinity = ColumnInfo.TEXT)
var ticketName: String? = null,
/**
* 存储此条数据时时间戳
*/
@ColumnInfo(name = "event_save_time", typeAffinity = ColumnInfo.INTEGER, index = true)
val eventSaveTime: Long = System.currentTimeMillis(),
@ColumnInfo(name = "update_status", typeAffinity = ColumnInfo.INTEGER)
var updateStatus:Int = notUpdate,
@ColumnInfo(name = "update_time", typeAffinity = ColumnInfo.INTEGER)
var upDateTime:Long? = 0L,
) {
companion object {
const val writeoffDataTable: String = "writeoff_data_table"
// 没有上传
const val notUpdate = 0
// 上传中
const val updating = 1
// 已上传
const val updated = 2
const val daliXiaoChengXu = "ehsafety"
const val saasXiaoChengXu = "mogogosafety"
}
}

View File

@@ -38,7 +38,7 @@ interface TaskDataDao {
@Query("SELECT * FROM ${TaskDataBean.taskDataTable} WHERE task_get_time > :zeroTime and status = ${TaskDataBean.useing}")
fun queryRunningTaskByStatus(zeroTime:Long = DateTimeUtil.getCurrentDateZero()): List<TaskDataBean>?
@Query("SELECT * FROM ${TaskDataBean.taskDataTable} WHERE task_get_time > :zeroTime and status = ${TaskDataBean.unUse} and line_id = :lineId")
@Query("SELECT * FROM ${TaskDataBean.taskDataTable} WHERE task_get_time > :zeroTime and status = ${TaskDataBean.unUse} and line_id = :lineId order by task_start_time")
fun queryUnuseTask(lineId: Long,zeroTime:Long = DateTimeUtil.getCurrentDateZero()): Observable<List<TaskDataBean>?>
@Query("DELETE FROM ${TaskDataBean.taskDataTable} WHERE task_get_time > :zeroTime and line_id = :lineId")

View File

@@ -0,0 +1,40 @@
package com.mogo.och.weaknet.repository.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.weaknet.repository.db.bean.WriteOffDataBean
@Dao
interface WriteOffDataDao {
//插入数据
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(vararg eventDataBean: WriteOffDataBean)
//删除数据
@Delete
fun delete(vararg eventDataBean: WriteOffDataBean)
// 删除过时数据
@Query("DELETE FROM ${WriteOffDataBean.writeoffDataTable} WHERE event_save_time < :zeroTime")
fun deleteObsoleteData(zeroTime: Long = DateTimeUtil.getCurrentDateZero()):Int
@Query("SELECT * FROM ${WriteOffDataBean.writeoffDataTable} WHERE event_save_time > :zeroTime and order_no = :orderNo order by event_save_time")
fun queryWriteOffByOrderNo(zeroTime: Long = DateTimeUtil.getCurrentDateZero(),orderNo:String): List<WriteOffDataBean>?
@Query("SELECT * FROM ${WriteOffDataBean.writeoffDataTable} WHERE event_save_time > :zeroTime and task_id = :taskId and update_status = ${WriteOffDataBean.notUpdate}")
fun queryWaitWriteOffByTaskId(taskId:Long,zeroTime: Long = DateTimeUtil.getCurrentDateZero()): List<WriteOffDataBean>?
@Query("SELECT * FROM ${WriteOffDataBean.writeoffDataTable} WHERE update_status = ${WriteOffDataBean.notUpdate} LIMIT 10 OFFSET 0")
fun queryWriteOffEventByStatusWithPage():List<WriteOffDataBean>?
@Query("SELECT * FROM ${WriteOffDataBean.writeoffDataTable} WHERE event_save_time > :zeroTime and task_id = :taskId and site_id = :siteId")
fun queryWriteOffByTaskAndSiteId(taskId: Long, siteId: Long,zeroTime: Long = DateTimeUtil.getCurrentDateZero()):List<WriteOffDataBean>?
}

View File

@@ -5,6 +5,7 @@ import com.mogo.och.common.module.manager.cache.OchSPManager
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.weaknet.model.EventModel
import com.mogo.och.weaknet.repository.db.IDbRepository
import com.mogo.och.weaknet.repository.db.MyDataBase
import com.mogo.och.weaknet.repository.db.bean.EventDataBean
@@ -23,7 +24,6 @@ object EventDb: IDbRepository {
return field
}
var eventCallback: EventCallback? = null
override fun release(){
eventDataDao = null
@@ -44,7 +44,7 @@ object EventDb: IDbRepository {
event.msgId = "${OchSPManager.getSn()}_${DateTimeUtil.getCurrentTimeStamp()}"
BizLoopManager.runInIoThread {
eventDataDao?.insert(event)
eventCallback?.notifySyn()
EventModel.notifySyn()
}
}
@@ -70,7 +70,7 @@ object EventDb: IDbRepository {
event.msgId = "${OchSPManager.getSn()}_${DateTimeUtil.getCurrentTimeStamp()}"
BizLoopManager.runInIoThread {
eventDataDao?.insert(event)
eventCallback?.notifySyn()
EventModel.notifySyn()
}
}
@@ -96,7 +96,7 @@ object EventDb: IDbRepository {
event.msgId = "${OchSPManager.getSn()}_${DateTimeUtil.getCurrentTimeStamp()}"
BizLoopManager.runInIoThread {
eventDataDao?.insert(event)
eventCallback?.notifySyn()
EventModel.notifySyn()
}
}
@@ -115,7 +115,7 @@ object EventDb: IDbRepository {
event.msgId = "${OchSPManager.getSn()}_${DateTimeUtil.getCurrentTimeStamp()}"
BizLoopManager.runInIoThread {
eventDataDao?.insert(event)
eventCallback?.notifySyn()
EventModel.notifySyn()
}
}
@@ -149,9 +149,4 @@ object EventDb: IDbRepository {
return eventDataDao?.queryWaitUploadInfo()
}
interface EventCallback {
fun notifySyn()
}
}

View File

@@ -117,7 +117,7 @@ object TaskDb : IDbRepository {
OchChainLogManager.writeChainLogDb("开始任务", "异常情况${lineId}_${lineName}_task:${taskId} 为未使用的状态 原因:${e.message}")
}
}
return@flatMap Observable.error(DataException(DataException.startTaskErrorCode,e.message))
return@flatMap Observable.error(DataException(DataException.startTaskErrorCode,e.message?:""))
}
updateCount?.let {
if(it<=0){

View File

@@ -0,0 +1,65 @@
package com.mogo.och.weaknet.repository.db.repository
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import com.mogo.och.weaknet.model.EventModel
import com.mogo.och.weaknet.repository.db.IDbRepository
import com.mogo.och.weaknet.repository.db.MyDataBase
import com.mogo.och.weaknet.repository.db.bean.WriteOffDataBean
import com.mogo.och.weaknet.repository.db.dao.WriteOffDataDao
object WriteOffDb: IDbRepository {
private var writeOffDataDao: WriteOffDataDao? = null
get() {
if(field==null){
field = MyDataBase.instance?.writeOffDataDao
register()
}
return field
}
override fun release(){
writeOffDataDao = null
}
fun addOrUpdate(vararg lineDataBean: WriteOffDataBean){
writeOffDataDao?.insert(*lineDataBean)
EventModel.notifySyn()
}
fun queryWaitUpdateEventCount(orderNo:String): List<WriteOffDataBean>? {
val queryWriteOffByOrderNo = writeOffDataDao?.queryWriteOffByOrderNo(orderNo = orderNo)
return queryWriteOffByOrderNo
}
fun queryWaitUpdateEvent(): List<WriteOffDataBean>? {
return writeOffDataDao?.queryWriteOffEventByStatusWithPage()
}
fun saveUpdateSuccess(writeOffEvents: List<WriteOffDataBean>) {
writeOffDataDao?.insert(*writeOffEvents.toTypedArray())
}
fun queryWaitUpdateEventByTaskId(taskId: Long): List<WriteOffDataBean>? {
return writeOffDataDao?.queryWaitWriteOffByTaskId(taskId)
}
fun queryWaitUpdateEventCountByTaskId(taskId: Long):Int {
val queryWriteOffByOrderNo = writeOffDataDao?.queryWaitWriteOffByTaskId(taskId)
return queryWriteOffByOrderNo?.size?:0
}
fun queryWriteOffByTaskAndSiteId(taskId: Long, siteId: Long): List<WriteOffDataBean>? {
return writeOffDataDao?.queryWriteOffByTaskAndSiteId(taskId,siteId)
}
fun deleteObsoleteData() {
writeOffDataDao?.deleteObsoleteData()?.let {
OchChainLogManager.writeChainLogDb("删除临时数据", "WriteOff删除数量:${it}")
}
}
}

View File

@@ -1,8 +1,14 @@
package com.mogo.och.weaknet.repository.exception
class DataException: RuntimeException {
var code:Int = 0
var msg:String = ""
constructor() : super()
constructor(code:Int,message: String?) : super("${code}_${message}")
constructor(code:Int, message: String) : super("${code}_${message}"){
this.code = code
this.msg = message
}
companion object{
val startTaskErrorCode = 10010
}

View File

@@ -1,16 +1,15 @@
package com.mogo.och.weaknet.repository
package com.mogo.och.weaknet.repository.line
import android.content.Context
import com.mogo.eagle.core.data.BaseData
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.repository.db.bean.LineDataBean
import com.mogo.och.weaknet.repository.db.bean.TaskDataBean
import io.reactivex.Observable
interface IRepository {
interface ILineRepository {
fun loadCurrentTaskInfo():Observable<Boolean>?
@@ -26,8 +25,6 @@ interface IRepository {
fun endTask( taskId: Long): Observable<Boolean>?
fun queryWriteoffCount(context: Context, taskId: Long, siteId: Long, callback: OchCommonServiceCallback<WriteOffCountResponse>?)
fun queryCarExecutableTaskList(ochCommonServiceCallback: OchCommonServiceCallback<CarExecutableTaskResponse>)
fun reportCabinEvent(context: Context?, data: ShuttleEventRequest?, callback: OchCommonServiceCallback<BaseData?>?)

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.impl
package com.mogo.och.weaknet.repository.line.impl
import android.content.Context
import com.mogo.commons.env.Project
@@ -15,25 +15,23 @@ import com.mogo.och.data.bean.ContraiInfo
import com.mogo.och.data.bean.LineInfo
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.model.LineModel
import com.mogo.och.weaknet.repository.db.bean.LineDataBean
import com.mogo.och.weaknet.repository.db.bean.TaskDataBean
import com.mogo.och.weaknet.repository.IRepository
import com.mogo.och.weaknet.repository.line.ILineRepository
import com.mogo.och.weaknet.repository.db.bean.TaskSiteDataBean
import com.mogo.och.weaknet.repository.net.NetInterface
import com.mogo.och.weaknet.repository.net.exception.NetException
import com.mogo.och.weaknet.repository.net.normal.NormalNetInterface
import com.mogo.och.weaknet.repository.net.normal.dali.bus.DaliBusServiceManager
import com.mogo.och.weaknet.repository.net.normal.mogo.bus.MogoBusServiceManager
import com.mogo.och.weaknet.repository.net.normal.mogo.shuttle.MogoShuttleServiceManager
import com.mogo.och.weaknet.repository.net.weaknet.saas.bus.SaasBusServiceManager
import com.mogo.och.weaknet.repository.net.project.dali.bus.DaliBusServiceManager
import com.mogo.och.weaknet.repository.net.project.mogo.bus.MogoBusServiceManager
import com.mogo.och.weaknet.repository.net.project.mogo.shuttle.MogoShuttleServiceManager
import io.reactivex.Observable
class NormalRepository: IRepository {
class NormalRepository: ILineRepository {
private val TAG = "NormalRepository"
private val tag = "NormalRepository"
private var normalNetInterface: NormalNetInterface?=null
private var normalLineInterface: NetInterface?=null
get() {
if(field==null){
when (ProjectUtils.getProjectType()) {
@@ -48,7 +46,7 @@ class NormalRepository: IRepository {
if(AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
throw NetException("非缓存weakNetInterface 初始化环境错误 isBus")
}else if(AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
field = DaliBusServiceManager()
field = DaliBusServiceManager
}
}
Project.MOGO -> {
@@ -67,7 +65,7 @@ class NormalRepository: IRepository {
}
override fun loadCurrentTaskInfo(): Observable<Boolean>? {
return normalNetInterface?.queryBusRoutes()
return normalLineInterface?.queryBusRoutes()
?.flatMap { busRoutesResult ->
if (!busRoutesResult.sites.isNullOrEmpty() && busRoutesResult.sites.size > 1) {
OchChainLogManager.writeChainLogDb(
@@ -75,23 +73,23 @@ class NormalRepository: IRepository {
"本地没有正在运行的数据,服务器端有${busRoutesResult}"
)
val result = mutableListOf<BusStationBean>()
var temp: BusStationBean? = null
var temp: BusStationBean?
var currentStationIndex = -1
var lineInfo: LineInfo?=null
busRoutesResult.sites.forEachIndexed { index, taskAndsite ->
temp = BusStationBean()
temp?.drivingStatus = (taskAndsite.drivingStatus ?: 0)
temp?.lat = (taskAndsite.lat ?: 0.0)
temp?.lon = (taskAndsite.lon ?: 0.0)
temp?.gcjLat = (taskAndsite.gcjLat ?: 0.0)
temp?.gcjLon = (taskAndsite.gcjLon ?: 0.0)
temp?.drivingStatus = taskAndsite.drivingStatus
temp?.lat = taskAndsite.lat
temp?.lon = taskAndsite.lon
temp?.gcjLat = taskAndsite.gcjLat
temp?.gcjLon = taskAndsite.gcjLon
temp?.introduction = taskAndsite.introduction
temp?.isLeaving = taskAndsite.isLeaving
temp?.name = taskAndsite.name
temp?.nameKr = taskAndsite.nameKr
temp?.isPlayTts = java.lang.Boolean.TRUE == taskAndsite.isPlayTts
temp?.seq = (taskAndsite.seq ?: 0)
temp?.siteId = if (taskAndsite.siteId == null) 0 else taskAndsite.siteId!!.toInt()
temp?.seq = taskAndsite.seq
temp?.siteId = taskAndsite.siteId
result.add(temp!!)
// 正在进行中的任务
if (temp!!.drivingStatus == TaskSiteDataBean.drivingStatusCurrent) {
@@ -126,6 +124,7 @@ class NormalRepository: IRepository {
if (LineModel.startStationIndex < stationlist.size-1) {
val endStation = stationlist[LineModel.startStationIndex + 1]
LineManager.setStartAndEndStation(startStation,endStation)
LineModel.callEyeMap(false)
}
}
return@flatMap Observable.just(true)
@@ -135,11 +134,11 @@ class NormalRepository: IRepository {
}
override fun queryCanUseLine(): Observable<List<LineDataBean>?>? {
return normalNetInterface?.queryBusLines()
return normalLineInterface?.queryBusLines()
}
override fun queryCanUserTask(lineId: Long): Observable<List<TaskDataBean>?>? {
return normalNetInterface?.queryBusTaskByLineId(lineId)
return normalLineInterface?.queryBusTaskByLineId(lineId)
}
override fun startTask(
@@ -148,7 +147,7 @@ class NormalRepository: IRepository {
taskTime: Long,
lineName: String
): Observable<Boolean>? {
return normalNetInterface?.switchLine(taskId)
return normalLineInterface?.switchLine(taskId)
}
override fun leaveStation(
@@ -158,11 +157,11 @@ class NormalRepository: IRepository {
lineId: Long,
taskStartTime: Long
): Observable<Boolean>? {
return normalNetInterface?.leaveStation(seq, siteId, taskId, System.currentTimeMillis())
return normalLineInterface?.leaveStation(seq, siteId, taskId, System.currentTimeMillis())
}
override fun arriveStation(seq: Int, siteId: Long, taskId: Long): Observable<Boolean>? {
return normalNetInterface?.arriveSiteStation(
return normalLineInterface?.arriveSiteStation(
seq,
siteId,
taskId,
@@ -171,16 +170,7 @@ class NormalRepository: IRepository {
}
override fun endTask(taskId: Long): Observable<Boolean>? {
return normalNetInterface?.endTask(taskId)
}
override fun queryWriteoffCount(
context: Context,
taskId: Long,
siteId: Long,
callback: OchCommonServiceCallback<WriteOffCountResponse>?
) {
return normalLineInterface?.endTask(taskId)
}
override fun queryCarExecutableTaskList(ochCommonServiceCallback: OchCommonServiceCallback<CarExecutableTaskResponse>) {
@@ -196,8 +186,8 @@ class NormalRepository: IRepository {
}
override fun release() {
normalNetInterface=null
CallerLogger.d(TAG,"重置 normalNetInterface")
normalLineInterface=null
CallerLogger.d(tag,"重置 normalNetInterface")
}

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.impl
package com.mogo.och.weaknet.repository.line.impl
import android.content.Context
import com.mogo.commons.AbsMogoApplication
@@ -14,7 +14,6 @@ import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest
import com.mogo.och.weaknet.bean.response.BusRoutesResponse
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.model.LineModel
import com.mogo.och.weaknet.model.LineModel.currentTask
import com.mogo.och.weaknet.repository.db.bean.ContrailDataBean
@@ -26,19 +25,19 @@ import com.mogo.och.weaknet.repository.db.repository.EventDb
import com.mogo.och.weaknet.repository.db.repository.LineDb
import com.mogo.och.weaknet.repository.db.repository.TaskDb
import com.mogo.och.weaknet.repository.db.repository.TaskSiteDb
import com.mogo.och.weaknet.repository.IRepository
import com.mogo.och.weaknet.repository.line.ILineRepository
import com.mogo.och.weaknet.repository.net.exception.NetException
import com.mogo.och.weaknet.repository.net.weaknet.WeakNetInterface
import com.mogo.och.weaknet.repository.net.weaknet.dali.shuttle.DaliShuttleServiceManager
import com.mogo.och.weaknet.repository.net.weaknet.saas.bus.SaasBusServiceManager
import com.mogo.och.weaknet.repository.net.weaknet.saas.shuttle.SaasShuttleServiceManager
import com.mogo.och.weaknet.repository.net.NetInterface
import com.mogo.och.weaknet.repository.net.project.dali.shuttle.DaliShuttleServiceManager
import com.mogo.och.weaknet.repository.net.project.saas.bus.SaasBusServiceManager
import com.mogo.och.weaknet.repository.net.project.saas.shuttle.SaasShuttleServiceManager
import io.reactivex.Observable
class WeaknetRepository : IRepository {
class WeaknetRepository : ILineRepository {
private val TAG = "ShuttleSaasRepository"
private val context = AbsMogoApplication.getApp()
private var weakNetInterface: WeakNetInterface?=null
private var weakNetInterface: NetInterface?=null
get() {
if(field==null){
when (ProjectUtils.getProjectType()) {
@@ -101,6 +100,7 @@ class WeaknetRepository : IRepository {
if (LineModel.startStationIndex < stationlist.size-1) {
val endStation = stationlist[LineModel.startStationIndex + 1]
LineManager.setStartAndEndStation(startStation,endStation)
LineModel.callEyeMap(false)
}
}
@@ -314,15 +314,6 @@ class WeaknetRepository : IRepository {
}
}
override fun queryWriteoffCount(
context: Context,
taskId: Long,
siteId: Long,
callback: OchCommonServiceCallback<WriteOffCountResponse>?
) {
weakNetInterface?.writeOffCount(context,taskId,siteId,callback)
}
override fun queryCarExecutableTaskList(
ochCommonServiceCallback: OchCommonServiceCallback<CarExecutableTaskResponse>
) {

View File

@@ -0,0 +1,63 @@
package com.mogo.och.weaknet.repository.net;
import android.content.Context;
import com.mogo.och.common.module.network.OchCommonServiceCallback;
import com.mogo.och.data.bean.BusRoutesResult;
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest;
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.weaknet.repository.db.bean.LineDataBean;
import com.mogo.och.weaknet.repository.db.bean.TaskDataBean;
import com.mogo.och.weaknet.repository.net.bean.request.PassengerWriteOffRequest;
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Observable;
public interface NetInterface {
default Observable<Boolean> switchLine(long taskId){
return null;
}
default Observable<Boolean> endTask(long taskId){
return Observable.just(true);
}
default Observable<Boolean> leaveStation(int seq, long siteId, long taskId, long writeVersion){
return Observable.just(true);
}
default Observable<Boolean> arriveSiteStation(int seq, long siteId, long taskId, long writeVersion){
return Observable.just(true);
}
default Observable<List<LineDataBean>> queryBusLines(){
return Observable.just(new ArrayList<>());
}
default Observable<List<TaskDataBean>> queryBusTaskByLineId(long lineId){
return Observable.just(new ArrayList<>());
}
default Observable<BusRoutesResult> queryBusRoutes(){
return Observable.just(new BusRoutesResult());
}
default Observable<Integer> writeOffCount(Context context , Long taskId, Long siteId){
return Observable.just(0);
}
default Observable<PassengerWriteOffResponse.Result> writeOffTicket(Context context,
PassengerWriteOffRequest ticketInfo){
return Observable.just(new PassengerWriteOffResponse.Result("",0,"",0L,0L));
}
default void queryCarExecutableTaskList(Context context , OchCommonServiceCallback<CarExecutableTaskResponse> callback){}
default void reportCabinEvent(Context context , ShuttleEventRequest data , OchCommonServiceCallback<BaseData> callback){}
}

View File

@@ -0,0 +1,50 @@
package com.mogo.och.weaknet.repository.net.bean.request;
public
/**
* @author congtaowang
* @since 2021/3/22
*
* 根据车机行驶线路站点信息
*/
class PassengerWriteOffRequest {
private String sn;
private String orderNo;
private String uid;
public PassengerWriteOffRequest(String orderNo, String uid) {
this.orderNo = orderNo;
this.uid = uid;
}
public PassengerWriteOffRequest(String sn, String orderNo, String uid) {
this.sn = sn;
this.orderNo = orderNo;
this.uid = uid;
}
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
}

View File

@@ -0,0 +1,14 @@
package com.mogo.och.weaknet.repository.net.bean.response
import com.mogo.eagle.core.data.BaseData
data class PassengerWriteOffResponse(val data: Result?) : BaseData(){
data class Result(
val phone: String?,
val ticketSize: Int?,
val ticketName: String?,
val remainingTimes: Long?,//剩余次数,
val businessTime:Long?,//业务时间
)
}

View File

@@ -1,31 +0,0 @@
package com.mogo.och.weaknet.repository.net.normal;
import android.content.Context;
import com.mogo.och.common.module.network.OchCommonServiceCallback;
import com.mogo.och.data.bean.BusRoutesResult;
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse;
import com.mogo.och.weaknet.repository.db.bean.LineDataBean;
import com.mogo.och.weaknet.repository.db.bean.TaskDataBean;
import java.util.List;
import io.reactivex.Observable;
public interface NormalNetInterface {
Observable<BusRoutesResult> queryBusRoutes();
Observable<Boolean> switchLine(long taskId);
Observable<Boolean> endTask(long taskId);
Observable<Boolean> leaveStation(int seq, long siteId, long taskId, long writeVersion);
Observable<Boolean> arriveSiteStation(int seq, long siteId, long taskId, long writeVersion);
Observable<List<LineDataBean>> queryBusLines();
Observable<List<TaskDataBean>> queryBusTaskByLineId(long lineId);
}

View File

@@ -1,31 +1,26 @@
package com.mogo.och.weaknet.repository.net.normal.dali.bus
package com.mogo.och.weaknet.repository.net.project.dali.bus
import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.network.OchCommonNet
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.common.module.network.OchCommonSubscribeImpl
import com.mogo.och.common.module.network.interceptor.transformIoTry
import com.mogo.och.common.module.network.interceptor.transformTry
import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.repository.db.bean.LineDataBean
import com.mogo.och.weaknet.repository.db.bean.TaskDataBean
import com.mogo.och.weaknet.repository.net.NetInterface
import com.mogo.och.weaknet.repository.net.bean.request.BusCloseTaskRequest
import com.mogo.och.weaknet.repository.net.bean.request.BusResetDrivingLineRequest
import com.mogo.och.weaknet.repository.net.bean.request.BusUpdateSiteStatusRequest
import com.mogo.och.weaknet.repository.net.normal.NormalNetInterface
import io.reactivex.Observable
/**
* @author: wangmingjun
* @date: 2021/10/20
*/
class DaliBusServiceManager: NormalNetInterface {
object DaliBusServiceManager: NetInterface {
private val mService: IDaliBusApiService =
MoGoRetrofitFactory.getInstance(OchCommonConst.getBaseUrl()).create(

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.net.normal.dali.bus
package com.mogo.och.weaknet.repository.net.project.dali.bus
import com.mogo.eagle.core.data.BaseData
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest
@@ -9,8 +9,10 @@ import com.mogo.och.weaknet.repository.net.bean.request.BusResetDrivingLineReque
import com.mogo.och.weaknet.repository.net.bean.request.BusRoutePlanningUpdateReqBean
import com.mogo.och.weaknet.repository.net.bean.request.BusUpdateSiteStatusRequest
import com.mogo.och.weaknet.repository.net.bean.request.CarHeartbeatReqBean
import com.mogo.och.weaknet.repository.net.bean.request.PassengerWriteOffRequest
import com.mogo.och.weaknet.repository.net.bean.response.BusQueryLineTaskResponse
import com.mogo.och.weaknet.repository.net.bean.response.BusQueryLinesResponse
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse
import io.reactivex.Observable
import retrofit2.http.Body
import retrofit2.http.GET
@@ -66,19 +68,6 @@ interface IDaliBusApiService {
fun arriveSiteStation(@Header("appId") appId: String?, @Header("ticket") ticket: String?, @Body request: BusUpdateSiteStatusRequest?): Observable<BaseData>
/**
* 车机端上传心跳数据只在出车状态时上传包含高德坐标系经纬度
* @param data
* @return
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/autopilot-car-hailing/location/v2/driver/bus/heartbeat")
fun runCarHeartbeat(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body data: CarHeartbeatReqBean?
): Observable<BaseData>
/**
* 查询车辆配置的所有路线
* @param appId
@@ -152,5 +141,12 @@ interface IDaliBusApiService {
@POST("/och-bus-cabin/cab/flow/v1/bus/driver/endTask")
fun writeOffCount(@Header("appId") appId: String?, @Header("ticket") ticket: String?, @Query("taskId") taskId: Long , @Query("siteId")siteId: Long ): Observable<WriteOffCountResponse>
/**
* 核销接口
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/och-vehicle/api/scanner/device/writeOff")
fun daliwriteOffTicket(@Header ("appId") appId:String, @Header("ticket") ticket:String, @Body request: PassengerWriteOffRequest):Observable<PassengerWriteOffResponse>
}

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.net.weaknet.dali.shuttle
package com.mogo.och.weaknet.repository.net.project.dali.shuttle
import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
@@ -6,6 +6,7 @@ import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.BaseData
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.manager.cache.OchSPManager
import com.mogo.och.common.module.network.OchCommonNet
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.common.module.network.OchCommonSubscribeImpl
@@ -14,56 +15,53 @@ import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.repository.net.weaknet.WeakNetInterface
import com.mogo.och.weaknet.repository.net.NetInterface
import com.mogo.och.weaknet.repository.net.bean.request.PassengerWriteOffRequest
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse
import io.reactivex.Observable
/**
* @author: wangmingjun
* @date: 2021/10/20
*/
object DaliShuttleServiceManager: WeakNetInterface {
object DaliShuttleServiceManager : NetInterface {
private val mService: IDaliShuttleApiService = MoGoRetrofitFactory.getInstance(OchCommonConst.getShuttleUrl()).create(
IDaliShuttleApiService::class.java
)
private val mService: IDaliShuttleApiService =
MoGoRetrofitFactory.getInstance(OchCommonConst.getShuttleUrl()).create(
IDaliShuttleApiService::class.java
)
/**
* 查询小巴车当前任务
* @param context
* @param callback
*/
override fun queryBusRoutes(): Observable<BusRoutesResult?>? {
//获取当前高德坐标
return mService.queryBusRoutes(
return mService.queryBusRoutes(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
SharedPrefsMgr.getInstance().token,
BusQueryLineStationsRequest()
) .transformIoTry()
.flatMap(OchCommonNet("saas shuttle queryBusRoutes",false))
).transformIoTry()
.flatMap(OchCommonNet("saas shuttle queryBusRoutes", false))
.flatMap {
Observable.just(it.data?:BusRoutesResult())
Observable.just(it.data ?: BusRoutesResult())
}
}
/**
* 只发生在大理和saas环境 查询当前站点核销的人数
*/
override fun writeOffCount(
context: Context,
taskId: Long?,
siteId: Long?,
callback: OchCommonServiceCallback<WriteOffCountResponse>?
) {
mService.writeOffCount(
override fun writeOffCount(context: Context?, taskId: Long?, siteId: Long?): Observable<Int> {
return mService.writeOffCount(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
SharedPrefsMgr.getInstance().token,
taskId?.toString(),
siteId?.toString()
)
.transformIoTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "writeOffCount"))
.flatMap(OchCommonNet("saas shuttle writeOffCount", false))
.flatMap {
Observable.just(it.data ?: 0)
}
}
/**
@@ -98,5 +96,22 @@ object DaliShuttleServiceManager: WeakNetInterface {
.subscribe(OchCommonSubscribeImpl(context, callback, "reportCabinEvent"))
}
override fun writeOffTicket(
context: Context,
ticketInfo: PassengerWriteOffRequest,
): Observable<PassengerWriteOffResponse.Result?>? {
ticketInfo.sn = OchSPManager.getSn()
return mService.daliwriteOffTicket(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
SharedPrefsMgr.getInstance().token,
ticketInfo
)
.transformIoTry()
.flatMap(OchCommonNet("dali shuttle writeOffCount",false))
.flatMap {
Observable.just(it.data)
}
}
}

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.net.weaknet.dali.shuttle;
package com.mogo.och.weaknet.repository.net.project.dali.shuttle;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest;
@@ -6,6 +6,8 @@ import com.mogo.och.weaknet.bean.request.ShuttleEventRequest;
import com.mogo.och.weaknet.bean.response.BusRoutesResponse;
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse;
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse;
import com.mogo.och.weaknet.repository.net.bean.request.PassengerWriteOffRequest;
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse;
import io.reactivex.Observable;
import retrofit2.http.Body;
@@ -41,6 +43,13 @@ public interface IDaliShuttleApiService {
@GET("och-shuttle-cabin/api/business/v1/task/writeOffCount")
Observable<WriteOffCountResponse> writeOffCount(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("taskId") String taskId, @Query("siteId") String siteId);
/**
* 实时核销 核销接口
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("/och-vehicle/api/scanner/device/writeOff")
Observable<PassengerWriteOffResponse> daliwriteOffTicket(@Header ("appId") String appId, @Header("ticket") String ticket, @Body PassengerWriteOffRequest request);
/**
* 同步 线路站点任务自驾轨迹信息
*/

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.net.normal.mogo.bus
package com.mogo.och.weaknet.repository.net.project.mogo.bus
import com.mogo.eagle.core.data.BaseData
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest

View File

@@ -1,29 +1,26 @@
package com.mogo.och.weaknet.repository.net.normal.mogo.bus
package com.mogo.och.weaknet.repository.net.project.mogo.bus
import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.network.OchCommonNet
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.common.module.network.interceptor.transformTry
import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.repository.db.bean.LineDataBean
import com.mogo.och.weaknet.repository.db.bean.TaskDataBean
import com.mogo.och.weaknet.repository.net.NetInterface
import com.mogo.och.weaknet.repository.net.bean.request.BusCloseTaskRequest
import com.mogo.och.weaknet.repository.net.bean.request.BusResetDrivingLineRequest
import com.mogo.och.weaknet.repository.net.bean.request.BusUpdateSiteStatusRequest
import com.mogo.och.weaknet.repository.net.normal.NormalNetInterface
import io.reactivex.Observable
/**
* @author: wangmingjun
* @date: 2021/10/20
*/
class MogoBusServiceManager: NormalNetInterface {
class MogoBusServiceManager: NetInterface {
private val mService: IMogoBusApiService =
MoGoRetrofitFactory.getInstance(OchCommonConst.getBaseUrl()).create(

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.net.normal.mogo.shuttle;
package com.mogo.och.weaknet.repository.net.project.mogo.shuttle;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest;

View File

@@ -1,29 +1,26 @@
package com.mogo.och.weaknet.repository.net.normal.mogo.shuttle
package com.mogo.och.weaknet.repository.net.project.mogo.shuttle
import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.network.OchCommonNet
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.common.module.network.interceptor.transformTry
import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.repository.db.bean.LineDataBean
import com.mogo.och.weaknet.repository.db.bean.TaskDataBean
import com.mogo.och.weaknet.repository.net.NetInterface
import com.mogo.och.weaknet.repository.net.bean.request.BusCloseTaskRequest
import com.mogo.och.weaknet.repository.net.bean.request.BusResetDrivingLineRequest
import com.mogo.och.weaknet.repository.net.bean.request.BusUpdateSiteStatusRequest
import com.mogo.och.weaknet.repository.net.normal.NormalNetInterface
import io.reactivex.Observable
/**
* @author: wangmingjun
* @date: 2021/10/20
*/
class MogoShuttleServiceManager: NormalNetInterface {
class MogoShuttleServiceManager: NetInterface {
private val mService: IMogoShuttleApiService = MoGoRetrofitFactory.getInstance(OchCommonConst.getShuttleUrl()).create(
IMogoShuttleApiService::class.java

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.net.weaknet.saas.bus;
package com.mogo.och.weaknet.repository.net.project.saas.bus;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest;
@@ -6,7 +6,9 @@ import com.mogo.och.weaknet.bean.response.BusRoutesResponse;
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse;
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest;
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse;
import com.mogo.och.weaknet.repository.net.bean.request.PassengerWriteOffRequest;
import com.mogo.och.weaknet.repository.net.bean.request.WriteOffCountReqBean;
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse;
import io.reactivex.Observable;
import retrofit2.http.Body;
@@ -42,6 +44,13 @@ public interface ISaasBusApiService {
@POST("/och-vehicle/api/car/v2/task/site/writeOffCount")
Observable<WriteOffCountResponse> writeOffCount(@Header ("appId") String appId, @Header("ticket") String ticket, @Body WriteOffCountReqBean writeOffCountReqBean);
/**
* 同步核销接口
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("/och-vehicle/api/car/v2/device/writeOff")
Observable<PassengerWriteOffResponse> saaswriteOffTicket(@Header ("appId") String appId, @Header("ticket") String ticket, @Body PassengerWriteOffRequest request);
/**
* 同步 线路站点任务自驾轨迹信息
*/

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.net.weaknet.saas.bus
package com.mogo.och.weaknet.repository.net.project.saas.bus
import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
@@ -12,19 +12,17 @@ import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.common.module.network.OchCommonSubscribeImpl
import com.mogo.och.common.module.network.interceptor.transformIoTry
import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.repository.net.bean.request.WriteOffCountReqBean
import com.mogo.och.weaknet.repository.net.weaknet.WeakNetInterface
import com.mogo.och.weaknet.repository.net.NetInterface
import io.reactivex.Observable
/**
* @author: wangmingjun
* @date: 2021/10/20
*/
object SaasBusServiceManager: WeakNetInterface {
object SaasBusServiceManager: NetInterface {
private val mService: ISaasBusApiService = MoGoRetrofitFactory.getInstance(OchCommonConst.getBaseUrl()).create(
ISaasBusApiService::class.java
@@ -49,29 +47,6 @@ object SaasBusServiceManager: WeakNetInterface {
}
}
/**
* 只发生在大理和saas环境 查询当前站点核销的人数
*/
override fun writeOffCount(
context: Context,
taskId: Long,
siteId: Long,
callback: OchCommonServiceCallback<WriteOffCountResponse>?
) {
OchSPManager.getSn()?.let {
mService.writeOffCount(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
SharedPrefsMgr.getInstance().token,
WriteOffCountReqBean(it,taskId,
siteId,
)
)
.transformIoTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "writeOffCount"))
}
}
/**
* 同步 线路站点任务自驾轨迹信息
*/

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.net.weaknet.saas.shuttle;
package com.mogo.och.weaknet.repository.net.project.saas.shuttle;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest;
@@ -6,7 +6,9 @@ import com.mogo.och.weaknet.bean.response.BusRoutesResponse;
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse;
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest;
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse;
import com.mogo.och.weaknet.repository.net.bean.request.PassengerWriteOffRequest;
import com.mogo.och.weaknet.repository.net.bean.request.WriteOffCountReqBean;
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse;
import io.reactivex.Observable;
import retrofit2.http.Body;
@@ -42,6 +44,13 @@ public interface ISaasShuttleApiService {
@POST("/och-vehicle/api/car/v2/task/site/writeOffCount")
Observable<WriteOffCountResponse> writeOffCount(@Header ("appId") String appId, @Header("ticket") String ticket, @Body WriteOffCountReqBean writeOffCountReqBean);
/**
* 同步核销接口
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("/och-vehicle/api/car/v2/device/writeOff")
Observable<PassengerWriteOffResponse> saaswriteOffTicket(@Header ("appId") String appId, @Header("ticket") String ticket, @Body PassengerWriteOffRequest request);
/**
* 同步 线路站点任务自驾轨迹信息
*/

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.repository.net.weaknet.saas.shuttle
package com.mogo.och.weaknet.repository.net.project.saas.shuttle
import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
@@ -15,16 +15,14 @@ import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.weaknet.bean.request.BusQueryLineStationsRequest
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.repository.net.bean.request.WriteOffCountReqBean
import com.mogo.och.weaknet.repository.net.weaknet.WeakNetInterface
import com.mogo.och.weaknet.repository.net.NetInterface
import io.reactivex.Observable
/**
* @author: wangmingjun
* @date: 2021/10/20
*/
object SaasShuttleServiceManager: WeakNetInterface {
object SaasShuttleServiceManager: NetInterface {
private val mService: ISaasShuttleApiService = MoGoRetrofitFactory.getInstance(OchCommonConst.getShuttleUrl()).create(
ISaasShuttleApiService::class.java
@@ -33,8 +31,6 @@ object SaasShuttleServiceManager: WeakNetInterface {
/**
* 查询小巴车当前任务
* @param context
* @param callback
*/
override fun queryBusRoutes(): Observable<BusRoutesResult?>? {
//获取当前高德坐标
@@ -49,29 +45,6 @@ object SaasShuttleServiceManager: WeakNetInterface {
}
}
/**
* 只发生在大理和saas环境 查询当前站点核销的人数
*/
override fun writeOffCount(
context: Context,
taskId: Long,
siteId: Long,
callback: OchCommonServiceCallback<WriteOffCountResponse>?
) {
OchSPManager.getSn()?.let {
mService.writeOffCount(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
SharedPrefsMgr.getInstance().token,
WriteOffCountReqBean(
it, taskId,
siteId,
)
)
.transformIoTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "writeOffCount"))
}
}
/**
* 同步 线路站点任务自驾轨迹信息
*/

View File

@@ -1,35 +0,0 @@
package com.mogo.och.weaknet.repository.net.weaknet;
import android.content.Context;
import com.mogo.och.common.module.network.OchCommonServiceCallback;
import com.mogo.och.data.bean.BusRoutesResult;
import com.mogo.och.weaknet.bean.request.ShuttleEventRequest;
import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse;
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse;
import com.mogo.eagle.core.data.BaseData;
import io.reactivex.Observable;
public interface WeakNetInterface {
Observable<BusRoutesResult> queryBusRoutes();
void writeOffCount(
Context context ,
Long taskId,
Long siteId,
OchCommonServiceCallback<WriteOffCountResponse> callback
);
void queryCarExecutableTaskList(
Context context ,
OchCommonServiceCallback<CarExecutableTaskResponse> callback
);
void reportCabinEvent(
Context context ,
ShuttleEventRequest data ,
OchCommonServiceCallback<BaseData> callback
);
}

View File

@@ -0,0 +1,29 @@
package com.mogo.och.weaknet.repository.writeoff
import android.content.Context
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDetialMsg
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.weaknet.bean.WaitUploadLine
import com.mogo.och.weaknet.bean.WriteOffPassenger
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse
import io.reactivex.Observable
interface IWriteOffRepository {
fun queryWriteoffCount(context: Context, taskId: Long, siteId: Long): Observable<Int>?
fun writeOffEvent(writeOffDetialMsg: WriteOffDetialMsg): Observable<PassengerWriteOffResponse.Result>?
fun release()
fun canCanEndTask(taskId: Long): Boolean {
return true
}
fun queryWaitUploadData(): Observable<MutableList<WaitUploadLine>>?
fun writeOffEvent4Socket(passenger: WriteOffPassenger) {
}
}

View File

@@ -0,0 +1,244 @@
package com.mogo.och.weaknet.repository.writeoff.impl
import android.content.Context
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.env.Project
import com.mogo.commons.env.ProjectUtils
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.och.common.module.biz.login.LoginStatusManager
import com.mogo.och.common.module.manager.autopilot.line.LineManager
import com.mogo.och.common.module.manager.cache.OchSPManager
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDetialMsg
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.weaknet.bean.WaitUploadLine
import com.mogo.och.weaknet.bean.WaitUploadTask
import com.mogo.och.weaknet.bean.WriteOffPassenger
import com.mogo.och.weaknet.model.LineModel
import com.mogo.och.weaknet.repository.db.bean.WriteOffDataBean
import com.mogo.och.weaknet.repository.db.repository.EventDb
import com.mogo.och.weaknet.repository.db.repository.WriteOffDb
import com.mogo.och.weaknet.repository.exception.DataException
import com.mogo.och.weaknet.repository.net.exception.NetException
import com.mogo.och.weaknet.repository.net.NetInterface
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse
import com.mogo.och.weaknet.repository.net.project.saas.bus.SaasBusServiceManager
import com.mogo.och.weaknet.repository.net.project.saas.shuttle.SaasShuttleServiceManager
import com.mogo.och.weaknet.repository.writeoff.IWriteOffRepository
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
class WriteOffCacheRepository : IWriteOffRepository {
private val TAG = "ShuttleSaasRepository"
private val context = AbsMogoApplication.getApp()
private var weakNetInterface: NetInterface?=null
get() {
if(field==null){
when (ProjectUtils.getProjectType()) {
Project.SAAS -> {
if(AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
field = SaasShuttleServiceManager
}else if(AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
field = SaasBusServiceManager
}
}
Project.DALI -> {
throw NetException("缓存weakNetInterface 初始化环境错误 Dali")
}
Project.MOGO -> {
throw NetException("缓存weakNetInterface 初始化环境错误 MOGO")
}
else->{
throw NetException("缓存weakNetInterface 初始化环境错误 未知")
}
}
}
return field
}
override fun queryWriteoffCount(
context: Context,
taskId: Long,
siteId: Long
): Observable<Int>? {
val queryWriteOffByTaskAndSiteId = WriteOffDb.queryWriteOffByTaskAndSiteId(taskId, siteId)
return Observable.just(queryWriteOffByTaskAndSiteId)
.flatMap {
return@flatMap Observable.just(it?.size ?:0)
}
}
override fun writeOffEvent(writeOffDetialMsg: WriteOffDetialMsg): Observable<PassengerWriteOffResponse.Result>? {
return Observable.just(writeOffDetialMsg)
.flatMap {
// 1、校验数据
/**
* 0、校验 tenantId
* 1、校验pipe 校验project
* 2、校验业务模式 bus和接驳
* 3、校验二维码有效性(向后1分钟有效)
* 4、校验乘车日期
* 5、校验线路
*
* 接驳
* 6、校验次数
* 7、同一个订单2分钟内只能执行一次
* 小巴
* 6、校验站点
*/
var lineId:Long?=null
var siteId:Long?=null
// 1、校验租户id
it.tenantId?.let { tenantId->
if(LoginStatusManager.getLoginInfo()?.tenantId==tenantId){
}else{
throw DataException(1012,"当前用户下单路线非当前的车辆所属公司")
}
}
// 2、校验project
if(ProjectUtils.isSaas()){
if(it.pipe != WriteOffDataBean.saasXiaoChengXu){
throw DataException(1012,"当前用户下单路线非当前的车辆所属公司")
}
}else if(ProjectUtils.isDali()){
if(it.pipe != WriteOffDataBean.daliXiaoChengXu){
throw DataException(1012,"当前用户下单路线非当前的车辆所属公司")
}
}
// 3、校验 bus和shuttle
if (LoginStatusManager.getBusInessType().name.lowercase()!=it.typeBiz) {
throw DataException(1005,"车辆未登录、或没有任务")
}
// 4 二维码1分钟失效
if(System.currentTimeMillis()-(it.expiryTime?:0L)>60_000){
throw DataException(6001,"二维码已过期")
}
// 5 校验乘车日期
if(!DateTimeUtil.isSameDay(System.currentTimeMillis(),it.bookingTime?:0)){
throw DataException(1009,"车票所选乘车日期非今日")
}
// 6、校验线路
if(it.lineId==LineManager.lineInfos?.lineId){
lineId = it.lineId
}else{
throw DataException(1006,"车票路线信息与当前车辆执行任务的路线信息不符合")
}
if (!it.orderNo.isNullOrEmpty()) {
val lastWriteOff = WriteOffDb.queryWaitUpdateEventCount(it.orderNo!!)
// 7、校验次数
if ((it.availableTimes ?: 0) >= (lastWriteOff?.size ?: 0)) {
throw DataException(1008, "车票剩余可用次数为0")
}
if (AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
// 8、同一个订单2分钟内只能核销一次
if (lastWriteOff != null && lastWriteOff.size > 0) {
if (System.currentTimeMillis() - lastWriteOff.last().eventSaveTime <= 120_000) {
throw DataException(6002, "同一订单核销间隔时间需大于2分钟")
}
}
val (start, _) = LineManager.getStations()
siteId = start?.siteId?.toLong() ?: 0
} else if (AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
// 8、校验起始站点
val (start, _) = LineManager.getStations()
if (start?.siteId?.toLong() == it.startStationId) {
siteId = it.startStationId
} else {
throw DataException(
1006,
"车票站点信息与当前车辆执行任务的站点信息不符合"
)
}
}
} else {
throw DataException(11000, "缺少orderNo")
}
val addWrite = WriteOffDataBean()
addWrite.expiryTime = it.expiryTime
addWrite.bookingTime = it.bookingTime
addWrite.type = it.type
addWrite.taskId = LineModel.currentTask?.taskId
addWrite.lineId = lineId
addWrite.siteId = siteId
addWrite.availableTimes = it.availableTimes
addWrite.orderNo = it.orderNo
addWrite.uid = it.uid
addWrite.phone = it.phone
addWrite.ticketSize = it.ticketSize
addWrite.ticketName = it.ticketName
addWrite.msgId = OchSPManager.getSn()+System.currentTimeMillis()
addWrite.driverId = LoginStatusManager.getLoginInfo()?.driverId?:0
addWrite.businessTime = System.currentTimeMillis()
WriteOffDb.addOrUpdate(addWrite)
val reslut = PassengerWriteOffResponse.Result(it.phone,it.ticketSize,it.ticketName,it.availableTimes?.toLong(),addWrite.businessTime)
return@flatMap Observable.just(reslut)
}
}
override fun canCanEndTask(taskId: Long): Boolean {
val queryWaitUpdateEventByTaskId = WriteOffDb.queryWaitUpdateEventByTaskId(taskId)
return queryWaitUpdateEventByTaskId.isNullOrEmpty()
}
override fun queryWaitUploadData(): Observable<MutableList<WaitUploadLine>>? {
return EventDb.queryWaitUploadData()
?.flatMap { waitUploadList->
val result = mutableListOf<WaitUploadLine>()
waitUploadList.forEach { wait->
if(wait.lineId!=null&&wait.lineName!=null&&wait.taskId!=null&&wait.taskStartTime!=null) {
val waitUpdateEventCount = WriteOffDb.queryWaitUpdateEventCountByTaskId(wait.taskId!!)
val tempTask = WaitUploadTask(wait.taskStartTime!!,wait.taskId!!,waitUpdateEventCount)
val tempLine = WaitUploadLine(wait.lineName!!, wait.lineId!!, mutableListOf(tempTask))
val haveSave = result.filter {
it.lineId==tempLine.lineId
}
if(haveSave.isEmpty()){
result.add(tempLine)
}else{
haveSave.first().task.add(tempTask)
}
}
}
Observable.just(result) }
?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
}
override fun writeOffEvent4Socket(passenger: WriteOffPassenger) {
val addWrite = WriteOffDataBean()
//addWrite.expiryTime = it.expiryTime
//addWrite.bookingTime = it.bookingTime
//addWrite.type = it.type
addWrite.taskId = LineModel.currentTask?.taskId
LineManager.getStationsWithLine { start, end, lineInfo ->
addWrite.siteId = start.siteId.toLong()
addWrite.lineId = lineInfo.lineId
}
//addWrite.availableTimes = it.availableTimes
addWrite.orderNo = passenger.orderNo
//addWrite.uid = it.uid
addWrite.phone = passenger.phone
addWrite.ticketSize = passenger.passengerSize
addWrite.ticketName = passenger.ticketName
//addWrite.msgId = OchSPManager.getSn()+System.currentTimeMillis()
addWrite.driverId = LoginStatusManager.getLoginInfo()?.driverId?:0
//addWrite.businessTime = System.currentTimeMillis()
addWrite.updateStatus = WriteOffDataBean.updated
WriteOffDb.addOrUpdate(addWrite)
}
override fun release() {
weakNetInterface = null
CallerLogger.d(TAG,"重置 weakNetInterface")
}
}

View File

@@ -0,0 +1,107 @@
package com.mogo.och.weaknet.repository.writeoff.impl
import android.content.Context
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.env.Project
import com.mogo.commons.env.ProjectUtils
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDetialMsg
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.weaknet.bean.WaitUploadLine
import com.mogo.och.weaknet.bean.WaitUploadTask
import com.mogo.och.weaknet.bean.response.WriteOffCountResponse
import com.mogo.och.weaknet.repository.db.repository.EventDb
import com.mogo.och.weaknet.repository.net.NetInterface
import com.mogo.och.weaknet.repository.net.bean.request.PassengerWriteOffRequest
import com.mogo.och.weaknet.repository.net.bean.response.PassengerWriteOffResponse
import com.mogo.och.weaknet.repository.net.exception.NetException
import com.mogo.och.weaknet.repository.net.project.dali.bus.DaliBusServiceManager
import com.mogo.och.weaknet.repository.net.project.dali.shuttle.DaliShuttleServiceManager
import com.mogo.och.weaknet.repository.writeoff.IWriteOffRepository
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
class WriteOffNormallRepository: IWriteOffRepository {
private val TAG = "WriteOffNormallRepository"
private var normalNetInterface: NetInterface?=null
get() {
if(field==null){
when (ProjectUtils.getProjectType()) {
Project.SAAS -> {
throw NetException("writeoff 核销 初始化环境错误 SAAS")
}
Project.DALI -> {
if(AppIdentityModeUtils.isShuttle(FunctionBuildConfig.appIdentityMode)) {
field = DaliShuttleServiceManager
}else if(AppIdentityModeUtils.isBus(FunctionBuildConfig.appIdentityMode)) {
field = DaliBusServiceManager
}
}
Project.MOGO -> {
throw NetException("writeoff 核销 初始化环境错误 MOGO")
}
else->{
throw NetException("writeoff 核销 初始化环境错误 未知")
}
}
}
return field
}
init {
}
override fun queryWriteoffCount(
context: Context,
taskId: Long,
siteId: Long,
): Observable<Int>? {
return normalNetInterface?.writeOffCount(context,taskId,siteId)
}
override fun writeOffEvent(writeOffDetialMsg: WriteOffDetialMsg): Observable<PassengerWriteOffResponse.Result>? {
val passengerWriteOffRequest = PassengerWriteOffRequest(writeOffDetialMsg.orderNo, writeOffDetialMsg.uid)
return normalNetInterface?.writeOffTicket(
AbsMogoApplication.getApp(),
passengerWriteOffRequest,
)
}
override fun release() {
normalNetInterface=null
CallerLogger.d(TAG,"重置 normalNetInterface")
}
override fun queryWaitUploadData(): Observable<MutableList<WaitUploadLine>>? {
return EventDb.queryWaitUploadData()
?.flatMap { waitUploadList->
val result = mutableListOf<WaitUploadLine>()
waitUploadList.forEach { wait->
if(wait.lineId!=null&&wait.lineName!=null&&wait.taskId!=null&&wait.taskStartTime!=null) {
val tempTask = WaitUploadTask(wait.taskStartTime!!,wait.taskId!!,0)
val tempLine = WaitUploadLine(wait.lineName!!, wait.lineId!!, mutableListOf(tempTask))
val haveSave = result.filter {
it.lineId==tempLine.lineId
}
if(haveSave.isEmpty()){
result.add(tempLine)
}else{
haveSave.first().task.add(tempTask)
}
}
}
Observable.just(result) }
?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
}
}

View File

@@ -44,7 +44,11 @@ class RunningTaskAdapter(
val lineTasks = dataList!![currentPosition]
val sb = StringBuilder().append("班次:")
lineTasks.task.forEach {
sb.append(TimeUtils.millis2String(it.taskStartTime, "HH:mm")).append(" ")
sb.append(TimeUtils.millis2String(it.taskStartTime, "HH:mm"))
if(it.waitUploadWriteOff>0){
sb.append("(${it.waitUploadWriteOff})")
}
sb.append(" ")
}
holder.actvLineTaskName.text = lineTasks.lineName
holder.actvWaitUploadItem.text = sb

View File

@@ -2,6 +2,7 @@ package com.mogo.och.weaknet.ui.taskrunned
import androidx.lifecycle.ViewModel
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.utils.RxUtils
import com.mogo.och.weaknet.bean.WaitUploadLine
import com.mogo.och.weaknet.model.EventModel
@@ -59,25 +60,28 @@ class RunningTastViewModel : ViewModel() {
}
fun queryNewData() {
EventModel.queryWaitUploadInfo()
?.subscribe(object : Observer<MutableList<WaitUploadLine>> {
override fun onSubscribe(d: Disposable) {
CallerLogger.d(TAG, "onSubscribe")
}
BizLoopManager.runInIoThread {
EventModel.queryWaitUploadInfo()
?.subscribe(object : Observer<MutableList<WaitUploadLine>> {
override fun onSubscribe(d: Disposable) {
CallerLogger.d(TAG, "onSubscribe")
}
override fun onError(e: Throwable) {
CallerLogger.d(TAG, "onError${e.printStackTrace()}")
}
override fun onError(e: Throwable) {
CallerLogger.d(TAG, "onError${e.printStackTrace()}")
}
override fun onComplete() {
CallerLogger.d(TAG, "onComplete")
}
override fun onComplete() {
CallerLogger.d(TAG, "onComplete")
}
override fun onNext(data: MutableList<WaitUploadLine>) {
this@RunningTastViewModel.viewCallback?.showData(data)
}
override fun onNext(data: MutableList<WaitUploadLine>) {
this@RunningTastViewModel.viewCallback?.showData(data)
}
})
}
})
}
fun uploadData() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -2,4 +2,25 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mogo.och.shuttle.weaknet.passenger">
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!--查找蓝牙设备-->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!--使当前设备可被其他蓝牙设备检测到-->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!--与已配对的蓝牙设备进行通讯-->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!--使用蓝牙扫描结果来推导物理位置-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>

View File

@@ -13,7 +13,7 @@ import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.biz.provider.CommonServiceImpl
import com.mogo.och.common.module.wigets.media.MediaPlayerActivity
import com.mogo.och.shuttle.weaknet.passenger.model.TicketModel
import com.mogo.och.shuttle.weaknet.passenger.ui.BusPStatusBarView
import com.mogo.och.shuttle.weaknet.passenger.ui.widget.BusPStatusBarView
import com.mogo.och.shuttle.weaknet.passenger.ui.BusPassengerRouteFragment
import com.mogo.och.shuttle.weaknet.passenger.ui.PM2BaseFragment
import com.mogo.och.shuttle.weaknet.passenger.ui.widget.M2StatusBarView
@@ -30,7 +30,7 @@ class ShuttlePassengerProvider : CommonServiceImpl() {
private var mPM2Fragment: Fragment?=null
override fun init(context: Context) {
TicketModel.load()
}
override fun getStatusBarView(context: Context): View {
@@ -59,11 +59,13 @@ class ShuttlePassengerProvider : CommonServiceImpl() {
BusPassengerRouteFragment()
}
}
TicketModel.load()
return mPM2Fragment!!
}
override fun resetFragment() {
super.resetFragment()
TicketModel.release()
mPM2Fragment = null
}

View File

@@ -0,0 +1,27 @@
package com.mogo.och.shuttle.weaknet.passenger.callback;
import com.mogo.och.data.bean.BusStationBean;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2022/4/6
*/
public interface ICommonCallback {
void updateLineInfo(String lineName);
void updateStationsInfo(List<BusStationBean> stations, int currentStationIndex, boolean isArrived);
void updateSpeed(int location);
void updateRemainMT(long meters, long timeInSecond);
void showNoTaskView(boolean isTrue);
/**
* false: 未开启自驾, true 开启自驾
*/
void updateAutoStatus(boolean isOpen);
default void updateLineStations(List<BusStationBean> stations){}
default void clearCustomPolyline(){}
}

View File

@@ -1,26 +1,120 @@
package com.mogo.och.shuttle.weaknet.passenger.model
import android.annotation.SuppressLint
import android.content.Context
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.env.ProjectUtils
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.StringUtils
import com.mogo.och.common.module.biz.lansocket.IOchLanPassengerStatusListener
import com.mogo.och.common.module.biz.lansocket.LoginLanPassengerSocket
import com.mogo.och.common.module.biz.media.MediaManager
import com.mogo.och.common.module.manager.autopilot.autopilot.IOchAutopilotStatusListener
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotStatusListenerManager
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager
import com.mogo.och.common.module.manager.distance.IDistanceListener
import com.mogo.och.common.module.manager.distance.TrajectoryAndDistanceManager
import com.mogo.och.common.module.manager.download.DownloadManager
import com.mogo.och.common.module.manager.socket.cloud.OCHSocketMessageManager
import com.mogo.och.common.module.manager.socket.lan.ILanMessageListener
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
import com.mogo.och.common.module.manager.socket.lan.bean.AppConnectMsg
import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
import com.mogo.och.common.module.manager.socket.lan.bean.TaskDetailsMsg
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.common.module.utils.PinYinUtil
import com.mogo.och.common.module.voice.VoiceNotice.showNotice
import com.mogo.och.common.module.wigets.media.MediaItem
import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.data.bean.BusStationBean
import com.mogo.och.data.bean.BusTransferData
import com.mogo.och.shuttle.weaknet.passenger.bean.response.ResponseSiteIntroduce
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
import com.mogo.och.shuttle.weaknet.passenger.constant.BusPassengerConst
import com.mogo.och.shuttle.weaknet.passenger.network.PassengerServiceManager
import kotlin.math.abs
@SuppressLint("StaticFieldLeak")
object CommonModel {
private val TAG: String = CommonModel::class.java.simpleName
var mContext: Context? = null
private var mCommonCallback: ICommonCallback? = null // bus路线信息更新
var mStations = mutableListOf<BusStationBean>()
var mNextStationIndex = 0 // A-B要到达站的index
@Volatile
var isGoingToNextStation = false //是否前往下一站过程中
var routesResult: BusRoutesResult? = null
fun init(context: Context) {
mContext = context.applicationContext
initListeners()
queryDriverByLocalDriver()
}
private fun initListeners() {
//自动驾驶状态监听
OchAutoPilotStatusListenerManager.addListener(TAG, mAutoPilotStatusListener)
// 定位监听
OchLocationManager.addGCJ02Listener(TAG, 3, mMapLocationListener)
// 监听站点距离
TrajectoryAndDistanceManager.addDistanceListener(TAG, trajectoryListener)
// 通用监听
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_COMMON.type, LanSocketManager.commonListener)
// 监听站点信息
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_TASK_DETAILS.type, typeTaskDetails)
// 注册监听和司机屏连接情况
LoginLanPassengerSocket.addListener(TAG, connectDriverListener)
}
fun releaseListeners() {
//自动驾驶状态监听
CallerAutoPilotStatusListenerManager.removeListener(TAG)
// 定位监听
OchLocationManager.removeGCJ02Listener(TAG)
// 监听站点距离
TrajectoryAndDistanceManager.removeListener(TAG)
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_COMMON.type, LanSocketManager.commonListener)
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_TASK_DETAILS.type, typeTaskDetails)
LoginLanPassengerSocket.removeListener(TAG)
cleanStation("release")
}
fun setRouteLineInfoCallback(callback: ICommonCallback?) {
this.mCommonCallback = callback
}
open class CommonModel {
val connectDriverListener = object : IOchLanPassengerStatusListener {
// 和司机屏连接发生变化后
override fun onDriverConnectChangeListener(isConnect: Boolean) {
super.onDriverConnectChangeListener(isConnect)
if(isConnect){
queryDriverByLocalDriver()
}
}
// 司机屏sn 发生变化后
override fun onDriverSnChagneListner(sn: String?) {
super.onDriverSnChagneListner(sn)
sn?.let {
@@ -29,12 +123,170 @@ open class CommonModel {
}
}
val mMapLocationListener: IMoGoChassisLocationGCJ02Listener =
object : IMoGoChassisLocationGCJ02Listener {
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
if (null == mogoLocation) return
updateSpeed(mogoLocation)
}
}
val mAutoPilotStatusListener: IOchAutopilotStatusListener =
object : IOchAutopilotStatusListener {
override fun onAutopilotStatusResponse(state: Int) {
d(SceneConstant.M_BUS_P, "onAutopilotStatusResponse ===== $state")
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING != state){
//美化模式下且行程中
if (FunctionBuildConfig.isDemoMode &&
mNextStationIndex >= 0 && mNextStationIndex <= mStations.size - 1
&& isGoingToNextStation
){
mCommonCallback?.updateAutoStatus(true)
}else{//非美化模式下
mCommonCallback?.updateAutoStatus(false)
}
}else{//自驾状态 2
mCommonCallback?.updateAutoStatus(true)
}
}
}
val trajectoryListener: IDistanceListener = object : IDistanceListener {
override fun distanceCallback(distance: Float) {
val lastTime = distance / BusPassengerConst.BUS_AVERAGE_SPEED * 3.6 //秒
d(SceneConstant.M_BUS_P, "轨迹排查==lastSumLength = $distance")
if (routesResult != null) {
for (site in routesResult!!.sites) {
if (site.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && !site.isLeaving) {
return
}
}
}
// 小于200m 播报站点介绍
if (distance < 200) {
val stationNext = mStations[mNextStationIndex]
if (!stationNext.isPlayTts) {
if (!StringUtils.isEmpty(stationNext.introduction)) {
showNotice(stationNext.introduction)
stationNext.isPlayTts = true
}
}
}
mCommonCallback?.updateRemainMT(
distance.toLong(),
lastTime.toLong()
)
}
}
val typeTaskDetails = object : ILanMessageListener<TaskDetailsMsg> {
override fun targetLan(): Class<TaskDetailsMsg> {
return TaskDetailsMsg::class.java
}
override fun onLanMsgReceived(first: TaskDetailsMsg?) {
first?.let {
if (first.msg?.isEmpty() == true) {
clearLocalRouteResult()
return
}
val result = GsonUtils.fromJson(first.msg, BusTransferData::class.java)
if (result != null && result.routesResult == null) {
clearLocalRouteResult()
}
if (result != null) {
routesResult = result.routesResult
updatePassengerRouteInfo(routesResult)
}
}
}
}
val b1CommonListener = object : ILanMessageListener<AppConnectMsg> {
override fun targetLan(): Class<AppConnectMsg> = AppConnectMsg::class.java
override fun onLanMsgReceived(first: AppConnectMsg?) {
first?.let {
if (it.isViewShow) { //消息盒子显示内容
OCHSocketMessageManager.pushAppOperationalMsgBox(
DateTimeUtil.getCurrentTimeStamp(), it.msg,
OCHSocketMessageManager.OPERATION_SYSTEM
)
}
}
}
}
fun clearLocalRouteResult(){
routesResult = null
mNextStationIndex = 0
cleanStation("queryDriverSiteByCoordinate")
isGoingToNextStation = false
mCommonCallback?.showNoTaskView(true)
}
fun updatePassengerRouteInfo(result: BusRoutesResult?) {
if (result == null) {
clearLocalRouteResult()
return
}
if (routesResult != null && routesResult!!.lineId != result.lineId) {
d(SceneConstant.M_BUS_P + TAG, "lineId change= clearCustomPolyline")
mCommonCallback?.clearCustomPolyline()
}
d(SceneConstant.M_BUS_P + TAG, "queryDriverSiteByCoordinate = update")
routesResult = result
if (result.sites != null) {
mCommonCallback?.updateLineInfo(result.name)
mCommonCallback?.showNoTaskView(false)
if (result.sites != null) {
val stations = result.sites
mStations.clear()
mStations.addAll(stations)
mCommonCallback?.updateLineStations(mStations)
for (i in stations.indices) {
val station = stations[i]
if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED
&& station.isLeaving && i + 1 < stations.size
) {
isGoingToNextStation = true
mCommonCallback?.updateStationsInfo(stations, i + 1, false)
mNextStationIndex = i + 1
val startStation = mStations[i]
val endStation = mStations[i + 1]
startStationVideo(endStation)
setTrajectoryStation(startStation, endStation, result.lineId)
updateAutopilotControlParameters(result, i)
return
} else if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && !station.isLeaving) {
if (i == stations.size - 1) {
cleanStation("updatePassengerRouteInfo最后一个站点")
}
isGoingToNextStation = false
Logger.d(SceneConstant.M_BUS_P + TAG, "order = station= arrive")
mCommonCallback?.updateStationsInfo(stations, i, true)
clearAutopilotControlParameters()
return
}
}
}
}
}
// 向司机屏请求业务数据
fun queryDriverByLocalDriver() {
//本地去请求司机端
val msg = TaskDetailsMsg("task", BusinessType.shuttle)
LanSocketManager.sendMsgToServer(msg)
}
// 查询sn 所配置的所有站点介绍视频
private fun querySiteIntroduce(){
AbsMogoApplication.getApp()?.let {
if (ProjectUtils.isSaas()) {
@@ -54,7 +306,7 @@ open class CommonModel {
}
}
}
// 去统一下载站点介绍
private fun downloadSiteIntroduce(response: ResponseSiteIntroduce) {
response.data?.forEach {siteIntroduceInfo ->
siteIntroduceInfo.introduceList.forEach {introduceInfo ->
@@ -63,5 +315,101 @@ open class CommonModel {
}
}
fun updateAutopilotControlParameters(
busRoutesResult: BusRoutesResult,
leaveIndex: Int
) {
val parameters = initAutopilotControlParameters(busRoutesResult, leaveIndex)
if (null == parameters) {
CallerLogger.e(SceneConstant.M_BUS_P, "AutopilotControlParameters is empty.")
return
}
CallerLogger.d(SceneConstant.M_BUS_P, "AutopilotControlParameters is update.")
CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters(parameters)
}
fun initAutopilotControlParameters(
busRoutesResult: BusRoutesResult,
leaveIndex: Int
): AutopilotControlParameters? {
if (busRoutesResult.sites == null) {
return null
}
val stations = busRoutesResult.sites
if (leaveIndex + 1 > stations.size - 1) {
CallerLogger.e(SceneConstant.M_BUS_P, "行程日志-mismatch condition1.")
return null
}
val currentStation = stations[leaveIndex]
val nextStation = stations[leaveIndex + 1]
val parameters = AutopilotControlParameters()
parameters.routeID = busRoutesResult.lineId
parameters.routeName = busRoutesResult.name
parameters.startName = PinYinUtil.getPinYinHeadChar(currentStation.name)
parameters.endName = PinYinUtil.getPinYinHeadChar(nextStation.name)
parameters.startLatLon =
AutopilotControlParameters.AutoPilotLonLat(currentStation.lat, currentStation.lon)
parameters.endLatLon =
AutopilotControlParameters.AutoPilotLonLat(nextStation.lat, nextStation.lon)
parameters.vehicleType = 10
if (parameters.autoPilotLine == null) {
parameters.autoPilotLine = AutopilotControlParameters.AutoPilotLine(
busRoutesResult.lineId.toLong(), busRoutesResult.name,
busRoutesResult.csvFileUrl, busRoutesResult.csvFileMd5,
busRoutesResult.txtFileUrl, busRoutesResult.txtFileMd5,
busRoutesResult.contrailSaveTime, busRoutesResult.carModel,
busRoutesResult.csvFileUrlDPQP, busRoutesResult.csvFileMd5DPQP,
busRoutesResult.txtFileUrlDPQP, busRoutesResult.txtFileMd5DPQP,
busRoutesResult.contrailSaveTimeDPQP
)
}
return parameters
}
fun clearAutopilotControlParameters() {
CallerLogger.d(SceneConstant.M_BUS_P, "AutopilotControlParameters is clear.")
CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters(null)
}
fun startStationVideo(startStationInfo: BusStationBean){
val introductionList = mutableListOf<MediaItem>()
startStationInfo.videoList?.forEach {
if(it.type==1) {
introductionList.add(
MediaItem(
MediaItem.PrioritySite, it.url,
MediaItem.MEDIA_TYPE_VIDEO,"","")
)
}
}
MediaManager.postSiteIntroduceInfo(introductionList)
}
fun setTrajectoryStation(
startStationInfo: BusStationBean,
endStationInfo: BusStationBean,
lineId: Int
) {
val startStation = MogoLocation()
startStation.longitude = startStationInfo.gcjLon
startStation.latitude = startStationInfo.gcjLat
val endStation = MogoLocation()
endStation.longitude = endStationInfo.gcjLon
endStation.latitude = endStationInfo.gcjLat
TrajectoryAndDistanceManager.setStationPoint(startStation, endStation, lineId.toLong())
}
fun cleanStation(type: String) {
d(SceneConstant.M_BUS_P, "清理站点:$type")
TrajectoryAndDistanceManager.setStationPoint(null, null, -1L)
}
fun updateSpeed(mogoLocation: MogoLocation) {
// km/h
val speedKM = (abs(mogoLocation.gnssSpeed) * 3.6f).toInt()
mCommonCallback?.updateSpeed(speedKM)
}
}

View File

@@ -1,346 +0,0 @@
package com.mogo.och.shuttle.weaknet.passenger.model
import android.annotation.SuppressLint
import android.content.Context
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.StringUtils
import com.mogo.och.common.module.biz.lansocket.LoginLanPassengerSocket
import com.mogo.och.common.module.biz.media.MediaManager
import com.mogo.och.common.module.manager.autopilot.autopilot.IOchAutopilotStatusListener
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotStatusListenerManager
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager
import com.mogo.och.common.module.manager.distance.IDistanceListener
import com.mogo.och.common.module.manager.distance.TrajectoryAndDistanceManager
import com.mogo.och.common.module.manager.socket.lan.ILanMessageListener
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
import com.mogo.och.common.module.manager.socket.lan.bean.TaskDetailsMsg
import com.mogo.och.common.module.utils.PinYinUtil
import com.mogo.och.common.module.voice.VoiceNotice.showNotice
import com.mogo.och.common.module.wigets.media.MediaItem
import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.data.bean.BusStationBean
import com.mogo.och.data.bean.BusTransferData
import com.mogo.och.shuttle.weaknet.passenger.callback.AutoPilotStatusCallback
import com.mogo.och.shuttle.weaknet.passenger.callback.DrivingInfoCallback
import com.mogo.och.shuttle.weaknet.passenger.constant.BusPassengerConst
import kotlin.math.abs
/**
* @author: wangmingjun
* @date: 2023/1/31
*/
@SuppressLint("StaticFieldLeak")
object LineModel:CommonModel(){
private var mContext: Context? = null
private var routesResult: BusRoutesResult? = null
private val TAG: String = LineModel::class.java.simpleName
var mStations = mutableListOf<BusStationBean>()
private var mNextStationIndex = 0 // A-B要到达站的index
private var isGoingToNextStation = false //是否前往下一站过程中
private var mDrivingInfoCallback: DrivingInfoCallback? = null //行程信息
private var mAutoStatusCallback: AutoPilotStatusCallback? = null //自动驾驶状态
fun init(context: Context) {
mContext = context
initListener()
queryDriverByLocalDriver()
}
private fun initListener() {
//自动驾驶状态监听
OchAutoPilotStatusListenerManager.addListener(TAG, mAutoPilotStatusListener)
// 定位监听
OchLocationManager.addGCJ02Listener(TAG, 3, mMapLocationListener)
// 监听站点距离
TrajectoryAndDistanceManager.addDistanceListener(TAG, trajectoryListener)
// 通用监听
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_COMMON.type,LanSocketManager.commonListener)
// 监听站点信息
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_TASK_DETAILS.type,typeTaskDetails)
LoginLanPassengerSocket.addListener(TAG, connectDriverListener)
}
fun releaseListener() {
//自动驾驶状态监听
CallerAutoPilotStatusListenerManager.removeListener(TAG)
// 定位监听
OchLocationManager.removeGCJ02Listener(TAG)
// 监听站点距离
cleanStation("release")
TrajectoryAndDistanceManager.removeListener(TAG)
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_COMMON.type,LanSocketManager.commonListener)
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_TASK_DETAILS.type,typeTaskDetails)
LoginLanPassengerSocket.removeListener(TAG)
}
fun setDrivingInfoCallback(drivingInfoCallback : DrivingInfoCallback?){
mDrivingInfoCallback = drivingInfoCallback
}
fun setAutoStatusCallback(autoPilotStatusCallback: AutoPilotStatusCallback?){
mAutoStatusCallback = autoPilotStatusCallback
}
private val typeTaskDetails = object : ILanMessageListener<TaskDetailsMsg> {
override fun targetLan(): Class<TaskDetailsMsg> {
return TaskDetailsMsg::class.java
}
override fun onLanMsgReceived(first: TaskDetailsMsg?) {
first?.let {
if (first.msg?.isEmpty() == true) {
updateLocalOrder()
return
}
val result = GsonUtils.fromJson(first.msg, BusTransferData::class.java)
if (result != null && result.routesResult == null){
updateLocalOrder()
}
if (result != null) {
routesResult = result.routesResult
updatePassengerRouteInfo(routesResult!!)
}
}
}
}
private val trajectoryListener: IDistanceListener = object : IDistanceListener {
override fun distanceCallback(distance: Float) {
val lastTime = distance / BusPassengerConst.BUS_AVERAGE_SPEED * 3.6 //秒
d(SceneConstant.M_BUS_P + TAG, "轨迹排查==lastSumLength = $distance")
if (routesResult != null) {
for (site in routesResult!!.sites) {
if (site.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && !site.isLeaving) {
return
}
}
}
// 小于200m 播报站点介绍
if (distance < 200) {
val stationNext = mStations[mNextStationIndex]
if (!stationNext.isPlayTts) {
if (!StringUtils.isEmpty(stationNext.introduction)) {
showNotice(stationNext.introduction)
stationNext.isPlayTts = true
}
}
}
mDrivingInfoCallback?.updateRemainMT(
distance.toLong(),
lastTime.toLong()
)
}
}
private val mMapLocationListener: IMoGoChassisLocationGCJ02Listener =
object : IMoGoChassisLocationGCJ02Listener{
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
if (null == mogoLocation) return
updateSpeed(mogoLocation)
}
}
private fun updateSpeed(mogoLocation: MogoLocation) {
// km/h
val speedKM = (abs(mogoLocation.gnssSpeed) * 3.6f).toInt()
mDrivingInfoCallback?.updateSpeed(speedKM)
}
private val mAutoPilotStatusListener: IOchAutopilotStatusListener =
object : IOchAutopilotStatusListener {
override fun onAutopilotStatusResponse(state: Int) {
super.onAutopilotStatusResponse(state)
d(SceneConstant.M_BUS_P+ TAG, "onAutopilotStatusResponse ===== $state")
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING != state){
//美化模式下且行程中
if (FunctionBuildConfig.isDemoMode &&
mNextStationIndex>= 0 && mNextStationIndex <= mStations.size - 1
&& isGoingToNextStation){
mAutoStatusCallback?.updateAutoStatus(true)
}else{//非美化模式下
mAutoStatusCallback?.updateAutoStatus(false)
}
}else{//自驾状态 2
mAutoStatusCallback?.updateAutoStatus(true)
}
}
}
private fun updateLocalOrder(){
routesResult = null
mNextStationIndex = 0
cleanStation("queryDriverSiteByCoordinate")
isGoingToNextStation = false
mDrivingInfoCallback?.showNoTaskView(true)
}
private fun updatePassengerRouteInfo(result: BusRoutesResult) {
if (routesResult != null && routesResult!!.lineId != result.lineId){
d(SceneConstant.M_BUS_P+ TAG, "lineId change= clearCustomPolyline")
mDrivingInfoCallback?.clearCustomPolyline()
}
d(SceneConstant.M_BUS_P+ TAG, "queryDriverSiteByCoordinate= update")
routesResult = result
mDrivingInfoCallback?.updateLine(result.name)
if (result.sites != null) {
mDrivingInfoCallback?.showNoTaskView(false)
val stations: List<BusStationBean> = result.sites
mStations.clear()
mStations.addAll(stations)
mDrivingInfoCallback?.updateLineStations(mStations)
for (i in stations.indices) {
val station: BusStationBean = stations[i]
if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED
&& station.isLeaving && i + 1 < stations.size) {
mDrivingInfoCallback?.updateStationsInfo(stations as MutableList<BusStationBean>, i + 1, false)
d(SceneConstant.M_BUS_P+ TAG,"och-rotting--mNextStationIndex = $mNextStationIndex , i = $i")
d(SceneConstant.M_BUS_P+ TAG,"och-rotting--start ")
isGoingToNextStation = true
mNextStationIndex = i + 1
val startStation = mStations[i]
val endStation = mStations[i + 1]
startStationVideo(endStation)
setTrajectoryStation(startStation, endStation, result.lineId)
updateAutopilotControlParameters(result,i)
return
} else if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && !station.isLeaving) {
d(SceneConstant.M_BUS_P+ TAG,"och-rotting--mNextStationIndex = $mNextStationIndex , i = $i")
d(SceneConstant.M_BUS_P+ TAG,"och-rotting--arrived ")
if (i == stations.size - 1) {
cleanStation("updatePassengerRouteInfo最后一个站点")
}
isGoingToNextStation = false
mDrivingInfoCallback?.updateStationsInfo(stations as MutableList<BusStationBean>, i, true)
clearAutopilotControlParameters()
return
}else{
// d(SceneConstant.M_BUS_P+TAG,"och-rotting--BusStationBean = " + GsonUtils.toJson(station))
}
}
}
}
private fun setTrajectoryStation(
startStationInfo: BusStationBean,
endStationInfo: BusStationBean,
lineId: Int
) {
val startStation = MogoLocation()
startStation.longitude = startStationInfo.gcjLon
startStation.latitude = startStationInfo.gcjLat
val endStation = MogoLocation()
endStation.longitude = endStationInfo.gcjLon
endStation.latitude = endStationInfo.gcjLat
TrajectoryAndDistanceManager.setStationPoint(startStation, endStation, lineId.toLong())
}
private fun startStationVideo(startStationInfo: BusStationBean){
val introductionList = mutableListOf<MediaItem>()
startStationInfo.videoList?.forEach {
if(it.type==1) {
introductionList.add(
MediaItem(
MediaItem.PrioritySite, it.url,
MediaItem.MEDIA_TYPE_VIDEO,"","")
)
}
}
MediaManager.postSiteIntroduceInfo(introductionList)
}
private fun cleanStation(type: String) {
d(SceneConstant.M_BUS_P + TAG, "清理站点:$type")
TrajectoryAndDistanceManager.setStationPoint(null, null, -1L)
}
private fun updateAutopilotControlParameters(
busRoutesResult: BusRoutesResult,
leaveIndex: Int
) {
val parameters = initAutopilotControlParameters(busRoutesResult, leaveIndex)
if (null == parameters) {
CallerLogger.e(SceneConstant.M_BUS_P + TAG, "AutopilotControlParameters is empty.")
return
}
CallerLogger.d(SceneConstant.M_BUS_P + TAG, "AutopilotControlParameters is update.")
CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters(parameters)
}
private fun initAutopilotControlParameters(
busRoutesResult: BusRoutesResult,
leaveIndex: Int
): AutopilotControlParameters? {
if (busRoutesResult.sites == null) {
return null
}
val stations = busRoutesResult.sites
if (leaveIndex + 1 > stations.size - 1) {
CallerLogger.e(SceneConstant.M_BUS_P + TAG, "行程日志-mismatch condition1.")
return null
}
val currentStation = stations[leaveIndex]
val nextStation = stations[leaveIndex + 1]
val parameters = AutopilotControlParameters()
parameters.routeID = busRoutesResult.lineId
parameters.routeName = busRoutesResult.name
parameters.startName = PinYinUtil.getPinYinHeadChar(currentStation.name)
parameters.endName = PinYinUtil.getPinYinHeadChar(nextStation.name)
parameters.startLatLon =
AutopilotControlParameters.AutoPilotLonLat(currentStation.lat, currentStation.lon)
parameters.endLatLon =
AutopilotControlParameters.AutoPilotLonLat(nextStation.lat, nextStation.lon)
parameters.vehicleType = 10
if (parameters.autoPilotLine == null) {
parameters.autoPilotLine = AutopilotControlParameters.AutoPilotLine(
busRoutesResult.lineId.toLong(), busRoutesResult.name,
busRoutesResult.csvFileUrl, busRoutesResult.csvFileMd5,
busRoutesResult.txtFileUrl, busRoutesResult.txtFileMd5,
busRoutesResult.contrailSaveTime, busRoutesResult.carModel,
busRoutesResult.csvFileUrlDPQP, busRoutesResult.csvFileMd5DPQP,
busRoutesResult.txtFileUrlDPQP, busRoutesResult.txtFileMd5DPQP,
busRoutesResult.contrailSaveTimeDPQP
)
}
return parameters
}
private fun clearAutopilotControlParameters() {
CallerLogger.d(SceneConstant.M_BUS_P + TAG, "AutopilotControlParameters is clear.")
CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters(null)
}
}

View File

@@ -1,35 +1,143 @@
package com.mogo.och.shuttle.weaknet.passenger.model
import com.mogo.commons.AbsMogoApplication
import android.annotation.SuppressLint
import android.bluetooth.BluetoothDevice
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS_P
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.RegexUtils
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffMsg
import com.mogo.och.common.module.manager.bluetooth.BleDevItem
import com.mogo.och.common.module.manager.bluetooth.BleManager
import com.mogo.och.common.module.manager.bluetooth.BleManager.BleDevListener
import com.mogo.och.common.module.manager.bluetooth.OchBluetoothGattCallback.ConnectListener
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.shuttle.weaknet.passenger.bean.request.PassengerWriteOffRequest
import com.mogo.och.shuttle.weaknet.passenger.bean.response.PassengerWriteOffResponse
import com.mogo.och.common.module.manager.scnner.ScannerManager
import com.mogo.och.common.module.manager.scnner.StateChangeListener
import com.mogo.och.shuttle.weaknet.passenger.network.PassengerServiceManager
import com.mogo.och.common.module.manager.socket.lan.ILanMessageListener
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDetialMsg
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffResultMsg
import com.mogo.och.common.module.utils.RxUtils
import java.net.URLDecoder
object TicketModel : StateChangeListener {
private const val TAG = "TicketModel"
init {
ScannerManager.addStateChangeListener(TAG, this)
// 等待链接
private val waitConnectDev = mutableListOf<BleDevItem>()
private val waitConnectDevNameList = mutableListOf<String>()
private val connectListener: ConnectListener = object : ConnectListener {
override fun sendDataSuccessAndCloseListener(device: BluetoothDevice) {
waitConnectDev.forEach {
if(it.dev==device){
waitConnectDev.remove(it)
return
}
}
}
}
init {
}
private val writeOffResultMsg = object : ILanMessageListener<WriteOffResultMsg> {
override fun targetLan(): Class<WriteOffResultMsg> = WriteOffResultMsg::class.java
override fun onLanMsgReceived(obj: WriteOffResultMsg?) {
findDeviceConnectAndSendData(obj,1)
}
}
@SuppressLint("MissingPermission")
private fun findDeviceConnectAndSendData(obj: WriteOffResultMsg?,count:Int){
OchChainLogManager.writeChainLogWriteOff("司机端核销成功","去连接蓝牙并发送数据 次数:${count}")
// 收到核销结果扫描蓝牙并写会核销结果
obj?.phone?.let {phone->
var haveDevices = false
var tempRemove:BleDevItem?=null
waitConnectDev.forEach {
if(it.dev.name == getBleName(phone)){
haveDevices = true
OchChainLogManager.writeChainLogWriteOff("司机端核销结果","${obj}_找到设备dev.name:${it.dev.name}${getBleName(phone)}")
when (obj.code) {
99 -> {
it.gattcallback.connectGatt("99",obj.businessTime)
}
0 -> {
it.gattcallback.connectGatt("00",obj.businessTime)
}
else -> {
it.gattcallback.connectGatt("01",obj.businessTime)
}
}
it.gattcallback.connectListener = connectListener
tempRemove = it
return@forEach
}
}
waitConnectDev.remove(tempRemove)
if(!haveDevices&&count<6){
RxUtils.createSubscribe {
// 没有找到设备重试5次
OchChainLogManager.writeChainLogWriteOff("司机端核销成功","2s后重试")
findDeviceConnectAndSendData(obj,count+1)
}
}
}
}
private val bleDevs = object : BleDevListener{
@SuppressLint("MissingPermission")
@Synchronized
override fun dataChange(scanList: MutableList<BleDevItem>) {
val tempList = mutableListOf<String>()
waitConnectDevNameList.forEach { waitConnectName->
scanList.forEach {
if(it.dev.name==waitConnectName){
waitConnectDev.add(it)
tempList.add(waitConnectName)
}
}
}
waitConnectDevNameList.removeAll(tempList)
}
}
fun load(){
OchChainLogManager.writeChainLogInit("初始化信息","核销功能初始化")
ScannerManager.addStateChangeListener(TAG, this)
// 核销信息
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_WRITEOFF_INFO_RESULT.type,writeOffResultMsg)
BleManager.listener = bleDevs
}
fun release(){
ScannerManager.removeListener(TAG)
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_WRITEOFF_INFO_RESULT.type,writeOffResultMsg)
BleManager.listener = null
}
override fun parseData(params: MutableMap<String, Any>, payload: String?) {
override fun parseData(params: MutableMap<String, String>, payload: String?) {
val expiryTime = params["expiryTime"]
val bookingTime = params["bookingTime"]
val lineId = params["lineId"]
val availableTimes = params["availableTimes"]
val orderNo = params["orderNo"]
val uid = params["uid"]
val phone = params["phone"]
val ticketSize = params["ticketSize"]
val ticketName = params["ticketName"]
val type = params["type"]
val pipe = params["pipe"]
val startStationId = params["startStationId"]
val tenantId = params["tenantId"]
if(orderNo is String && uid is String){
var phoneNum = ""
if(phone is String){
@@ -37,99 +145,67 @@ object TicketModel : StateChangeListener {
phoneNum = phone
}
}
writeOffTicket(orderNo,uid,phoneNum)
try {
val writeOffDetail = WriteOffDetialMsg(0,"",
expiryTime?.toLong()?:0,
bookingTime?.toLong()?:0,
lineId?.toLong()?:0,
availableTimes?.toInt()?:0,
orderNo,
uid,
phoneNum,
ticketSize?.toInt()?:0,
URLDecoder.decode(ticketName,"UTF-8"),
type,
pipe,
startStationId?.toLong()?:0,
tenantId?.toLong()?:0
)
CallerLogger.d(M_BUS_P + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(writeOffDetail))
LanSocketManager.sendMsgToServer(writeOffDetail)
addWaitConnectDevName(phone)
scanBle()
}catch (e:Exception){
e.printStackTrace()
CallerLogger.d(M_BUS_P + TAG, "")
// 通知司机屏二维码错误
val writeOffDetail = WriteOffDetialMsg(code = 3001, msg = "参数错误:${payload}")
CallerLogger.d(M_BUS_P + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(writeOffDetail))
LanSocketManager.sendMsgToServer(writeOffDetail)
}
}else{
// 通知司机屏二维码错误
sendMessage2Driver("参数错误:${payload}","")
val writeOffDetail = WriteOffDetialMsg(code = 3001, msg = "参数错误:${payload}")
CallerLogger.d(M_BUS_P + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(writeOffDetail))
LanSocketManager.sendMsgToServer(writeOffDetail)
}
}
private fun writeOffTicket(orderNo: String, uid: String, phoneNum: String) {
val passengerWriteOffRequest = PassengerWriteOffRequest(orderNo, uid)
PassengerServiceManager.writeOffTicket(AbsMogoApplication.getApp(),
passengerWriteOffRequest,
object : OchCommonServiceCallback<PassengerWriteOffResponse> {
override fun onSuccess(data: PassengerWriteOffResponse?) {
if (data?.data == null) return
val ticketInfo =
"核销成功:票种名称:${data.data.ticketName},车票数量:${data.data.ticketSize},预留手机号:${data.data.phone},时间:${data.data.remainingTimes}"
CallerLogger.d(M_BUS_P + TAG, ticketInfo)
sendMessage2DriverSuccess(data.data,orderNo)
}
private fun addWaitConnectDevName(phone: String?) {
var tempPhone = phone
tempPhone?.let {
waitConnectDevNameList.add( getBleName(it))
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(M_BUS_P + TAG, "核销失败 ${code}-----${msg}")
}
when (code) {
6002 -> {
sendMessage2Driver("同一订单核销间隔时间需大于2分钟",phoneNum)
}
1009 -> {
sendMessage2Driver("车票所选乘车日期非今日",phoneNum)
}
1005 -> {
sendMessage2Driver("车辆未登录、或没有任务",phoneNum)
}
1006 -> {
sendMessage2Driver("车票路线信息与当前车辆执行任务的路线信息不符合",phoneNum)
}
1008 -> {
sendMessage2Driver("车票剩余可用次数为0",phoneNum)
}
6001 -> {
sendMessage2Driver("二维码已过期",phoneNum)
}
1012 -> {
sendMessage2Driver("当前用户下单路线非当前的车辆所属公司",phoneNum)
}
else -> {
when (msg) {
"6002" -> {
sendMessage2Driver("同一订单核销间隔时间需大于2分钟",phoneNum)
}
"1009" -> {
sendMessage2Driver("车票所选乘车日期非今日",phoneNum)
}
"1005" -> {
sendMessage2Driver("车辆未登录、或没有任务",phoneNum)
}
"1006" -> {
sendMessage2Driver("车票路线信息与当前车辆执行任务的路线信息不符合",phoneNum)
}
"1008" -> {
sendMessage2Driver("车票剩余可用次数为0",phoneNum)
}
"6001" -> {
sendMessage2Driver("二维码已过期",phoneNum)
}
"1012" -> {
sendMessage2Driver("当前用户下单路线非当前的车辆所属公司",phoneNum)
}
else -> {
sendMessage2Driver(msg?:"",phoneNum)
}
}
}
}
}
override fun onError(message: String) {
sendMessage2Driver("网络错误",phoneNum)
}
fun getBleName(phone: String):String{
var tempPhone = phone
tempPhone.let {
if (it.length > 8) {
//截取电话号码前三位
val phoneNumPre = it.substring(0, 3)
//截取电话号码后四位
val phoneNumFix = it.substring(7)
tempPhone = "${phoneNumPre}$phoneNumFix"
}
)
}
return tempPhone
}
private fun sendMessage2Driver(message:String,phone:String){
val msg = WriteOffMsg(false, phone, 0, "", "验票失败,${message}","")
CallerLogger.d(M_BUS_P + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg))
LanSocketManager.sendMsgToServer(msg)
private fun scanBle() {
BizLoopManager.runInMainThread{
BleManager.scanLeDevice()
}
}
private fun sendMessage2DriverSuccess(message: PassengerWriteOffResponse.Result, orderNo: String){
val msg = WriteOffMsg(true, message.phone, message.ticketSize, message.ticketName, "",orderNo)
CallerLogger.d(M_BUS_P + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg))
LanSocketManager.sendMsgToServer(msg)
}
}

View File

@@ -2,22 +2,13 @@ package com.mogo.och.shuttle.weaknet.passenger.network
import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.commons.env.ProjectUtils
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.utilcode.util.StringUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.biz.lansocket.LoginLanPassengerSocket
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.common.module.network.OchCommonSubscribeImpl
import com.mogo.och.common.module.network.interceptor.transformTry
import com.mogo.och.shuttle.weaknet.passenger.bean.request.PassengerQueryLineRequest
import com.mogo.och.shuttle.weaknet.passenger.bean.request.PassengerWriteOffRequest
import com.mogo.och.shuttle.weaknet.passenger.bean.response.PassengerOperationStatusResponse
import com.mogo.och.shuttle.weaknet.passenger.bean.response.PassengerRoutesResponse
import com.mogo.och.shuttle.weaknet.passenger.bean.response.PassengerWriteOffResponse
import com.mogo.och.shuttle.weaknet.passenger.bean.response.ResponseSiteIntroduce
/**
@@ -32,43 +23,7 @@ object PassengerServiceManager {
ServiceApi::class.java)
/**
* 查询司机端出车收车状态,以及车牌号
* @param context
* @param callback
*/
@JvmStatic
fun writeOffTicket(
context: Context,
ticketInfo: PassengerWriteOffRequest,
callback: OchCommonServiceCallback<PassengerWriteOffResponse>?,
) {
ticketInfo.sn = LoginLanPassengerSocket.driverSn
if(StringUtils.isEmpty(LoginLanPassengerSocket.driverSn)){
ToastUtils.showShort("请链接司机屏${ticketInfo.uid}")
OchChainLogManager.writeChainLogScanner(TAG +"onError","无司机屏sn请处理")
return
}
if(ProjectUtils.isSaas()) {
mShuttleBusPassengerServiceApi.saaswriteOffTicket(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
SharedPrefsMgr.getInstance().token,
ticketInfo
)
.transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "writeOff"))
}else if(ProjectUtils.isDali()) {
mShuttleBusPassengerServiceApi.daliwriteOffTicket(
MoGoAiCloudClientConfig.getInstance().serviceAppId,
SharedPrefsMgr.getInstance().token,
ticketInfo
)
.transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "writeOff"))
}
}
/**
* 查询绑定行驶的小巴车路线
* 查询绑定行驶的小巴车路线包含站点的站点广告
* @param context
* @param callback
*/

View File

@@ -19,19 +19,7 @@ import retrofit2.http.Query;
*/
public interface ServiceApi {
/**
* 核销接口
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("/och-vehicle/api/scanner/device/writeOff")
Observable<PassengerWriteOffResponse> daliwriteOffTicket(@Header ("appId") String appId, @Header("ticket") String ticket, @Body PassengerWriteOffRequest request);
/**
* 核销接口
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("/och-vehicle/api/car/v2/device/writeOff")
Observable<PassengerWriteOffResponse> saaswriteOffTicket(@Header ("appId") String appId, @Header("ticket") String ticket, @Body PassengerWriteOffRequest request);
/**
* 查询车辆对应站点的所有视频介绍视频

View File

@@ -1,9 +0,0 @@
package com.mogo.och.shuttle.weaknet.passenger.callback;
/**
* @author: wangmingjun
* @date: 2021/10/22
*/
public interface IBusPassegerDriverStatusCallback {
void changeOperationStatus(boolean changeStatus);
}

View File

@@ -1,18 +0,0 @@
package com.mogo.och.shuttle.weaknet.passenger.callback;
/**
* Created on 2022/3/31
*
* Model->Presenter回调ADAS相关自动驾驶状态回调到达终点等等
*/
public interface IBusPassengerADASStatusCallback {
// 自动驾驶可用状态
void onAutopilotEnable();
// 自动驾驶不可用状态
void onAutopilotDisable();
// 自动驾驶运行中
void onAutopilotRunning();
}

View File

@@ -1,9 +0,0 @@
package com.mogo.och.shuttle.weaknet.passenger.callback;
/**
* Created on 2022/3/31
*/
public interface IBusPassengerAutopilotPlanningCallback {
void routePlanningToNextStationChanged(long meters, long timeInSecond);
}

View File

@@ -1,13 +0,0 @@
package com.mogo.och.shuttle.weaknet.passenger.callback;
import com.mogo.eagle.core.data.map.MogoLocation;
/**
* Created on 2022/3/31
*
* Model->Presenter回调状态控制器监听accOn、adas ui show、voice ui show、push ui show、v2x ui show等等
*/
public interface IBusPassengerControllerStatusCallback {
// 自车定位
void onCarLocationChanged(MogoLocation location);
}

View File

@@ -1,16 +0,0 @@
package com.mogo.och.shuttle.weaknet.passenger.callback;
import com.mogo.och.data.bean.BusStationBean;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2022/4/6
*/
public interface IBusPassengerRouteLineInfoCallback {
void updateLineInfo(String lineName);
void updateStationsInfo(List<BusStationBean> stations, int currentStationIndex, boolean isArrived);
void showNoTaskView();
void hideNoTaskView();
}

View File

@@ -1,390 +0,0 @@
package com.mogo.och.shuttle.weaknet.passenger.model
import android.annotation.SuppressLint
import android.content.Context
import com.mogo.aicloud.services.socket.MogoAiCloudSocketManager
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.StringUtils
import com.mogo.och.common.module.biz.lansocket.IOchLanPassengerStatusListener
import com.mogo.och.common.module.biz.lansocket.LoginLanPassengerSocket
import com.mogo.och.common.module.biz.media.MediaManager
import com.mogo.och.common.module.manager.autopilot.autopilot.IOchAutopilotStatusListener
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotStatusListenerManager
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager
import com.mogo.och.common.module.manager.distance.IDistanceListener
import com.mogo.och.common.module.manager.distance.TrajectoryAndDistanceManager
import com.mogo.och.common.module.manager.socket.cloud.AbnormalFactorsLoopManager
import com.mogo.och.common.module.manager.socket.cloud.OCHSocketMessageManager
import com.mogo.och.common.module.manager.socket.lan.ILanMessageListener
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
import com.mogo.och.common.module.manager.socket.lan.bean.AppConnectMsg
import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
import com.mogo.och.common.module.manager.socket.lan.bean.TaskDetailsMsg
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.common.module.utils.PinYinUtil
import com.mogo.och.common.module.voice.VoiceNotice.showNotice
import com.mogo.och.common.module.wigets.media.MediaItem
import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.data.bean.BusStationBean
import com.mogo.och.data.bean.BusTransferData
import com.mogo.och.shuttle.weaknet.passenger.callback.IBusPassegerDriverStatusCallback
import com.mogo.och.shuttle.weaknet.passenger.callback.IBusPassengerADASStatusCallback
import com.mogo.och.shuttle.weaknet.passenger.callback.IBusPassengerAutopilotPlanningCallback
import com.mogo.och.shuttle.weaknet.passenger.callback.IBusPassengerControllerStatusCallback
import com.mogo.och.shuttle.weaknet.passenger.callback.IBusPassengerRouteLineInfoCallback
import com.mogo.och.shuttle.weaknet.passenger.constant.BusPassengerConst
import java.util.concurrent.ConcurrentHashMap
/**
* Created on 2022/3/31
*/
@SuppressLint("StaticFieldLeak")
object BusPassengerModel :CommonModel(){
private val TAG: String = BusPassengerModel::class.java.simpleName
private var mContext: Context? = null
private var mADASStatusCallback: IBusPassengerADASStatusCallback? = null //Model->Presenter自动驾驶状态相关
private var mAutopilotPlanningCallback: IBusPassengerAutopilotPlanningCallback? = null //Model->Presenter自动驾驶线路规划
private val mControllerStatusCallbackMap: MutableMap<String, IBusPassengerControllerStatusCallback> = ConcurrentHashMap()
private var mDriverStatusCallback: IBusPassegerDriverStatusCallback? = null //出车收车状态
private var mRouteLineInfoCallback: IBusPassengerRouteLineInfoCallback? = null // bus路线信息更新
private var routesResult: BusRoutesResult? = null
var mStations: MutableList<BusStationBean> = ArrayList()
private var mNextStationIndex = 0 // 要到达站的index
@Volatile
private var isGoingToNextStation = false
fun init(context: Context) {
mContext = context.applicationContext
initListeners()
queryDriverByLocalDriver()
}
fun setDriverStatusCallback(callback: IBusPassegerDriverStatusCallback?) {
this.mDriverStatusCallback = callback
}
fun setRouteLineInfoCallback(callback: IBusPassengerRouteLineInfoCallback?) {
this.mRouteLineInfoCallback = callback
}
fun setMoGoAutopilotPlanningListener(moGoAutopilotPlanningCallback: IBusPassengerAutopilotPlanningCallback?) {
this.mAutopilotPlanningCallback = moGoAutopilotPlanningCallback
}
fun setADASStatusCallback(callback: IBusPassengerADASStatusCallback?) {
this.mADASStatusCallback = callback
}
fun setControllerStatusCallback(
tag: String?,
callback: IBusPassengerControllerStatusCallback?
) {
if (tag == null || "" == tag) return
if (callback == null) {
mControllerStatusCallbackMap.remove(tag)
return
}
mControllerStatusCallbackMap[tag] = callback
}
private fun clearLocalRouteResult() {
if (routesResult != null) {
routesResult = null
}
mNextStationIndex = 0
cleanStation("queryDriverSiteByCoordinate")
if (mRouteLineInfoCallback != null) {
mRouteLineInfoCallback!!.showNoTaskView()
}
}
private fun updatePassengerRouteInfo(result: BusRoutesResult?) {
if (result == null) {
clearLocalRouteResult()
return
}
d(SceneConstant.M_BUS_P + TAG, "queryDriverSiteByCoordinate = update")
routesResult = result
if (mRouteLineInfoCallback != null) {
mRouteLineInfoCallback!!.updateLineInfo(result.name)
mRouteLineInfoCallback!!.hideNoTaskView()
if (result.sites != null) {
val stations = result.sites
mStations.clear()
mStations.addAll(stations)
for (i in stations.indices) {
val station = stations[i]
if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && station.isLeaving && i + 1 < stations.size) {
Logger.d(SceneConstant.M_BUS_P + TAG, "order = station= leave")
isGoingToNextStation = true
mRouteLineInfoCallback!!.updateStationsInfo(stations, i + 1, false)
mNextStationIndex = i + 1
val startStation = mStations[i]
val endStation = mStations[i + 1]
startStationVideo(endStation)
setTrajectoryStation(startStation, endStation, result.lineId)
updateAutopilotControlParameters(result,i)
return
} else if (station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && !station.isLeaving) {
if (i == stations.size - 1) {
cleanStation("updatePassengerRouteInfo最后一个站点")
}
isGoingToNextStation = false
Logger.d(SceneConstant.M_BUS_P + TAG, "order = station= arrive")
mRouteLineInfoCallback!!.updateStationsInfo(stations, i, true)
clearAutopilotControlParameters()
return
}
}
}
}
}
fun release() {
releaseListeners()
cleanStation("release")
}
private fun initListeners() {
// 2021.11.1重构自动驾驶 实现接口 IMoGoAutopilotStatusListener 注册监听 替换IMogoAdasOCHCallback接口
OchAutoPilotStatusListenerManager.addListener(TAG, mGoAutopilotStatusListener)
OchLocationManager.addGCJ02Listener(TAG, 3, mMapLocationListener)
// 通用监听
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_COMMON.type, commonListener)
// 监听站点信息
LanSocketManager.registerSocketMessageListener(DPMsgType.TYPE_TASK_DETAILS.type, typeTaskDetails)
AbnormalFactorsLoopManager.startLoopAbnormalFactors(mContext!!)
TrajectoryAndDistanceManager.addDistanceListener(TAG, trajectoryListener)
LoginLanPassengerSocket.addListener(TAG,connectDriverListener)
}
private fun releaseListeners() {
// 注销定位监听
OchLocationManager.removeGCJ02Listener(TAG)
MogoAiCloudSocketManager.getInstance(mContext)
.unregisterLifecycleListener(10010)
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_COMMON.type, commonListener)
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_TASK_DETAILS.type, typeTaskDetails)
AbnormalFactorsLoopManager.stopLoopAbnormalFactors()
LoginLanPassengerSocket.removeListener(TAG)
}
private val commonListener = object : ILanMessageListener<AppConnectMsg> {
override fun targetLan(): Class<AppConnectMsg> = AppConnectMsg::class.java
override fun onLanMsgReceived(first: AppConnectMsg?) {
first?.let {
if (it.isViewShow) { //消息盒子显示内容
OCHSocketMessageManager.pushAppOperationalMsgBox(
DateTimeUtil.getCurrentTimeStamp(), it.msg,
OCHSocketMessageManager.OPERATION_SYSTEM
)
}
}
}
}
private val typeTaskDetails = object : ILanMessageListener<TaskDetailsMsg> {
override fun targetLan(): Class<TaskDetailsMsg> = TaskDetailsMsg::class.java
override fun onLanMsgReceived(first: TaskDetailsMsg?) {
first?.let {
if (first.msg!!.isEmpty()) {
clearLocalRouteResult()
return
}
val result = GsonUtils.fromJson(first.msg, BusTransferData::class.java)
if (result != null && result.routesResult == null){
clearLocalRouteResult()
}
mDriverStatusCallback?.changeOperationStatus(result!!.loginStatus == 1)
if (result != null) { //已司机端传来的为准
routesResult = result.routesResult
updatePassengerRouteInfo(routesResult)
}
}
}
}
private val trajectoryListener: IDistanceListener = object : IDistanceListener {
override fun distanceCallback(distance: Float) {
val lastTime = distance / BusPassengerConst.BUS_AVERAGE_SPEED * 3.6 //秒
d(SceneConstant.M_BUS_P + TAG, "轨迹排查==lastSumLength = $distance")
if (routesResult != null) {
for (site in routesResult!!.sites) {
if (site.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED && !site.isLeaving) {
return
}
}
}
// 小于200m 播报站点介绍
if (distance < 200) {
val stationNext = mStations[mNextStationIndex]
if (!stationNext.isPlayTts) {
if (!StringUtils.isEmpty(stationNext.introduction)) {
showNotice(stationNext.introduction)
stationNext.isPlayTts = true
}
}
}
mAutopilotPlanningCallback!!.routePlanningToNextStationChanged(
distance.toLong(), lastTime.toLong()
)
}
}
private val mMapLocationListener: IMoGoChassisLocationGCJ02Listener =
object : IMoGoChassisLocationGCJ02Listener {
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
if (null == mogoLocation) return
for (callback in mControllerStatusCallbackMap.values) {
callback.onCarLocationChanged(mogoLocation)
}
}
}
private val mGoAutopilotStatusListener: IOchAutopilotStatusListener =
object : IOchAutopilotStatusListener {
override fun onAutopilotStatusResponse(state: Int) {
if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
//2022.7.20 自动驾驶更换成带档位的
if (mADASStatusCallback != null) mADASStatusCallback!!.onAutopilotRunning()
} else {
if (FunctionBuildConfig.isDemoMode && mNextStationIndex >= 0 && mNextStationIndex <= mStations.size - 1 && isGoingToNextStation) {
Logger.d(
SceneConstant.M_BUS_P + TAG,
"FunctionBuildConfig.isDemoMode is true"
)
return
}
if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE) {
if (mADASStatusCallback != null) mADASStatusCallback!!.onAutopilotEnable()
} else if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE) {
if (mADASStatusCallback != null) mADASStatusCallback!!.onAutopilotDisable()
} else if (state == IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING) {
if (mADASStatusCallback != null) mADASStatusCallback!!.onAutopilotRunning()
}
}
}
}
private fun setTrajectoryStation(
startStationInfo: BusStationBean,
endStationInfo: BusStationBean,
lineId: Int
) {
val startStation = MogoLocation()
startStation.longitude = startStationInfo.gcjLon
startStation.latitude = startStationInfo.gcjLat
val endStation = MogoLocation()
endStation.longitude = endStationInfo.gcjLon
endStation.latitude = endStationInfo.gcjLat
TrajectoryAndDistanceManager.setStationPoint(startStation, endStation, lineId.toLong())
}
private fun startStationVideo(startStationInfo: BusStationBean){
val introductionList = mutableListOf<MediaItem>()
startStationInfo.videoList?.forEach {
if(it.type==1) {
introductionList.add(
MediaItem(
MediaItem.PrioritySite, it.url,
MediaItem.MEDIA_TYPE_VIDEO,"","")
)
}
}
MediaManager.postSiteIntroduceInfo(introductionList)
}
private fun cleanStation(type: String) {
d(SceneConstant.M_BUS_P + TAG, "清理站点:$type")
TrajectoryAndDistanceManager.setStationPoint(null, null, -1L)
}
private fun updateAutopilotControlParameters(
busRoutesResult: BusRoutesResult,
leaveIndex: Int
) {
val parameters = initAutopilotControlParameters(busRoutesResult, leaveIndex)
if (null == parameters) {
CallerLogger.e(SceneConstant.M_BUS_P + TAG, "AutopilotControlParameters is empty.")
return
}
CallerLogger.d(SceneConstant.M_BUS_P + TAG, "AutopilotControlParameters is update.")
CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters(parameters)
}
private fun initAutopilotControlParameters(
busRoutesResult: BusRoutesResult,
leaveIndex: Int
): AutopilotControlParameters? {
if (busRoutesResult.sites == null) {
return null
}
val stations = busRoutesResult.sites
if (leaveIndex + 1 > stations.size - 1) {
CallerLogger.e(SceneConstant.M_BUS_P + TAG, "行程日志-mismatch condition1.")
return null
}
val currentStation = stations[leaveIndex]
val nextStation = stations[leaveIndex + 1]
val parameters = AutopilotControlParameters()
parameters.routeID = busRoutesResult.lineId
parameters.routeName = busRoutesResult.name
parameters.startName = PinYinUtil.getPinYinHeadChar(currentStation.name)
parameters.endName = PinYinUtil.getPinYinHeadChar(nextStation.name)
parameters.startLatLon =
AutopilotControlParameters.AutoPilotLonLat(currentStation.lat, currentStation.lon)
parameters.endLatLon =
AutopilotControlParameters.AutoPilotLonLat(nextStation.lat, nextStation.lon)
parameters.vehicleType = 10
if (parameters.autoPilotLine == null) {
parameters.autoPilotLine = AutopilotControlParameters.AutoPilotLine(
busRoutesResult.lineId.toLong(), busRoutesResult.name,
busRoutesResult.csvFileUrl, busRoutesResult.csvFileMd5,
busRoutesResult.txtFileUrl, busRoutesResult.txtFileMd5,
busRoutesResult.contrailSaveTime, busRoutesResult.carModel,
busRoutesResult.csvFileUrlDPQP, busRoutesResult.csvFileMd5DPQP,
busRoutesResult.txtFileUrlDPQP, busRoutesResult.txtFileMd5DPQP,
busRoutesResult.contrailSaveTimeDPQP
)
}
return parameters
}
private fun clearAutopilotControlParameters() {
CallerLogger.d(SceneConstant.M_BUS_P + TAG, "AutopilotControlParameters is clear.")
CallerAutoPilotStatusListenerManager.updateAutopilotControlParameters(null)
}
}

View File

@@ -3,31 +3,24 @@ package com.mogo.och.shuttle.weaknet.passenger.presenter
import androidx.lifecycle.LifecycleOwner
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.mvp.Presenter
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.data.bean.BusStationBean
import com.mogo.och.shuttle.weaknet.passenger.callback.IBusPassegerDriverStatusCallback
import com.mogo.och.shuttle.weaknet.passenger.callback.IBusPassengerADASStatusCallback
import com.mogo.och.shuttle.weaknet.passenger.callback.IBusPassengerAutopilotPlanningCallback
import com.mogo.och.shuttle.weaknet.passenger.callback.IBusPassengerControllerStatusCallback
import com.mogo.och.shuttle.weaknet.passenger.callback.IBusPassengerRouteLineInfoCallback
import com.mogo.och.shuttle.weaknet.passenger.model.BusPassengerModel
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
import com.mogo.och.shuttle.weaknet.passenger.ui.BusPassengerRouteFragment
/**
* Created on 2022/3/31
*/
class BaseBusPassengerPresenter(view: BusPassengerRouteFragment?) :
Presenter<BusPassengerRouteFragment?>(view), IBusPassengerADASStatusCallback,
IBusPassengerControllerStatusCallback, IBusPassegerDriverStatusCallback,
IBusPassengerRouteLineInfoCallback, IBusPassengerAutopilotPlanningCallback {
Presenter<BusPassengerRouteFragment?>(view),
ICommonCallback {
private val TAG: String = BaseBusPassengerPresenter::class.java.simpleName
init {
BusPassengerModel.init(AbsMogoApplication.getApp())
CommonModel.init(AbsMogoApplication.getApp())
initListeners()
}
@@ -40,77 +33,27 @@ class BaseBusPassengerPresenter(view: BusPassengerRouteFragment?) :
super.onDestroy(owner)
releaseListeners()
BusPassengerModel.release()
CommonModel.releaseListeners()
}
private fun initListeners() {
BusPassengerModel.setADASStatusCallback(this)
BusPassengerModel.setControllerStatusCallback(TAG, this)
BusPassengerModel.setDriverStatusCallback(this)
BusPassengerModel.setRouteLineInfoCallback(this)
BusPassengerModel.setMoGoAutopilotPlanningListener(this)
CommonModel.setRouteLineInfoCallback(this)
}
private fun releaseListeners() {
BusPassengerModel.setADASStatusCallback(null)
BusPassengerModel.setControllerStatusCallback(TAG, null)
BusPassengerModel.setDriverStatusCallback(null)
BusPassengerModel.setRouteLineInfoCallback(null)
BusPassengerModel.setMoGoAutopilotPlanningListener(null)
CommonModel.setRouteLineInfoCallback(null)
}
override fun onAutopilotEnable() {
UiThreadHandler.post({
if (mView != null) {
mView!!.onAutopilotStatusChanged(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE
)
}
}, UiThreadHandler.MODE.QUEUE)
}
override fun onAutopilotDisable() {
UiThreadHandler.post({
if (mView != null) {
mView!!.onAutopilotStatusChanged(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE
)
}
}, UiThreadHandler.MODE.QUEUE)
}
override fun onAutopilotRunning() {
UiThreadHandler.post({
if (mView != null) {
mView!!.onAutopilotStatusChanged(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
)
}
}, UiThreadHandler.MODE.QUEUE)
}
override fun onCarLocationChanged(location: MogoLocation) {
UiThreadHandler.post({
if (location != null && mView != null) {
mView!!.onCarLocationChanged(location)
}
}, UiThreadHandler.MODE.QUEUE)
}
override fun changeOperationStatus(changeStatus: Boolean) {
UiThreadHandler.post({
if (mView != null) {
mView!!.changeOperationStatus(changeStatus)
}
}, UiThreadHandler.MODE.QUEUE)
override fun updateSpeed(location: Int) {
BizLoopManager.runInMainThread{
mView?.onCarLocationChanged(location)
}
}
override fun updateLineInfo(lineName: String) {
UiThreadHandler.post({
if (mView != null) {
mView!!.updateLineInfo(lineName)
}
}, UiThreadHandler.MODE.QUEUE)
BizLoopManager.runInMainThread{
mView?.updateLineInfo(lineName)
}
}
override fun updateStationsInfo(
@@ -118,34 +61,30 @@ class BaseBusPassengerPresenter(view: BusPassengerRouteFragment?) :
currentStationIndex: Int,
isArrived: Boolean
) {
UiThreadHandler.post({
if (mView != null) {
mView!!.updateStationsInfo(stations, currentStationIndex, isArrived)
}
}, UiThreadHandler.MODE.QUEUE)
BizLoopManager.runInMainThread{
mView?.updateStationsInfo(stations, currentStationIndex, isArrived)
}
}
override fun showNoTaskView() {
UiThreadHandler.post({
if (mView != null) {
mView!!.showNoTaskView()
override fun showNoTaskView(isShow:Boolean) {
BizLoopManager.runInMainThread{
if(isShow) {
mView?.showNoTaskView()
}else{
mView?.hideNoTaskView()
}
}, UiThreadHandler.MODE.QUEUE)
}
}
override fun hideNoTaskView() {
UiThreadHandler.post({
if (mView != null) {
mView!!.hideNoTaskView()
}
}, UiThreadHandler.MODE.QUEUE)
override fun updateAutoStatus(isOpen: Boolean) {
BizLoopManager.runInMainThread{
mView?.onAutopilotStatusChanged(isOpen)
}
}
override fun routePlanningToNextStationChanged(meters: Long, timeInSecond: Long) {
UiThreadHandler.post({
if (mView != null) {
mView!!.updateRoutePlanningToNextStation(meters, timeInSecond)
}
}, UiThreadHandler.MODE.QUEUE)
override fun updateRemainMT(meters: Long, timeInSecond: Long) {
BizLoopManager.runInMainThread{
mView?.updateRoutePlanningToNextStation(meters, timeInSecond)
}
}
}

View File

@@ -62,13 +62,6 @@ public class BusPassengerRouteFragment extends
private AppCompatTextView mCurrentArriveTip;
private AppCompatImageView mSpeakArrivedIv;
/**
* 改变自动驾驶状态
*
* @param status 2 - running 1 - enable 2 - disable
*/
private int mPrevAPStatus = -1;
@Override
public int getStationPanelViewId() {
return R.layout.shuttle_p_weak_jl_route_fragment;
@@ -179,18 +172,6 @@ public class BusPassengerRouteFragment extends
}
}
public void changeOperationStatus(boolean status) {
if (!status) {
emptyTv.setText(getString(R.string.shuttle_p_jl_no_out));
mNoLineInfoView.setVisibility(View.VISIBLE);
mRouteInfoView.setVisibility(View.GONE);
mLineName.setText(getContext().getString(R.string.shuttle_p_jl_no_line));
updateArrivedStation(null,0,true);
clearMapView();
clearMapMarkers();
}
}
public void showNoTaskView(){
if (mNoLineInfoView.getVisibility() == View.GONE){
mNoLineInfoView.setVisibility(View.VISIBLE);
@@ -279,13 +260,8 @@ public class BusPassengerRouteFragment extends
// lastBearing = bearing;
// }
public void onCarLocationChanged(MogoLocation location) {
updateSpeedView((float) location.getGnssSpeed());
}
public void updateSpeedView(float speed){
int speedKM = (int) (Math.abs(speed) * 3.6F);
mSpeedTv.setText(String.valueOf(speedKM));
public void onCarLocationChanged(int location) {
mSpeedTv.setText(String.valueOf(location));
}
public void updateCurrentStation(int position) {
@@ -355,21 +331,17 @@ public class BusPassengerRouteFragment extends
mCurrentArriveTip.setText(Html.fromHtml(str));
}
public void onAutopilotStatusChanged(int status) {
public void onAutopilotStatusChanged(boolean isOpen) {
UiThreadHandler.post(new Runnable() {
@Override
public void run() {
// 3. 其他过程直接更新
if (mPrevAPStatus != status){
AutopilotStatusChanged(status);
}
mPrevAPStatus = status;
AutopilotStatusChanged(isOpen);
}
});
}
public void AutopilotStatusChanged(int status) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == status) {
public void AutopilotStatusChanged(boolean isOpen) {
if (isOpen) {
mAutopilotIv.setImageResource(R.drawable.shuttle_p_jl_auto_open);
} else {
mAutopilotIv.setImageResource(R.drawable.shuttle_p_jl_auto_close);

View File

@@ -1,4 +1,4 @@
package com.mogo.och.shuttle.weaknet.passenger.ui
package com.mogo.och.shuttle.weaknet.passenger.ui.widget
import android.content.Context
import android.util.AttributeSet

View File

@@ -1,4 +1,4 @@
package com.mogo.och.shuttle.weaknet.passenger.ui
package com.mogo.och.shuttle.weaknet.passenger.ui.widget
import android.annotation.*
import android.content.Context
@@ -11,11 +11,9 @@ import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager
import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.util.AppUtils
import com.mogo.och.shuttle.weaknet.passenger.R
import kotlinx.android.synthetic.main.shuttle_p_weak_jl_view_status_bar.view.tv_shuttle_b1_p_version
import kotlinx.coroutines.*
import me.jessyan.autosize.utils.AutoSizeUtils
/**

View File

@@ -1,4 +1,4 @@
package com.mogo.och.shuttle.weaknet.passenger.ui
package com.mogo.och.shuttle.weaknet.passenger.ui.widget
import android.content.Context
import android.util.AttributeSet

View File

@@ -1,14 +0,0 @@
package com.mogo.och.shuttle.weaknet.passenger.callback
/**
* @author: wangmingjun
* @date: 2023/2/13
*/
interface AutoPilotStatusCallback {
/**
* false: 未开启自驾, true 开启自驾
*/
fun updateAutoStatus(isOpen: Boolean)
fun updateAutoStatus(status: Int)
}

View File

@@ -1,18 +0,0 @@
package com.mogo.och.shuttle.weaknet.passenger.callback
import com.mogo.och.data.bean.BusStationBean
/**
* @author: wangmingjun
* @date: 2023/2/2
*/
interface DrivingInfoCallback {
fun updateSpeed(speed: Int)
fun updatePlateNumber(carNum: String)
fun updateLine(lineName: String)
fun updateRemainMT(meters : Long, timeInSecond : Long) // 米,秒
fun showNoTaskView(isTrue : Boolean)
fun updateLineStations(stations: MutableList<BusStationBean>)
fun updateStationsInfo(stations: MutableList<BusStationBean>, i: Int, isArrived: Boolean)
fun clearCustomPolyline()
}

View File

@@ -4,18 +4,18 @@ import androidx.lifecycle.LifecycleOwner
import com.amap.api.maps.model.LatLng
import com.mogo.commons.mvp.Presenter
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.shuttle.weaknet.passenger.callback.AutoPilotStatusCallback
import com.mogo.och.shuttle.weaknet.passenger.callback.DrivingInfoCallback
import com.mogo.och.shuttle.weaknet.passenger.model.PM2ADASModel
import com.mogo.och.shuttle.weaknet.passenger.model.LineModel
import com.mogo.och.shuttle.weaknet.passenger.ui.PM2DrivingInfoFragment
import com.mogo.och.data.bean.BusStationBean
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
class PM2DrivingPresenter(view: PM2DrivingInfoFragment?) :
Presenter<PM2DrivingInfoFragment?>(view), DrivingInfoCallback, AutoPilotStatusCallback {
Presenter<PM2DrivingInfoFragment?>(view),
ICommonCallback {
init {
LineModel.init(context)
CommonModel.init(context)
PM2ADASModel.INSTANCE.init(context)
initListener()
}
@@ -23,17 +23,15 @@ class PM2DrivingPresenter(view: PM2DrivingInfoFragment?) :
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
destroyListener()
LineModel.releaseListener()
CommonModel.releaseListeners()
}
private fun initListener(){
LineModel.setDrivingInfoCallback(this)
LineModel.setAutoStatusCallback(this)
CommonModel.setRouteLineInfoCallback(this)
}
private fun destroyListener(){
LineModel.setDrivingInfoCallback(null)
LineModel.setAutoStatusCallback(null)
CommonModel.setRouteLineInfoCallback(null)
}
override fun updateSpeed(speed: Int) {
@@ -45,13 +43,7 @@ class PM2DrivingPresenter(view: PM2DrivingInfoFragment?) :
}
}
override fun updatePlateNumber(carNum: String) {
ThreadUtils.runOnUiThread {
mView?.updateCarPlateNum(carNum)
}
}
override fun updateLine(lineName: String) {
override fun updateLineInfo(lineName: String) {
ThreadUtils.runOnUiThread {
mView?.updateTaskName(lineName)
}
@@ -128,9 +120,5 @@ class PM2DrivingPresenter(view: PM2DrivingInfoFragment?) :
}
}
override fun updateAutoStatus(status: Int) {
}
}

View File

@@ -28,23 +28,11 @@ class PM2BaseFragment :
}
override fun initViews() {
//横竖屏
// setScreenDirection()
tv_shuttle_b2_p_version.text = "版本:${AppUtils.getAppVersionName()}"
//隐藏小地图
initFragment()
}
// private fun setScreenDirection() {
// var ro = Settings.System.getInt(context?.contentResolver,
// Settings.System.USER_ROTATION,Surface.ROTATION_270)
// if (ro != Surface.ROTATION_270){
// ro = Surface.ROTATION_270
// }
// Settings.System.putInt(context?.contentResolver,
// Settings.System.USER_ROTATION,ro)
// }
/**
* 初始化行程信息,高静地图,宣传 三个fragment
*/

View File

@@ -15,6 +15,7 @@ import com.mogo.och.shuttle.weaknet.passenger.R
import com.mogo.och.shuttle.weaknet.passenger.presenter.PM2DrivingPresenter
import com.mogo.och.common.module.utils.DateTimeUtil.*
import com.mogo.och.common.module.utils.NumberFormatUtil
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.data.bean.BusStationBean
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.auto_tv
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.clg_distance_left_time
@@ -41,16 +42,24 @@ import kotlin.math.roundToInt
class PM2DrivingInfoFragment :
MvpFragment<PM2DrivingInfoFragment?, PM2DrivingPresenter?>() {
val stationIcon = BitmapFactory.decodeResource(AbsMogoApplication.getApp().resources, R.drawable.shuttle_p_m2_map_staton_icon)
val stationPassIcon = BitmapFactory.decodeResource(AbsMogoApplication.getApp().resources, R.drawable.shuttle_p_m2_map_staton_arrived_icon)
val startStationIcon = BitmapFactory.decodeResource(AbsMogoApplication.getApp().resources, R.drawable.shuttle_p_m2_map_start_icon)
val endStationIcon = BitmapFactory.decodeResource(AbsMogoApplication.getApp().resources, R.drawable.shuttle_p_m2_map_end_icon)
private val stationIcon = BitmapFactory.decodeResource(
AbsMogoApplication.getApp().resources,
R.drawable.shuttle_p_m2_map_staton_icon
)
private val stationPassIcon = BitmapFactory.decodeResource(
AbsMogoApplication.getApp().resources,
R.drawable.shuttle_p_m2_map_staton_arrived_icon
)
private val startStationIcon = BitmapFactory.decodeResource(
AbsMogoApplication.getApp().resources,
R.drawable.shuttle_p_m2_map_start_icon
)
private val endStationIcon = BitmapFactory.decodeResource(
AbsMogoApplication.getApp().resources,
R.drawable.shuttle_p_m2_map_end_icon
)
/**
* 改变自动驾驶状态
*
* @param status 2 - running 1 - enable 2 - disable
*/
override fun getLayoutId(): Int {
return R.layout.shuttle_p_m2_driving_info_fragment
}
@@ -65,38 +74,14 @@ class PM2DrivingInfoFragment :
true
}
line_name_tv.setTextColor(resources.getColor(R.color.shuttle_p_m2_line_name_tv_color))
station_name_tv.setTextColor(resources.getColor(R.color.shuttle_p_m2_line_name_tv_color))
line_name_tv.setTextColor(ResourcesUtils.getColor(R.color.shuttle_p_m2_line_name_tv_color))
station_name_tv.setTextColor(ResourcesUtils.getColor(R.color.shuttle_p_m2_line_name_tv_color))
speed_tv.setVertrial(true)
val intArrayOf = intArrayOf(
requireContext().resources.getColor(R.color.shuttle_p_m2_color_43cefe),
requireContext().resources.getColor(R.color.shuttle_p_m2_color_1466fb)
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_43cefe),
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_1466fb),
)
speed_tv.setmColorList(intArrayOf)
// current_time_tv.onClick {
// //测试V2X消息
// CallerMsgBoxManager.saveMsgBox(
// MsgBoxBean(
// MsgBoxType.V2X,
// V2XMsg(
// "6666",
// "超速行驶",
// ""
// )
// )
// )
//
// val noticeTrafficStylePushData = NoticeTrafficStylePushData()
// noticeTrafficStylePushData.content= "测试公告布局"
// val noticeFromCloudMsg = NoticeFrCloudMsg(null, noticeTrafficStylePushData, 1)
// CallerMsgBoxManager.saveMsgBox(
// MsgBoxBean(
// MsgBoxType.NOTICE, noticeFromCloudMsg)
// )
// BPRouteDataTestUtils.converToRouteData()
// }
}
override fun initViews(savedInstanceState: Bundle?) {
@@ -111,50 +96,34 @@ class PM2DrivingInfoFragment :
override fun onResume() {
super.onResume()
overMapView?.let{
it.onResume()
}
overMapView?.onResume()
}
override fun onPause() {
super.onPause()
overMapView?.let{
it.onPause()
}
overMapView?.onPause()
}
override fun onDestroyView() {
overMapView?.onDestroy()
if (mPresenter != null) {
mPresenter?.onDestroy(this)
}
mPresenter?.onDestroy(this)
super.onDestroyView()
}
fun updateSpeed(speed: Int){
fun updateSpeed(speed: Int) {
speed_tv.text = speed.toString()
}
fun updateCarPlateNum(plateNum : String){
}
fun updateTaskName(name: String){
fun updateTaskName(name: String) {
line_name_tv.text = name
}
fun changeOperationStatus(status:Boolean){
if (!status){
updateNoOrderUI()
}
}
fun showNoTaskView(haveTask: Boolean){
fun showNoTaskView(haveTask: Boolean) {
setLineInfoView(haveTask)
}
private fun setLineInfoView(isShow: Boolean){
if (!isShow){
private fun setLineInfoView(isShow: Boolean) {
if (!isShow) {
updateNoOrderUI()
}
}
@@ -162,19 +131,16 @@ class PM2DrivingInfoFragment :
private fun updateNoOrderUI() {
line_name_tv.text = resources.getString(R.string.shuttle_p_m2_not_select_line_content)
updateNoStationView()
overMapView?.let {
it.clearSiteMarkers()
}
overMapView?.clearSiteMarkers()
clearCustomPolyline()
}
fun clearCustomPolyline(){
overMapView?.let {
it.clearCustomPolyline()
}
fun clearCustomPolyline() {
overMapView?.clearCustomPolyline()
}
private fun updateNoStationView(){
station_name_tv.setTextColor(resources.getColor(R.color.shuttle_p_m2_next_tv_color))
private fun updateNoStationView() {
station_name_tv.setTextColor(ResourcesUtils.getColor(R.color.shuttle_p_m2_next_tv_color))
station_name_tv.text = resources.getString(R.string.shuttle_p_m2_empty_tv)
tv_distance.text = resources.getString(R.string.shuttle_p_m2_empty_remain_km)
tv_left_time.text = resources.getString(R.string.shuttle_p_m2_empty_remain_minute)
@@ -186,12 +152,32 @@ class PM2DrivingInfoFragment :
}
fun updateAutoStatus(isAutoPilot: Boolean) {
if (isAutoPilot){
context?.let { auto_tv.setTextColor(ContextCompat.getColor(it,R.color.shuttle_p_m2_white_color)) }
context?.let { auto_tv.background = ContextCompat.getDrawable(it,R.drawable.shuttle_p_m2_auto_button_bg) }
}else{
context?.let { auto_tv.setTextColor(ContextCompat.getColor(it,R.color.shuttle_p_m2_color_7094ad)) }
context?.let { auto_tv.background = ContextCompat.getDrawable(it,R.drawable.shuttle_p_m2_bg_p_m2_auto) }
if (isAutoPilot) {
context?.let {
auto_tv.setTextColor(
ContextCompat.getColor(
it,
R.color.shuttle_p_m2_white_color
)
)
}
context?.let {
auto_tv.background =
ContextCompat.getDrawable(it, R.drawable.shuttle_p_m2_auto_button_bg)
}
} else {
context?.let {
auto_tv.setTextColor(
ContextCompat.getColor(
it,
R.color.shuttle_p_m2_color_7094ad
)
)
}
context?.let {
auto_tv.background =
ContextCompat.getDrawable(it, R.drawable.shuttle_p_m2_bg_p_m2_auto)
}
}
}
@@ -200,38 +186,40 @@ class PM2DrivingInfoFragment :
stationsPass: MutableList<LatLng>,
startStation: LatLng?,
endStation: LatLng?
){
) {
overMapView?.let {
val stationsList: MutableList<SiteMarkerBean> = mutableListOf()
startStation?.let { start->
stationsList.add(SiteMarkerBean(start,startStationIcon,0.5f,0.5f))
startStation?.let { start ->
stationsList.add(SiteMarkerBean(start, startStationIcon, 0.5f, 0.5f))
}
for (stationsPass in stationsPass) {
stationsList.add(SiteMarkerBean(stationsPass,stationPassIcon,0.5f,0.5f))
for (stationPass in stationsPass) {
stationsList.add(SiteMarkerBean(stationPass, stationPassIcon, 0.5f, 0.5f))
}
for (stationsPass in stations) {
stationsList.add(SiteMarkerBean(stationsPass,stationIcon,0.5f,0.5f))
for (stationPass in stations) {
stationsList.add(SiteMarkerBean(stationPass, stationIcon, 0.5f, 0.5f))
}
endStation?.let {end->
stationsList.add(SiteMarkerBean(end,endStationIcon,0.5f,0.5f))
endStation?.let { end ->
stationsList.add(SiteMarkerBean(end, endStationIcon, 0.5f, 0.5f))
}
it.drawSiteMarkers(stationsList)
}
}
fun updateStationsInfo(stations: MutableList<BusStationBean>, i: Int, isArrived: Boolean){
fun updateStationsInfo(stations: MutableList<BusStationBean>, i: Int, isArrived: Boolean) {
if (stations.size == 0) return
if (0<= i && i<stations.size){
station_name_tv.setTextColor(resources.getColor(R.color.shuttle_p_m2_next_tv_color))
station_name_tv.text = stations[i].name
if (0 <= i && i < stations.size) {
station_name_tv.setTextColor(ResourcesUtils.getColor(R.color.shuttle_p_m2_next_tv_color))
station_name_tv.text = stations[i].name
}
if (isArrived){//到站
if (isArrived) {//到站
tv_distance.text = resources.getString(R.string.shuttle_p_m2_empty_remain_km)
tv_left_time.text = resources.getString(R.string.shuttle_p_m2_empty_remain_minute)
tv_next_station_title.text = resources.getString(R.string.shuttle_p_m2_station_title_arrived_tv)
tv_next_station_title.text =
resources.getString(R.string.shuttle_p_m2_station_title_arrived_tv)
haveLineAndArrivedStation()
}else{ //前往目的地中
tv_next_station_title.text = resources.getString(R.string.shuttle_p_m2_next_station_title)
} else { //前往目的地中
tv_next_station_title.text =
resources.getString(R.string.shuttle_p_m2_next_station_title)
haveLineAndArriveingStation()
}
}
@@ -259,7 +247,7 @@ class PM2DrivingInfoFragment :
"${time}分钟".also { tv_left_time.text = it }
}
fun noLineShow(){
fun noLineShow() {
// 没有线路展示
group_not_select_line.visibility = View.VISIBLE
// 下一个站点
@@ -271,16 +259,18 @@ class PM2DrivingInfoFragment :
iv_animal_list.visibility = View.GONE
}
// 有线路正在到站点
fun haveLineAndArriveingStation(){
fun haveLineAndArriveingStation() {
group_not_select_line.visibility = View.GONE
group_stationinfo.visibility = View.VISIBLE
clg_distance_left_time.visibility = View.VISIBLE
tv_arrived_notice.visibility = View.GONE
iv_animal_list.visibility = View.GONE
}
// 有线路到达站点
private fun haveLineAndArrivedStation(){
private fun haveLineAndArrivedStation() {
group_not_select_line.visibility = View.GONE
group_stationinfo.visibility = View.VISIBLE
clg_distance_left_time.visibility = View.GONE

View File

@@ -19,6 +19,7 @@ import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.util.ClickUtils
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.shuttle.weaknet.passenger.R
import kotlinx.android.synthetic.main.shuttle_p_m2_view_status_bar.view.aciv_wait_ele
import kotlinx.android.synthetic.main.shuttle_p_m2_view_status_bar.view.progress
import kotlinx.android.synthetic.main.shuttle_p_m2_view_status_bar.view.tv_power_cos
import kotlinx.coroutines.*
@@ -64,10 +65,11 @@ class M2StatusBarView @JvmOverloads constructor(
CallerChassisStatesListenerManager.addListener(TAG,this)
progress?.also {
it.progress = 50
it.progress = 0
aciv_wait_ele.visibility = VISIBLE
}
tv_power_cos?.also {
it.text = "50%"
it.text = "检测中"
}
}
@@ -104,6 +106,7 @@ class M2StatusBarView @JvmOverloads constructor(
progress?.also { it.progress = power }
tv_power_cos?.also {it.text = "$power%" }
}
aciv_wait_ele.visibility = GONE
}
}
} finally {

View File

@@ -30,6 +30,6 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/no_order_data_iv"
android:text="@string/shuttle_p_jl_no_out"/>
android:text="@string/shuttle_p_jl_no_task"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -32,7 +32,7 @@
android:layout_marginStart="@dimen/dp_40" />
<!--魔方连接状态 蓝牙-->
<com.mogo.och.shuttle.weaknet.passenger.ui.BusPBlueToothView
<com.mogo.och.shuttle.weaknet.passenger.ui.widget.BusPBlueToothView
android:id="@+id/blueToothView"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

View File

@@ -145,7 +145,7 @@
<com.mogo.och.common.module.wigets.MarqueeTextView
android:id="@+id/station_name_tv"
android:layout_width="0dp"
android:layout_width="@dimen/dp_450"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_6"
android:ellipsize="marquee"

View File

@@ -58,6 +58,16 @@
app:layout_constraintRight_toLeftOf="@+id/tv_power_cos"
app:layout_constraintTop_toTopOf="@+id/iv_logon" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/aciv_wait_ele"
android:src="@drawable/shuttle_p_m2_electricity"
app:layout_constraintTop_toTopOf="@+id/progress"
app:layout_constraintBottom_toBottomOf="@+id/progress"
app:layout_constraintStart_toStartOf="@+id/progress"
app:layout_constraintEnd_toEndOf="@+id/progress"
android:layout_width="@dimen/dp_12"
android:layout_height="@dimen/dp_18"/>
<TextView
android:id="@+id/tv_power_cos"
android:layout_width="wrap_content"

View File

@@ -3,6 +3,7 @@ package com.mogo.och.unmanned.taxi.network
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.BaseData
import com.mogo.och.common.module.manager.cache.OchSPManager
import com.mogo.och.data.taxi.QueryCarOrderByNoReqBean
import com.mogo.och.data.taxi.QueryCarOrderByNoRespBean
import com.mogo.och.unmanned.taxi.bean.ArriveSiteReqBean
@@ -150,4 +151,12 @@ interface TaxiTaskWithOrderServiceApi {
@Body data: QueryCarOrderByNoReqBean?
): Observable<QueryCarOrderByNoRespBean>
@Headers("Content-type:application/json;charset=UTF-8")
@GET("/och-taxi-cabin/api/flow/v1/resetInit")
fun resetInit(
@Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
@Header("ticket") ticket: String = SharedPrefsMgr.getInstance().token,
@Query("sn") sn: String? = OchSPManager.getSn()
): Observable<QueryCarOrderByNoRespBean>
}

View File

@@ -157,6 +157,18 @@ object TaxiTaskWithOrderServiceManager {
.subscribe(OchCommonSubscribeImpl(context, callback, "orderCompleted"))
}
/**
* 服务完成
*/
@JvmStatic
fun resetInit(
context: Context, callback: OchCommonServiceCallback<BaseData>?
) {
mOCHTaxiServiceApi.resetInit().transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "orderCompleted"))
}
/**
* 取消订单
*/

View File

@@ -1,5 +1,7 @@
package com.mogo.och.unmanned.taxi.ui.base;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleOwner;
@@ -80,6 +82,11 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
}
private final OchTransformDispatch ochTransform = new OchTransformDispatch(){
@Override
public void setVideoView(@Nullable View target) {
}
@Override
public void logout() {
TaxiTaskModel.INSTANCE.logout();

View File

@@ -1,641 +0,0 @@
package com.mogo.och.unmanned.taxi.ui.routing;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.view.View;
import android.view.ViewPropertyAnimator;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
/**
* This implementation of {@link RecyclerView.ItemAnimator} provides basic
* animations on remove, add, and move events that happen to the items in
* a RecyclerView. RecyclerView uses a DefaultItemAnimator by default.
*
* @see RecyclerView#setItemAnimator(RecyclerView.ItemAnimator)
*/
public class TaxiRoutingChooseLineItemOpenAnimator extends DefaultItemAnimator {
private static final boolean DEBUG = false;
private static TimeInterpolator sDefaultInterpolator;
private final ArrayList<RecyclerView.ViewHolder> mPendingRemovals = new ArrayList<>();
private final ArrayList<RecyclerView.ViewHolder> mPendingAdditions = new ArrayList<>();
private final ArrayList<MoveInfo> mPendingMoves = new ArrayList<>();
private final ArrayList<ChangeInfo> mPendingChanges = new ArrayList<>();
private final ArrayList<ArrayList<RecyclerView.ViewHolder>> mAdditionsList = new ArrayList<>();
private final ArrayList<ArrayList<MoveInfo>> mMovesList = new ArrayList<>();
private final ArrayList<ArrayList<ChangeInfo>> mChangesList = new ArrayList<>();
private final ArrayList<RecyclerView.ViewHolder> mAddAnimations = new ArrayList<>();
private final ArrayList<RecyclerView.ViewHolder> mMoveAnimations = new ArrayList<>();
private final ArrayList<RecyclerView.ViewHolder> mRemoveAnimations = new ArrayList<>();
private final ArrayList<RecyclerView.ViewHolder> mChangeAnimations = new ArrayList<>();
private static class MoveInfo {
public RecyclerView.ViewHolder holder;
public int fromX, fromY, toX, toY;
MoveInfo(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
this.holder = holder;
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
}
}
private static class ChangeInfo {
public RecyclerView.ViewHolder oldHolder, newHolder;
public int fromX, fromY, toX, toY;
private ChangeInfo(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder) {
this.oldHolder = oldHolder;
this.newHolder = newHolder;
}
ChangeInfo(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder,
int fromX, int fromY, int toX, int toY) {
this(oldHolder, newHolder);
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
}
@Override
public String toString() {
return "ChangeInfo{"
+ "oldHolder=" + oldHolder
+ ", newHolder=" + newHolder
+ ", fromX=" + fromX
+ ", fromY=" + fromY
+ ", toX=" + toX
+ ", toY=" + toY
+ '}';
}
}
@Override
public void runPendingAnimations() {
boolean removalsPending = !mPendingRemovals.isEmpty();
boolean movesPending = !mPendingMoves.isEmpty();
boolean changesPending = !mPendingChanges.isEmpty();
boolean additionsPending = !mPendingAdditions.isEmpty();
if (!removalsPending && !movesPending && !additionsPending && !changesPending) {
// nothing to animate
return;
}
// First, remove stuff
for (RecyclerView.ViewHolder holder : mPendingRemovals) {
animateRemoveImpl(holder);
}
mPendingRemovals.clear();
// Next, move stuff
if (movesPending) {
final ArrayList<MoveInfo> moves = new ArrayList<>(mPendingMoves);
mMovesList.add(moves);
mPendingMoves.clear();
Runnable mover = () -> {
for (MoveInfo moveInfo : moves) {
animateMoveImpl(moveInfo.holder, moveInfo.fromX, moveInfo.fromY,
moveInfo.toX, moveInfo.toY);
}
moves.clear();
mMovesList.remove(moves);
};
if (removalsPending) {
View view = moves.get(0).holder.itemView;
ViewCompat.postOnAnimationDelayed(view, mover, getRemoveDuration());
} else {
mover.run();
}
}
// Next, change stuff, to run in parallel with move animations
if (changesPending) {
final ArrayList<ChangeInfo> changes = new ArrayList<>(mPendingChanges);
mChangesList.add(changes);
mPendingChanges.clear();
Runnable changer = () -> {
for (ChangeInfo change : changes) {
animateChangeImpl(change);
}
changes.clear();
mChangesList.remove(changes);
};
if (removalsPending) {
RecyclerView.ViewHolder holder = changes.get(0).oldHolder;
ViewCompat.postOnAnimationDelayed(holder.itemView, changer, getRemoveDuration());
} else {
changer.run();
}
}
// Next, add stuff
if (additionsPending) {
final ArrayList<RecyclerView.ViewHolder> additions = new ArrayList<>(mPendingAdditions);
mAdditionsList.add(additions);
mPendingAdditions.clear();
Runnable adder = () -> {
for (RecyclerView.ViewHolder holder : additions) {
animateAddImpl(holder);
}
additions.clear();
mAdditionsList.remove(additions);
};
if (removalsPending || movesPending || changesPending) {
long removeDuration = removalsPending ? getRemoveDuration() : 0;
long moveDuration = movesPending ? getMoveDuration() : 0;
long changeDuration = changesPending ? getChangeDuration() : 0;
long totalDelay = removeDuration + Math.max(moveDuration, changeDuration);
View view = additions.get(0).itemView;
ViewCompat.postOnAnimationDelayed(view, adder, totalDelay);
} else {
adder.run();
}
}
}
@Override
public boolean animateRemove(final RecyclerView.ViewHolder holder) {
resetAnimation(holder);
mPendingRemovals.add(holder);
return true;
}
private void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
final View view = holder.itemView;
final ViewPropertyAnimator animation = view.animate();
mRemoveAnimations.add(holder);
animation.setDuration(getRemoveDuration()).alpha(0).setListener(
new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchRemoveStarting(holder);
}
@Override
public void onAnimationEnd(Animator animator) {
animation.setListener(null);
view.setAlpha(1);
dispatchRemoveFinished(holder);
mRemoveAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
@Override
public boolean animateAdd(final RecyclerView.ViewHolder holder) {
resetAnimation(holder);
holder.itemView.setAlpha(0);
mPendingAdditions.add(holder);
return true;
}
void animateAddImpl(final RecyclerView.ViewHolder holder) {
final View view = holder.itemView;
final ViewPropertyAnimator animation = view.animate();
mAddAnimations.add(holder);
animation.alpha(1).setDuration(getAddDuration())
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchAddStarting(holder);
}
@Override
public void onAnimationCancel(Animator animator) {
view.setAlpha(1);
}
@Override
public void onAnimationEnd(Animator animator) {
animation.setListener(null);
dispatchAddFinished(holder);
mAddAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
@Override
public boolean animateMove(final RecyclerView.ViewHolder holder, int fromX, int fromY,
int toX, int toY) {
final View view = holder.itemView;
fromX += (int) holder.itemView.getTranslationX();
fromY += (int) holder.itemView.getTranslationY();
resetAnimation(holder);
int deltaX = toX - fromX;
int deltaY = toY - fromY;
if (deltaX == 0 && deltaY == 0) {
dispatchMoveFinished(holder);
return false;
}
if (deltaX != 0) {
view.setTranslationX(-deltaX);
}
if (deltaY != 0) {
view.setTranslationY(-deltaY);
}
mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
return true;
}
void animateMoveImpl(final RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
final View view = holder.itemView;
final int deltaX = toX - fromX;
final int deltaY = toY - fromY;
if (deltaX != 0) {
view.animate().translationX(0);
}
if (deltaY != 0) {
view.animate().translationY(0);
}
// TODO: make EndActions end listeners instead, since end actions aren't called when
// vpas are canceled (and can't end them. why?)
// need listener functionality in VPACompat for this. Ick.
final ViewPropertyAnimator animation = view.animate();
mMoveAnimations.add(holder);
animation.setDuration(getMoveDuration()).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchMoveStarting(holder);
}
@Override
public void onAnimationCancel(Animator animator) {
if (deltaX != 0) {
view.setTranslationX(0);
}
if (deltaY != 0) {
view.setTranslationY(0);
}
}
@Override
public void onAnimationEnd(Animator animator) {
animation.setListener(null);
dispatchMoveFinished(holder);
mMoveAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
@Override
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder,
int fromX, int fromY, int toX, int toY) {
if (oldHolder == newHolder) {
// Don't know how to run change animations when the same view holder is re-used.
// run a move animation to handle position changes.
return animateMove(oldHolder, fromX, fromY, toX, toY);
}
final float prevTranslationX = oldHolder.itemView.getTranslationX();
final float prevTranslationY = oldHolder.itemView.getTranslationY();
final float prevAlpha = oldHolder.itemView.getAlpha();
resetAnimation(oldHolder);
int deltaX = (int) (toX - fromX - prevTranslationX);
int deltaY = (int) (toY - fromY - prevTranslationY);
// recover prev translation state after ending animation
oldHolder.itemView.setTranslationX(prevTranslationX);
oldHolder.itemView.setTranslationY(prevTranslationY);
oldHolder.itemView.setAlpha(prevAlpha);
if (newHolder != null) {
// carry over translation values
resetAnimation(newHolder);
newHolder.itemView.setTranslationX(-deltaX);
newHolder.itemView.setTranslationY(-deltaY);
newHolder.itemView.setAlpha(0);
}
mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY));
return true;
}
void animateChangeImpl(final ChangeInfo changeInfo) {
final RecyclerView.ViewHolder holder = changeInfo.oldHolder;
final View view = holder == null ? null : holder.itemView;
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;
final View newView = newHolder != null ? newHolder.itemView : null;
if (view != null) {
final ViewPropertyAnimator oldViewAnim = view.animate().setDuration(
getChangeDuration());
mChangeAnimations.add(changeInfo.oldHolder);
oldViewAnim.translationX((float) (changeInfo.toX - changeInfo.fromX));
oldViewAnim.translationY((float) (changeInfo.toY - changeInfo.fromY));
oldViewAnim.alpha(0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchChangeStarting(changeInfo.oldHolder, true);
}
@Override
public void onAnimationEnd(Animator animator) {
oldViewAnim.setListener(null);
view.setAlpha(1);
view.setTranslationX(0);
view.setTranslationY(0);
dispatchChangeFinished(changeInfo.oldHolder, true);
mChangeAnimations.remove(changeInfo.oldHolder);
dispatchFinishedWhenDone();
}
}).start();
}
if (newView != null) {
final ViewPropertyAnimator newViewAnimation = newView.animate();
mChangeAnimations.add(changeInfo.newHolder);
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration())
.alpha(1).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchChangeStarting(changeInfo.newHolder, false);
}
@Override
public void onAnimationEnd(Animator animator) {
newViewAnimation.setListener(null);
newView.setAlpha(1);
newView.setTranslationX(0);
newView.setTranslationY(0);
dispatchChangeFinished(changeInfo.newHolder, false);
mChangeAnimations.remove(changeInfo.newHolder);
dispatchFinishedWhenDone();
}
}).start();
}
}
private void endChangeAnimation(List<ChangeInfo> infoList, RecyclerView.ViewHolder item) {
for (int i = infoList.size() - 1; i >= 0; i--) {
ChangeInfo changeInfo = infoList.get(i);
if (endChangeAnimationIfNecessary(changeInfo, item)) {
if (changeInfo.oldHolder == null && changeInfo.newHolder == null) {
infoList.remove(changeInfo);
}
}
}
}
private void endChangeAnimationIfNecessary(ChangeInfo changeInfo) {
if (changeInfo.oldHolder != null) {
endChangeAnimationIfNecessary(changeInfo, changeInfo.oldHolder);
}
if (changeInfo.newHolder != null) {
endChangeAnimationIfNecessary(changeInfo, changeInfo.newHolder);
}
}
private boolean endChangeAnimationIfNecessary(ChangeInfo changeInfo, RecyclerView.ViewHolder item) {
boolean oldItem = false;
if (changeInfo.newHolder == item) {
changeInfo.newHolder = null;
} else if (changeInfo.oldHolder == item) {
changeInfo.oldHolder = null;
oldItem = true;
} else {
return false;
}
item.itemView.setAlpha(1);
item.itemView.setTranslationX(0);
item.itemView.setTranslationY(0);
dispatchChangeFinished(item, oldItem);
return true;
}
@Override
public void endAnimation(RecyclerView.ViewHolder item) {
final View view = item.itemView;
// this will trigger end callback which should set properties to their target values.
view.animate().cancel();
// TODO if some other animations are chained to end, how do we cancel them as well?
for (int i = mPendingMoves.size() - 1; i >= 0; i--) {
MoveInfo moveInfo = mPendingMoves.get(i);
if (moveInfo.holder == item) {
view.setTranslationY(0);
view.setTranslationX(0);
dispatchMoveFinished(item);
mPendingMoves.remove(i);
}
}
endChangeAnimation(mPendingChanges, item);
if (mPendingRemovals.remove(item)) {
view.setAlpha(1);
dispatchRemoveFinished(item);
}
if (mPendingAdditions.remove(item)) {
view.setAlpha(1);
dispatchAddFinished(item);
}
for (int i = mChangesList.size() - 1; i >= 0; i--) {
ArrayList<ChangeInfo> changes = mChangesList.get(i);
endChangeAnimation(changes, item);
if (changes.isEmpty()) {
mChangesList.remove(i);
}
}
for (int i = mMovesList.size() - 1; i >= 0; i--) {
ArrayList<MoveInfo> moves = mMovesList.get(i);
for (int j = moves.size() - 1; j >= 0; j--) {
MoveInfo moveInfo = moves.get(j);
if (moveInfo.holder == item) {
view.setTranslationY(0);
view.setTranslationX(0);
dispatchMoveFinished(item);
moves.remove(j);
if (moves.isEmpty()) {
mMovesList.remove(i);
}
break;
}
}
}
for (int i = mAdditionsList.size() - 1; i >= 0; i--) {
ArrayList<RecyclerView.ViewHolder> additions = mAdditionsList.get(i);
if (additions.remove(item)) {
view.setAlpha(1);
dispatchAddFinished(item);
if (additions.isEmpty()) {
mAdditionsList.remove(i);
}
}
}
// animations should be ended by the cancel above.
//noinspection Pointless BooleanExpression,ConstantConditions
if (mRemoveAnimations.remove(item) && DEBUG) {
throw new IllegalStateException("after animation is cancelled, item should not be in "
+ "mRemoveAnimations list");
}
//noinspection Pointless BooleanExpression,ConstantConditions
if (mAddAnimations.remove(item) && DEBUG) {
throw new IllegalStateException("after animation is cancelled, item should not be in "
+ "mAddAnimations list");
}
//noinspection Pointless BooleanExpression,ConstantConditions
if (mChangeAnimations.remove(item) && DEBUG) {
throw new IllegalStateException("after animation is cancelled, item should not be in "
+ "mChangeAnimations list");
}
//noinspection Pointless BooleanExpression,ConstantConditions
if (mMoveAnimations.remove(item) && DEBUG) {
throw new IllegalStateException("after animation is cancelled, item should not be in "
+ "mMoveAnimations list");
}
dispatchFinishedWhenDone();
}
private void resetAnimation(RecyclerView.ViewHolder holder) {
if (sDefaultInterpolator == null) {
sDefaultInterpolator = new ValueAnimator().getInterpolator();
}
holder.itemView.animate().setInterpolator(sDefaultInterpolator);
endAnimation(holder);
}
@Override
public boolean isRunning() {
return (!mPendingAdditions.isEmpty()
|| !mPendingChanges.isEmpty()
|| !mPendingMoves.isEmpty()
|| !mPendingRemovals.isEmpty()
|| !mMoveAnimations.isEmpty()
|| !mRemoveAnimations.isEmpty()
|| !mAddAnimations.isEmpty()
|| !mChangeAnimations.isEmpty()
|| !mMovesList.isEmpty()
|| !mAdditionsList.isEmpty()
|| !mChangesList.isEmpty());
}
/**
* Check the state of currently pending and running animations. If there are none
* pending/running, call {@link #dispatchAnimationsFinished()} to notify any
* listeners.
*/
void dispatchFinishedWhenDone() {
if (!isRunning()) {
dispatchAnimationsFinished();
}
}
@Override
public void endAnimations() {
int count = mPendingMoves.size();
for (int i = count - 1; i >= 0; i--) {
MoveInfo item = mPendingMoves.get(i);
View view = item.holder.itemView;
view.setTranslationY(0);
view.setTranslationX(0);
dispatchMoveFinished(item.holder);
mPendingMoves.remove(i);
}
count = mPendingRemovals.size();
for (int i = count - 1; i >= 0; i--) {
RecyclerView.ViewHolder item = mPendingRemovals.get(i);
dispatchRemoveFinished(item);
mPendingRemovals.remove(i);
}
count = mPendingAdditions.size();
for (int i = count - 1; i >= 0; i--) {
RecyclerView.ViewHolder item = mPendingAdditions.get(i);
item.itemView.setAlpha(1);
dispatchAddFinished(item);
mPendingAdditions.remove(i);
}
count = mPendingChanges.size();
for (int i = count - 1; i >= 0; i--) {
endChangeAnimationIfNecessary(mPendingChanges.get(i));
}
mPendingChanges.clear();
if (!isRunning()) {
return;
}
int listCount = mMovesList.size();
for (int i = listCount - 1; i >= 0; i--) {
ArrayList<MoveInfo> moves = mMovesList.get(i);
count = moves.size();
for (int j = count - 1; j >= 0; j--) {
MoveInfo moveInfo = moves.get(j);
RecyclerView.ViewHolder item = moveInfo.holder;
View view = item.itemView;
view.setTranslationY(0);
view.setTranslationX(0);
dispatchMoveFinished(moveInfo.holder);
moves.remove(j);
if (moves.isEmpty()) {
mMovesList.remove(moves);
}
}
}
listCount = mAdditionsList.size();
for (int i = listCount - 1; i >= 0; i--) {
ArrayList<RecyclerView.ViewHolder> additions = mAdditionsList.get(i);
count = additions.size();
for (int j = count - 1; j >= 0; j--) {
RecyclerView.ViewHolder item = additions.get(j);
View view = item.itemView;
view.setAlpha(1);
dispatchAddFinished(item);
additions.remove(j);
if (additions.isEmpty()) {
mAdditionsList.remove(additions);
}
}
}
listCount = mChangesList.size();
for (int i = listCount - 1; i >= 0; i--) {
ArrayList<ChangeInfo> changes = mChangesList.get(i);
count = changes.size();
for (int j = count - 1; j >= 0; j--) {
endChangeAnimationIfNecessary(changes.get(j));
if (changes.isEmpty()) {
mChangesList.remove(changes);
}
}
}
cancelAll(mRemoveAnimations);
cancelAll(mMoveAnimations);
cancelAll(mAddAnimations);
cancelAll(mChangeAnimations);
dispatchAnimationsFinished();
}
void cancelAll(List<RecyclerView.ViewHolder> viewHolders) {
for (int i = viewHolders.size() - 1; i >= 0; i--) {
viewHolders.get(i).itemView.animate().cancel();
}
}
/**
* {@inheritDoc}
* <p>
* If the payload list is not empty, DefaultItemAnimator returns <code>true</code>.
* When this is the case:
* <ul>
* <li>If you override {@link #animateChange(RecyclerView.ViewHolder, RecyclerView.ViewHolder, int, int, int, int)}, both
* ViewHolder arguments will be the same instance.
* </li>
* <li>
* If you are not overriding {@link #animateChange(RecyclerView.ViewHolder, RecyclerView.ViewHolder, int, int, int, int)},
* then DefaultItemAnimator will call {@link #animateMove(RecyclerView.ViewHolder, int, int, int, int)} and
* run a move animation instead.
* </li>
* </ul>
*/
@Override
public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder,
@NonNull List<Object> payloads) {
return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder, payloads);
}
}

View File

@@ -1,98 +0,0 @@
package com.mogo.och.unmanned.taxi.ui.routing
import android.content.Context
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.LifecycleObserver
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
import com.mogo.och.unmanned.taxi.R
class TaxiRoutingFeedbackDialog : BaseFloatDialog, LifecycleObserver {
private var commonConfirm: TextView? = null
private var commonCancel: TextView? = null
private var commonTips: TextView? = null
private var commonCloseIcon: ImageView? = null
private var clickListener: TaxiRoutingFeedBackDialogClickListener? = null
constructor(builder: Builder, context: Context) : super(context) {
commonTips?.text = builder.tipsStr
commonCancel?.text = builder.cancelStr
commonConfirm?.text = builder.confirmStr
clickListener = builder.clickListener
}
init {
setContentView(R.layout.unmanned_dialog_routing_feedback_result)
setCanceledOnTouchOutside(true)
commonConfirm = findViewById(R.id.routing_common_confirm)
commonCancel = findViewById(R.id.routing_common_cancel)
commonTips = findViewById(R.id.routing_common_tips)
commonCloseIcon = findViewById(R.id.closeDialogIcon)
commonCloseIcon?.setOnClickListener {
dismiss()
}
commonConfirm?.setOnClickListener {
clickListener?.confirm()
dismiss()
}
commonCancel?.setOnClickListener {
clickListener?.cancel()
dismiss()
}
}
fun showDialog() {
if (isShowing) {
return
}
show()
}
fun hideDialog() {
if (isShowing) {
dismiss()
}
}
interface TaxiRoutingFeedBackDialogClickListener {
fun confirm()
fun cancel()
}
class Builder {
var tipsStr: String = ""
var confirmStr: String = ""
var cancelStr: String = ""
var clickListener: TaxiRoutingFeedBackDialogClickListener? = null
fun tips(tips: String): Builder {
this.tipsStr = tips
return this
}
fun confirmStr(commit: String): Builder {
this.confirmStr = commit
return this
}
fun cancelStr(cancel: String): Builder {
this.cancelStr = cancel
return this
}
fun clickListener(listener: TaxiRoutingFeedBackDialogClickListener): Builder {
this.clickListener = listener
return this
}
fun build(context: Context): TaxiRoutingFeedbackDialog? {
return TaxiRoutingFeedbackDialog(this, context)
}
}
}

View File

@@ -1,73 +0,0 @@
package com.mogo.och.unmanned.taxi.ui.routing
import android.animation.ObjectAnimator
import android.content.Context
import android.view.animation.LinearInterpolator
import androidx.lifecycle.LifecycleObserver
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.unmanned.taxi.R
import kotlinx.android.synthetic.main.unmanned_dialog_routing_loading.dialog_loading_text
import kotlinx.android.synthetic.main.unmanned_dialog_routing_loading.dialog_loading_view
/**
* loading
*/
class TaxiRoutingLoadingDialog : BaseFloatDialog, LifecycleObserver {
private var objectAnimator: ObjectAnimator? = null
private val mLoadingView by lazy { dialog_loading_view }
private val mLoadingText by lazy { dialog_loading_text }
private var mRunnable:Runnable= Runnable {
ToastUtils.showLong("超时未响应,请求失败")
hideLoading()
}
constructor(context: Context) : super(context)
init {
setContentView(R.layout.unmanned_dialog_routing_loading)
setCanceledOnTouchOutside(false)
}
/**
* 开始旋转
*/
private fun startRotation() {
objectAnimator = ObjectAnimator.ofFloat(mLoadingView, "rotation", -720f, 0f)
objectAnimator?.let {
it.duration = 3000
it.repeatCount = -1
it.interpolator = LinearInterpolator()
it.start()
}
}
/**
* 停止旋转
*/
private fun stopRotation() {
objectAnimator?.let {
if (it.isRunning) {
it.end()
objectAnimator = null
}
}
}
/**
* 显示dialog
*/
fun showLoading() {
mLoadingText.text = "请求中,请稍后..."
startRotation()
show()
}
/**
* 隐藏dialog
*/
fun hideLoading() {
stopRotation()
dismiss()
}
}

Some files were not shown because too many files have changed in this diff Show More