From beb802e8c2c61948df6c7f841c8cf3d180312a7e Mon Sep 17 00:00:00 2001 From: yezhiqiu <123456@qq.com> Date: Tue, 21 Jul 2026 16:06:42 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=AE=8C=E6=88=90=E5=9B=BD=E5=86=85=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=B3=A8=E5=86=8C=E6=8E=A5=E5=8F=A3=E9=80=BB=E8=BE=91?= =?UTF-8?q?=202.=E5=89=94=E9=99=A4=E9=83=A8=E5=88=86=E6=9C=AA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=AD=97=E7=AC=A6=E4=B8=B2=E7=9A=84key=203.=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E6=94=AF=E6=8C=81=2032=20=E4=BD=8D=20=EF=BC=8C?= =?UTF-8?q?=E5=8F=AA=E6=94=AF=E6=8C=81'arm64-v8a',=20'x86=5F64'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/abbidot/tracker/base/BaseFragment.kt | 8 ++ .../java/com/abbidot/tracker/bean/UserBean.kt | 3 +- .../cn/RechargeOrderDetailCNActivity.kt | 48 ++++--- .../forgot/ForgetPasswordCNFinishFragment.kt | 4 +- .../forgot/ForgetPasswordCNStartFragment.kt | 3 +- .../ui/fragment/login/BindPhoneCNFragment.kt | 5 +- .../fragment/login/LoginCNAccountFragment.kt | 4 +- .../ui/fragment/login/LoginCNCodeFragment.kt | 5 +- .../ui/fragment/login/LoginCNFirstFragment.kt | 2 +- .../register/RegisterCNFinishFragment.kt | 35 +++-- .../register/RegisterCNStartFragment.kt | 3 +- .../tracker/retrofit2/INetworkService.kt | 35 ++--- .../abbidot/tracker/retrofit2/NetworkApi.kt | 25 +--- .../activity/account/CreateAccountActivity.kt | 2 +- .../activity/account/cn/LoginV2CNActivity.kt | 102 +++++++++++++- .../activity/device/AddNewTracker1Activity.kt | 22 ++- .../account/CreateAccountV2ThreeFragment.kt | 28 +++- .../ui/fragment/account/EmailValidFragment.kt | 125 ++++++++++++++---- .../account/cn/AccountCnPhoneFragment.kt | 53 +++++++- .../java/com/abbidot/tracker/util/Util.kt | 1 + .../tracker/vm/UserProfileViewModel.kt | 15 +-- .../fragment/vm => vm/cn}/LoginCNViewModel.kt | 31 +++-- .../vm => vm/cn}/RegisterCNViewModel.kt | 20 +-- .../abbidot/tracker/wxapi/WXEntryActivity.kt | 2 +- .../main/res/layout/activity_history_data.xml | 1 - .../activity_recharge_order_detail_cn.xml | 8 +- .../res/layout/fragment_account_cn_phone.xml | 1 + .../main/res/layout/item_recharge_amount.xml | 94 ------------- .../layout_device_recharge_describe.xml | 80 ----------- app/src/main/res/values-zh-rCN/strings.xml | 117 ++++++++-------- 30 files changed, 440 insertions(+), 442 deletions(-) rename app/src/main/java/com/abbidot/tracker/{deprecated/ui/fragment/vm => vm/cn}/LoginCNViewModel.kt (82%) rename app/src/main/java/com/abbidot/tracker/{deprecated/ui/fragment/vm => vm/cn}/RegisterCNViewModel.kt (71%) delete mode 100644 app/src/main/res/layout/item_recharge_amount.xml delete mode 100644 app/src/main/res/layout/layout_device_recharge_describe.xml diff --git a/app/src/main/java/com/abbidot/tracker/base/BaseFragment.kt b/app/src/main/java/com/abbidot/tracker/base/BaseFragment.kt index 5f4e0b9..b18f2d9 100644 --- a/app/src/main/java/com/abbidot/tracker/base/BaseFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/base/BaseFragment.kt @@ -15,6 +15,7 @@ import androidx.fragment.app.FragmentActivity import androidx.viewbinding.ViewBinding import com.abbidot.baselibrary.util.LogUtil import com.abbidot.tracker.R +import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.GetResultCallback import com.abbidot.tracker.util.Util import com.qmuiteam.qmui.alpha.QMUIAlphaButton @@ -114,6 +115,13 @@ abstract class BaseFragment( (activity as BaseActivity<*>).showToast(resIdString, isFinish, gravity) } + /** + * 按钮开启/禁用点击 + */ + fun setButtonEnabled(v: View, enabled: Int = ConstantInt.SpecialType) { + (activity as BaseActivity<*>).setButtonEnabled(v, enabled) + } + /** * 设置多个view的监听事件 */ diff --git a/app/src/main/java/com/abbidot/tracker/bean/UserBean.kt b/app/src/main/java/com/abbidot/tracker/bean/UserBean.kt index c9f184c..ac66ab8 100644 --- a/app/src/main/java/com/abbidot/tracker/bean/UserBean.kt +++ b/app/src/main/java/com/abbidot/tracker/bean/UserBean.kt @@ -10,6 +10,7 @@ import com.abbidot.tracker.constant.ConstantInt data class UserBean( var userId: String, var email: String, + var phone: String, var token: String, var userName: String, var wxId: String, @@ -22,5 +23,5 @@ data class UserBean( ) { //设置空的构造方法 - constructor() : this("", "", "", "", "", 0, 0, 0, 0, ConstantInt.Type1) + constructor() : this("", "", "", "", "", "", 0, 0, 0, 0, ConstantInt.Type1) } diff --git a/app/src/main/java/com/abbidot/tracker/deprecated/ui/activity/profile/recharge/cn/RechargeOrderDetailCNActivity.kt b/app/src/main/java/com/abbidot/tracker/deprecated/ui/activity/profile/recharge/cn/RechargeOrderDetailCNActivity.kt index 1a5b012..5ccb36a 100644 --- a/app/src/main/java/com/abbidot/tracker/deprecated/ui/activity/profile/recharge/cn/RechargeOrderDetailCNActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/deprecated/ui/activity/profile/recharge/cn/RechargeOrderDetailCNActivity.kt @@ -11,13 +11,11 @@ import androidx.lifecycle.lifecycleScope import com.abbidot.baselibrary.constant.EventName import com.abbidot.baselibrary.eventbus.XEventBus import com.abbidot.baselibrary.util.LogUtil -import com.abbidot.baselibrary.util.Utils import com.abbidot.tracker.R import com.abbidot.tracker.alipay.PayResult import com.abbidot.tracker.base.BaseActivity import com.abbidot.tracker.bean.RechargeDeviceBean import com.abbidot.tracker.bean.SetMealBean -import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.ConstantString import com.abbidot.tracker.constant.GetResultCallback import com.abbidot.tracker.databinding.ActivityRechargeOrderDetailCnBinding @@ -73,7 +71,7 @@ class RechargeOrderDetailCNActivity : BaseActivity(FragmentRegisterCnFinishBinding::inflate) { - private val mRegisterCNViewModel: RegisterCNViewModel by viewModels() +// private val mRegisterCNViewModel: RegisterCNViewModel by viewModels() // private val mLoginCNViewModel: LoginCNViewModel by viewModels() companion object { @@ -34,20 +31,20 @@ class RegisterCNFinishFragment : } override fun liveDataObserve() { - mRegisterCNViewModel.mPhoneRegisterResultLiveData.observe(viewLifecycleOwner) { - dealRequestResult(it, object : GetResultCallback { - override fun onResult(any: Any) { -// val data = it.getOrNull() -// data?.apply { -// val activity = activity as LoginRegisterCNActivity -// mLoginCNViewModel.loginSuccess(activity, this) -// } - showToast(R.string.txt_registered_successfully) - val activity = activity as LoginRegisterCNActivity - activity.switchFragment(LoginRegisterCNActivity.Fragment_Account_Login) - } - }) - } +// mRegisterCNViewModel.mPhoneRegisterResultLiveData.observe(viewLifecycleOwner) { +// dealRequestResult(it, object : GetResultCallback { +// override fun onResult(any: Any) { +//// val data = it.getOrNull() +//// data?.apply { +//// val activity = activity as LoginRegisterCNActivity +//// mLoginCNViewModel.loginSuccess(activity, this) +//// } +// showToast(R.string.txt_registered_successfully) +// val activity = activity as LoginRegisterCNActivity +// activity.switchFragment(LoginRegisterCNActivity.Fragment_Account_Login) +// } +// }) +// } } /** @@ -60,7 +57,7 @@ class RegisterCNFinishFragment : return } val activity = activity as LoginRegisterCNActivity - mRegisterCNViewModel.register(this, activity.mPhone, password) +// mRegisterCNViewModel.register(this, activity.mPhone, password) } override fun onClick(v: View?) { diff --git a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/register/RegisterCNStartFragment.kt b/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/register/RegisterCNStartFragment.kt index 59f2cab..23fd38e 100644 --- a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/register/RegisterCNStartFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/register/RegisterCNStartFragment.kt @@ -10,9 +10,9 @@ import com.abbidot.tracker.base.BaseFragment import com.abbidot.tracker.constant.GetResultCallback import com.abbidot.tracker.databinding.FragmentRegisterCnStartBinding import com.abbidot.tracker.deprecated.ui.activity.LoginRegisterCNActivity -import com.abbidot.tracker.deprecated.ui.fragment.vm.RegisterCNViewModel import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.vm.CountDownTimerViewModel +import com.abbidot.tracker.vm.cn.RegisterCNViewModel /** @@ -63,7 +63,6 @@ class RegisterCNStartFragment : mCountDownTimerViewModel.mCountDownEndLiveData.observe(viewLifecycleOwner) { mViewBinding.llRegisterCnGetPhoneCode.btnGetCode.apply { isEnabled = true - text = getString(R.string.register_txt_get_code) } } 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 19c24c7..2ca5981 100644 --- a/app/src/main/java/com/abbidot/tracker/retrofit2/INetworkService.kt +++ b/app/src/main/java/com/abbidot/tracker/retrofit2/INetworkService.kt @@ -123,21 +123,12 @@ interface INetworkService { @POST("user$VERSION_NUMBER/register") suspend fun registerV2( @Field("email") email: String, + @Field("phone") phone: String, @Field("password") password: String, @Field("userName") userName: String, @Field("countryCode") countryCode: String ): BaseResponse - /** - * 注册 - */ - @FormUrlEncoded - @POST("user/register") - suspend fun register( - @Field("email") email: String, - @Field("password") password: String, - @Field("userName") userName: String - ): BaseResponse /** * 获取用户信息 @@ -1402,11 +1393,12 @@ interface INetworkService { /** * 发送验证码 */ - @GET("user/sendCode") - suspend fun sendCode( - @Query("phone") phone: String, - //发送类型 1是验证码登录 2微信绑定 3注册 4忘记密码 - @Query("type") type: Int + @FormUrlEncoded + @POST("user/sendPhoneCode") + suspend fun sendPhoneCode( + @Field("phone") phone: String, + //验证码类型 1是注册 2是忘记密码 3是验证码登录 4微信绑定 + @Field("type") type: Int ): BaseResponse /** @@ -1422,7 +1414,7 @@ interface INetworkService { * 手机号验证码验证 */ @FormUrlEncoded - @POST("user/validateCode") + @POST("user/phoneValidateCode") suspend fun validatePhoneCode( @Field("phone") phone: String, @Field("code") code: String, //验证码类型 1是注册 2是忘记密码 @@ -1433,20 +1425,11 @@ interface INetworkService { * 账号密码登录 */ @FormUrlEncoded - @POST("user/accountPasswordLogin") + @POST("user/login") suspend fun accountPasswordLogin( @Field("phone") phone: String, @Field("password") password: String ): BaseResponse - /** - * 用户注册 - */ - @FormUrlEncoded - @POST("user/register") - suspend fun register( - @Field("phone") phone: String, @Field("password") password: String - ): BaseResponse - /** * 重置密码 */ 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 5637eb6..acf38bc 100644 --- a/app/src/main/java/com/abbidot/tracker/retrofit2/NetworkApi.kt +++ b/app/src/main/java/com/abbidot/tracker/retrofit2/NetworkApi.kt @@ -40,16 +40,10 @@ object NetworkApi : BaseNetworkApi(INetworkService.BASE_URL) { /** * 注册/创建用户 */ - suspend fun registerV2(email: String, password: String, userName: String, countryCode: String) = - getResult { - service.registerV2(email, password, userName, countryCode) - } - - /** - * 注册 - */ - suspend fun register(email: String, password: String, userName: String) = getResult { - service.register(email, password, userName) + suspend fun registerV2( + email: String, phone: String, password: String, userName: String, countryCode: String + ) = getResult { + service.registerV2(email, phone, password, userName, countryCode) } /** @@ -1304,8 +1298,8 @@ object NetworkApi : BaseNetworkApi(INetworkService.BASE_URL) { /** * 发送验证码 */ - suspend fun sendCode(phone: String, type: Int) = getResult { - service.sendCode(phone, type) + suspend fun sendPhoneCode(phone: String, type: Int) = getResult { + service.sendPhoneCode(phone, type) } /** @@ -1329,13 +1323,6 @@ object NetworkApi : BaseNetworkApi(INetworkService.BASE_URL) { service.accountPasswordLogin(phone, password) } - /** - * 用户注册 - */ - suspend fun register(phone: String, password: String) = getResult { - service.register(phone, password) - } - /** * 重置密码 */ diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/account/CreateAccountActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/account/CreateAccountActivity.kt index d8ea27d..fb44120 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/account/CreateAccountActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/account/CreateAccountActivity.kt @@ -206,7 +206,7 @@ class CreateAccountActivity : password = Utils.get32Md5Value(password) mUserViewModel.registerV2( - this@CreateAccountActivity, email, password, name, mCountryCommon.getCountryCode() + this@CreateAccountActivity, email,"", password, name, mCountryCommon.getCountryCode() ) } } diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/account/cn/LoginV2CNActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/account/cn/LoginV2CNActivity.kt index bf9815d..d6bf918 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/account/cn/LoginV2CNActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/account/cn/LoginV2CNActivity.kt @@ -4,15 +4,32 @@ import android.content.Intent import android.graphics.Paint import android.text.InputFilter import android.text.InputType +import android.text.TextUtils +import android.view.Gravity import android.view.View +import androidx.activity.viewModels +import com.abbidot.baselibrary.constant.EventName +import com.abbidot.baselibrary.eventbus.XEventBus +import com.abbidot.baselibrary.util.AppUtils +import com.abbidot.baselibrary.util.Utils import com.abbidot.tracker.R import com.abbidot.tracker.base.BaseActivity +import com.abbidot.tracker.constant.ConstantInt +import com.abbidot.tracker.constant.GetResultCallback import com.abbidot.tracker.databinding.ActivityLoginV2CnBinding +import com.abbidot.tracker.ui.activity.set.FirstPermissionsActivity +import com.abbidot.tracker.util.Util import com.abbidot.tracker.util.ViewUtil +import com.abbidot.tracker.vm.cn.LoginCNViewModel class LoginV2CNActivity : BaseActivity(ActivityLoginV2CnBinding::inflate) { + private val mLoginCNViewModel: LoginCNViewModel by viewModels() + + private var isShowPassword = false + private var isCurrentPostEven = false + override fun getTopBar() = mViewBinding.loginV2CnTopBar.titleTopBar override fun initData() { @@ -24,7 +41,7 @@ class LoginV2CNActivity : ilLoginV2CnPhone.let { it.tvInputNameTitle.setText(R.string.login_txt_phone) it.etInputContent.setHint(R.string.login_txt_phone) - it.etInputContent.inputType = InputType.TYPE_CLASS_PHONE + it.etInputContent.inputType = InputType.TYPE_CLASS_NUMBER val filters = arrayOf(InputFilter.LengthFilter(11)) it.etInputContent.filters = filters ViewUtil.instance.setInputViewErrorHideClick( @@ -47,13 +64,51 @@ class LoginV2CNActivity : tvLoginV2CnForgotPassword.paintFlags = Paint.UNDERLINE_TEXT_FLAG setOnClickListenerViews( - tvLoginV2CnForgotPassword, + tvLoginV2CnForgotPassword, btnLoginV2CnLogin, ilLoginV2CnPassword.ivInputRepresentImage, btnLoginV2CnLogin, btnLoginV2CnLoginCode ) } } + override fun liveDataObserve() { + XEventBus.observe(this, EventName.FinishActivity) { + if (!isCurrentPostEven) finish() + } + mLoginCNViewModel.mAccountPwdLoginResultLiveData.observe(this) { + dealRequestResult(it, object : GetResultCallback { + override fun onResult(any: Any) { + it.getOrNull()?.apply { + isCurrentPostEven = true + Util.dealLoginSuccessData(mContext, this) + + showToast(R.string.txt_login_successful, gravity = Gravity.CENTER) + loginSuccessGo() + } + } + + override fun onRequestError(exceptionCode: String?) { + setButtonEnabled(mViewBinding.btnLoginV2CnLogin, ConstantInt.Type1) + } + + override fun onInterceptCode() { + setButtonEnabled(mViewBinding.btnLoginV2CnLogin, ConstantInt.Type1) + } + }) + } + } + + private fun loginSuccessGo() { + val hasPermissions = Util.checkNeedPermissionsEnabled(mContext) + mViewBinding.btnLoginV2CnLogin.postDelayed({ + if (hasPermissions) { + startActivityFinish(Util.checkBindDeviceAndPetGoActivity(mContext)) + } else { + startActivityFinish(Intent(mContext, FirstPermissionsActivity::class.java)) + } + }, 1000) + } + private fun goForgotPassword() { Intent(mContext, ForgotPasswordCNActivity::class.java).apply { // val email = mViewBinding.ilLoginV2EmailAddress.etInputContent.text.toString() @@ -62,6 +117,39 @@ class LoginV2CNActivity : } } + private fun loginClick() { + mViewBinding.apply { + var phone = ilLoginV2CnPhone.etInputContent.text.toString() + var password = ilLoginV2CnPassword.etInputContent.text.toString() + var isSure = true + + if (AppUtils.isDebug()) { + if (TextUtils.equals("12", phone)) { + phone = "13049437653" + password = "123456" + } + } + if (TextUtils.isEmpty(phone) || phone.length < 11) { + isSure = false + ViewUtil.instance.setInputViewErrorShow( + mContext, ilLoginV2CnPhone.rlEtInputLayout, tvPhoneErrorTipLoginCn + ) + } + if (TextUtils.isEmpty(password)) { + isSure = false + ViewUtil.instance.setInputViewErrorShow( + mContext, ilLoginV2CnPassword.rlEtInputLayout, tvPasswordErrorTipLoginCn + ) + } + if (!isSure) return + + setButtonEnabled(btnLoginV2CnLogin, ConstantInt.Type0) + password = Utils.get32Md5Value(password) + + mLoginCNViewModel.accountPasswordLogin(phone, password) + } + } + override fun onClick(v: View?) { mViewBinding.apply { when (v!!) { @@ -72,7 +160,17 @@ class LoginV2CNActivity : ) ) + ilLoginV2CnPassword.ivInputRepresentImage -> { + isShowPassword = !isShowPassword + ViewUtil.instance.showAndHidePasswordClick( + ilLoginV2CnPassword.etInputContent, + ilLoginV2CnPassword.ivInputRepresentImage, + isShowPassword + ) + } + tvLoginV2CnForgotPassword -> goForgotPassword() + btnLoginV2CnLogin -> loginClick() } } } diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/device/AddNewTracker1Activity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/device/AddNewTracker1Activity.kt index 1ea8c6c..9478f53 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/device/AddNewTracker1Activity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/device/AddNewTracker1Activity.kt @@ -5,6 +5,7 @@ import android.view.View import androidx.activity.viewModels import com.abbidot.baselibrary.constant.EventName import com.abbidot.baselibrary.eventbus.XEventBus +import com.abbidot.baselibrary.util.AppUtils import com.abbidot.tracker.R import com.abbidot.tracker.base.BaseActivity import com.abbidot.tracker.bean.FamilyBean @@ -12,6 +13,7 @@ import com.abbidot.tracker.constant.ConstantString import com.abbidot.tracker.constant.GetResultCallback import com.abbidot.tracker.databinding.ActivityAddNewTracker1Binding import com.abbidot.tracker.ui.activity.account.LoginV2Activity +import com.abbidot.tracker.ui.activity.account.cn.LoginV2CNActivity import com.abbidot.tracker.ui.activity.pet.ShowInviteDeviceActivity import com.abbidot.tracker.util.Util import com.abbidot.tracker.vm.FamilyViewModel @@ -103,11 +105,21 @@ class AddNewTracker1Activity : mViewBinding.apply { when (v!!) { btnChargePowerOnNext -> checkPermissions() - tvChargePowerOnBackLoginBtn -> startActivityFinish( - Intent( - mContext, LoginV2Activity::class.java - ) - ) + tvChargePowerOnBackLoginBtn -> { + if (AppUtils.isChina()) { + startActivityFinish( + Intent( + mContext, LoginV2CNActivity::class.java + ) + ) + } else { + startActivityFinish( + Intent( + mContext, LoginV2Activity::class.java + ) + ) + } + } } } } diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/account/CreateAccountV2ThreeFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/account/CreateAccountV2ThreeFragment.kt index 8fffa21..86ed8de 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/account/CreateAccountV2ThreeFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/account/CreateAccountV2ThreeFragment.kt @@ -9,9 +9,11 @@ import androidx.core.widget.addTextChangedListener import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import com.abbidot.baselibrary.list.BaseRecyclerAdapter +import com.abbidot.baselibrary.util.AppUtils import com.abbidot.baselibrary.util.Utils import com.abbidot.tracker.R import com.abbidot.tracker.base.BaseFragment +import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.GetResultCallback import com.abbidot.tracker.databinding.FragmentCreateAccountV2ThreeBinding import com.abbidot.tracker.ui.activity.account.AddEmailValidActivity @@ -20,6 +22,7 @@ import com.abbidot.tracker.ui.common.CountryCommon import com.abbidot.tracker.util.Util import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.vm.UserProfileViewModel +import java.util.Locale /** @@ -141,6 +144,18 @@ class CreateAccountV2ThreeFragment : BaseFragment( private val mCountDownTimerViewModel: CountDownTimerViewModel by viewModels() private val mRegisterViewModel: UserProfileViewModel by viewModels() + private val mRegisterCNViewModel: RegisterCNViewModel by viewModels() private val mResendCodeTime = 5 * 60 private var mEmail = "" private var mBtnString = "" - private var mEmailCodeType = 0 + private var mVerifyCodeType = 0 - private var mOnOkClickListener: OnClickListener?=null + private var mOnOkClickListener: OnClickListener? = null companion object { @JvmStatic @@ -49,7 +53,7 @@ open class EmailValidFragment : BaseFragment( ) = EmailValidFragment().apply { mContext = context mBtnString = btnString - mEmailCodeType = emailCodeType + mVerifyCodeType = emailCodeType mOnOkClickListener = okClickListener } } @@ -127,33 +131,83 @@ open class EmailValidFragment : BaseFragment( } } - mRegisterViewModel.apply { - mGetEmailCodeLiveData.observe(viewLifecycleOwner) { - dealRequestResult(it, object : GetResultCallback { - override fun onResult(any: Any) { - it.getOrNull()?.apply { + if (AppUtils.isChina()) { + mRegisterCNViewModel.apply { + mSendCodeResultLiveData.observe(viewLifecycleOwner) { + dealRequestResult(it, object : GetResultCallback { + override fun onResult(any: Any) { showToast(R.string.txt_code_success, gravity = Gravity.CENTER) + mCountDownTimerViewModel.startCountDown(mResendCodeTime.toLong()) + } + + override fun onRequestError(exceptionCode: String?) { + setResendCodeBtnEnabled(true) + } + }) + } + mValidateCodeResultLiveData.observe(viewLifecycleOwner) { + dealRequestResult(it, object : GetResultCallback { + override fun onResult(any: Any) { + it.getOrNull()?.apply { + mOnOkClickListener?.onClick(view) + } + } + + override fun onInterceptCode() { + setButtonEnabled( + mViewBinding.btnForgotPasswordV2TwoContinue, ConstantInt.Type1 + ) + } + + override fun onRequestError(exceptionCode: String?) { + setButtonEnabled( + mViewBinding.btnForgotPasswordV2TwoContinue, ConstantInt.Type1 + ) + } + }) + } + } + } else { + mRegisterViewModel.apply { + mGetEmailCodeLiveData.observe(viewLifecycleOwner) { + dealRequestResult(it, object : GetResultCallback { + override fun onResult(any: Any) { + it.getOrNull()?.apply { + showToast(R.string.txt_code_success, gravity = Gravity.CENTER) // mViewBinding.tvForgotPasswordV2CountdownTime.visibility = View.VISIBLE // mViewBinding.tvForgotPasswordV2TimeRemaining.visibility = View.VISIBLE // mViewBinding.tvForgotPasswordV2TimeSec.visibility = View.VISIBLE - mCountDownTimerViewModel.startCountDown(mResendCodeTime.toLong()) + mCountDownTimerViewModel.startCountDown(mResendCodeTime.toLong()) + } } - } - override fun onRequestError(exceptionCode: String?) { - setResendCodeBtnEnabled(true) - } - }) - } - - mValidateCodeLiveData.observe(viewLifecycleOwner) { - dealRequestResult(it, object : GetResultCallback { - override fun onResult(any: Any) { - it.getOrNull()?.apply { - mOnOkClickListener?.onClick(view) + override fun onRequestError(exceptionCode: String?) { + setResendCodeBtnEnabled(true) } - } - }) + }) + } + + mValidateCodeLiveData.observe(viewLifecycleOwner) { + dealRequestResult(it, object : GetResultCallback { + override fun onResult(any: Any) { + it.getOrNull()?.apply { + mOnOkClickListener?.onClick(view) + } + } + + override fun onInterceptCode() { + setButtonEnabled( + mViewBinding.btnForgotPasswordV2TwoContinue, ConstantInt.Type1 + ) + } + + override fun onRequestError(exceptionCode: String?) { + setButtonEnabled( + mViewBinding.btnForgotPasswordV2TwoContinue, ConstantInt.Type1 + ) + } + }) + } } } } @@ -190,9 +244,16 @@ open class EmailValidFragment : BaseFragment( return } - mRegisterViewModel.validateCode( - this@EmailValidFragment, mEmail, content, mEmailCodeType - ) + setButtonEnabled(mViewBinding.btnForgotPasswordV2TwoContinue, ConstantInt.Type0) + if (AppUtils.isChina()) { + mRegisterCNViewModel.validatePhoneCode( + this@EmailValidFragment, mEmail, content, mVerifyCodeType + ) + } else { + mRegisterViewModel.validateCode( + this@EmailValidFragment, mEmail, content, mVerifyCodeType + ) + } } } @@ -203,9 +264,15 @@ open class EmailValidFragment : BaseFragment( tvForgotPasswordResendCodeBtn -> { setResendCodeBtnEnabled(false) - mRegisterViewModel.getEmailCode( - activity as BaseActivity<*>, mEmail, mEmailCodeType - ) + if (AppUtils.isChina()) { + mRegisterCNViewModel.sendCode( + this@EmailValidFragment, mEmail, mVerifyCodeType + ) + } else { + mRegisterViewModel.getEmailCode( + activity as BaseActivity<*>, mEmail, mVerifyCodeType + ) + } } } } diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/account/cn/AccountCnPhoneFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/account/cn/AccountCnPhoneFragment.kt index 0a29ea1..d2f24a0 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/account/cn/AccountCnPhoneFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/account/cn/AccountCnPhoneFragment.kt @@ -3,13 +3,18 @@ package com.abbidot.tracker.ui.fragment.account.cn import android.content.Context import android.text.InputFilter import android.text.InputType +import android.text.TextUtils import android.view.View import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels import com.abbidot.tracker.R import com.abbidot.tracker.base.BaseFragment +import com.abbidot.tracker.constant.ConstantInt +import com.abbidot.tracker.constant.GetResultCallback import com.abbidot.tracker.databinding.FragmentAccountCnPhoneBinding import com.abbidot.tracker.ui.activity.account.AddEmailValidActivity import com.abbidot.tracker.util.ViewUtil +import com.abbidot.tracker.vm.cn.RegisterCNViewModel /** * A simple [Fragment] subclass. @@ -19,6 +24,8 @@ import com.abbidot.tracker.util.ViewUtil class AccountCnPhoneFragment : BaseFragment(FragmentAccountCnPhoneBinding::inflate) { + private val mRegisterCNViewModel: RegisterCNViewModel by viewModels() + companion object { @JvmStatic fun newInstance(context: Context) = @@ -35,7 +42,7 @@ class AccountCnPhoneFragment : it.etInputContent.setHint(R.string.login_txt_phone) val filters = arrayOf(InputFilter.LengthFilter(11)) it.etInputContent.filters = filters - it.etInputContent.inputType = InputType.TYPE_CLASS_PHONE + it.etInputContent.inputType = InputType.TYPE_CLASS_NUMBER ViewUtil.instance.setInputViewErrorHideClick( mContext!!, it.rlEtInputLayout, tvAccountCnPhoneErrorTip, it.etInputContent ) @@ -44,12 +51,50 @@ class AccountCnPhoneFragment : } } + override fun liveDataObserve() { + mRegisterCNViewModel.mSendCodeResultLiveData.observe(viewLifecycleOwner) { + dealRequestResult(it, object : GetResultCallback { + override fun onResult(any: Any) { + showToast(R.string.txt_code_success) + getHostActivity(AddEmailValidActivity::class.java)?.switchFragment(1) + setButtonEnabled(mViewBinding.btnAccountCnPhoneContinue, ConstantInt.Type1) + } + + override fun onRequestError(exceptionCode: String?) { + setButtonEnabled(mViewBinding.btnAccountCnPhoneContinue, ConstantInt.Type1) + } + }) + } + } + + private fun registerCNPhoneContinue() { + mViewBinding.apply { + if (!ilAccountCnPhonePolicyTerms.cbLoginAgreePrivacyCheckbox.isChecked) { + val tips = getString(R.string.register_txt_agree1) + getString( + R.string.register_txt_policy + ) + getString(R.string.register_txt_agree2) + getString( + R.string.register_txt_terms + ) + showToast(tips) + return + } + val phone = ilAccountCnPhoneEditLayout.etInputContent.text.toString() + if (TextUtils.isEmpty(phone) || phone.length < 11) { + ViewUtil.instance.setInputViewErrorShow( + mContext!!, ilAccountCnPhoneEditLayout.rlEtInputLayout, tvAccountCnPhoneErrorTip + ) + return + } + getHostActivity(AddEmailValidActivity::class.java)?.setToEmail(phone) + setButtonEnabled(btnAccountCnPhoneContinue, ConstantInt.Type0) + mRegisterCNViewModel.sendCode(this@AccountCnPhoneFragment, phone, 1) + } + } + override fun onClick(v: View?) { mViewBinding.apply { when (v!!) { - btnAccountCnPhoneContinue -> getHostActivity(AddEmailValidActivity::class.java)?.switchFragment( - 1 - ) + btnAccountCnPhoneContinue -> registerCNPhoneContinue() } } } diff --git a/app/src/main/java/com/abbidot/tracker/util/Util.kt b/app/src/main/java/com/abbidot/tracker/util/Util.kt index 1e41dca..e50528a 100644 --- a/app/src/main/java/com/abbidot/tracker/util/Util.kt +++ b/app/src/main/java/com/abbidot/tracker/util/Util.kt @@ -556,6 +556,7 @@ class Util { userBean.apply { MMKVUtil.putString(MMKVKey.UserId, userId) MMKVUtil.putString(MMKVKey.Email, email) + MMKVUtil.putString(MMKVKey.Phone, phone) MMKVUtil.putString(MMKVKey.Token, token) MMKVUtil.putString(MMKVKey.UserName, userName) MMKVUtil.putInt(MMKVKey.MeasureUnit, measurementUnitType) diff --git a/app/src/main/java/com/abbidot/tracker/vm/UserProfileViewModel.kt b/app/src/main/java/com/abbidot/tracker/vm/UserProfileViewModel.kt index 287f014..66976a6 100644 --- a/app/src/main/java/com/abbidot/tracker/vm/UserProfileViewModel.kt +++ b/app/src/main/java/com/abbidot/tracker/vm/UserProfileViewModel.kt @@ -23,7 +23,6 @@ class UserProfileViewModel : ViewModel() { val mGetEmailCodeLiveData = MutableLiveData>() val mValidateCodeLiveData = MutableLiveData>() - private val mRegisterLiveData = MutableLiveData>() val mCountryCodeLiveData = MutableLiveData>>() val mRegisterV2LiveData = MutableLiveData>() val mUpdateUserInfoLiveData = MutableLiveData>() @@ -55,17 +54,6 @@ class UserProfileViewModel : ViewModel() { } } - /** - * 注册 - */ - fun register(fragment: BaseFragment<*>, email: String, password: String, userName: String) { - fragment.showLoading(true) - viewModelScope.launch { - val result = NetworkApi.register(email, password, userName) - mRegisterLiveData.value = result - } - } - /** * 获取国家代码号 */ @@ -83,13 +71,14 @@ class UserProfileViewModel : ViewModel() { fun registerV2( activity: BaseActivity<*>, email: String, + phone: String, password: String, userName: String, countryCode: String ) { activity.showLoading(true) viewModelScope.launch { - val result = NetworkApi.registerV2(email, password, userName, countryCode) + val result = NetworkApi.registerV2(email,phone, password, userName, countryCode) mRegisterV2LiveData.value = result } } diff --git a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/vm/LoginCNViewModel.kt b/app/src/main/java/com/abbidot/tracker/vm/cn/LoginCNViewModel.kt similarity index 82% rename from app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/vm/LoginCNViewModel.kt rename to app/src/main/java/com/abbidot/tracker/vm/cn/LoginCNViewModel.kt index 66de680..e3236e0 100644 --- a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/vm/LoginCNViewModel.kt +++ b/app/src/main/java/com/abbidot/tracker/vm/cn/LoginCNViewModel.kt @@ -1,4 +1,4 @@ -package com.abbidot.tracker.deprecated.ui.fragment.vm +package com.abbidot.tracker.vm.cn import android.content.Intent import androidx.lifecycle.MutableLiveData @@ -9,17 +9,16 @@ import com.abbidot.baselibrary.constant.EventName import com.abbidot.baselibrary.constant.MMKVKey import com.abbidot.baselibrary.eventbus.XEventBus import com.abbidot.baselibrary.util.MMKVUtil -import com.abbidot.baselibrary.util.Utils import com.abbidot.tracker.R +import com.abbidot.tracker.base.BaseActivity import com.abbidot.tracker.base.BaseFragment import com.abbidot.tracker.bean.UserBean import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.retrofit2.NetworkApi -import com.abbidot.tracker.deprecated.ui.activity.LoginRegisterCNActivity import com.abbidot.tracker.ui.activity.HomeV2Activity import dagger.hilt.android.scopes.ActivityRetainedScoped import kotlinx.coroutines.launch -import java.util.* +import java.util.Random import javax.inject.Inject /** @@ -48,15 +47,17 @@ class LoginCNViewModel @Inject constructor() : ViewModel() { /** * 处理微信、登录成功返回 */ - fun loginSuccess(activity: LoginRegisterCNActivity, - userBean: UserBean, - tipRes: Int = R.string.txt_login_successful) { + fun loginSuccess( + activity: BaseActivity<*>, + userBean: UserBean, + tipRes: Int = R.string.txt_login_successful + ) { //判断有没有绑定手机号 if (userBean.status == ConstantInt.Close) { - activity.apply { - mWXId = userBean.wxId - switchFragment(LoginRegisterCNActivity.Fragment_Bind_Phone) - } +// activity.apply { +// mWXId = userBean.wxId +// switchFragment(LoginRegisterCNActivity.Fragment_Bind_Phone) +// } } else { //通知欢迎页面关闭 XEventBus.post(EventName.FinishActivity) @@ -104,13 +105,11 @@ class LoginCNViewModel @Inject constructor() : ViewModel() { } /** - * 验证码登录 + * 密码登录 */ - fun accountPasswordLogin(fragment: BaseFragment<*>, phone: String, password: String) { - fragment.showLoading(true) + fun accountPasswordLogin(phone: String, password: String) { viewModelScope.launch { - val pwd = Utils.get32Md5Value(password) - val result = NetworkApi.accountPasswordLogin(phone, pwd) + val result = NetworkApi.accountPasswordLogin(phone, password) mAccountPwdLoginResultLiveData.value = result } } diff --git a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/vm/RegisterCNViewModel.kt b/app/src/main/java/com/abbidot/tracker/vm/cn/RegisterCNViewModel.kt similarity index 71% rename from app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/vm/RegisterCNViewModel.kt rename to app/src/main/java/com/abbidot/tracker/vm/cn/RegisterCNViewModel.kt index bcb911c..30d3c3a 100644 --- a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/vm/RegisterCNViewModel.kt +++ b/app/src/main/java/com/abbidot/tracker/vm/cn/RegisterCNViewModel.kt @@ -1,4 +1,4 @@ -package com.abbidot.tracker.deprecated.ui.fragment.vm +package com.abbidot.tracker.vm.cn import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -16,17 +16,17 @@ import kotlinx.coroutines.launch class RegisterCNViewModel : ViewModel() { val mSendCodeResultLiveData = MutableLiveData>() val mValidateCodeResultLiveData = MutableLiveData>() - val mPhoneRegisterResultLiveData = MutableLiveData>() +// val mPhoneRegisterResultLiveData = MutableLiveData>() val mSetNewPasswordResultLiveData = MutableLiveData>() /** * 发送验证码 - * @param type 发送类型 1是验证码登录 2微信绑定 3注册 4忘记密码 + * @param type 验证码类型 1是注册 2是忘记密码 3是验证码登录 4微信绑定 */ fun sendCode(fragment: BaseFragment<*>, phone: String, type: Int) { fragment.showLoading(true) viewModelScope.launch { - val result = NetworkApi.sendCode(phone, type) + val result = NetworkApi.sendPhoneCode(phone, type) mSendCodeResultLiveData.value = result } } @@ -42,18 +42,6 @@ class RegisterCNViewModel : ViewModel() { } } - /** - * 注册 - */ - fun register(fragment: BaseFragment<*>, phone: String, password: String) { - fragment.showLoading(true) - viewModelScope.launch { - val pwd = Utils.get32Md5Value(password) - val result = NetworkApi.register(phone, pwd) - mPhoneRegisterResultLiveData.value = result - } - } - /** * 重置密码 */ diff --git a/app/src/main/java/com/abbidot/tracker/wxapi/WXEntryActivity.kt b/app/src/main/java/com/abbidot/tracker/wxapi/WXEntryActivity.kt index 13656a3..960ac41 100644 --- a/app/src/main/java/com/abbidot/tracker/wxapi/WXEntryActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/wxapi/WXEntryActivity.kt @@ -3,7 +3,7 @@ package com.abbidot.tracker.wxapi import com.abbidot.baselibrary.constant.EventName import com.abbidot.baselibrary.eventbus.XEventBus import com.abbidot.baselibrary.util.LogUtil -import com.abbidot.tracker.deprecated.ui.fragment.vm.LoginCNViewModel +import com.abbidot.tracker.vm.cn.LoginCNViewModel import com.hjq.toast.Toaster import com.tencent.mm.opensdk.constants.ConstantsAPI import com.tencent.mm.opensdk.modelbase.BaseResp diff --git a/app/src/main/res/layout/activity_history_data.xml b/app/src/main/res/layout/activity_history_data.xml index bb9f64b..1bc2c29 100644 --- a/app/src/main/res/layout/activity_history_data.xml +++ b/app/src/main/res/layout/activity_history_data.xml @@ -66,7 +66,6 @@ android:layout_width="wrap_content" android:layout_below="@id/history_data_address" android:layout_marginTop="@dimen/dp_24" - android:text="@string/txt_show_track_point" android:textSize="@dimen/textSize16" app:typeface="@string/roboto_regular_font" /> diff --git a/app/src/main/res/layout/activity_recharge_order_detail_cn.xml b/app/src/main/res/layout/activity_recharge_order_detail_cn.xml index 62cde5a..164b7a1 100644 --- a/app/src/main/res/layout/activity_recharge_order_detail_cn.xml +++ b/app/src/main/res/layout/activity_recharge_order_detail_cn.xml @@ -28,12 +28,7 @@ android:layout_width="match_parent" android:layout_height="@dimen/dp_130" /> - + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/layout_device_recharge_describe.xml b/app/src/main/res/layout/layout_device_recharge_describe.xml deleted file mode 100644 index 953a12f..0000000 --- a/app/src/main/res/layout/layout_device_recharge_describe.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d39a9f8..3742d72 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -44,47 +44,40 @@ - 还没有收到验证码? + 从地面测量到宠物肩胛骨的最高点 电量:%s%% %s年 - %d年 - %d磅 - %d/100 已获得 + 更新时间:%s - 显示轨迹/点 - 确定要分享\'%s\'的宠物数据 + + 请选择2 \~ 9张照片 - 此后以%.2f/年续订,可随时取消 - 已优惠%d - %d年连接订阅 - 订阅计划有效期至%s - 自动续订已关闭,订阅计划将在%s之后不可用 - 保存并确认 + 版本%s 服务协议 接受隐私政策与条款。 该设备已被%s绑定 运动目标 结束时间 - $%s/月 + 为宠物定制每日趣味活动,专注早晚互动,兼顾其需求、物种与品种 +\t邀请 共享的家庭成员可查看宠物位置和日期,但无法编辑 - 宠物信息设置成功,获得安全徽章! + 请输入发送至 %s 的4位数验证码 剩余时间:\t - 注册即表示接受服务条款和隐私政策 + 确认6字符ID与追踪器背面一致 在设备背面找到6位数ID 设备ID错误,请核对后重试 - 设备已被绑定,请核对后重试 + 配对成功 有效期至 (续订价 这是您宠物的常驻地吗? - %s英尺 (ft) - %s英里/小时 (mph) + + 解绑 %s 您确定要删除家庭成员%s •\t 确保活动数据同步准确的必要条件。 @@ -95,10 +88,10 @@ 选择“宠物” > “追踪器” ,点击“GPS更新间隔” ,选择3/5/10/15分钟。 (更短的网络连接间隔会更快耗尽设备电量。默认情况下,网络每15分钟重新连接一次。) 当直播开启时,追踪器进入快速定位和联网状态,通常在15-20秒内完成。此模式耗电最快,因此最好仅在紧急情况下使用。 - 开启通知:前往“账户” > "设置"。点击"通知"并开启。 + 续费: /月 x%s - /%s 年 + 将发送验证码至 %s 升级至高级版,解锁独家功能! 检测到新固件版本:%s @@ -122,7 +115,7 @@ 1.设备1次更换\n2. 专属客户支持\n3. 年度保障服务 1. VIP 优先支持\n2. 快速更换服务(含1次)\n3. 增强型保障\n4. 无忧宠物保护 %s 分钟 - 截止至%s + %s 分钟 欢迎使用爱彼宠物!为了更好地保障您的权益,我们将在本《隐私政策》声明中向您说明我们如何收集、使用、处理和保障您提供给我们的信息。请仔细阅读《隐私政策》和《服务条款》。 是的 @@ -198,20 +191,18 @@ 忘记密码? 微信登录 验证码登录 - Apple登录 - 账号登录 - 设置新密码 + + + 验证码已发送 没有账号? - 密码登录 + 注册 - 嗨, + 返回登录 - 设置密码 + 昵称 - 获取 - 我们已将验证码发送到您的电子邮件 - 验证码 + 下一步 重新发送 同意《服务协议》和《隐私政策》 @@ -220,22 +211,22 @@ 《服务协议》 《隐私政策》 提交 - 绑定 - 完成 - 数据 + + + 地图 我的 - 我的订单 - 帮助中心 + + 反馈中心 设置 - 设置 + 消息中心 - 语言 + 帐户 关于 清除缓存 - 退出登录 + 反馈中心 问题类型(必填) 关于APP @@ -246,48 +237,47 @@ 请留下您的邮箱,以便我们更快地帮助您 上传图片 名称 - 性别 + 生日 - 地点 + 邮箱 - 手机 + 品种 体重 肩高 如何测量身高 保存 标签 - 输入设备ID + 激活 - 激活并继续 + 不用了,谢谢 - 激活 + 我的设备 - 设备 + 我的设备 - 被授权的 + LED灯 - 围栏 - 设置 + + 新宠物 解绑 网络 GPS - + 蓝牙已连接 蓝牙未连接 LED灯 - 围栏 + 家人 - 添加家人 - 邀请您的家人分享宠物的位置或活动。 家庭成员不能创建围栏或修改设置。 + 邀请 发送成功 返回 追踪间隔 - 关机 + 围栏 围栏详情 名称 @@ -707,7 +697,7 @@ 订阅详情 设备ID 套餐: - /年) + 续订日期: 添加常驻地可提升电池续航并提供额外安全保障 建立WiFi区域 @@ -757,8 +747,8 @@ 尚无成员 +邀请 邀请成员 - 这将从您的账户中永久删除所有 - 数据 + + 直播时长 关于直播时长 @@ -885,15 +875,14 @@ 如何获取? 邀请家人 活跃时长: - 您的朋友 - 邀请您成为 - 的家人。 + + 有效期至: 过期于: - - 自动续费 + + 订阅订单 订单号: 请输入您的退款原因 @@ -902,10 +891,8 @@ 等待处理 退款中 已退款 - /年,于 - 续费: - /月,于 - 换新保障 + + 输入折扣码 验证 年度护理