列表,个人中心
This commit is contained in:
@@ -80,4 +80,6 @@ dependencies {
|
||||
implementation "androidx.camera:camera-view:1.0.0-alpha25"
|
||||
//圆形视图库
|
||||
implementation 'com.makeramen:roundedimageview:2.3.0'
|
||||
//完整版引入
|
||||
implementation 'io.github.carguo:gsyvideoplayer:13.2.1'
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ object AppConfig {
|
||||
const val SEND_CODE_SCENE_LOGIN = "login"
|
||||
//验证码场景 --重置密码
|
||||
const val SEND_CODE_SCENE_RESET = "resetPwd"
|
||||
//验证码场景 --更换手机号
|
||||
const val SEND_CODE_SCENE_REBIND = "rebind"
|
||||
|
||||
@Volatile
|
||||
var userToken: String = ""
|
||||
|
||||
@@ -276,7 +276,17 @@ abstract class BaseActivity<VB : ViewBinding, P : IPresenter<*>> :
|
||||
}
|
||||
}
|
||||
dialog.setCanceledOnTouchOutside(touchOutsideCancel)
|
||||
dialog.setOnShowListener { dialog.window?.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT)) }
|
||||
dialog.setOnShowListener {
|
||||
dialog.window?.apply {
|
||||
// 直接设置窗口宽度,确保屏幕左右各保留 50dp,避免 AlertDialog 默认宽度影响根布局 margin。
|
||||
setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
|
||||
setLayout(
|
||||
(resources.displayMetrics.widthPixels -
|
||||
2 * (50 * resources.displayMetrics.density).toInt()),
|
||||
WindowManager.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
@@ -322,7 +332,17 @@ abstract class BaseActivity<VB : ViewBinding, P : IPresenter<*>> :
|
||||
}
|
||||
}
|
||||
dialog.setCanceledOnTouchOutside(touchOutsideCancel)
|
||||
dialog.setOnShowListener { dialog.window?.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT)) }
|
||||
dialog.setOnShowListener {
|
||||
dialog.window?.apply {
|
||||
// 固定窗口宽度,确保输入弹窗左右各保留 50dp。
|
||||
setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
|
||||
setLayout(
|
||||
(resources.displayMetrics.widthPixels -
|
||||
2 * (50 * resources.displayMetrics.density).toInt()),
|
||||
WindowManager.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
@@ -370,7 +390,17 @@ abstract class BaseActivity<VB : ViewBinding, P : IPresenter<*>> :
|
||||
val dialog = AlertDialog.Builder(this).setView(view).create()
|
||||
view.findViewById<TextView>(R.id.permissionCancel).setOnClickListener { dialog.dismiss(); onCancel() }
|
||||
view.findViewById<TextView>(R.id.permissionAllow).setOnClickListener { dialog.dismiss(); onAllow() }
|
||||
dialog.setOnShowListener { dialog.window?.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT)) }
|
||||
dialog.setOnShowListener {
|
||||
dialog.window?.apply {
|
||||
// 动态权限确认弹窗固定左右各 50dp,避免使用 AlertDialog 默认宽度。
|
||||
setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
|
||||
setLayout(
|
||||
(resources.displayMetrics.widthPixels -
|
||||
2 * (50 * resources.displayMetrics.density).toInt()),
|
||||
WindowManager.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
|
||||
@@ -276,7 +276,17 @@ abstract class BaseFragment<VB : ViewBinding, P : IPresenter<*>> : Fragment(), I
|
||||
}
|
||||
}
|
||||
dialog.setCanceledOnTouchOutside(touchOutsideCancel)
|
||||
dialog.setOnShowListener { dialog.window?.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT)) }
|
||||
dialog.setOnShowListener {
|
||||
dialog.window?.apply {
|
||||
// 直接设置窗口宽度,确保屏幕左右各保留 50dp,避免 AlertDialog 默认宽度影响根布局 margin。
|
||||
setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
|
||||
setLayout(
|
||||
(resources.displayMetrics.widthPixels -
|
||||
2 * (50 * resources.displayMetrics.density).toInt()),
|
||||
WindowManager.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
@@ -322,7 +332,17 @@ abstract class BaseFragment<VB : ViewBinding, P : IPresenter<*>> : Fragment(), I
|
||||
}
|
||||
}
|
||||
dialog.setCanceledOnTouchOutside(touchOutsideCancel)
|
||||
dialog.setOnShowListener { dialog.window?.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT)) }
|
||||
dialog.setOnShowListener {
|
||||
dialog.window?.apply {
|
||||
// 固定窗口宽度,确保输入弹窗左右各保留 50dp。
|
||||
setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
|
||||
setLayout(
|
||||
(resources.displayMetrics.widthPixels -
|
||||
2 * (50 * resources.displayMetrics.density).toInt()),
|
||||
WindowManager.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
@@ -368,7 +388,17 @@ abstract class BaseFragment<VB : ViewBinding, P : IPresenter<*>> : Fragment(), I
|
||||
val dialog = AlertDialog.Builder(requireContext()).setView(view).create()
|
||||
view.findViewById<TextView>(R.id.permissionCancel).setOnClickListener { dialog.dismiss(); onCancel() }
|
||||
view.findViewById<TextView>(R.id.permissionAllow).setOnClickListener { dialog.dismiss(); onAllow() }
|
||||
dialog.setOnShowListener { dialog.window?.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT)) }
|
||||
dialog.setOnShowListener {
|
||||
dialog.window?.apply {
|
||||
// 动态权限确认弹窗固定左右各 50dp,避免使用 AlertDialog 默认宽度。
|
||||
setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
|
||||
setLayout(
|
||||
(resources.displayMetrics.widthPixels -
|
||||
2 * (50 * resources.displayMetrics.density).toInt()),
|
||||
WindowManager.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
/** 关闭并释放顶部权限提示弹窗。 */
|
||||
|
||||
@@ -4,6 +4,8 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
import com.juhabi.birds.base.BaseFragment
|
||||
import com.juhabi.birds.mine.model.MineUserInfo
|
||||
import com.juhabi.birds.R
|
||||
@@ -14,6 +16,8 @@ import com.juhabi.birds.mine.mvp.MineContract
|
||||
import com.juhabi.birds.mine.mvp.MineImpl
|
||||
import com.juhabi.birds.mine.mvp.MinePresenter
|
||||
import com.juhabi.birds.util.manager.UserInfoManager
|
||||
import com.juhabi.birds.AppConfig
|
||||
import com.juhabi.birds.login.LoginActivity
|
||||
|
||||
/**
|
||||
* 个人中心
|
||||
@@ -31,11 +35,13 @@ class MineFragment : BaseFragment<MineCenterLayoutBinding, MinePresenter>(),
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
displayCacheSize()
|
||||
/** 页面恢复显示时重新请求当前用户的个人信息。 */
|
||||
presenter?.getUserInfo()
|
||||
}
|
||||
|
||||
override fun initView(savedInstanceState: Bundle?) {
|
||||
displayCacheSize()
|
||||
listOf(
|
||||
binding.linearXgmm,
|
||||
binding.linearGhsj,
|
||||
@@ -62,6 +68,23 @@ class MineFragment : BaseFragment<MineCenterLayoutBinding, MinePresenter>(),
|
||||
goTo(UpdateUserAccount::class.java, null)
|
||||
}
|
||||
|
||||
R.id.linear_qchc -> {
|
||||
showDialogtext(
|
||||
"提示",
|
||||
"清除当前应用缓存?",
|
||||
"确定",
|
||||
"取消",
|
||||
object : OnDialogClick {
|
||||
override fun onCancelClick() {
|
||||
}
|
||||
|
||||
override fun onConfirmClick() {
|
||||
clearCache()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
//退出登录
|
||||
R.id.tv_logout -> {
|
||||
@@ -75,7 +98,8 @@ class MineFragment : BaseFragment<MineCenterLayoutBinding, MinePresenter>(),
|
||||
}
|
||||
|
||||
override fun onConfirmClick() {
|
||||
// 退出登录接口后续接入
|
||||
// 用户确认后调用服务端退出登录接口。
|
||||
presenter?.userLogout()
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -108,4 +132,75 @@ class MineFragment : BaseFragment<MineCenterLayoutBinding, MinePresenter>(),
|
||||
override fun showError(message: String) {
|
||||
showMessage(message)
|
||||
}
|
||||
|
||||
override fun onLogoutSuccess(message: String) {
|
||||
val context = context ?: return
|
||||
// 服务端退出成功后清除本地账号信息,避免应用重启后恢复旧登录状态。
|
||||
UserInfoManager.clearUser(context)
|
||||
AppConfig.USER_LOGIN = false
|
||||
showMessage(message)
|
||||
|
||||
// 清空之前的页面栈,防止用户返回到已登录页面。
|
||||
goToClearTask(LoginActivity::class.java, null)
|
||||
}
|
||||
|
||||
/** 查询应用缓存大小,并将结果显示在个人中心页面。 */
|
||||
private fun displayCacheSize() {
|
||||
val context = context ?: return
|
||||
Thread {
|
||||
val cacheSize = getFolderSize(context.cacheDir)
|
||||
val sizeText = formatCacheSize(cacheSize)
|
||||
activity?.runOnUiThread {
|
||||
if (isAdded && view != null) {
|
||||
binding.tvTotalCache.text = sizeText
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
/** 清理应用缓存,删除完成后重新创建缓存目录并刷新显示。 */
|
||||
private fun clearCache() {
|
||||
val context = context ?: return
|
||||
Thread {
|
||||
deleteDir(context.cacheDir)
|
||||
context.cacheDir.mkdirs()
|
||||
activity?.runOnUiThread {
|
||||
if (isAdded && view != null) {
|
||||
binding.tvTotalCache.text = formatCacheSize(0L)
|
||||
showMessage("缓存清理成功")
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
/** 递归计算目录下所有文件的字节数。 */
|
||||
private fun getFolderSize(directory: File?): Long {
|
||||
if (directory == null || !directory.exists()) {
|
||||
return 0L
|
||||
}
|
||||
if (directory.isFile) {
|
||||
return directory.length()
|
||||
}
|
||||
return directory.listFiles()?.sumOf { file -> getFolderSize(file) } ?: 0L
|
||||
}
|
||||
|
||||
/** 递归删除文件或目录。 */
|
||||
private fun deleteDir(file: File?): Boolean {
|
||||
if (file == null || !file.exists()) {
|
||||
return true
|
||||
}
|
||||
if (file.isDirectory) {
|
||||
file.listFiles()?.forEach { child -> deleteDir(child) }
|
||||
}
|
||||
return file.delete()
|
||||
}
|
||||
|
||||
/** 大于等于 1 MB 使用 MB,否则使用 KB,保持与旧 Java 页面一致。 */
|
||||
private fun formatCacheSize(bytes: Long): String {
|
||||
return if (bytes >= 1024L * 1024L) {
|
||||
String.format(Locale.US, "%.2f MB", bytes / (1024.0 * 1024.0))
|
||||
} else {
|
||||
String.format(Locale.US, "%d KB", bytes / 1024L)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.juhabi.birds.mine
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.CountDownTimer
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
@@ -14,12 +15,15 @@ import com.juhabi.birds.mine.mvp.MineContract
|
||||
import com.juhabi.birds.mine.mvp.MineImpl
|
||||
import com.juhabi.birds.mine.mvp.MinePresenter
|
||||
import com.juhabi.birds.util.manager.UserInfoManager
|
||||
import com.juhabi.birds.util.ToastUtil
|
||||
|
||||
/**
|
||||
* 修改手机号
|
||||
*/
|
||||
class UpdateUserAccount : BaseActivity<UpdateUserPhoneLayoutBinding, MinePresenter>(),
|
||||
MineContract.MineView, View.OnClickListener {
|
||||
private var codeCountDownTimer: CountDownTimer? = null
|
||||
private var newPhoneCodeCountDownTimer: CountDownTimer? = null
|
||||
override fun createBinding(inflater: LayoutInflater): UpdateUserPhoneLayoutBinding {
|
||||
return UpdateUserPhoneLayoutBinding.inflate(inflater)
|
||||
}
|
||||
@@ -59,22 +63,132 @@ class UpdateUserAccount : BaseActivity<UpdateUserPhoneLayoutBinding, MinePresen
|
||||
}
|
||||
|
||||
R.id.tv_confirm_getcode ->{
|
||||
|
||||
// 新接口根据登录态识别当前手机号,不需要传手机号或验证码场景。
|
||||
presenter?.getCurrentPhoneCode()
|
||||
}
|
||||
|
||||
R.id.tv_confirmAccount ->{
|
||||
// 只有填写旧手机号收到的验证码后,才能进入新手机号填写页面。
|
||||
val confirmCode = binding.EtConfirmCode.text.toString().trim()
|
||||
if (confirmCode.isBlank()) {
|
||||
ToastUtil.showShort(mContext, "验证码不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 服务端校验通过后,再进入新手机号填写页面。
|
||||
presenter?.verifyOldPhone(confirmCode)
|
||||
}
|
||||
|
||||
R.id.tv_new_phone_getcode ->{
|
||||
// 新手机号不能为空,校验通过后使用 rebind 场景发送验证码。
|
||||
val newPhone = binding.etNewPhone.text.toString().trim()
|
||||
if (newPhone.isBlank()) {
|
||||
ToastUtil.showShort(mContext, "新手机号不能为空")
|
||||
return
|
||||
}
|
||||
presenter?.sendNewPhoneCode(newPhone)
|
||||
}
|
||||
|
||||
R.id.tv_submit_new_account ->{
|
||||
//绑定新的手机号码
|
||||
val newPhone = binding.etNewPhone.text.toString().trim()
|
||||
val code = binding.etNewPhoneCode.text.toString().trim()
|
||||
if (newPhone.isBlank()) {
|
||||
ToastUtil.showShort(mContext, "新手机号不能为空")
|
||||
return
|
||||
}
|
||||
if (code.isBlank()) {
|
||||
ToastUtil.showShort(mContext, "验证码不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
// 手机号和验证码校验通过后,提交新手机号换绑请求。
|
||||
presenter?.updateBindNewPhone(newPhone, code)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun showError(message: String) {
|
||||
hideLoading()
|
||||
ToastUtil.showShort(mContext, message)
|
||||
}
|
||||
|
||||
override fun sendCodeSuccess(message: String) {
|
||||
hideLoading()
|
||||
ToastUtil.showShort(mContext, message)
|
||||
codeCountDownTimer?.cancel()
|
||||
binding.tvConfirmGetcode.apply {
|
||||
isEnabled = false
|
||||
isClickable = false
|
||||
setBackgroundResource(R.drawable.shape_register_code_disabled_bg)
|
||||
text = getString(R.string.register_code_countdown, CODE_COUNTDOWN_SECONDS)
|
||||
}
|
||||
codeCountDownTimer = object : CountDownTimer(CODE_COUNTDOWN_MILLIS, 1_000L) {
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
val secondsRemaining = (millisUntilFinished + 999L) / 1_000L
|
||||
binding.tvConfirmGetcode.text = getString(
|
||||
R.string.register_code_countdown,
|
||||
secondsRemaining
|
||||
)
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
codeCountDownTimer = null
|
||||
binding.tvConfirmGetcode.apply {
|
||||
isEnabled = true
|
||||
isClickable = true
|
||||
setBackgroundResource(R.drawable.shape_register_code_bg)
|
||||
setText(R.string.register_get_code)
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
override fun onVerifyOldPhoneSuccess(message: String) {
|
||||
hideLoading()
|
||||
ToastUtil.showShort(mContext, message)
|
||||
// 当前手机号验证成功后,隐藏验证区域并展示新手机号输入区域。
|
||||
binding.linearConfirmUserAccount.visibility = View.GONE
|
||||
binding.linearNewUserAccount.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
override fun newPhoneCodeSuccess(message: String) {
|
||||
hideLoading()
|
||||
ToastUtil.showShort(mContext, message)
|
||||
newPhoneCodeCountDownTimer?.cancel()
|
||||
binding.tvNewPhoneGetcode.apply {
|
||||
isEnabled = false
|
||||
isClickable = false
|
||||
setBackgroundResource(R.drawable.shape_register_code_disabled_bg)
|
||||
text = getString(R.string.register_code_countdown, CODE_COUNTDOWN_SECONDS)
|
||||
}
|
||||
newPhoneCodeCountDownTimer = object : CountDownTimer(CODE_COUNTDOWN_MILLIS, 1_000L) {
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
val secondsRemaining = (millisUntilFinished + 999L) / 1_000L
|
||||
binding.tvNewPhoneGetcode.text = getString(
|
||||
R.string.register_code_countdown,
|
||||
secondsRemaining
|
||||
)
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
newPhoneCodeCountDownTimer = null
|
||||
binding.tvNewPhoneGetcode.apply {
|
||||
isEnabled = true
|
||||
isClickable = true
|
||||
setBackgroundResource(R.drawable.shape_register_code_bg)
|
||||
setText(R.string.register_get_code)
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
override fun onUpdateBindNewPhoneSuccess(message: String) {
|
||||
hideLoading()
|
||||
ToastUtil.showShort(mContext, message)
|
||||
// 返回个人中心后,MineFragment 会在 onResume 中重新获取最新用户资料。
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun getUserInfoSuccess(userInfo: MineUserInfo) {
|
||||
@@ -83,5 +197,18 @@ class UpdateUserAccount : BaseActivity<UpdateUserPhoneLayoutBinding, MinePresen
|
||||
override fun onVersionChecked(versionInfo: AppVersionInfo) {
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
codeCountDownTimer?.cancel()
|
||||
codeCountDownTimer = null
|
||||
newPhoneCodeCountDownTimer?.cancel()
|
||||
newPhoneCodeCountDownTimer = null
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val CODE_COUNTDOWN_SECONDS = 60L
|
||||
const val CODE_COUNTDOWN_MILLIS = CODE_COUNTDOWN_SECONDS * 1_000L
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -3,6 +3,9 @@ package com.juhabi.birds.mine.mvp
|
||||
import com.juhabi.birds.base.IView
|
||||
import com.juhabi.birds.main.model.AppVersionInfo
|
||||
import com.juhabi.birds.mine.model.MineUserInfo
|
||||
import com.juhabi.birds.network.BaseBean
|
||||
import com.juhabi.birds.login.model.SendCodeEntity
|
||||
import org.json.JSONObject
|
||||
|
||||
interface MineContract {
|
||||
interface Callback<T> {
|
||||
@@ -17,6 +20,15 @@ interface MineContract {
|
||||
callback: Callback<AppVersionInfo>
|
||||
)
|
||||
fun modifyPassword(oldPassword: String, newPassword: String, callback: Callback<String>)
|
||||
fun getCurrentPhoneCode(callback: Callback<BaseBean<Any>>)
|
||||
fun sendPhoneCode(request: JSONObject, callback: Callback<BaseBean<SendCodeEntity>>)
|
||||
fun verifyOldPhone(oldCode: String, callback: Callback<BaseBean<Any>>)
|
||||
fun updateBindNewPhone(
|
||||
newPhoneNumber: String,
|
||||
code: String,
|
||||
callback: Callback<BaseBean<Any>>
|
||||
)
|
||||
fun userLogout(callback: Callback<BaseBean<Any>>)
|
||||
fun cancel()
|
||||
}
|
||||
|
||||
@@ -25,5 +37,15 @@ interface MineContract {
|
||||
fun onVersionChecked(versionInfo: AppVersionInfo)
|
||||
/** 修改密码成功回调,非修改密码页面无需处理。 */
|
||||
fun onModifyPasswordSuccess(message: String) {}
|
||||
/** 发送验证码成功回调。 */
|
||||
fun sendCodeSuccess(message: String) {}
|
||||
/** 新手机号验证码发送成功回调。 */
|
||||
fun newPhoneCodeSuccess(message: String) {}
|
||||
/** 当前手机号验证成功回调。 */
|
||||
fun onVerifyOldPhoneSuccess(message: String) {}
|
||||
/** 新手机号绑定成功回调。 */
|
||||
fun onUpdateBindNewPhoneSuccess(message: String) {}
|
||||
/** 退出登录成功回调。 */
|
||||
fun onLogoutSuccess(message: String) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,12 +11,177 @@ import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import org.json.JSONObject
|
||||
import com.juhabi.birds.login.model.SendCodeEntity
|
||||
|
||||
class MineImpl : MineContract.DataModel {
|
||||
private val mainHandler = Handler(Looper.getMainLooper())
|
||||
private var userInfoCall: Call<BaseBean<MineUserInfo>>? = null
|
||||
private var versionCall: Call<BaseBean<AppVersionInfo>>? = null
|
||||
private var modifyPasswordCall: Call<BaseBean<Any>>? = null
|
||||
private var sendCodeCall: Call<BaseBean<Any>>? = null
|
||||
private var verifyOldPhoneCall: Call<BaseBean<Any>>? = null
|
||||
private var newPhoneCodeCall: Call<BaseBean<SendCodeEntity>>? = null
|
||||
private var updateBindNewPhoneCall: Call<BaseBean<Any>>? = null
|
||||
private var logoutCall: Call<BaseBean<Any>>? = null
|
||||
|
||||
override fun getCurrentPhoneCode(
|
||||
callback: MineContract.Callback<BaseBean<Any>>
|
||||
) {
|
||||
sendCodeCall?.cancel()
|
||||
sendCodeCall = ApiClient.apiService
|
||||
.getCurrentPhoneCode(NetworkManager.getToken())
|
||||
.also { call ->
|
||||
call.enqueue(object : Callback<BaseBean<Any>> {
|
||||
override fun onResponse(
|
||||
call: Call<BaseBean<Any>>,
|
||||
response: Response<BaseBean<Any>>
|
||||
) {
|
||||
mainHandler.post {
|
||||
response.body()?.let(callback::success)
|
||||
?: callback.fail("验证码发送失败")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(
|
||||
call: Call<BaseBean<Any>>,
|
||||
error: Throwable
|
||||
) {
|
||||
if (!call.isCanceled) {
|
||||
mainHandler.post { callback.fail(error.message ?: "网络请求失败") }
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun sendPhoneCode(
|
||||
request: JSONObject,
|
||||
callback: MineContract.Callback<BaseBean<SendCodeEntity>>
|
||||
) {
|
||||
newPhoneCodeCall?.cancel()
|
||||
newPhoneCodeCall = ApiClient.apiService
|
||||
.sendPhoneCode(NetworkManager.getToken(), NetworkManager.toRequestBody(request))
|
||||
.also { call ->
|
||||
call.enqueue(object : Callback<BaseBean<SendCodeEntity>> {
|
||||
override fun onResponse(
|
||||
call: Call<BaseBean<SendCodeEntity>>,
|
||||
response: Response<BaseBean<SendCodeEntity>>
|
||||
) {
|
||||
mainHandler.post {
|
||||
response.body()?.let(callback::success)
|
||||
?: callback.fail("验证码发送失败")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(
|
||||
call: Call<BaseBean<SendCodeEntity>>,
|
||||
error: Throwable
|
||||
) {
|
||||
if (!call.isCanceled) {
|
||||
mainHandler.post { callback.fail(error.message ?: "网络请求失败") }
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun verifyOldPhone(
|
||||
oldCode: String,
|
||||
callback: MineContract.Callback<BaseBean<Any>>
|
||||
) {
|
||||
verifyOldPhoneCall?.cancel()
|
||||
val requestBody = JSONObject().apply {
|
||||
put("oldCode", oldCode.trim())
|
||||
}
|
||||
verifyOldPhoneCall = ApiClient.apiService
|
||||
.verifyOldPhone(NetworkManager.getToken(), NetworkManager.toRequestBody(requestBody))
|
||||
.also { call ->
|
||||
call.enqueue(object : Callback<BaseBean<Any>> {
|
||||
override fun onResponse(
|
||||
call: Call<BaseBean<Any>>,
|
||||
response: Response<BaseBean<Any>>
|
||||
) {
|
||||
mainHandler.post {
|
||||
response.body()?.let(callback::success)
|
||||
?: callback.fail("当前手机号验证失败")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<BaseBean<Any>>, error: Throwable) {
|
||||
if (!call.isCanceled) {
|
||||
mainHandler.post {
|
||||
callback.fail(error.message ?: "网络请求失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateBindNewPhone(
|
||||
newPhoneNumber: String,
|
||||
code: String,
|
||||
callback: MineContract.Callback<BaseBean<Any>>
|
||||
) {
|
||||
updateBindNewPhoneCall?.cancel()
|
||||
val requestBody = JSONObject().apply {
|
||||
put("newPhoneNumber", newPhoneNumber.trim())
|
||||
put("code", code.trim())
|
||||
}
|
||||
updateBindNewPhoneCall = ApiClient.apiService
|
||||
.updateBindNewPhone(
|
||||
NetworkManager.getToken(),
|
||||
NetworkManager.toRequestBody(requestBody)
|
||||
)
|
||||
.also { call ->
|
||||
call.enqueue(object : Callback<BaseBean<Any>> {
|
||||
override fun onResponse(
|
||||
call: Call<BaseBean<Any>>,
|
||||
response: Response<BaseBean<Any>>
|
||||
) {
|
||||
mainHandler.post {
|
||||
response.body()?.let(callback::success)
|
||||
?: callback.fail("手机号更换失败")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<BaseBean<Any>>, error: Throwable) {
|
||||
if (!call.isCanceled) {
|
||||
mainHandler.post {
|
||||
callback.fail(error.message ?: "网络请求失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun userLogout(callback: MineContract.Callback<BaseBean<Any>>) {
|
||||
logoutCall?.cancel()
|
||||
logoutCall = ApiClient.apiService
|
||||
.userLogout(NetworkManager.getToken())
|
||||
.also { call ->
|
||||
call.enqueue(object : Callback<BaseBean<Any>> {
|
||||
override fun onResponse(
|
||||
call: Call<BaseBean<Any>>,
|
||||
response: Response<BaseBean<Any>>
|
||||
) {
|
||||
mainHandler.post {
|
||||
response.body()?.let(callback::success)
|
||||
?: callback.fail("退出登录失败")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<BaseBean<Any>>, error: Throwable) {
|
||||
if (!call.isCanceled) {
|
||||
mainHandler.post {
|
||||
callback.fail(error.message ?: "网络请求失败")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getUserInfo(
|
||||
params: Map<String, String>,
|
||||
@@ -145,6 +310,16 @@ class MineImpl : MineContract.DataModel {
|
||||
versionCall = null
|
||||
modifyPasswordCall?.cancel()
|
||||
modifyPasswordCall = null
|
||||
sendCodeCall?.cancel()
|
||||
sendCodeCall = null
|
||||
verifyOldPhoneCall?.cancel()
|
||||
verifyOldPhoneCall = null
|
||||
newPhoneCodeCall?.cancel()
|
||||
newPhoneCodeCall = null
|
||||
updateBindNewPhoneCall?.cancel()
|
||||
updateBindNewPhoneCall = null
|
||||
logoutCall?.cancel()
|
||||
logoutCall = null
|
||||
mainHandler.removeCallbacksAndMessages(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,149 @@ package com.juhabi.birds.mine.mvp
|
||||
import com.juhabi.birds.base.BasePresenter
|
||||
import com.juhabi.birds.main.model.AppVersionInfo
|
||||
import com.juhabi.birds.mine.model.MineUserInfo
|
||||
import com.juhabi.birds.network.BaseBean
|
||||
import com.juhabi.birds.login.model.SendCodeEntity
|
||||
import org.json.JSONObject
|
||||
|
||||
class MinePresenter(private val mineImpl: MineImpl) : BasePresenter<MineContract.MineView>() {
|
||||
|
||||
/** 通过登录态向当前绑定的手机号发送验证码,无需额外请求参数。 */
|
||||
fun getCurrentPhoneCode() {
|
||||
val currentView = view ?: return
|
||||
currentView.showLoading()
|
||||
mineImpl.getCurrentPhoneCode(object : MineContract.Callback<BaseBean<Any>> {
|
||||
override fun success(data: BaseBean<Any>) {
|
||||
view?.apply {
|
||||
hideLoading()
|
||||
if (data.code == 0 || data.code == 200) {
|
||||
sendCodeSuccess(data.message.ifBlank { "验证码已发送" })
|
||||
} else {
|
||||
showError(data.message.ifBlank { "验证码发送失败" })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun fail(message: String) {
|
||||
view?.apply {
|
||||
hideLoading()
|
||||
showError(message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 向新手机号发送 rebind 场景验证码。 */
|
||||
fun sendNewPhoneCode(phoneNumber: String) {
|
||||
val currentView = view ?: return
|
||||
currentView.showLoading()
|
||||
val request = JSONObject().apply {
|
||||
put("phoneNumber", phoneNumber.trim())
|
||||
put("scene", com.juhabi.birds.AppConfig.SEND_CODE_SCENE_REBIND)
|
||||
}
|
||||
mineImpl.sendPhoneCode(request, object : MineContract.Callback<BaseBean<SendCodeEntity>> {
|
||||
override fun success(data: BaseBean<SendCodeEntity>) {
|
||||
view?.apply {
|
||||
hideLoading()
|
||||
if (data.code == 0 || data.code == 200) {
|
||||
newPhoneCodeSuccess(data.message.ifBlank { "验证码已发送" })
|
||||
} else {
|
||||
showError(data.message.ifBlank { "验证码发送失败" })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun fail(message: String) {
|
||||
view?.apply {
|
||||
hideLoading()
|
||||
showError(message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 校验当前手机号收到的验证码。 */
|
||||
fun verifyOldPhone(oldCode: String) {
|
||||
val currentView = view ?: return
|
||||
currentView.showLoading()
|
||||
mineImpl.verifyOldPhone(oldCode, object : MineContract.Callback<BaseBean<Any>> {
|
||||
override fun success(data: BaseBean<Any>) {
|
||||
view?.apply {
|
||||
hideLoading()
|
||||
if (data.code == 0 || data.code == 200) {
|
||||
onVerifyOldPhoneSuccess(
|
||||
data.message.ifBlank { "当前手机号验证成功" }
|
||||
)
|
||||
} else {
|
||||
showError(data.message.ifBlank { "当前手机号验证失败" })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun fail(message: String) {
|
||||
view?.apply {
|
||||
hideLoading()
|
||||
showError(message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 提交新手机号和验证码,完成手机号换绑。 */
|
||||
fun updateBindNewPhone(newPhoneNumber: String, code: String) {
|
||||
val currentView = view ?: return
|
||||
currentView.showLoading()
|
||||
mineImpl.updateBindNewPhone(
|
||||
newPhoneNumber,
|
||||
code,
|
||||
object : MineContract.Callback<BaseBean<Any>> {
|
||||
override fun success(data: BaseBean<Any>) {
|
||||
view?.apply {
|
||||
hideLoading()
|
||||
if (data.code == 0 || data.code == 200) {
|
||||
onUpdateBindNewPhoneSuccess(
|
||||
data.message.ifBlank { "手机号更换成功" }
|
||||
)
|
||||
} else {
|
||||
showError(data.message.ifBlank { "手机号更换失败" })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun fail(message: String) {
|
||||
view?.apply {
|
||||
hideLoading()
|
||||
showError(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/** 调用服务端退出登录接口,并统一分发成功或失败结果。 */
|
||||
fun userLogout() {
|
||||
val currentView = view ?: return
|
||||
currentView.showLoading()
|
||||
mineImpl.userLogout(object : MineContract.Callback<BaseBean<Any>> {
|
||||
override fun success(data: BaseBean<Any>) {
|
||||
view?.apply {
|
||||
hideLoading()
|
||||
if (data.code == 0 || data.code == 200) {
|
||||
onLogoutSuccess(data.message.ifBlank { "退出登录成功" })
|
||||
} else {
|
||||
showError(data.message.ifBlank { "退出登录失败" })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun fail(message: String) {
|
||||
view?.apply {
|
||||
hideLoading()
|
||||
showError(message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun getUserInfo() {
|
||||
val currentView = view ?: return
|
||||
currentView.showLoading()
|
||||
|
||||
@@ -23,6 +23,14 @@ interface ApiService {
|
||||
|
||||
|
||||
//发送手机验证码
|
||||
/**
|
||||
* 入参
|
||||
* {
|
||||
* "phoneNumber": "15550099523",
|
||||
* "scene": "场景值"
|
||||
* }
|
||||
*
|
||||
*/
|
||||
@POST("app/auth/sms/code")
|
||||
fun sendPhoneCode(@HeaderMap headers: Map<String, String>, @Body requestBody: RequestBody): Call<BaseBean<SendCodeEntity>>
|
||||
|
||||
@@ -194,6 +202,48 @@ interface ApiService {
|
||||
fun modifyPassword(@HeaderMap headers: Map<String, String>, @Body requestBody: RequestBody): Call<BaseBean<Any>>
|
||||
|
||||
|
||||
/**
|
||||
* 验证原手机号--发送短信
|
||||
*
|
||||
* 不需要任何入参,
|
||||
*/
|
||||
@POST("app/user/phone/old-code")
|
||||
fun getCurrentPhoneCode(@HeaderMap headers: Map<String, String>): Call<BaseBean<Any>>
|
||||
|
||||
|
||||
/**
|
||||
* 验证原手机号--验证手机号
|
||||
*
|
||||
* 入参
|
||||
*{
|
||||
* "oldCode": "123456"
|
||||
* }
|
||||
*
|
||||
*/
|
||||
@POST("app/user/phone/verify-old")
|
||||
fun verifyOldPhone(@HeaderMap headers: Map<String, String>, @Body requestBody: RequestBody): Call<BaseBean<Any>>
|
||||
|
||||
|
||||
/**
|
||||
* 更换新的绑定手机号码
|
||||
{
|
||||
"newPhoneNumber": "string",
|
||||
"code": "string"
|
||||
}
|
||||
*/
|
||||
@PUT("app/user/phone")
|
||||
fun updateBindNewPhone(@HeaderMap headers: Map<String, String>, @Body requestBody: RequestBody): Call<BaseBean<Any>>
|
||||
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*
|
||||
* 不需要任何入参,
|
||||
*/
|
||||
@POST("app/auth/logout")
|
||||
fun userLogout(@HeaderMap headers: Map<String, String>): Call<BaseBean<Any>>
|
||||
|
||||
|
||||
|
||||
|
||||
@GET("app/v1/checkVersion")
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
android:id="@+id/contentDialog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="36dp"
|
||||
android:background="@drawable/bg_confirm_dialog"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@mipmap/img_back_black"
|
||||
android:src="@mipmap/icon_back_white"
|
||||
android:layout_marginStart="10dp"/>
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
|
||||
@@ -140,13 +140,25 @@
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="9"
|
||||
android:layout_weight="5"
|
||||
android:layout_marginStart="18dp"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/white"
|
||||
android:text="清除缓存"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_total_cache"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:layout_marginStart="18dp"
|
||||
android:gravity="end"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/white"
|
||||
android:text=""
|
||||
android:singleLine="true"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="24dp"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
android:id="@+id/contentDialog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="36dp"
|
||||
android:background="@drawable/bg_confirm_dialog"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
android:id="@+id/linear_confirm_user_account"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="visible">
|
||||
<LinearLayout
|
||||
@@ -121,6 +122,7 @@
|
||||
android:id="@+id/linear_new_user_account"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
<LinearLayout
|
||||
|
||||
BIN
app/src/main/res/mipmap-xhdpi/icon_back_white.png
Normal file
BIN
app/src/main/res/mipmap-xhdpi/icon_back_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 808 B |
BIN
app/src/main/res/mipmap-xxhdpi/icon_back_white.png
Normal file
BIN
app/src/main/res/mipmap-xxhdpi/icon_back_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/icon_back_white.png
Normal file
BIN
app/src/main/res/mipmap-xxxhdpi/icon_back_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Reference in New Issue
Block a user