package com.igo.user.ui.logistics import android.Manifest import android.animation.ObjectAnimator import android.app.Activity import android.content.Intent import android.content.pm.PackageManager import android.util.Log import android.view.View import android.widget.CheckBox import android.widget.CheckedTextView import android.widget.EditText import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView import androidx.constraintlayout.widget.Group import androidx.core.app.ActivityCompat import androidx.core.os.bundleOf import cn.sinata.xldutils.defaultScheduler import cn.sinata.xldutils.fragment.BaseFragment import cn.sinata.xldutils.gone import cn.sinata.xldutils.toBrowser import cn.sinata.xldutils.utils.SpanBuilder import cn.sinata.xldutils.utils.myToast import cn.sinata.xldutils.utils.optInt import cn.sinata.xldutils.utils.showAllowingStateLoss import cn.sinata.xldutils.utils.toTime import cn.sinata.xldutils.visible import com.facebook.drawee.view.SimpleDraweeView import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.SupportMapFragment import com.google.android.gms.maps.model.LatLng import com.igo.user.IGoApplication import com.igo.user.R import com.igo.user.dialog.ChooseReserveTimeDialog import com.igo.user.dialog.SingleWheelDialog import com.igo.user.dialog.TipDialog import com.igo.user.interfaces.StringCallback import com.igo.user.network.HttpManager import com.igo.user.network.entity.GeoBean import com.igo.user.network.requestByF import com.igo.user.ui.MainActivity import com.igo.user.ui.mine.OrderActivity import com.igo.user.ui.mine.TripOrderFragment import com.igo.user.ui.trip.ChoosePositionActivity import com.igo.user.ui.trip.OrderDetailActivity import com.igo.user.utils.Const import com.igo.user.utils.google.AMapKit import com.igo.user.utils.pay.PayListener import com.igo.user.utils.pay.PayUtil import com.tbruyelle.rxpermissions2.RxPermissions import io.reactivex.subscribers.DisposableSubscriber import org.jetbrains.anko.backgroundResource import org.jetbrains.anko.find import org.jetbrains.anko.sdk27.coroutines.onClick import org.jetbrains.anko.support.v4.dip import org.jetbrains.anko.support.v4.find import org.jetbrains.anko.support.v4.startActivity import org.jetbrains.anko.support.v4.startActivityForResult import java.math.RoundingMode import androidx.core.view.isVisible import com.igo.user.extension.extClearInvalidZero class LogisticsFragment : BaseFragment(), PayListener { override fun contentViewId() = R.layout.fragment_logistics var type = Const.OrderType.TYPE_SAME_CITY //默认为同城物流 private val DEFAULT_SCALE_LEVEL = 18f private var startByChoose = false //true 通过选择出发地移动地图,false 通过手势拖动地图 private var startByLocal = false //true 通过复位按钮移动地图,false 通过手势拖动地图 //取件经纬度 private var startLon = 0.0 private var startLat = 0.0 private var startName = "" //收件信息 private var receiveName = "" private var receivePhone = "" private var receiveRegion = "" // private var provinceIndex = 0 // private var cityIndex = 0 // private var regionIndex = 0 private var receiveAddress = "" private var endLat = 0.0 private var endLon = 0.0 private var timeFormat = "" //取件时间:例 2020-09-17 21:00:00 private var isFirstOrder = true //货物信息 private var goodsType = 1 //货物类型(1=普通货物,2=贵重货物) private var goodsNum = 1 //货物数量 private var remark = "" private var orderMoney = 0.0 //物流费用 private var fastMoney = 0 //加急费用 var aMap: GoogleMap? = null private val mainActivity by lazy { activity as MainActivity } private var carTypeId = 0 //车型id private var carTypeIndex = -1 //选中的位置 private val tv_tips by lazy { find(R.id.tv_tips) } private val iv_location by lazy { find(R.id.iv_location) } private val tv_start by lazy { find(R.id.tv_start) } private val tv_receiver by lazy { find(R.id.tv_receiver) } private val tv_type by lazy { find(R.id.tv_type) } private val tv_time by lazy { find(R.id.tv_time) } private val tv_action by lazy { find(R.id.tv_action) } private val tv_center by lazy { find(R.id.tv_center) } private val cb_fast by lazy { find(R.id.cb_fast) } private val iv_center_logistics by lazy { find(R.id.iv_center_logistics) } private val group_fast by lazy { find(R.id.group_fast) } private val cl_types by lazy { find(R.id.cl_types) } private val tv_empty by lazy { find(R.id.tv_empty) } private val tv_error by lazy { find(R.id.tv_error) } private val tv_retry by lazy { find(R.id.tv_retry) } private val ll_type by lazy { find(R.id.ll_type) } private val ll_estimate_price by lazy { find(R.id.ll_estimate_price) } private val tv_estimate_price by lazy { find(R.id.tv_estimate_price) } //预估价格 private var estimatePrice: Double = 0.0 private val tipsDialog by lazy { val dialog = SingleWheelDialog() dialog.arguments = bundleOf( "title" to "修改加急金额", "subTitle" to "加急费用归司机所有,添加将提高应答率", "data" to (1..20).map { "${it}元" }) dialog.setCallback(object : StringCallback { override fun onRlt(rlt: String) { tv_tips.text = rlt fastMoney = rlt.substring(0, rlt.length - 1).toInt() } }) dialog } private val successDialog by lazy { val dialog = TipDialog() dialog.arguments = bundleOf("msg" to getString(R.string.您已下单成功), "isAlert" to true) dialog.setDismissCallback(object : TipDialog.OnDismiss { override fun onDismiss() { startActivity("type" to TripOrderFragment.TYPE_LOGISTICS) } }) dialog } override fun onFirstVisibleToUser() { enableMyLocation() initClick() PayUtil.addPayListener(this) } private fun initClick() { //点击归位 iv_location.setOnClickListener { startByLocal = true aMap?.animateCamera( CameraUpdateFactory.newLatLngZoom( IGoApplication.getCurrentLocation(), DEFAULT_SCALE_LEVEL ) ) } tv_start.onClick { startActivityForResult( Const.RequestCode.LOGISTICS_START, "isLogistics" to true ) } tv_receiver.onClick { if (mainActivity.checkLogin()) { if (startName.isEmpty()) { myToast(getString(R.string.请先选择起点)) return@onClick } /*if (SPUtils.instance().getString(Const.User.EMAIL).isEmpty()){ //当前登录但没有设置邮箱,强制设置邮箱 startActivity("isRegister" to true,"isPackage" to true) }else*/ startActivityForResult( Const.RequestCode.LOGISTICS_RECEIVER, "name" to receiveName, "type" to type, "phone" to receivePhone, "region" to receiveRegion, "address" to receiveAddress, "startLat" to startLat, "startLon" to startLon, "endLat" to endLat, "endLon" to endLon ) } } // tv_type.onClick { // if (startName.isEmpty()){ // myToast("请选择取件地点") // return@onClick // } // if (receiveAddress.isEmpty()){ // myToast("请完善收货人信息") // return@onClick // } // if (mainActivity.checkLogin()) // startActivityForResult(Const.RequestCode.LOGISTICS_TYPE,"address" to receiveRegion+receiveAddress, // "lat" to startLat,"lon" to startLon,"type" to type) // } tv_time.onClick { val chooseReserveTimeDialog = ChooseReserveTimeDialog() chooseReserveTimeDialog.arguments = bundleOf("title" to "设置取货时间") chooseReserveTimeDialog.setCallback(object : ChooseReserveTimeDialog.Callback { override fun onOk(s: String, formatS: String) { tv_time.text = s timeFormat = formatS } }) chooseReserveTimeDialog.show(childFragmentManager, "timeLogistics") } tv_tips.onClick { if (cb_fast.isChecked && !tipsDialog.isAdded) { tipsDialog.show(childFragmentManager, "tips") } } tv_action.onClick { // if (timeFormat.isEmpty()){ // myToast("请选择司机取货时间") // return@onClick // } // if (type == Const.OrderType.TYPE_SAME_CITY&&cb_fast.isChecked&&fastMoney == 0){ // myToast("请选择加急费用") // return@onClick // } if (isFirstOrder) { startActivityForResult( Const.RequestCode.LOGISTICS_RULE, "carTypeId" to carTypeId, "goodsNum" to goodsNum, "goodsType" to goodsType, "startLat" to startLat, "startLon" to startLon, "endLat" to endLat, "endLon" to endLon, "receiveAddress" to receiveAddress, "receiveName" to receiveName, "receivePhone" to receivePhone, "startName" to startName, "fastMoney" to fastMoney, "type" to type, "urgent" to if (cb_fast.isChecked) 2 else 1, "remark" to tv_type.text.toString(), "estimatePrice" to estimatePrice, ) } else createOrder() } cb_fast.setOnCheckedChangeListener { _, isChecked -> if (!isChecked) { fastMoney = 0 tv_tips.text = "" } } tv_retry.onClick { getPrice() } } private var locCount = 0L //定位次数 private fun initMap() { val fragment = childFragmentManager.findFragmentById(R.id.mMapView) as SupportMapFragment AMapKit.initMap(fragment) { it -> val requireActivity = requireActivity() if (ActivityCompat.checkSelfPermission( requireActivity, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( requireActivity, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) { return@initMap } aMap = it.apply { isMyLocationEnabled = true uiSettings.isMyLocationButtonEnabled = false setOnMyLocationChangeListener { Log.e(Const.Tag, "当前定位:lat:" + it.latitude + ",lon:" + it.longitude) IGoApplication.setLocation(it.latitude, it.longitude) // IGoApplication.address = it.address // IGoApplication.cityCode = it.extras.getString("adcode")?:"" if (locCount < 1) { moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(it.latitude, it.longitude), DEFAULT_SCALE_LEVEL)) } locCount++ } setOnCameraMoveStartedListener { if (startByLocal) tv_center.text = getString(R.string.local_ing) } setOnCameraIdleListener { if (!startByChoose && iv_center_logistics.isVisible) { startLat = cameraPosition.target.latitude startLon = cameraPosition.target.longitude getPoi(startLat, startLon) } startByChoose = false startByLocal = false val objectAnimator = ObjectAnimator.ofFloat(iv_center_logistics, "translationY", 0f, -30f, 0f) .setDuration(600) val objectAnimator1 = ObjectAnimator.ofFloat(tv_center, "translationY", 0f, -30f, 0f) .setDuration(600) objectAnimator.start() objectAnimator1.start() tv_center.text = getString(R.string.在这里领取) } moveCamera(CameraUpdateFactory.newLatLngZoom(IGoApplication.getCurrentLocation(), DEFAULT_SCALE_LEVEL)) } } } /** * Enables the My Location layer if the fine location permission has been granted. */ private fun enableMyLocation() { val subscribe = RxPermissions(requireActivity()).request( Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION ).subscribe { if (it) initMap() else { myToast(getString(R.string.没有权限)) } } } private fun createOrder() { showDialog() val currentLocation = IGoApplication.getCurrentLocation() HttpManager.smallLogistics( carTypeId, "$endLon,$endLat", goodsNum, goodsType, receiveAddress, currentLocation.latitude, currentLocation.longitude, receiveName, receivePhone, tv_type.text.toString(), startName, startLat, startLon, fastMoney, System.currentTimeMillis().toTime(), type, if (cb_fast.isChecked) 2 else 1 ).requestByF(this) { _, data -> data?.run { // if (optInt("state") == 7){ // val tipDialog = TipDialog() // tipDialog.arguments = bundleOf("msg" to getString(R.string.有订单未支付),"ok" to getString(R.string.立即支付),"cancel" to getString(R.string.取消)) // tipDialog.setCallback(object :TipDialog.OnClickCallback{ // override fun onOk() { // startActivity("type" to type,"id" to optInt("id")) // } // // override fun onCancel() { // } // }) // tipDialog.show(childFragmentManager,"unpay") // }else{ //startActivity("type" to type, "id" to optInt("id")) startActivity("id" to optInt("id"), "type" to type) back() // } } } } /** * @param way 1=微信,2=支付宝,3=余额,4=现金 */ private fun pay(way: Int, id: Int, couponId: Int?, cardId: String?) { HttpManager.payTaxiOrder(id, way, 4, couponId, cardId).requestByF(this) { _, data -> if (way in 3..4) onPaySuccess() else { requireActivity().toBrowser(data.toString() ?: "") } } } /** * 返回 * @param isBackHome true:直接返回到首页 */ fun back(isBackHome: Boolean = true) { isFirstOrder = true group_fast.gone() tv_action.gone() cl_types.gone() ll_type.removeAllViews() carTypeIndex = -1 carTypeId = 0 iv_center_logistics.visible() tv_center.visible() iv_location.visible() mainActivity.updateTitleVisibility(false, false) mainActivity.updateLogisticsTitle(false) mainActivity.updateTabVisibility(true) aMap?.uiSettings?.isScrollGesturesEnabled = true aMap?.uiSettings?.isZoomGesturesEnabled = true if (isBackHome) { tv_receiver.text = "" receiveAddress = "" receiveRegion = "" receiveName = "" receivePhone = "" endLat = 0.0 endLon = 0.0 // provinceIndex = 0 // cityIndex = 0 // regionIndex = 0 } tv_type.setText("") tv_start.isEnabled = true tv_receiver.isEnabled = true tv_type.isEnabled = true tv_time.text = "" timeFormat = "" cb_fast.isChecked = false tv_tips.text = "" fastMoney = 0 } /**检查返回状态*/ fun checkBack(): Boolean { return try { if (tv_action.isVisible) { //先返回到上一步 back() false } else true } catch (e: Exception) { true } } /** * 获取支付金额 */ private fun getPrice() { if (startName.isNotEmpty() && endLat != 0.0) { tv_action.visible() cl_types.gone() showDialog() aMap?.uiSettings?.isScrollGesturesEnabled = false aMap?.uiSettings?.isZoomGesturesEnabled = false ll_type.removeAllViews() ll_type.gone() HttpManager.queryPayMoney("$startLon,$startLat", "$endLon,$endLat", type) .requestByF(this, true, { _, data -> if (data?.isEmpty() == true) { tv_empty.visible() ll_estimate_price.gone() tv_action.isEnabled = false } else { tv_action.isEnabled = true tv_error.gone() tv_retry.gone() data!!.forEachIndexed { index, it -> val view = layoutInflater.inflate(R.layout.item_car_price, ll_type, false) val tv_name = view.find(R.id.tv_name) val tv_price = view.find(R.id.tv_price) val iv_car = view.find(R.id.iv_car) val ll_car = view.find(R.id.ll_car) tv_name.text = it.name tv_price.text = getString(R.string.预估价格, it.amount).replace(",", ".").extClearInvalidZero() iv_car.setImageURI(it.img) ll_estimate_price.visible() tv_estimate_price.visible() estimatePrice = it.amount.toBigDecimal().setScale( 2, RoundingMode.HALF_UP ).toDouble() tv_estimate_price.text = "FCFA $estimatePrice".extClearInvalidZero() if (index == 0) { //默认选择第一个 carTypeId = it.id carTypeIndex = 0 tv_name.isChecked = true tv_price.isChecked = true ll_car.elevation = dip(3).toFloat() ll_car.backgroundResource = R.drawable.bg_white_6dp } view.onClick { _ -> showCarPriceNote(it.fareTypeNote) if (index != carTypeIndex) { tv_name.isChecked = true tv_price.isChecked = true ll_car.elevation = dip(3).toFloat() ll_car.backgroundResource = R.drawable.bg_white_6dp if (carTypeIndex != -1) ll_type.getChildAt(carTypeIndex).apply { val tv_name = find(R.id.tv_name) val tv_price = find(R.id.tv_price) val ll_car = find(R.id.ll_car) tv_name.isChecked = false tv_price.isChecked = false ll_car.elevation = 0f ll_car.backgroundResource = 0 } carTypeIndex = index carTypeId = it.id } } ll_type.addView(view) } } }) { _, _ -> tv_error.visible() tv_retry.visible() ll_estimate_price.gone() tv_action.isEnabled = false } } } fun changeType(newType: Int) { if (newType != type) { type = newType } } /** * 运费说明 * 点击车型图片即弹窗说明 */ private fun showCarPriceNote(msg: String) { val tipDialog = TipDialog() tipDialog.arguments = bundleOf("msg" to msg, "isAlert" to true, "noTitle" to true) tipDialog.showAllowingStateLoss(childFragmentManager, "note") } /** * 获取poi信息 */ private var poiSearchDisposable: DisposableSubscriber? = null fun getPoi(lat: Double?, lng: Double?) { if (lat == null || lng == null) { return } //如果上一次还没处理完,取消订阅 if (poiSearchDisposable != null && !poiSearchDisposable!!.isDisposed) { poiSearchDisposable?.dispose() } poiSearchDisposable = object : DisposableSubscriber() { override fun onComplete() { } override fun onNext(t: GeoBean?) { if (view == null) { return } val address = if (t != null && t.status == "OK") { t.results.firstOrNull()?.formatted_address } else { null } startName = address ?: "" tv_start?.text = address } override fun onError(t: Throwable?) { if (view == null) { return } startName = "" tv_start.text = getString(R.string.选择领取点) } } HttpManager.geoCode(lat, lng).defaultScheduler().subscribe(poiSearchDisposable) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (resultCode == Activity.RESULT_OK) { // if (requestCode == Const.RequestCode.LOGISTICS_RULE) { // createOrder() // } if (data != null) when (requestCode) { Const.RequestCode.LOGISTICS_START -> { startLat = data.getDoubleExtra("lat", 0.0) startLon = data.getDoubleExtra("lon", 0.0) startByChoose = true aMap?.animateCamera( CameraUpdateFactory.newLatLng( LatLng( startLat, startLon ) ) ) startName = data.getStringExtra("name") ?: "" tv_start.text = startName getPrice() } Const.RequestCode.LOGISTICS_RECEIVER -> { receiveName = data.getStringExtra("name") ?: "" receivePhone = data.getStringExtra("phone") ?: "" receiveRegion = data.getStringExtra("region") ?: "" receiveAddress = data.getStringExtra("address") ?: "" endLat = data.getDoubleExtra("lat", 0.0) endLon = data.getDoubleExtra("lon", 0.0) /* HttpManager.judgingTheCity("${endLat},${endLon}","${startLat},${startLon}").request(mainActivity,true,{_,data-> Log.e( "onActivityResult: ", "同一城市") toast("同一城市") }){a,b-> toast("报错") Log.e( "onActivityResult: error", Gson().toJson(a)) Log.e( "onActivityResult: error", Gson().toJson(b)) }*/ val receiver = "%s %s\n%s%s".format( receiveName, receivePhone, receiveRegion, receiveAddress ) tv_receiver.text = SpanBuilder(receiver).color( requireActivity(), receiver.length - receiveAddress.length - receiveRegion.length, receiver.length, cn.sinata.xldutils.R.color.textColor99 ).size( receiver.length - receiveAddress.length - receiveRegion.length, receiver.length, 12 ).build() getPrice() } Const.RequestCode.LOGISTICS_TYPE -> { // isFirstOrder = data.getBooleanExtra("isFirstOrder",false) // goodsType = data.getIntExtra("goodsType",0) // goodsNum = data.getIntExtra("goodsNum",0) // remark = data.getStringExtra("remark")?:"" // tv_type.text = "%sX%d".format(if (goodsType == 1) "普通小件" else "贵重物品",goodsNum) } } } } override fun onDestroyView() { if (poiSearchDisposable?.isDisposed == false) { poiSearchDisposable?.dispose() } super.onDestroyView() } override fun onDestroy() { super.onDestroy() PayUtil.removePayListener(this) } override fun onPaySuccess() { if (!successDialog.isAdded) successDialog.show(childFragmentManager, "suc") } override fun onPayCancel() { startActivity("type" to TripOrderFragment.TYPE_LOGISTICS) } }