[页面调整]
This commit is contained in:
yangyakun
2024-04-17 20:22:04 +08:00
parent 4d6f017ade
commit 78e5570274
20 changed files with 573 additions and 337 deletions

View File

@@ -4,7 +4,6 @@ import android.content.Context
import android.view.View
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.commons.debug.DebugConfig
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
@@ -24,8 +23,7 @@ import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType
import com.mogo.och.common.module.manager.socket.lan.bean.EnvType
import com.mogo.och.common.module.manager.socket.lan.bean.ProjectType
import com.mogo.och.common.module.manager.socket.lan.bean.VehicleType
import com.mogo.och.common.module.utils.Project
import com.mogo.och.common.module.utils.ProjectUtils
import com.mogo.och.common.module.utils.FlavorUtils
/**
* 网约车小巴业务实现入口
@@ -89,50 +87,13 @@ class LoginProvider : LoginService {
}
override fun checkBusiness(businessType: Int): Boolean {
val businessEnum = BusinessEnum.valueOf(businessType)
FunctionBuildConfig.supportBusiness.forEach {
when (it) {
"shuttle" -> {
val isSupply = businessEnum == BusinessEnum.Shuttle
if (isSupply) {
return isSupply
}
}
"bus" -> {
val isSupply = businessEnum == BusinessEnum.Bus
if (isSupply) {
return isSupply
}
}
"taxi" -> {
val isSupply = businessEnum == BusinessEnum.Taxi
if (isSupply) {
return isSupply
}
}
"charter" -> {
val isSupply = businessEnum == BusinessEnum.Charter
if (isSupply) {
return isSupply
}
}
else -> {}
}
val businessInfo = FlavorUtils.getBusinessInfo(businessType)
if(businessInfo.isEmpty()){
return true
}
if (loginFragment is ILoginViewCallback) {
val reaseon = when (businessEnum) {
BusinessEnum.Taxi -> "后台配置为:出租车模式、请检查应用或配置"
BusinessEnum.Bus -> "后台配置为:小巴模式、请检查应用或配置"
BusinessEnum.Shuttle -> "后台配置为:接驳模式、请检查应用或配置"
BusinessEnum.Charter -> "后台配置为:包车模式、请检查应用或配置"
else -> "后台配置为:未知模式${businessType}、请检查应用或配置"
}
UiThreadHandler.post({
(loginFragment as ILoginViewCallback).showErrorInfo(reaseon)
(loginFragment as ILoginViewCallback).showErrorInfo(businessInfo)
},UiThreadHandler.MODE.QUEUE)
}
return false
@@ -145,70 +106,27 @@ class LoginProvider : LoginService {
businessType: BusinessType
): Boolean {
val isProjectSupply = when (ProjectUtils.getProjectType()) {
Project.SAAS -> projectType == ProjectType.saas
Project.DALI -> projectType == ProjectType.dali
Project.MOGO -> projectType == ProjectType.mogo
Project.YANTAI -> projectType == ProjectType.yantai
}
val envTypeSupply = when (DebugConfig.getNetMode()) {
2 -> {
envType == EnvType.qa
}
3 -> {
envType == EnvType.online
}
4 -> {
envType == EnvType.demo
}
else -> {
envType == EnvType.qa
}
}
val vehicleTypeSupply =
if (AppIdentityModeUtils.isT1T2(FunctionBuildConfig.appIdentityMode)) {
vehicleType == VehicleType.T1T2
} else if (AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode)) {
vehicleType == VehicleType.M1
} else if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
vehicleType == VehicleType.B1
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
vehicleType == VehicleType.B2
} else {
vehicleType == VehicleType.C1
}
val businessTypeSupply = checkBusinessMine(businessType)
if(isProjectSupply&&envTypeSupply&&vehicleTypeSupply&&businessTypeSupply){
val checkAllEnv = FlavorUtils.checkAllEnv(projectType, envType, vehicleType, businessType)
if(checkAllEnv.isEmpty()){
}else{
if (loginFragment is ILoginViewCallback) {
changeStatus(checkAllEnv)
UiThreadHandler.post({
(loginFragment as ILoginViewCallback).checkAllEnv(projectType,envType,vehicleType,businessType)
changeStatus(checkAllEnv)
(loginFragment as ILoginViewCallback).checkAllEnv(checkAllEnv)
},UiThreadHandler.MODE.QUEUE)
}
}
return isProjectSupply&&envTypeSupply&&vehicleTypeSupply&&businessTypeSupply
return checkAllEnv.isEmpty()
}
fun checkBusinessMine(businessType: BusinessType) :Boolean{
if(businessType==BusinessType.none){
return true
}
FunctionBuildConfig.supportBusiness.forEach {
if (businessType.name == it) {
return true
}
}
return false
override fun changeStatus(currentStatus: String) {
(loginFragment as ILoginViewCallback).updateStatus(currentStatus)
}
override fun setLoginInfo(loginInfo: LoginInfo) {
CallerLogger.d(tag, "setLoginInfo:${loginInfo}")
this.loginInfo = loginInfo

View File

@@ -9,10 +9,7 @@ interface ILoginViewCallback {
fun showErrorInfo(errorInfo: String)
fun checkAllEnv(
projectType: ProjectType,
envType: EnvType,
vehicleType: VehicleType,
businessType: BusinessType
reason:String
){}
fun updateStatus(status:String){}

View File

@@ -7,6 +7,8 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.och.biz.login.callback.ITaxiLoginCallback
import com.mogo.och.biz.login.model.LoginModel
import com.mogo.och.biz.login.ui.LoginPassengerFragment
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.manager.loop.LoopInfo
/**
* @author congtaowang
@@ -26,6 +28,7 @@ class LoginPassengerPresenter(view: LoginPassengerFragment?) : Presenter<LoginPa
private fun initListeners() {
LoginModel.init(AbsMogoApplication.getApp())
LoginModel.setiTaxiLoginCallback(this)
BizLoopManager.setLoopFunction(TAG, LoopInfo(2,::showStatus))
}
override fun onCreate(owner: LifecycleOwner) {
@@ -33,10 +36,13 @@ class LoginPassengerPresenter(view: LoginPassengerFragment?) : Presenter<LoginPa
CallerLogger.d(TAG, "乘客屏-登录-登陆")
}
private fun showStatus(){
mView?.showStatus()
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
BizLoopManager.removeLoopFunction(TAG)
}
override fun getPhoneCodeSuccess() {

View File

@@ -191,10 +191,7 @@ class LoginFragment : MvpFragment<LoginFragment?, LoginPresenter?>(), ILoginView
}
override fun checkAllEnv(
projectType: ProjectType,
envType: EnvType,
vehicleType: VehicleType,
businessType: BusinessType
reason:String
) {
// 司机屏不用处理 只处理 后台返回的业务模型就行
}

View File

@@ -4,21 +4,18 @@ import android.view.View
import androidx.appcompat.widget.AppCompatTextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.call.telematic.CallerTelematicManager
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.AppUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.biz.R
import com.mogo.och.biz.login.callback.ILoginViewCallback
import com.mogo.och.biz.login.presenter.LoginPassengerPresenter
import com.mogo.och.biz.login.ui.debugview.BusinessView
import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType
import com.mogo.och.common.module.manager.socket.lan.bean.EnvType
import com.mogo.och.common.module.manager.socket.lan.bean.ProjectType
import com.mogo.och.common.module.manager.socket.lan.bean.VehicleType
import com.mogo.och.common.module.biz.lansocket.LoginLanPassengerSocket
import com.mogo.och.common.module.utils.FlavorUtils
import kotlinx.android.synthetic.main.biz_login_view.eiv_Info
import java.lang.StringBuilder
/**
@@ -34,6 +31,8 @@ class LoginPassengerFragment : MvpFragment<LoginPassengerFragment?, LoginPasseng
private var actv_app_version: AppCompatTextView?=null
private var actv_connect_status: AppCompatTextView?=null
private val statusList = mutableListOf<String>()
override fun getLayoutId(): Int {
if (AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode) &&
@@ -58,12 +57,13 @@ class LoginPassengerFragment : MvpFragment<LoginPassengerFragment?, LoginPasseng
actv_app_version= findViewById(R.id.actv_app_version)
actv_connect_status= findViewById(R.id.actv_connect_status)
biz_actv_login_show_sn?.text = SharedPrefsMgr.getInstance().sn
biz_actv_login_show_sn?.setOnLongClickListener {
actv_app_version?.text = FlavorUtils.getInfo()
actv_app_version?.setOnLongClickListener {
bv_switch_business?.selectBusniess()
true
}
actv_app_version?.text = "版本号:${AppUtils.getAppVersionName()}"
CallerLogger.d(TAG, "init")
}
@@ -85,62 +85,38 @@ class LoginPassengerFragment : MvpFragment<LoginPassengerFragment?, LoginPasseng
}
override fun checkAllEnv(
projectType: ProjectType,
envType: EnvType,
vehicleType: VehicleType,
businessType: BusinessType
reason:String
) {
val info = StringBuilder()
info.append("司机屏支持的业务模式")
when (projectType) {
ProjectType.dali -> info.append("大理环境")
ProjectType.mogo -> info.append("衡阳环境")
ProjectType.saas -> info.append("saas环境")
ProjectType.yantai -> info.append("烟台环境")
}
when (envType) {
EnvType.qa -> info.append("、qa测试环境")
EnvType.online -> info.append("、正式环境环境")
EnvType.demo -> info.append("、开发环境环境")
}
when (vehicleType) {
VehicleType.T1T2 -> info.append("、车型是:T1T2")
VehicleType.C1 -> info.append("、车型是:B2")
VehicleType.B1 -> info.append("、车型是:B1")
VehicleType.B2 -> info.append("、车型是:B2")
VehicleType.M1 -> info.append("、车型是:M1")
}
info.append("、支持的业务类型有:")
when (businessType) {
BusinessType.none -> {
return
}
BusinessType.bus -> info.append("小巴车")
BusinessType.shuttle -> info.append("接驳车")
BusinessType.charter -> info.append("包车")
BusinessType.taxi -> info.append("出租车")
BusinessType.taxiunmanned -> info.append("无人化出租车")
}
eiv_Info.visibility = View.VISIBLE
eiv_Info.showErrinfo(info.toString())
eiv_Info.showErrinfo(reason)
}
override fun updateStatus(status: String) {
actv_connect_status?.text = "当前状态:${status}"
statusList.add(status)
}
override fun onResume() {
super.onResume()
CallerLogger.d(TAG, "onResume")
if (CallerTelematicManager.getClientConnStatus()) {
updateStatus("连接成功 司机SN:${LoginLanPassengerSocket.driverSn}")
}else{
updateStatus("连接司机屏中")
}
}
override fun onPause() {
super.onPause()
CallerLogger.d(TAG, "onPause")
}
fun showStatus() {
if (statusList.isNotEmpty()) {
val removeFirst = statusList.removeFirst()
UiThreadHandler.post({
actv_connect_status?.text = "当前状态:${removeFirst}"
}, UiThreadHandler.MODE.QUEUE)
}
}
}

View File

@@ -15,7 +15,6 @@ import kotlinx.android.synthetic.main.biz_login_business_view.view.actv_business
import kotlinx.android.synthetic.main.biz_login_business_view.view.actv_business_charter
import kotlinx.android.synthetic.main.biz_login_business_view.view.actv_business_shuttle
import kotlinx.android.synthetic.main.biz_login_business_view.view.actv_business_taxi
import kotlinx.android.synthetic.main.biz_login_errorinfo_view.view.actv_countdown
class BusinessView : ConstraintLayout, BusinessViewModel.IErrorInfoViewCallback {

View File

@@ -3,26 +3,16 @@ package com.mogo.och.biz.login.ui.errorview
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.appcompat.widget.AppCompatTextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import com.mogo.commons.debug.DebugConfig
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.och.biz.R
import com.mogo.och.biz.login.ui.debugview.BusinessViewModel
import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType
import com.mogo.och.common.module.manager.socket.lan.bean.EnvType
import com.mogo.och.common.module.manager.socket.lan.bean.ProjectType
import com.mogo.och.common.module.manager.socket.lan.bean.VehicleType
import com.mogo.och.common.module.utils.Project
import com.mogo.och.common.module.utils.ProjectUtils
import kotlinx.android.synthetic.main.biz_login_errorinfo_view.view.actv_countdown
import kotlinx.android.synthetic.main.biz_login_errorinfo_view.view.actv_error_body
import kotlinx.android.synthetic.main.biz_login_errorinfo_view.view.actv_error_head
import kotlinx.android.synthetic.main.biz_login_errorinfo_view.view.actv_see
import java.lang.StringBuilder
import com.mogo.och.common.module.biz.lansocket.LoginLanPassengerSocket
import com.mogo.och.common.module.utils.FlavorUtils
class ErrorInfoView : ConstraintLayout, ErrorInfoViewModel.IErrorInfoViewCallback {
@@ -33,75 +23,53 @@ class ErrorInfoView : ConstraintLayout, ErrorInfoViewModel.IErrorInfoViewCallbac
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(
context,
attributeSet,
defStyleAttr
)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
constructor(
context: Context,
attributeSet: AttributeSet,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attributeSet, defStyleAttr, defStyleRes)
private var actv_see: AppCompatTextView? = null
private var actv_countdown: AppCompatTextView? = null
private var actv_error_body: AppCompatTextView? = null
private var actv_error_head: AppCompatTextView? = null
private var viewModel: ErrorInfoViewModel? = null
private fun initView() {
LayoutInflater.from(context).inflate(R.layout.biz_login_errorinfo_view, this, true)
if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode) &&
if (AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode) &&
AppIdentityModeUtils.isPassenger((FunctionBuildConfig.appIdentityMode))
) {
actv_see.visibility = GONE
LayoutInflater.from(context)
.inflate(R.layout.biz_login_errorinfo_view_1920x1080, this, true)
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode) &&
AppIdentityModeUtils.isPassenger((FunctionBuildConfig.appIdentityMode))
) {
LayoutInflater.from(context)
.inflate(R.layout.biz_login_errorinfo_view_1080x1920, this, true)
} else {
LayoutInflater.from(context)
.inflate(R.layout.biz_login_errorinfo_view_2560x1600, this, true)
}
actv_see = findViewById(R.id.actv_see)
actv_countdown = findViewById(R.id.actv_countdown)
actv_error_body = findViewById(R.id.actv_error_body)
actv_error_head = findViewById(R.id.actv_error_head)
actv_see.onClick {
actv_see?.onClick {
viewModel?.cancleCountDown()
actv_countdown.text = "10s"
actv_countdown?.text = "10s"
visibility = GONE
}
val info = StringBuilder()
when (ProjectUtils.getProjectType()) {
Project.SAAS -> info.append("saas环境")
Project.DALI -> info.append("大理环境")
Project.MOGO -> info.append("衡阳环境")
Project.YANTAI -> info.append("烟台环境")
}
when (DebugConfig.getNetMode()) {
2 -> {
info.append("、qa测试环境")
}
3 -> {
info.append("、正式环境环境")
}
4 -> {
info.append("、开发环境环境")
}
else -> {
info.append("、qa测试环境")
}
}
val vehicleTypeSupply =
if (AppIdentityModeUtils.isT1T2(FunctionBuildConfig.appIdentityMode)) {
info.append("、车型是:T1T2")
} else if (AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode)) {
info.append("、车型是:M1")
} else if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
info.append("、车型是:B1")
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
info.append("、车型是:B2")
} else {
info.append("、车型是:C1")
}
info.append("、支持的业务类型有:")
FunctionBuildConfig.supportBusiness.forEachIndexed { index, s ->
if (index==FunctionBuildConfig.supportBusiness.size-1) {
info.append(s)
}else{
info.append("$s")
}
}
actv_error_body.text = info
actv_error_body?.text = FlavorUtils.getInfo()
}
@@ -119,9 +87,9 @@ class ErrorInfoView : ConstraintLayout, ErrorInfoViewModel.IErrorInfoViewCallbac
override fun onVisibilityAggregated(isVisible: Boolean) {
super.onVisibilityAggregated(isVisible)
if(isVisible){
if (isVisible) {
viewModel?.showCountDown()
}else{
} else {
}
}
@@ -135,15 +103,16 @@ class ErrorInfoView : ConstraintLayout, ErrorInfoViewModel.IErrorInfoViewCallbac
}
override fun setCountDownText(countDown: String, isEnd: Boolean) {
if(isEnd){
if (isEnd) {
visibility = GONE
}else{
actv_countdown.text = countDown
} else {
actv_countdown?.text = countDown
}
}
fun showErrinfo(errorInfo: String) {
actv_error_head.text = errorInfo
actv_error_head?.text = errorInfo
actv_error_body?.text = "${FlavorUtils.getInfo()} 司机SN:${LoginLanPassengerSocket.driverSn}"
}
}

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/dp_751"
android:layout_height="@dimen/dp_568"
android:background="@drawable/biz_login_error_info">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_countdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_35"
android:layout_marginEnd="@dimen/dp_45"
android:textColor="@color/biz_login_72A7FF"
android:textSize="@dimen/dp_40"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="10s" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_error_head"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_114"
android:layout_marginStart="@dimen/dp_48"
android:layout_marginEnd="@dimen/dp_48"
android:gravity="center"
android:textStyle="bold"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_44"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="当前Apk为包车模式配置为接驳模式请检查应用或配置" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_error_body"
android:layout_width="match_parent"
android:layout_marginStart="@dimen/dp_48"
android:layout_marginEnd="@dimen/dp_48"
android:layout_marginTop="@dimen/dp_39"
android:layout_height="0dp"
android:gravity="center"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_40"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/actv_error_head"
tools:text="T1 passanger-Saas Online-5.4.1001 AppSN12342392349 司机SN0383423942739" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/dp_939"
android:layout_height="@dimen/dp_710"
android:background="@drawable/biz_login_error_info">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_countdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_35"
android:layout_marginEnd="@dimen/dp_45"
android:textColor="@color/biz_login_72A7FF"
android:textSize="@dimen/dp_40"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="10s" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_error_head"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_120"
android:layout_marginStart="@dimen/dp_60"
android:layout_marginEnd="@dimen/dp_60"
android:gravity="center"
android:textStyle="bold"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_46"
app:layout_constraintBottom_toTopOf="@+id/actv_error_body"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="当前Apk为包车模式配置为接驳模式请检查应用或配置" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_error_body"
android:layout_width="match_parent"
android:layout_marginStart="@dimen/dp_60"
android:layout_marginEnd="@dimen/dp_60"
android:layout_height="0dp"
android:gravity="center"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_40"
app:layout_constraintBottom_toTopOf="@+id/actv_see"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.495"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/actv_error_head"
tools:text="T1 passanger-Saas Online-5.4.1001 AppSN12342392349 司机SN0383423942739" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_see"
android:layout_width="@dimen/dp_350"
android:layout_height="@dimen/dp_130"
android:layout_marginBottom="@dimen/dp_80"
android:background="@drawable/biz_login_error_see"
android:gravity="center"
android:text="@string/biz_log_i_see"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_46"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/actv_error_body" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -2,8 +2,8 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_width="@dimen/dp_939"
android:layout_height="@dimen/dp_730"
android:background="@drawable/biz_login_error_info">
<androidx.appcompat.widget.AppCompatTextView

View File

@@ -12,10 +12,10 @@
android:id="@+id/actv_connect_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dp_10"
android:text="当前状态:等待中"
android:text="当前状态:连接司机屏中"
android:textColor="@color/white"
android:textSize="@dimen/dp_44"
android:gravity="center"
android:textSize="@dimen/dp_36"
app:layout_constraintBottom_toTopOf="@+id/actv_app_version"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
@@ -25,9 +25,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dp_70"
android:gravity="center"
android:text="版本号:6.4.0"
android:textColor="@color/white"
android:textSize="@dimen/dp_44"
android:textSize="@dimen/dp_36"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />

View File

@@ -14,9 +14,9 @@
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dp_10"
android:layout_marginBottom="@dimen/dp_70"
android:text="当前状态:等待中"
android:text="当前状态:连接司机屏中"
android:textColor="@color/white"
android:textSize="@dimen/dp_44"
android:textSize="@dimen/dp_36"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/actv_app_version"
app:layout_constraintHorizontal_chainStyle="packed"
@@ -30,7 +30,7 @@
android:layout_marginBottom="@dimen/dp_70"
android:text="版本号:6.4.0"
android:textColor="@color/white"
android:textSize="@dimen/dp_44"
android:textSize="@dimen/dp_36"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/actv_connect_status" />

View File

@@ -14,7 +14,7 @@
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dp_10"
android:layout_marginBottom="@dimen/dp_70"
android:text="当前状态:等待中"
android:text="当前状态:连接司机屏中"
android:textColor="@color/white"
android:textSize="@dimen/dp_44"
app:layout_constraintBottom_toBottomOf="parent"

View File

@@ -15,20 +15,11 @@ import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType
import com.mogo.och.common.module.manager.socket.lan.bean.ChangeBusinessType
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
import com.mogo.och.common.module.manager.socket.lan.bean.EnvCheck
import com.mogo.och.common.module.manager.socket.lan.bean.EnvType
import com.mogo.och.common.module.manager.socket.lan.bean.ProjectType
import com.mogo.och.common.module.manager.socket.lan.bean.VehicleType
import com.mogo.och.common.module.utils.Project
import com.mogo.och.common.module.utils.ProjectUtils
import com.mogo.och.common.module.utils.FlavorUtils
object LoginLanDriverSocket : ILoginCallback {
private const val TAG = "LoginLanSocket"
var vehicleType: VehicleType? = null
var businessType: BusinessType? = null
var projectType: ProjectType? = null
var envType: EnvType? = null
// 客户端注册
private val registerListener = object : ILanMessageListener<BaseDPMsg> {
override fun target(): Class<BaseDPMsg> {
@@ -38,14 +29,14 @@ object LoginLanDriverSocket : ILoginCallback {
override fun onMsgReceived(obj: Array<in BaseDPMsg>) {
println("-------${obj}")
if(LoginStatusManager.isLogin()) {
getEnvCheck()
FlavorUtils.getEnvCheck()
val msg =
ChangeBusinessType(vehicleType!!, businessType!!, projectType!!, envType!!)
ChangeBusinessType(FlavorUtils.vehicleType!!, FlavorUtils.businessType!!, FlavorUtils.projectType!!, FlavorUtils.envType!!)
LanSocketManager.sendMsgToClient(msg)
}else{
getEnvCheck()
FlavorUtils.getEnvCheck()
val msg =
ChangeBusinessType(vehicleType!!, BusinessType.none, projectType!!, envType!!)
ChangeBusinessType(FlavorUtils.vehicleType!!, BusinessType.none, FlavorUtils.projectType!!, FlavorUtils.envType!!)
LanSocketManager.sendMsgToClient(msg)
}
}
@@ -70,90 +61,26 @@ object LoginLanDriverSocket : ILoginCallback {
super.onStatusChange(currentStatus)
when (currentStatus) {
LoginStatusEnum.Login -> {
getEnvCheck()
FlavorUtils.getEnvCheck()
val msg =
ChangeBusinessType(vehicleType!!, businessType!!, projectType!!, envType!!)
ChangeBusinessType(FlavorUtils.vehicleType!!, FlavorUtils.businessType!!, FlavorUtils.projectType!!, FlavorUtils.envType!!)
LanSocketManager.sendMsgToClient(msg)
BizLoopManager.setLoopFunction(TAG, LoopInfo(60 * 5, ::loopCheck))
BizLoopManager.setLoopFunction(TAG, LoopInfo(60, ::loopCheck))
}
else -> {
BizLoopManager.removeLoopFunction(TAG)
val msg =
ChangeBusinessType(vehicleType!!, BusinessType.none, projectType!!, envType!!)
ChangeBusinessType(FlavorUtils.vehicleType!!, BusinessType.none, FlavorUtils.projectType!!, FlavorUtils.envType!!)
LanSocketManager.sendMsgToClient(msg)
}
}
}
private fun loopCheck() {
getEnvCheck()
val msg = EnvCheck(vehicleType!!, businessType!!, projectType!!, envType!!)
FlavorUtils.getEnvCheck()
val msg = EnvCheck(FlavorUtils.vehicleType!!, FlavorUtils.businessType!!, FlavorUtils.projectType!!, FlavorUtils.envType!!)
LanSocketManager.sendMsgToClient(msg)
}
private fun getEnvCheck() {
vehicleType =
if (AppIdentityModeUtils.isT1T2(FunctionBuildConfig.appIdentityMode)) {
VehicleType.T1T2
} else if (AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode)) {
VehicleType.M1
} else if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
VehicleType.B1
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
VehicleType.B2
} else {
VehicleType.C1
}
businessType =
when (AppIdentityModeUtils.getProduct(FunctionBuildConfig.appIdentityMode)) {
AppIdentityModeUtils.Product.BUS -> {
BusinessType.bus
}
AppIdentityModeUtils.Product.TAXI -> {
BusinessType.taxi
}
AppIdentityModeUtils.Product.SWEEPER -> {
BusinessType.none
}
AppIdentityModeUtils.Product.SHUTTLE -> {
BusinessType.shuttle
}
AppIdentityModeUtils.Product.CHARTER -> {
BusinessType.charter
}
else -> {
BusinessType.none
}
}
projectType = when (ProjectUtils.getProjectType()) {
Project.SAAS -> ProjectType.saas
Project.DALI -> ProjectType.dali
Project.MOGO -> ProjectType.mogo
Project.YANTAI -> ProjectType.yantai
}
envType = when (DebugConfig.getNetMode()) {
2 -> {
EnvType.qa
}
3 -> {
EnvType.online
}
4 -> {
EnvType.demo
}
else -> {
EnvType.qa
}
}
}
}

View File

@@ -3,9 +3,11 @@ package com.mogo.och.common.module.biz.lansocket
import com.mogo.eagle.core.function.api.telematic.IReceivedMsgListener
import com.mogo.eagle.core.function.call.telematic.CallerTelematicListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.Logger
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.biz.login.BusinessEnum
import com.mogo.och.common.module.biz.login.LoginStatusEnum
import com.mogo.och.common.module.biz.login.LoginStatusManager
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.BaseDPMsg
@@ -16,16 +18,21 @@ import com.mogo.och.common.module.manager.socket.lan.bean.EnvCheck
import com.mogo.och.common.module.manager.socket.lan.bean.EnvType
import com.mogo.och.common.module.manager.socket.lan.bean.ProjectType
import com.mogo.och.common.module.manager.socket.lan.bean.VehicleType
import java.lang.StringBuilder
import kotlin.properties.Delegates
object LoginLanPassengerSocket : IReceivedMsgListener {
private const val TAG = "LoginLanSocket"
private var driverSn: String by Delegates.observable("") { _, oldV, newV ->
var driverSn: String by Delegates.observable("") { _, oldV, newV ->
if (oldV != newV) {
// 司机屏发生变化
val msg = BaseDPMsg(type = DPMsgType.TYPE_CLIENT_REGISTER.type)
LanSocketManager.sendMsgToServer(msg)
LoginStatusManager.changeStatus("连接成功 司机SN:${newV}")
if(newV.isNotEmpty()){
OchChainLogManager.writeChainLogNetLanSocketConnect("局域网socket链接状态","已连接 sn${newV}")
}
}
}
@@ -38,7 +45,12 @@ object LoginLanPassengerSocket : IReceivedMsgListener {
override fun onMsgReceived(obj: Array<in EnvCheck>) {
if (obj.isNotEmpty()) {
val first = obj.first() as EnvCheck
checkEnv(first.projectType, first.envType, first.vehicleType, first.businessType)
val checkEnv = checkEnv(first.projectType, first.envType, first.vehicleType, first.businessType)
if(checkEnv){
}else{
LoginStatusManager.setLoginStatus(LoginStatusEnum.Logout)
}
}
}
@@ -69,6 +81,8 @@ object LoginLanPassengerSocket : IReceivedMsgListener {
first.businessType
)
if(checkEnv){
val status = StringBuilder()
status.append("切换业务模式<当前:${LoginStatusManager.getBusInessType().name}")
when (first.businessType) {
BusinessType.none -> {
LoginStatusManager.setBusinessType(BusinessEnum.None.code)
@@ -80,7 +94,12 @@ object LoginLanPassengerSocket : IReceivedMsgListener {
BusinessType.taxi -> LoginStatusManager.setBusinessType(BusinessEnum.Taxi.code)
BusinessType.taxiunmanned ->LoginStatusManager.setBusinessType(BusinessEnum.Taxi.code)
}
LoginStatusManager.setLoginStatus(LoginStatusEnum.Login)
status.append(", 后台配置:${LoginStatusManager.getBusInessType().name}>")
LoginStatusManager.changeStatus(status.toString())
UiThreadHandler.postDelayed({
LoginStatusManager.setLoginStatus(LoginStatusEnum.Login)
},2000)
}
}
}

View File

@@ -34,4 +34,6 @@ interface LoginService :CommonService {
businessType: BusinessType
): Boolean
fun changeStatus(currentStatus: String)
}

View File

@@ -126,5 +126,11 @@ object LoginStatusManager : CallerBase<ILoginCallback>() {
return false
}
fun changeStatus(status: String) {
loginService?.let {
it.changeStatus(status)
}
}
}

View File

@@ -23,14 +23,20 @@ object OchChainLogManager {
const val EVENT_KEY_INFE_ERROR = "event_key_och_error"
const val EVENT_KEY_INFO_Net = "event_key_och_net"
const val EVENT_KEY_INFO_SOCKET = "event_key_och_socket"
const val EVENT_KEY_INFO_SOCKET = "analytics_event_och_track_screen_msg"
const val EVENT_KEY_INFO_SOCKET_CONNECT = "analytics_event_och_track_screen_connect"
fun writeChainLogNet(info: String, changeInfo: String){
writeChainLog(info,changeInfo,true,EVENT_KEY_INFO_Net)
}
fun writeChainLogLanSocket(info: String, changeInfo: String){
writeChainLog(info,changeInfo,true,EVENT_KEY_INFO_SOCKET)
fun writeChainLogNetLanSocketConnect(info: String, changeInfo: String){
writeChainLog(info,changeInfo,true,EVENT_KEY_INFO_SOCKET_CONNECT)
}
fun writeChainLogLanSocket(info: String, changeInfo: String,action:String){
val map = hashMapOf<String, Any>()
map["action"] = action
writeChainLog(info,changeInfo,true,EVENT_KEY_INFO_SOCKET, map)
}
/**
@@ -44,7 +50,7 @@ object OchChainLogManager {
paramIndexes = [0,1]
)
@JvmStatic
fun writeChainLog(Info: String, changeInfo: String,upload:Boolean = true,eventID:String=EVENT_KEY_INFE_WITH_CHANGE) {
fun writeChainLog(Info: String, changeInfo: String,upload:Boolean = true,eventID:String=EVENT_KEY_INFE_WITH_CHANGE,patch:HashMap<String, Any>?=null) {
try {
d(SceneConstant.M_OCHCOMMON + TAG, Info)
d(SceneConstant.M_OCHCOMMON + TAG, changeInfo)
@@ -57,6 +63,9 @@ object OchChainLogManager {
params["time"] = DateTimeUtils.getTimeText(DateTimeUtils.yyyy_MM_dd_HH_mm_ss)
params["info"] = Info
params["changeInfo"] = changeInfo
patch?.let {
params.putAll(it)
}
MogoAnalyticUtils.track(eventID, params)
}
}catch (e:Exception){

View File

@@ -26,7 +26,7 @@ object LanSocketManager : IReceivedMsgListener {
fun sendMsgToClient(msg: BaseDPMsg?) {
val message = GsonUtils.toJson(msg)
CallerLogger.d(TAG, "sendMsgToClient: $message")
OchChainLogManager.writeChainLogLanSocket("发送msg到各个端",message)
OchChainLogManager.writeChainLogLanSocket("发送msg到各个端",message,"send")
CallerTelematicManager.sendMsgToAllClients(OchCommonConst.BUSINESS_STRING, message.toByteArray())
}
@@ -34,13 +34,13 @@ object LanSocketManager : IReceivedMsgListener {
fun sendMsgToServer(msg: BaseDPMsg?) {
val message = GsonUtils.toJson(msg)
CallerLogger.d(TAG, "sendMsgToServer:$message")
OchChainLogManager.writeChainLogLanSocket("发送msg到服务端(司机)",message)
OchChainLogManager.writeChainLogLanSocket("发送msg到服务端(司机)",message,"send")
CallerTelematicManager.sendMsgToServer(OchCommonConst.BUSINESS_STRING, message.toByteArray())
}
override fun onReceivedMsg(type: Int, byteArray: ByteArray) {
CallerLogger.d(TAG, "收到数据:_type:${type},byteArray:${String(byteArray)}")
OchChainLogManager.writeChainLogLanSocket("收到数据","type:${type},byteArray:${String(byteArray)}")
OchChainLogManager.writeChainLogLanSocket("收到数据","type:${type},byteArray:${String(byteArray)}","receive")
if (OchCommonConst.BUSINESS_STRING == type) {
try {
val baseMsg = GsonUtils.fromJson(String(byteArray), BaseDPMsg::class.java)

View File

@@ -0,0 +1,287 @@
package com.mogo.och.common.module.utils
import com.mogo.commons.debug.DebugConfig
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.util.AppUtils
import com.mogo.och.common.module.biz.login.BusinessEnum
import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType
import com.mogo.och.common.module.manager.socket.lan.bean.EnvType
import com.mogo.och.common.module.manager.socket.lan.bean.ProjectType
import com.mogo.och.common.module.manager.socket.lan.bean.VehicleType
import kotlin.text.StringBuilder
object FlavorUtils {
var vehicleType: VehicleType? = null
var businessType: BusinessType? = null
var projectType: ProjectType? = null
var envType: EnvType? = null
fun getInfo():String{
val info = StringBuilder()
when (ProjectUtils.getProjectType()) {
Project.SAAS -> info.append("saas")
Project.DALI -> info.append("dali")
Project.MOGO -> info.append("mogo")
Project.YANTAI -> info.append("yantai")
}
if (AppIdentityModeUtils.isT1T2(FunctionBuildConfig.appIdentityMode)) {
info.append(" T1T2")
} else if (AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode)) {
info.append(" M1")
} else if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
info.append(" B1")
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
info.append(" B2")
} else {
info.append(" C1")
}
when (DebugConfig.getNetMode()) {
2 -> {
info.append(" qa ")
}
3 -> {
info.append(" online ")
}
4 -> {
info.append(" demo ")
}
else -> {
info.append(" qa ")
}
}
info.append(" Passenger")
info.append(" ${AppUtils.getAppVersionName()}")
info.append(" AppSN:${SharedPrefsMgr.getInstance().sn}")
return info.toString()
}
fun getBusinessInfo(businessType: Int):String {
val businessEnum = BusinessEnum.valueOf(businessType)
FunctionBuildConfig.supportBusiness.forEach {
when (it) {
"shuttle" -> {
val isSupply = businessEnum == BusinessEnum.Shuttle
if (isSupply) {
return ""
}
}
"bus" -> {
val isSupply = businessEnum == BusinessEnum.Bus
if (isSupply) {
return ""
}
}
"taxi" -> {
val isSupply = businessEnum == BusinessEnum.Taxi
if (isSupply) {
return ""
}
}
"charter" -> {
val isSupply = businessEnum == BusinessEnum.Charter
if (isSupply) {
return ""
}
}
else -> {}
}
}
val reason = StringBuilder()
reason.append("业务异常<当前支持:")
FunctionBuildConfig.supportBusiness.forEachIndexed { index, s ->
if(index==FunctionBuildConfig.supportBusiness.size-1){
reason.append(s)
}else{
reason.append("${s},")
}
}
when (businessEnum) {
BusinessEnum.Taxi -> reason.append(" 后台配置:taxi")
BusinessEnum.Bus -> reason.append(" 后台配置:bus")
BusinessEnum.Shuttle -> reason.append(" 后台配置:shuttle")
BusinessEnum.Charter -> reason.append(" 后台配置:charter")
else -> reason.append(" 后台配置:未知")
}
return reason.toString()
}
fun getEnvCheck() {
businessType =
when (AppIdentityModeUtils.getProduct(FunctionBuildConfig.appIdentityMode)) {
AppIdentityModeUtils.Product.BUS -> {
BusinessType.bus
}
AppIdentityModeUtils.Product.TAXI -> {
BusinessType.taxi
}
AppIdentityModeUtils.Product.SWEEPER -> {
BusinessType.none
}
AppIdentityModeUtils.Product.SHUTTLE -> {
BusinessType.shuttle
}
AppIdentityModeUtils.Product.CHARTER -> {
BusinessType.charter
}
else -> {
BusinessType.none
}
}
if(vehicleType==null||projectType==null||envType==null) {
vehicleType =
if (AppIdentityModeUtils.isT1T2(FunctionBuildConfig.appIdentityMode)) {
VehicleType.T1T2
} else if (AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode)) {
VehicleType.M1
} else if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
VehicleType.B1
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
VehicleType.B2
} else {
VehicleType.C1
}
projectType = when (ProjectUtils.getProjectType()) {
Project.SAAS -> ProjectType.saas
Project.DALI -> ProjectType.dali
Project.MOGO -> ProjectType.mogo
Project.YANTAI -> ProjectType.yantai
}
envType = when (DebugConfig.getNetMode()) {
2 -> {
EnvType.qa
}
3 -> {
EnvType.online
}
4 -> {
EnvType.demo
}
else -> {
EnvType.qa
}
}
}
}
fun checkAllEnv( projectType: ProjectType,
envType: EnvType,
vehicleType: VehicleType,
businessType: BusinessType):String{
val reason = StringBuilder()
val isProjectSupply = when (ProjectUtils.getProjectType()) {
Project.SAAS -> projectType == ProjectType.saas
Project.DALI -> projectType == ProjectType.dali
Project.MOGO -> projectType == ProjectType.mogo
Project.YANTAI -> projectType == ProjectType.yantai
}
if(!isProjectSupply){
reason.append("项目异常<当前:${ProjectUtils.getProjectType().name}, 后台配置:${projectType.name}> ")
}
val currentVehicle:String
val vehicleTypeSupply =
if (AppIdentityModeUtils.isT1T2(FunctionBuildConfig.appIdentityMode)) {
currentVehicle = VehicleType.T1T2.name
vehicleType == VehicleType.T1T2
} else if (AppIdentityModeUtils.isM1(FunctionBuildConfig.appIdentityMode)) {
currentVehicle = VehicleType.M1.name
vehicleType == VehicleType.M1
} else if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
currentVehicle = VehicleType.B1.name
vehicleType == VehicleType.B1
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
currentVehicle = VehicleType.B2.name
vehicleType == VehicleType.B2
} else {
currentVehicle = VehicleType.C1.name
vehicleType == VehicleType.C1
}
if(!vehicleTypeSupply){
reason.append("车型异常<当前:${currentVehicle}, 后台配置:${vehicleType.name}> ")
}
val currentenvType:String
val envTypeSupply = when (DebugConfig.getNetMode()) {
2 -> {
currentenvType = EnvType.qa.name
envType == EnvType.qa
}
3 -> {
currentenvType = EnvType.online.name
envType == EnvType.online
}
4 -> {
currentenvType = EnvType.demo.name
envType == EnvType.demo
}
else -> {
currentenvType = EnvType.qa.name
envType == EnvType.qa
}
}
if(!envTypeSupply){
reason.append("环境异常<当前:${currentenvType} 后台配置:${envType.name}> ")
}
val businessTypeSupply = checkBusinessMine(businessType)
if(!businessTypeSupply){
reason.append("业务异常<当前支持:")
FunctionBuildConfig.supportBusiness.forEachIndexed { index, s ->
if(index==FunctionBuildConfig.supportBusiness.size-1){
reason.append(s)
}else{
reason.append("${s},")
}
}
reason.append(" 后台配置:${businessType.name}> ")
}
return reason.toString()
}
fun checkBusinessMine(businessType: BusinessType) :Boolean{
if(businessType==BusinessType.none){
return true
}
FunctionBuildConfig.supportBusiness.forEach {
if (businessType.name == it) {
return true
}
}
return false
}
}