From 0b8561316c92ab924132f9404ef103a32624fcda Mon Sep 17 00:00:00 2001 From: yezhiqiu <983577727@qq.com> Date: Mon, 20 Oct 2025 15:41:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=9D=E9=99=A9=E6=9C=8D=E5=8A=A1=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 1 - .../compile-file-map.properties | 2 +- app/build.gradle | 4 +- .../abbidot/tracker/bean/CommonDataBean.kt | 10 + .../tracker/retrofit2/INetworkService.kt | 13 +- .../abbidot/tracker/retrofit2/NetworkApi.kt | 7 + .../activity/subscribe/ChoosePlanActivity.kt | 29 +- .../subscribe/SureSubscriptionPlanActivity.kt | 336 ++++++++++++++---- .../map/baidumap/BaseBaiduMapFragment.kt | 5 +- .../map/googlemap/BaseGoogleMapFragment.kt | 2 +- .../abbidot/tracker/vm/GeoCoderViewModel.kt | 89 +++-- .../tracker/vm/GoogleLocationViewModel.kt | 104 ++++++ .../tracker/vm/SubscriptionManageViewModel.kt | 14 +- ...yout_sure_subscribe_plan_detail_layout.xml | 23 +- 14 files changed, 516 insertions(+), 123 deletions(-) create mode 100644 app/src/main/java/com/abbidot/tracker/bean/CommonDataBean.kt create mode 100644 app/src/main/java/com/abbidot/tracker/vm/GoogleLocationViewModel.kt diff --git a/.idea/misc.xml b/.idea/misc.xml index 2006b65..c67ba6b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/FastBleLib/build/intermediates/incremental/release/packageReleaseResources/compile-file-map.properties b/FastBleLib/build/intermediates/incremental/release/packageReleaseResources/compile-file-map.properties index 6eb27cd..e62b9bf 100644 --- a/FastBleLib/build/intermediates/incremental/release/packageReleaseResources/compile-file-map.properties +++ b/FastBleLib/build/intermediates/incremental/release/packageReleaseResources/compile-file-map.properties @@ -1 +1 @@ -#Tue Sep 09 14:41:15 CST 2025 +#Fri Oct 17 18:14:44 CST 2025 diff --git a/app/build.gradle b/app/build.gradle index b3bd9b0..2586355 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,8 +29,8 @@ android { minSdkVersion 23 targetSdkVersion 35 versionCode 2020 -// versionName "2.0.20" - versionName "2.0.20-Beta4" + versionName "2.0.20" +// versionName "2.0.20-Beta5" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/com/abbidot/tracker/bean/CommonDataBean.kt b/app/src/main/java/com/abbidot/tracker/bean/CommonDataBean.kt new file mode 100644 index 0000000..4ceb200 --- /dev/null +++ b/app/src/main/java/com/abbidot/tracker/bean/CommonDataBean.kt @@ -0,0 +1,10 @@ +package com.abbidot.tracker.bean + +/** + *Created by .yzq on 2025/10/16/周四. + * @link + * @description: + */ +data class CommonDataBean( + var taxRate: Double, var surplusSafeValidMonths: Int, var reactivationFee: Double +) diff --git a/app/src/main/java/com/abbidot/tracker/retrofit2/INetworkService.kt b/app/src/main/java/com/abbidot/tracker/retrofit2/INetworkService.kt index 8a5869a..6d6615c 100644 --- a/app/src/main/java/com/abbidot/tracker/retrofit2/INetworkService.kt +++ b/app/src/main/java/com/abbidot/tracker/retrofit2/INetworkService.kt @@ -3,6 +3,7 @@ package com.abbidot.tracker.retrofit2 import com.abbidot.baselibrary.network.base.BaseResponse import com.abbidot.tracker.bean.ActiveTimeBean import com.abbidot.tracker.bean.AlipayOrderBean +import com.abbidot.tracker.bean.CommonDataBean import com.abbidot.tracker.bean.CountryCodeBean import com.abbidot.tracker.bean.DeviceBean import com.abbidot.tracker.bean.DeviceDetailBean @@ -55,7 +56,7 @@ interface INetworkService { //亚马逊服务器(国外ip) const val BASE_URL_ABROAD = "https://aws.abbidot.com/abbidot/" -// const val BASE_URL_ABROAD = "http://192.168.0.229:8080/abbidot/" +// const val BASE_URL_ABROAD = "http://192.168.0.220:8080/abbidot/" // const val BASE_URL_ABROAD = "$IP_SERVER:8443/abbidotServer/" //亚马逊服务器(国内ip) @@ -1267,7 +1268,15 @@ interface INetworkService { @GET("order$SUBSCRIPTIONS_V3/reactivation/fee") suspend fun getReactivationFee( @Query("orderId") orderId: String - ): BaseResponse + ): BaseResponse + + /** + * 获取具体国家地区税率 + */ + @GET("order$SUBSCRIPTIONS_V3/plan/getTaxRateByRegionName") + suspend fun getTaxRateByRegionName( + @Query("countryCode") countryCode: String, @Query("regionName") regionName: String + ): BaseResponse /** * 创建Stripe订单发起支付 diff --git a/app/src/main/java/com/abbidot/tracker/retrofit2/NetworkApi.kt b/app/src/main/java/com/abbidot/tracker/retrofit2/NetworkApi.kt index e9fbe46..08fe3ae 100644 --- a/app/src/main/java/com/abbidot/tracker/retrofit2/NetworkApi.kt +++ b/app/src/main/java/com/abbidot/tracker/retrofit2/NetworkApi.kt @@ -1143,6 +1143,13 @@ object NetworkApi : BaseNetworkApi(INetworkService.BASE_URL) { service.updateSubscriptionStatus(subscriptionId, status) } + /** + * 获取具体国家地区税率 + */ + suspend fun getTaxRateByRegionName(countryCode: String, regionName: String) = getResult { + service.getTaxRateByRegionName(countryCode, regionName) + } + /** * 获取SIM卡重新激活费用 */ diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/ChoosePlanActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/ChoosePlanActivity.kt index db0a8d5..3b2fdf9 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/ChoosePlanActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/ChoosePlanActivity.kt @@ -139,22 +139,27 @@ class ChoosePlanActivity : } } + private fun goSureSubscriptionPlan() { + Util.checkLocationPermissionsGpsEnabled(mContext, { + Intent( + mContext, SureSubscriptionPlanActivity::class.java + ).let { + if (mChoosePlanAdapter.getData().isNotEmpty()) { + val cPlan = mChoosePlanAdapter.getData()[mSelectPlanIndex] + it.putExtra(ConstantString.SetMeal, cPlan) + it.putExtra(ConstantString.Upgrade, isUpgrade) + it.putExtra(ConstantString.LkSetMeal, mOrderBean) + it.putExtra(ConstantString.RechargeType, mRechargeType) + startActivity(it) + } + } + }) + } override fun onClick(v: View?) { mViewBinding.apply { when (v!!) { - btnSelectChoosePlanContinue -> Intent( - mContext, SureSubscriptionPlanActivity::class.java - ).let { - if (mChoosePlanAdapter.getData().isNotEmpty()) { - val cPlan = mChoosePlanAdapter.getData()[mSelectPlanIndex] - it.putExtra(ConstantString.SetMeal, cPlan) - it.putExtra(ConstantString.Upgrade, isUpgrade) - it.putExtra(ConstantString.LkSetMeal, mOrderBean) - it.putExtra(ConstantString.RechargeType, mRechargeType) - startActivity(it) - } - } + btnSelectChoosePlanContinue -> goSureSubscriptionPlan() } } } diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt index e0084f7..cea8114 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt @@ -25,6 +25,8 @@ import com.abbidot.tracker.databinding.ActivitySureSubscriptionPlanBinding import com.abbidot.tracker.ui.activity.WebViewActivity import com.abbidot.tracker.util.Util import com.abbidot.tracker.util.ViewUtil +import com.abbidot.tracker.vm.GeoCoderViewModel +import com.abbidot.tracker.vm.GoogleLocationViewModel import com.abbidot.tracker.vm.SubscriptionManageViewModel import kotlin.math.abs @@ -32,6 +34,8 @@ class SureSubscriptionPlanActivity : BaseActivity(ActivitySureSubscriptionPlanBinding::inflate) { private val mSubscriptionViewModel: SubscriptionManageViewModel by viewModels() + private val mGoogleLocationViewModel: GoogleLocationViewModel by viewModels() + private val mGeoCoderViewModel: GeoCoderViewModel by viewModels() private var mPackageBean: PackageBean? = null private var mOrderBean: SubscriptionsOrderBean? = null @@ -43,7 +47,7 @@ class SureSubscriptionPlanActivity : private var mSumInsuranceMoney = 0.0 //税率 - private val mTaxRate = 0.0825 + private var mTaxRate = 0.0825 //付款的总金额(含税) private var mTotalWithTaxMoney = 0.0 @@ -81,21 +85,21 @@ class SureSubscriptionPlanActivity : mSummaryAdapter = SureSubscribeSummaryAdapter(this, mutableListOf()) - mOrderBean?.let { - if (isUpgrade) { - it.isUpdateOrder = ConstantInt.Type1 - //套餐总天数 - val totalDay = if (it.mealUnit == ConstantString.PackageUnitYear) { - it.mealPeriod * 365 - } else { - 30 * it.planTimeMonthsCount - } - mResidualMoney = - ((it.totalAmountWithTax - it.tax - it.reactivatePrice) / totalDay) * it.surplusDays - } else { - it.isUpdateOrder = ConstantInt.Type0 - } - } +// mOrderBean?.let { +// if (isUpgrade) { +// it.isUpdateOrder = ConstantInt.Type1 +// //套餐总天数 +// val totalDay = if (it.mealUnit == ConstantString.PackageUnitYear) { +// it.mealPeriod * 365 +// } else { +// 30 * it.planTimeMonthsCount +// } +// mResidualMoney = +// ((it.totalAmountWithTax - it.tax - it.reactivatePrice) / totalDay) * it.surplusDays +// } else { +// it.isUpdateOrder = ConstantInt.Type0 +// } +// } mViewBinding.apply { ViewUtil.instance.setRecyclerViewVerticalLinearLayout( @@ -105,7 +109,186 @@ class SureSubscriptionPlanActivity : bottom = AppUtils.dpToPx(4) ) +// mOrderBean?.let { +// ilSubscribePlanDetail.tvSureSubscribePlanDeviceId.text = it.deviceOutId +// val nowTimestamp = System.currentTimeMillis() +// +// mPackageBean?.let { p -> +// ilSubscribePlanDetail.tvSureSubscribePlanPer.text = String.format( +// getString(R.string.txt_month_unit), "${p.planTimeMonthsCount}" +// ) +// val renewalString = if (p.mealUnit == ConstantString.PackageUnitYear) { +//// ilSubscribePlanDetail.tvSureSubscribePlanPer.text = +//// String.format(getString(R.string.txt_year_unit), p.period) +// val renewalTimestamp = +// Utils.getAfterHowTimestamp(nowTimestamp, p.period * 365L) +// val renewalDate = +// Utils.formatTime(renewalTimestamp, Utils.DATE_FORMAT_PATTERN_EN7) +// if (p.period > 1) { +// String.format( +// getString(R.string.txt_renewal_years), +// "${p.autoRenewPrice}", +// "${p.period}", +// renewalDate +// ) +// } else { +// String.format( +// getString(R.string.txt_renewal_year), +// "${p.autoRenewPrice}", +// renewalDate +// ) +// } +// } else { +// val renewalTimestamp = +// Utils.getAfterHowTimestamp(nowTimestamp, 30L * p.planTimeMonthsCount) +// val renewalDate = +// Utils.formatTime(renewalTimestamp, Utils.DATE_FORMAT_PATTERN_EN7) +// if (p.planTimeMonthsCount > 1) { +// String.format( +// getString(R.string.txt_renewal_months), +// "${p.autoRenewPrice}", +// "${p.planTimeMonthsCount}", +// renewalDate +// ) +// } else { +// String.format( +// getString(R.string.txt_renewal_month), +// "${p.autoRenewPrice}", +// renewalDate +// ) +// } +// } +// ilSubscribePlanDetail.tvSureSubscribePlanUnderused.text = renewalString +// ilSubscribePlanDetail.tvSureSubscribePlanMoneySum.text = String.format( +// getString(R.string.txt_money_unit), "${p.autoRenewPrice}" +// ) +// +// val packageName = "${p.planName}(${p.planCategory})" +// ilSubscribePlanDetail.tvSureSubscribePlanName.text = packageName +// val price = p.planPrice +//// val price = if (p.discountedPrice > 0.0) p.discountedPrice else p.planPrice +// val priceString = String.format( +// getString(R.string.txt_money_unit), +// Utils.formatDecimal(price / p.planTimeMonthsCount, 1) +// ) +// ilSubscribePlanDetail.tvSureSubscribePlanMoney.text = priceString +// +// ViewUtil.instance.addMenuBean( +// mSummaryAdapter.getData(), +// p.planName, +// "$price", +// colorRedId = R.color.data_black_color +// ) +// mTotalMoney += price +// mSumInsuranceMoney = +// Utils.formatDecimal(p.everyMonthSafeFee * p.period * 12, 1).toDouble() +// ViewUtil.instance.addMenuBean( +// mSummaryAdapter.getData(), +// getString(R.string.txt_annual_care_text), +// "$mSumInsuranceMoney", +// colorRedId = R.color.data_black_color +// ) +// mTotalMoney += mSumInsuranceMoney +// +// val insuranceMoneyString = +// String.format(getString(R.string.txt_month_unit), "${p.period * 12}") +// ilSubscribePlanInsurance.tvSureSubscribePlanInsurancePer.text = +// insuranceMoneyString +// ilSubscribePlanInsurance.tvSureSubscribePlanInsurancePerMoney.text = +// String.format(getString(R.string.txt_money_unit), "${p.everyMonthSafeFee}") +// ilSubscribePlanInsurance.tvSureSubscribePlanInsuranceMoney.text = +// String.format(getString(R.string.txt_money_unit), "$mSumInsuranceMoney") +// +// if (isUpgrade) { +// mTotalMoney -= mResidualMoney +// ViewUtil.instance.addMenuBean( +// mSummaryAdapter.getData(), +// getString(R.string.txt_residual_value), +// Utils.formatDecimal(mResidualMoney, 1), +// colorRedId = R.color.red_color5, +// isSwitch = true +// ) +// } +// ViewUtil.instance.addMenuBean( +// mSummaryAdapter.getData(), +// getString(R.string.txt_sales_tax), +// "0", +// colorRedId = R.color.data_black_color +// ) +// } +// +// //判断套餐是否过期 +// if (!TextUtils.isEmpty(it.orderNum) && it.surplusDays == 0L && it.subscriptionStatus == ConstantInt.Close) { +// mOrderBean?.reactivation = 1 +// mSubscriptionViewModel.getReactivationFee(it.orderNum) +// } else { +// mOrderBean?.reactivation = 0 +// mOrderBean?.reactivatePrice = 0.0 +// updateMoney() +// } +// } + + //添加下划线 + ilSubscribePlanDetail.tvSureSubscribePlanTermsConditions.paint.flags = + Paint.UNDERLINE_TEXT_FLAG + + ilSubscribePlanInsurance.cbSureSubscribeInsureSwitch.setOnCheckedChangeListener { buttonView, isChecked -> + mOrderBean?.let { order -> + if (isUpgrade && order.annualCareType == ConstantInt.Type1) { + ilSubscribePlanInsurance.cbSureSubscribeInsureSwitch.isChecked = !isChecked + showToast(R.string.txt_annual_care_included, gravity = Gravity.CENTER) + return@setOnCheckedChangeListener + } + val list = mSummaryAdapter.getData() + if (isChecked) { + MenuTxtBean( + getString(R.string.txt_annual_care_text), "$mSumInsuranceMoney" + ).let { + it.colorRedId = R.color.data_black_color + list.add(1, it) + } + mTotalMoney += mSumInsuranceMoney + } else { + list.removeAt(1) + mTotalMoney -= mSumInsuranceMoney + mSummaryAdapter.notifyItemRemoved(1) + } + updateMoney() + } + } + setOnClickListenerViews( + btnSureSubscribePlan1Continue, + ilSubscribePlanDetail.tvSureSubscribePlanTermsConditions, + ilSubscribePlanInsurance.ivSureSubscribePlanInsurance + ) + + if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) { + sureSubscriptionDetail() + } else { + setButtonEnabled(btnSureSubscribePlan1Continue, ConstantInt.Type0) + mGoogleLocationViewModel.getLastLocation(mContext) + } + } + } + + private fun sureSubscriptionDetail() { + mViewBinding.apply { + setButtonEnabled(btnSureSubscribePlan1Continue, ConstantInt.Type1) mOrderBean?.let { + if (isUpgrade) { + it.isUpdateOrder = ConstantInt.Type1 + //套餐总天数 + val totalDay = if (it.mealUnit == ConstantString.PackageUnitYear) { + it.mealPeriod * 365 + } else { + 30 * it.planTimeMonthsCount + } + mResidualMoney = (it.autoRenewPrice / totalDay) * it.surplusDays + } else { + it.isUpdateOrder = ConstantInt.Type0 + } + + ilSubscribePlanDetail.tvSureSubscribePlanDeviceId.text = it.deviceOutId val nowTimestamp = System.currentTimeMillis() @@ -155,6 +338,9 @@ class SureSubscriptionPlanActivity : } } ilSubscribePlanDetail.tvSureSubscribePlanUnderused.text = renewalString + ilSubscribePlanDetail.tvSureSubscribePlanMoneySum.text = String.format( + getString(R.string.txt_money_unit), "${p.autoRenewPrice}" + ) val packageName = "${p.planName}(${p.planCategory})" ilSubscribePlanDetail.tvSureSubscribePlanName.text = packageName @@ -211,49 +397,22 @@ class SureSubscriptionPlanActivity : } //判断套餐是否过期 - if (!TextUtils.isEmpty(it.orderNum) && it.surplusDays == 0L && it.subscriptionStatus == ConstantInt.Close) { - mOrderBean?.reactivation = 1 - mSubscriptionViewModel.getReactivationFee(it.orderNum) - } else { +// if (!TextUtils.isEmpty(it.orderNum) && it.surplusDays == 0L && it.subscriptionStatus == ConstantInt.Close) { +// mOrderBean?.reactivation = 1 +// mSubscriptionViewModel.getReactivationFee(it.orderNum) +// } else { +// mOrderBean?.reactivation = 0 +// mOrderBean?.reactivatePrice = 0.0 +// updateMoney() +// } + if (TextUtils.isEmpty(it.orderNum)) { mOrderBean?.reactivation = 0 mOrderBean?.reactivatePrice = 0.0 updateMoney() + } else { + mSubscriptionViewModel.getReactivationFee(it.orderNum) } } - - //添加下划线 - ilSubscribePlanDetail.tvSureSubscribePlanTermsConditions.paint.flags = - Paint.UNDERLINE_TEXT_FLAG - - ilSubscribePlanInsurance.cbSureSubscribeInsureSwitch.setOnCheckedChangeListener { buttonView, isChecked -> - mOrderBean?.let { order -> - if (isUpgrade && order.annualCareType == ConstantInt.Type1) { - ilSubscribePlanInsurance.cbSureSubscribeInsureSwitch.isChecked = !isChecked - showToast(R.string.txt_annual_care_included, gravity = Gravity.CENTER) - return@setOnCheckedChangeListener - } - val list = mSummaryAdapter.getData() - if (isChecked) { - MenuTxtBean( - getString(R.string.txt_annual_care_text), "$mSumInsuranceMoney" - ).let { - it.colorRedId = R.color.data_black_color - list.add(1, it) - } - mTotalMoney += mSumInsuranceMoney - } else { - list.removeAt(1) - mTotalMoney -= mSumInsuranceMoney - mSummaryAdapter.notifyItemRemoved(1) - } - updateMoney() - } - } - setOnClickListenerViews( - btnSureSubscribePlan1Continue, - ilSubscribePlanDetail.tvSureSubscribePlanTermsConditions, - ilSubscribePlanInsurance.ivSureSubscribePlanInsurance - ) } } @@ -267,9 +426,10 @@ class SureSubscriptionPlanActivity : XEventBus.post(EventName.RefreshPackage) finish() } - mSubscriptionViewModel.mReactivationFeeLiveData.observe(this) { - dealRequestResult(it, object : GetResultCallback { - override fun onResult(any: Any) { + mSubscriptionViewModel.apply { + mReactivationFeeLiveData.observe(this@SureSubscriptionPlanActivity) { + dealRequestResult(it, object : GetResultCallback { + override fun onResult(any: Any) { // it.getOrNull()?.apply { // mOrderBean?.reactivatePrice = this // mSummaryAdapter.getData().add( @@ -280,16 +440,64 @@ class SureSubscriptionPlanActivity : // }) // mTotalMoney += this // } - updateMoney() - } - }) + it.getOrNull()?.apply { + mPackageBean?.let { p -> + mTotalMoney -= mSumInsuranceMoney + val howSafeValidMonths = + p.planTimeMonthsCount - surplusSafeValidMonths + if (howSafeValidMonths > 0) { + val insuranceMoneyString = String.format( + getString(R.string.txt_month_unit), "$howSafeValidMonths" + ) + mViewBinding.ilSubscribePlanInsurance.tvSureSubscribePlanInsurancePer.text = + insuranceMoneyString + mSumInsuranceMoney = Utils.formatDecimal( + howSafeValidMonths * p.everyMonthSafeFee, 1 + ).toDouble() + mTotalMoney += mSumInsuranceMoney + mViewBinding.ilSubscribePlanInsurance.tvSureSubscribePlanInsuranceMoney.text = + String.format( + getString(R.string.txt_money_unit), + "$mSumInsuranceMoney" + ) + } else { + mSumInsuranceMoney = 0.0 + mViewBinding.ilSubscribePlanInsurance.root.visibility = + View.GONE + } + mSummaryAdapter.getData()[1].menuValue = "$mSumInsuranceMoney" + } + } + updateMoney() + } + }) + } + + mRegionalTaxRateLiveData.observe(this@SureSubscriptionPlanActivity) { + dealRequestResult(it, object : GetResultCallback { + override fun onResult(any: Any) { + it.getOrNull()?.apply { + mTaxRate = taxRate + sureSubscriptionDetail() + } + } + }) + } + } + mGoogleLocationViewModel.mGoogleLocationLiveData.observe(this) { + mGeoCoderViewModel.getLatLonAddress(it.latitude, it.longitude) + } + mGeoCoderViewModel.mLatLonAddressLiveData.observe(this) { + mSubscriptionViewModel.getTaxRateByRegionName( + mGeoCoderViewModel.mCountryCode, mGeoCoderViewModel.mRegion + ) } } private fun updateMoney() { mViewBinding.apply { val list = mSummaryAdapter.getData() - val taxMoney = Utils.formatDecimal(mTaxRate * mTotalMoney, 1).toDouble() + val taxMoney = abs(Utils.formatDecimal(mTaxRate * mTotalMoney, 1).toDouble()) mOrderBean?.tax = taxMoney list[list.size - 1].menuValue = taxMoney.toString() mTotalWithTaxMoney = taxMoney + mTotalMoney @@ -332,8 +540,10 @@ class SureSubscriptionPlanActivity : planTimeMonthsCount = cPlan.planTimeMonthsCount mealUnit = cPlan.mealUnit planCategory = cPlan.planCategory -// autoRenewPrice = Utils.formatDecimal(cPlan.autoRenewPrice * mTaxRate, 1).toDouble() - autoRenewPrice = cPlan.autoRenewPrice + autoRenewPrice = + Utils.formatDecimal(cPlan.autoRenewPrice + cPlan.autoRenewPrice * mTaxRate, 1) + .toDouble() +// autoRenewPrice = cPlan.autoRenewPrice mealDesc = mViewBinding.ilSubscribePlanDetail.tvSureSubscribePlanMoney.text.toString() + mViewBinding.ilSubscribePlanDetail.tvSureSubscribePlanPer.text.toString() } diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/BaseBaiduMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/BaseBaiduMapFragment.kt index fb97a14..14228ea 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/BaseBaiduMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/BaseBaiduMapFragment.kt @@ -161,6 +161,9 @@ abstract class BaseBaiduMapFragment : mMapView.onPause() } + override fun liveDataObserve() { + + } /** * 卫星标准地图模式切换 @@ -653,7 +656,7 @@ abstract class BaseBaiduMapFragment : //通过LocationClientOption设置LocationClient相关参数 val option = LocationClientOption() // 打开gps - option.isOpenGps = true + option.openGps = true // 设置坐标类型 option.setCoorType(mCoordType) //设置定位刷新间隔 diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt index 8d39531..1cd52ba 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt @@ -883,7 +883,7 @@ abstract class BaseGoogleMapFragment : // The Fused Location Provider provides access to location APIs. private val mFusedLocationClient: FusedLocationProviderClient by lazy { - LocationServices.getFusedLocationProviderClient(mContext!!)// + LocationServices.getFusedLocationProviderClient(mContext!!) } private var mCancellationTokenSource: CancellationTokenSource? = null diff --git a/app/src/main/java/com/abbidot/tracker/vm/GeoCoderViewModel.kt b/app/src/main/java/com/abbidot/tracker/vm/GeoCoderViewModel.kt index fa2b42a..27fce1c 100644 --- a/app/src/main/java/com/abbidot/tracker/vm/GeoCoderViewModel.kt +++ b/app/src/main/java/com/abbidot/tracker/vm/GeoCoderViewModel.kt @@ -31,6 +31,12 @@ class GeoCoderViewModel : ViewModel() { var mLat = 0.0 var mLon = 0.0 + + //地区、州、省 + var mRegion = "" + + //国家缩写 + var mCountryCode = "" var mAddress = "" val mLatLonAddressLiveData = MutableLiveData() @@ -64,6 +70,8 @@ class GeoCoderViewModel : ViewModel() { if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) { baiduMapReverseGeocoder(latitude, longitude) } else { +// baiduMapReverseGeocoder(-110.95, 44.65) +// mapBoxReverseGeocoder(42.23, -103.18) mapBoxReverseGeocoder(latitude, longitude) } } @@ -77,52 +85,59 @@ class GeoCoderViewModel : ViewModel() { SearchEngine.createSearchEngineWithBuiltInDataProviders(SearchEngineSettings()) } mMapboxSearchRequestTask?.cancel() - mMapboxSearchRequestTask = mSearchEngine?.search(ReverseGeoOptions( - center = Point.fromLngLat(longitude, latitude) - ), object : SearchCallback { - override fun onError(e: Exception) { - LogUtil.e(" Mapbox反地理编码error,${e.message}") + mMapboxSearchRequestTask = mSearchEngine?.search( + ReverseGeoOptions( + center = Point.fromLngLat(longitude, latitude) + ), object : SearchCallback { + override fun onError(e: Exception) { + LogUtil.e(" Mapbox反地理编码error,${e.message}") // mLatLonAddressLiveData.value = "" - baiduMapReverseGeocoder(latitude, longitude) - } + baiduMapReverseGeocoder(latitude, longitude) + } - override fun onResults( - results: List, responseInfo: ResponseInfo - ) { - LogUtil.e(results.toString()) - if (results.isNotEmpty()) { - val searchResult = results[0] - var address = "" - searchResult.address?.let { - if (!TextUtils.isEmpty(it.street)) { - address += "${it.street} " + override fun onResults( + results: List, responseInfo: ResponseInfo + ) { + LogUtil.e(results.toString()) + if (results.isNotEmpty()) { + val searchResult = results[0] + var address = "" + searchResult.metadata?.let { + it.countryIso1?.let { countryCode -> + mCountryCode = countryCode.uppercase() + } } + searchResult.address?.let { + if (!TextUtils.isEmpty(it.street)) { + address += "${it.street} " + } // if (!TextUtils.isEmpty(it.houseNumber)) { // address += "${it.houseNumber} " // } - if (!TextUtils.isEmpty(it.locality)) { - address += "${it.locality} " + if (!TextUtils.isEmpty(it.locality)) { + address += "${it.locality} " + } + if (!TextUtils.isEmpty(it.place)) { + address += "${it.place} " + } + if (isShowDetailAddress && !TextUtils.isEmpty(it.region)) { + address += "${it.region} " + } + if (isShowDetailAddress && !TextUtils.isEmpty(it.country)) { + address += "${it.country}" + } + mRegion = it.region.toString() } - if (!TextUtils.isEmpty(it.place)) { - address += "${it.place} " - } - if (isShowDetailAddress && !TextUtils.isEmpty(it.region)) { - address += "${it.region} " - } - if (isShowDetailAddress && !TextUtils.isEmpty(it.country)) { - address += "${it.country}" - } - } // address = address?.replace("null", "") - mAddress = address - LogUtil.e("Mapbox反地理编码:$mAddress") - mLatLonAddressLiveData.value = mAddress - } else { + mAddress = address + LogUtil.e("Mapbox反地理编码:$mAddress") + mLatLonAddressLiveData.value = mAddress + } else { // mLatLonAddressLiveData.value = ""- - baiduMapReverseGeocoder(latitude, longitude) + baiduMapReverseGeocoder(latitude, longitude) + } } - } - }) + }) } /** @@ -164,6 +179,8 @@ class GeoCoderViewModel : ViewModel() { if (!TextUtils.isEmpty(streetNumber)) { address += streetNumber } + mRegion = province + mCountryCode = countryCodeIso2.uppercase() LogUtil.e("百度地图反向地理编码详细地址,${streetNumber},${town},${street},$result") } //详细地址 diff --git a/app/src/main/java/com/abbidot/tracker/vm/GoogleLocationViewModel.kt b/app/src/main/java/com/abbidot/tracker/vm/GoogleLocationViewModel.kt new file mode 100644 index 0000000..ea54dfb --- /dev/null +++ b/app/src/main/java/com/abbidot/tracker/vm/GoogleLocationViewModel.kt @@ -0,0 +1,104 @@ +package com.abbidot.tracker.vm + +import android.annotation.SuppressLint +import android.content.Context +import android.location.Location +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.abbidot.baselibrary.util.LogUtil +import com.abbidot.tracker.util.LonAndLatUtil +import com.google.android.gms.location.FusedLocationProviderClient +import com.google.android.gms.location.LocationServices +import com.google.android.gms.location.Priority +import com.google.android.gms.tasks.CancellationTokenSource +import com.google.android.gms.tasks.Task + +/** + *Created by .yzq on 2025/10/16/周四. + * @link + * @description: + */ +class GoogleLocationViewModel : ViewModel() { + + val mGoogleLocationLiveData = MutableLiveData() + + // The Fused Location Provider provides access to location APIs. + private var mFusedLocationClient: FusedLocationProviderClient? = null + private var mCancellationTokenSource: CancellationTokenSource? = null + + + /** + * 获取最后位置,用户当前的位置 + */ + @SuppressLint("MissingPermission") + fun getLastLocation(context: Context) { + if (null == mFusedLocationClient) { + mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context) + } + mFusedLocationClient!!.lastLocation.addOnCompleteListener { taskLocation -> + var location: Location? = null + if (taskLocation.isSuccessful && taskLocation.result != null) { + location = taskLocation.result + LonAndLatUtil.currentUserGPSLat = location.latitude + LonAndLatUtil.currentUserGPSLon = location.longitude + LogUtil.e("Google,getLastLocation:${location.latitude}, ${location.longitude}") + } else { + LogUtil.e("Google,getLastLocation:exception" + taskLocation.exception) + } + location?.let { + mGoogleLocationLiveData.value = it + } + if (null == location) requestCurrentLocation(context) + } + + } + + /** + * 请求用户当前的位置 + */ + @SuppressLint("MissingPermission") + private fun requestCurrentLocation(context: Context) { + try { + if (null == mFusedLocationClient) { + mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context) + } + if (null == mCancellationTokenSource) { + mCancellationTokenSource = CancellationTokenSource() + } +// val currentLocationTask = mFusedLocationClient.getCurrentLocation( +// LocationRequest.PRIORITY_HIGH_ACCURACY, mCancellationTokenSource!!.token +// ) + val currentLocationTask = mFusedLocationClient!!.getCurrentLocation( + Priority.PRIORITY_HIGH_ACCURACY, mCancellationTokenSource!!.token + ) + currentLocationTask.addOnCompleteListener { task: Task -> + var location: Location? = null + val result = if (task.isSuccessful && task.result != null) { + location = task.result + LonAndLatUtil.currentUserGPSLat = location.latitude + LonAndLatUtil.currentUserGPSLon = location.longitude + "(success): ${location.latitude}, ${location.longitude}" + } else { + val exception = task.exception + "(failure): $exception" + } + + LogUtil.e("Google,requestCurrentLocation $result") + location?.let { + mGoogleLocationLiveData.value = it + } + } + } catch (e: Exception) { + LogUtil.e("Google,requestCurrentLocation异常:${e.message}") + } + } + + private fun stopLocation() { + mCancellationTokenSource?.cancel() + } + + override fun onCleared() { + super.onCleared() + stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/vm/SubscriptionManageViewModel.kt b/app/src/main/java/com/abbidot/tracker/vm/SubscriptionManageViewModel.kt index 5982c7c..9fa69d5 100644 --- a/app/src/main/java/com/abbidot/tracker/vm/SubscriptionManageViewModel.kt +++ b/app/src/main/java/com/abbidot/tracker/vm/SubscriptionManageViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.abbidot.baselibrary.constant.MMKVKey import com.abbidot.baselibrary.util.MMKVUtil +import com.abbidot.tracker.bean.CommonDataBean import com.abbidot.tracker.bean.OrderBean import com.abbidot.tracker.bean.PackageBean import com.abbidot.tracker.bean.PackageTypeBean @@ -26,8 +27,9 @@ class SubscriptionManageViewModel : ViewModel() { val mUpdateStatusListLiveData = MutableLiveData>() val mSubscriptionsHistoryLiveData = MutableLiveData>>() - val mReactivationFeeLiveData = MutableLiveData>() + val mReactivationFeeLiveData = MutableLiveData>() val mRefundLiveData = MutableLiveData>() + val mRegionalTaxRateLiveData = MutableLiveData>() fun getSubscriptionsOrder() { viewModelScope.launch { @@ -113,4 +115,14 @@ class SubscriptionManageViewModel : ViewModel() { mReactivationFeeLiveData.value = result } } + + /** + * 获取具体国家地区税率 + */ + fun getTaxRateByRegionName(countryCode: String, regionName: String) { + viewModelScope.launch { + val result = NetworkApi.getTaxRateByRegionName(countryCode, regionName) + mRegionalTaxRateLiveData.value = result + } + } } \ No newline at end of file diff --git a/app/src/main/res/layout/layout_sure_subscribe_plan_detail_layout.xml b/app/src/main/res/layout/layout_sure_subscribe_plan_detail_layout.xml index 6e21e31..a392099 100644 --- a/app/src/main/res/layout/layout_sure_subscribe_plan_detail_layout.xml +++ b/app/src/main/res/layout/layout_sure_subscribe_plan_detail_layout.xml @@ -64,13 +64,30 @@ android:layout_marginTop="@dimen/dp_10" android:text="@string/txt_renewal_year" android:textSize="@dimen/textSize14" - app:typeface="@string/roboto_bold_font" /> + app:typeface="@string/roboto_regular_font" /> + + + +