操作密码弹窗修改2
This commit is contained in:
@@ -27,6 +27,9 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.DefenseApplication">
|
android:theme="@style/Theme.DefenseApplication">
|
||||||
|
<activity
|
||||||
|
android:name=".personal.LoginPasswordActivity"
|
||||||
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".personal.InvitationCodeActivity"
|
android:name=".personal.InvitationCodeActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import android.graphics.Color
|
|||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.text.TextPaint
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
@@ -43,6 +42,7 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
private var lastClickTime: Long = 0 // 上次点击时间,用于防止多次点击
|
private var lastClickTime: Long = 0 // 上次点击时间,用于防止多次点击
|
||||||
private var expireTimeDialog: BottomSheetDialog? = null // 时效选择弹窗
|
private var expireTimeDialog: BottomSheetDialog? = null // 时效选择弹窗
|
||||||
private var isLoading = false // 是否正在加载
|
private var isLoading = false // 是否正在加载
|
||||||
|
private var hasGeneratedQrCode = false // 是否已经生成过二维码
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val EXPIRE_24H = 24 * 60 * 60 * 1000L
|
const val EXPIRE_24H = 24 * 60 * 60 * 1000L
|
||||||
@@ -64,9 +64,8 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
binding.tvExpireTime.text = getString(R.string.expire_24h)
|
binding.tvExpireTime.text = getString(R.string.expire_24h)
|
||||||
// 默认显示灰色占位区域,二维码不可见
|
// 默认显示灰色占位区域,二维码不可见
|
||||||
hideQrCode()
|
hideQrCode()
|
||||||
|
// 初始按钮文字为"生成二维码"
|
||||||
// 页面加载时查询推荐码状态
|
binding.btnRegenerate.text = getString(R.string.generate_invite_code)
|
||||||
queryRecommendationCodeStatus()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initListener() {
|
private fun initListener() {
|
||||||
@@ -91,116 +90,30 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
// 撤销邀请按钮
|
// 撤销邀请按钮
|
||||||
binding.btnCancelInvite.setOnClickListener {
|
binding.btnCancelInvite.setOnClickListener {
|
||||||
cancelInvitation()
|
showPasswordDialog {
|
||||||
|
cancelInvitation()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重新生成按钮
|
// 生成/重新生成按钮
|
||||||
binding.btnRegenerate.setOnClickListener {
|
binding.btnRegenerate.setOnClickListener {
|
||||||
regenerateInvitation()
|
showPasswordDialog {
|
||||||
}
|
generateOrRegenerateInvitation()
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询推荐码状态
|
|
||||||
*/
|
|
||||||
private fun queryRecommendationCodeStatus() {
|
|
||||||
isLoading = true
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
try {
|
|
||||||
// 注意:接口需要传入code参数,但我们可能不知道当前的推荐码
|
|
||||||
// 这里使用空字符串或默认值进行查询
|
|
||||||
val response = RetrofitNetwork.getNetworkService().selectRecommendationCode("")
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
isLoading = false
|
|
||||||
if (response.code == 200) {
|
|
||||||
// 有推荐码,解析返回的数据
|
|
||||||
handleRecommendationCodeResponse(response.data)
|
|
||||||
} else {
|
|
||||||
// 没有推荐码或查询失败,生成默认24小时的推荐码
|
|
||||||
generateDefaultRecommendationCode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
isLoading = false
|
|
||||||
// 网络异常,生成默认24小时的推荐码
|
|
||||||
generateDefaultRecommendationCode()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理推荐码查询响应
|
* 生成或重新生成邀请码
|
||||||
*/
|
*/
|
||||||
private fun handleRecommendationCodeResponse(data: Any?) {
|
private fun generateOrRegenerateInvitation() {
|
||||||
// 解析返回的数据,获取推荐码和过期时间
|
// 根据当前选择的时效生成邀请码
|
||||||
// 这里需要根据实际接口返回格式进行解析
|
|
||||||
if (data is Map<*, *>) {
|
|
||||||
generatedInviteCode = data["code"]?.toString() ?: ""
|
|
||||||
expireTimestamp = data["expireTime"]?.toString()?.toLongOrNull() ?: 0L
|
|
||||||
|
|
||||||
// 检查推荐码是否过期
|
|
||||||
if (expireTimestamp > 0 && System.currentTimeMillis() < expireTimestamp) {
|
|
||||||
// 推荐码有效,显示二维码
|
|
||||||
qrCodeContent = "{\"type\":\"invite\",\"code\":\"$generatedInviteCode\",\"expire\":$expireTimestamp}"
|
|
||||||
showQrCode()
|
|
||||||
generateQRCode()
|
|
||||||
|
|
||||||
// 根据过期时间设置显示的时效
|
|
||||||
val remainingTime = expireTimestamp - System.currentTimeMillis()
|
|
||||||
if (remainingTime > EXPIRE_24H) {
|
|
||||||
// 超过24小时,认为是7天的
|
|
||||||
expireTimeInMillis = EXPIRE_7D
|
|
||||||
selectedExpireOption = 1
|
|
||||||
binding.tvExpireTime.text = getString(R.string.expire_7d)
|
|
||||||
} else {
|
|
||||||
expireTimeInMillis = EXPIRE_24H
|
|
||||||
selectedExpireOption = 0
|
|
||||||
binding.tvExpireTime.text = getString(R.string.expire_24h)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 推荐码已过期,生成新的默认24小时推荐码
|
|
||||||
generateDefaultRecommendationCode()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 数据格式不对,生成新的推荐码
|
|
||||||
generateDefaultRecommendationCode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成默认24小时的推荐码
|
|
||||||
*/
|
|
||||||
private fun generateDefaultRecommendationCode() {
|
|
||||||
expireTimeInMillis = EXPIRE_24H
|
|
||||||
selectedExpireOption = 0
|
|
||||||
binding.tvExpireTime.text = getString(R.string.expire_24h)
|
|
||||||
|
|
||||||
// 生成推荐码(本地生成,实际应该调用API)
|
|
||||||
generateQRCode()
|
generateQRCode()
|
||||||
showQrCode()
|
showQrCode()
|
||||||
}
|
// 更新按钮文字为"重新生成"
|
||||||
|
binding.btnRegenerate.text = getString(R.string.regenerate)
|
||||||
/**
|
hasGeneratedQrCode = true
|
||||||
* 处理生成推荐码成功
|
ToastUtils.showSuccess(this, getString(R.string.operation_success))
|
||||||
*/
|
|
||||||
private fun handleGenerateSuccess(data: Any?, expireDays: Int) {
|
|
||||||
// 解析返回的数据
|
|
||||||
if (data is Map<*, *>) {
|
|
||||||
generatedInviteCode = data["code"]?.toString() ?: ""
|
|
||||||
expireTimestamp = data["expireTime"]?.toString()?.toLongOrNull() ?: (System.currentTimeMillis() + expireTimeInMillis)
|
|
||||||
qrCodeContent = "{\"type\":\"invite\",\"code\":\"$generatedInviteCode\",\"expire\":$expireTimestamp}"
|
|
||||||
|
|
||||||
showQrCode()
|
|
||||||
generateQRCode()
|
|
||||||
} else {
|
|
||||||
// 如果接口没有返回推荐码,本地生成一个
|
|
||||||
generateInviteCode()
|
|
||||||
showQrCode()
|
|
||||||
generateQRCode()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showExpireTimeDialog() {
|
private fun showExpireTimeDialog() {
|
||||||
@@ -260,7 +173,9 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateQRCode() {
|
private fun generateQRCode() {
|
||||||
val content = if (qrCodeContent.isNotEmpty()) qrCodeContent else generateInviteCode()
|
// 检查二维码是否过期,如果过期则生成新的邀请码
|
||||||
|
val isExpired = expireTimestamp > 0 && System.currentTimeMillis() > expireTimestamp
|
||||||
|
val content = if (qrCodeContent.isNotEmpty() && !isExpired) qrCodeContent else generateInviteCode()
|
||||||
val qrBitmap = createQRCodeWithLogo(content, 400, 400)
|
val qrBitmap = createQRCodeWithLogo(content, 400, 400)
|
||||||
binding.ivQrCode.setImageBitmap(qrBitmap)
|
binding.ivQrCode.setImageBitmap(qrBitmap)
|
||||||
}
|
}
|
||||||
@@ -476,18 +391,48 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
generatedInviteCode = ""
|
generatedInviteCode = ""
|
||||||
qrCodeContent = ""
|
qrCodeContent = ""
|
||||||
expireTimestamp = 0
|
expireTimestamp = 0
|
||||||
|
hasGeneratedQrCode = false
|
||||||
|
// 恢复按钮文字为"生成邀请码"
|
||||||
|
binding.btnRegenerate.text = getString(R.string.generate_invite_code)
|
||||||
// 显示提示
|
// 显示提示
|
||||||
ToastUtils.showSuccess(this, getString(R.string.operation_success))
|
ToastUtils.showSuccess(this, getString(R.string.operation_success))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重新生成邀请码
|
* 显示密码输入对话框
|
||||||
|
* @param onSuccess 验证成功后的回调
|
||||||
*/
|
*/
|
||||||
private fun regenerateInvitation() {
|
private fun showPasswordDialog(onSuccess: () -> Unit) {
|
||||||
// 根据当前选择的时效重新生成邀请码
|
val dialog = PasswordInputDialog(this)
|
||||||
generateQRCode()
|
dialog.setTitle(getString(R.string.input_op_pwd))
|
||||||
showQrCode()
|
dialog.setOnConfirmListener { password ->
|
||||||
ToastUtils.showSuccess(this, getString(R.string.operation_success))
|
verifyPassword(password, dialog, onSuccess)
|
||||||
|
}
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证操作密码
|
||||||
|
*/
|
||||||
|
private fun verifyPassword(password: String, dialog: PasswordInputDialog, onSuccess: () -> Unit) {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.verifyOptionPassword(VerifyOptionPasswordRequest(password))
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200) {
|
||||||
|
dialog.dismiss()
|
||||||
|
onSuccess.invoke()
|
||||||
|
} else {
|
||||||
|
dialog.showError(getString(R.string.password_error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
dialog.showError(getString(R.string.network_error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
package com.example.defenseapplication.personal
|
package com.example.defenseapplication.personal
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
|
||||||
import android.text.TextWatcher
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.blankj.utilcode.util.SPUtils
|
|
||||||
import com.example.defenseapplication.R
|
import com.example.defenseapplication.R
|
||||||
import com.example.defenseapplication.bean.UpdateUserInfo
|
import com.example.defenseapplication.bean.UpdateUserInfo
|
||||||
|
import com.example.defenseapplication.bean.VerifyOptionPasswordRequest
|
||||||
import com.example.defenseapplication.databinding.OperationPasswordActivityBinding
|
import com.example.defenseapplication.databinding.OperationPasswordActivityBinding
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.example.defenseapplication.utils.RetrofitNetwork
|
||||||
|
import com.example.defenseapplication.view.CustomDialogFragment
|
||||||
|
import com.example.defenseapplication.view.LoadingDialog
|
||||||
|
import com.example.defenseapplication.view.showDefenseDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -20,6 +21,7 @@ import kotlinx.coroutines.withContext
|
|||||||
class OperationPasswordActivity : AppCompatActivity() {
|
class OperationPasswordActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var binding: OperationPasswordActivityBinding
|
private lateinit var binding: OperationPasswordActivityBinding
|
||||||
|
private var isLoading = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -31,6 +33,7 @@ class OperationPasswordActivity : AppCompatActivity() {
|
|||||||
.titleBar(binding.topBar)
|
.titleBar(binding.topBar)
|
||||||
.init()
|
.init()
|
||||||
|
|
||||||
|
getUserInfo()
|
||||||
initListener()
|
initListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,104 +42,151 @@ class OperationPasswordActivity : AppCompatActivity() {
|
|||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.swOperationPassword.setOnCheckedChangeListener { _, isChecked ->
|
binding.changePassword.setOnClickListener {
|
||||||
when (isChecked) {
|
showOldPasswordDialog()
|
||||||
true -> {
|
|
||||||
binding.etPassword.isEnabled = true
|
|
||||||
binding.etConfirmPassword.isEnabled = true
|
|
||||||
Toast.makeText(this, getString(R.string.operation_password_enabled), Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
false -> {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
try {
|
|
||||||
val response = RetrofitNetwork.getNetworkService().updateUserInfo(UpdateUserInfo(optionPassword = ""))
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
if (response.code == 200) {
|
|
||||||
binding.etPassword.isEnabled = false
|
|
||||||
binding.etConfirmPassword.isEnabled = false
|
|
||||||
SPUtils.getInstance().remove("operation_password")
|
|
||||||
Toast.makeText(this@OperationPasswordActivity, getString(R.string.operation_password_disabled), Toast.LENGTH_SHORT).show()
|
|
||||||
finish()
|
|
||||||
} else {
|
|
||||||
binding.swOperationPassword.isChecked = true
|
|
||||||
Toast.makeText(this@OperationPasswordActivity, response.msg ?: "操作失败", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
binding.swOperationPassword.isChecked = true
|
|
||||||
Toast.makeText(this@OperationPasswordActivity, getString(R.string.network_error), Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.etPassword.addTextChangedListener(object : TextWatcher {
|
binding.swOperationPassword.setOnCheckedChangeListener { _, isChecked ->
|
||||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
if (!isLoading) {
|
||||||
|
updateOptionStatus(isChecked)
|
||||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
|
||||||
|
|
||||||
override fun afterTextChanged(s: Editable?) {
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.etConfirmPassword.addTextChangedListener(object : TextWatcher {
|
private fun getUserInfo() {
|
||||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
isLoading = true
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().getUserInfo()
|
||||||
override fun afterTextChanged(s: Editable?) {
|
withContext(Dispatchers.Main) {
|
||||||
}
|
isLoading = false
|
||||||
})
|
if (response.code == 200) {
|
||||||
|
response.data?.optionStatus?.let { status ->
|
||||||
binding.btnConfirmReset.setOnClickListener {
|
binding.swOperationPassword.isChecked = status == "0"
|
||||||
val password = binding.etPassword.text.toString()
|
|
||||||
val confirmPassword = binding.etConfirmPassword.text.toString()
|
|
||||||
|
|
||||||
if (password.isEmpty()) {
|
|
||||||
Toast.makeText(this, getString(R.string.password_cannot_empty), Toast.LENGTH_SHORT).show()
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password.length != 6) {
|
|
||||||
Toast.makeText(this, getString(R.string.password_must_be_6_digits), Toast.LENGTH_SHORT).show()
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
|
|
||||||
if (confirmPassword.isEmpty()) {
|
|
||||||
Toast.makeText(this, getString(R.string.please_confirm_password), Toast.LENGTH_SHORT).show()
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password != confirmPassword) {
|
|
||||||
Toast.makeText(this, getString(R.string.password_mismatch), Toast.LENGTH_SHORT).show()
|
|
||||||
return@setOnClickListener
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.btnConfirmReset.isEnabled = false
|
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
try {
|
|
||||||
val response = RetrofitNetwork.getNetworkService().updateUserInfo(UpdateUserInfo(optionPassword = password))
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
binding.btnConfirmReset.isEnabled = true
|
|
||||||
if (response.code == 200) {
|
|
||||||
SPUtils.getInstance().put("operation_password", password)
|
|
||||||
Toast.makeText(this@OperationPasswordActivity, getString(R.string.operation_success), Toast.LENGTH_SHORT).show()
|
|
||||||
finish()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(this@OperationPasswordActivity, response.msg ?: "操作失败", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this@OperationPasswordActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
}
|
||||||
withContext(Dispatchers.Main) {
|
} catch (e: Exception) {
|
||||||
binding.btnConfirmReset.isEnabled = true
|
withContext(Dispatchers.Main) {
|
||||||
Toast.makeText(this@OperationPasswordActivity, getString(R.string.network_error), Toast.LENGTH_SHORT).show()
|
isLoading = false
|
||||||
}
|
Toast.makeText(this@OperationPasswordActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateOptionStatus(isChecked: Boolean) {
|
||||||
|
isLoading = true
|
||||||
|
val status = if (isChecked) "0" else "1"
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.updateUserInfo(UpdateUserInfo(optionStatus = status))
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
if (response.code != 200) {
|
||||||
|
binding.swOperationPassword.isChecked = !isChecked
|
||||||
|
Toast.makeText(this@OperationPasswordActivity, R.string.update_failed, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
binding.swOperationPassword.isChecked = !isChecked
|
||||||
|
Toast.makeText(this@OperationPasswordActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showOldPasswordDialog() {
|
||||||
|
val dialog = PasswordInputDialog(this)
|
||||||
|
dialog.setTitle(getString(R.string.input_op_pwd))
|
||||||
|
dialog.setOnConfirmListener { password ->
|
||||||
|
verifyOldPassword(password, dialog)
|
||||||
|
}
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun verifyOldPassword(password: String, dialog: PasswordInputDialog) {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.verifyOptionPassword(VerifyOptionPasswordRequest(password))
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200) {
|
||||||
|
dialog.dismiss()
|
||||||
|
showNewPasswordDialog()
|
||||||
|
} else {
|
||||||
|
dialog.showError(getString(R.string.password_error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
dialog.showError(getString(R.string.network_error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showNewPasswordDialog() {
|
||||||
|
val dialog = PasswordInputDialog(this)
|
||||||
|
dialog.setTitle(getString(R.string.input_new_op_pwd))
|
||||||
|
dialog.setOnConfirmListener { newPassword ->
|
||||||
|
updatePassword(newPassword, dialog)
|
||||||
|
}
|
||||||
|
dialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updatePassword(newPassword: String, dialog: PasswordInputDialog) {
|
||||||
|
dialog.dismiss()
|
||||||
|
val loadingDialog = LoadingDialog(this)
|
||||||
|
loadingDialog.show()
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.updateUserInfo(UpdateUserInfo(optionPassword = newPassword))
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200) {
|
||||||
|
Toast.makeText(
|
||||||
|
this@OperationPasswordActivity,
|
||||||
|
R.string.password_update_success,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
finish()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
this@OperationPasswordActivity,
|
||||||
|
R.string.password_update_failed,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
Toast.makeText(
|
||||||
|
this@OperationPasswordActivity,
|
||||||
|
R.string.network_error,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showSuccessDialog() {
|
||||||
|
val config = CustomDialogFragment.Config(
|
||||||
|
title = getString(R.string.tip),
|
||||||
|
message = getString(R.string.password_update_success),
|
||||||
|
positiveText = getString(R.string.confirm),
|
||||||
|
negativeText = null
|
||||||
|
)
|
||||||
|
showDefenseDialog(config, onPositiveClick = {
|
||||||
|
finish()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,23 +2,13 @@ package com.example.defenseapplication.personal
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.R
|
|
||||||
import com.example.defenseapplication.bean.VerifyOptionPasswordRequest
|
|
||||||
import com.example.defenseapplication.databinding.PasswordManagementActivityBinding
|
import com.example.defenseapplication.databinding.PasswordManagementActivityBinding
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
//密码管理
|
//密码管理
|
||||||
class PasswordManagementActivity : AppCompatActivity() {
|
class PasswordManagementActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var binding: PasswordManagementActivityBinding
|
private lateinit var binding: PasswordManagementActivityBinding
|
||||||
private lateinit var passwordDialog: PasswordInputDialog
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = PasswordManagementActivityBinding.inflate(layoutInflater)
|
binding = PasswordManagementActivityBinding.inflate(layoutInflater)
|
||||||
@@ -34,50 +24,12 @@ class PasswordManagementActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.loginPassword.setOnClickListener {
|
binding.loginPassword.setOnClickListener {
|
||||||
startActivity(Intent(this, ChangePasswordActivity::class.java))
|
startActivity(Intent(this, LoginPasswordActivity::class.java))
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.operationPassword.setOnClickListener {
|
binding.operationPassword.setOnClickListener {
|
||||||
showPasswordDialog()
|
startActivity(Intent(this, OperationPasswordActivity::class.java))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showPasswordDialog() {
|
|
||||||
passwordDialog = PasswordInputDialog(this).apply {
|
|
||||||
setOnConfirmListener { inputPassword ->
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
try {
|
|
||||||
val response = RetrofitNetwork.getNetworkService().verifyOptionPassword(VerifyOptionPasswordRequest(inputPassword))
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
if (response.code == 200) {
|
|
||||||
startActivity(Intent(this@PasswordManagementActivity, OperationPasswordActivity::class.java))
|
|
||||||
dismiss()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(this@PasswordManagementActivity, response.msg ?: "校验失败", Toast.LENGTH_SHORT).show()
|
|
||||||
showError(getString(R.string.password_error))
|
|
||||||
clearPassword()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
Toast.makeText(this@PasswordManagementActivity, "网络请求失败", Toast.LENGTH_SHORT).show()
|
|
||||||
showError(getString(R.string.password_error))
|
|
||||||
clearPassword()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setOnDismissListener {
|
|
||||||
// Dialog dismissed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
passwordDialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
if (::passwordDialog.isInitialized) {
|
|
||||||
passwordDialog.dismiss()
|
|
||||||
}
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -22,6 +22,7 @@ class PasswordInputDialog(context: Context) : Dialog(context) {
|
|||||||
private lateinit var binding: DialogPasswordInputBinding
|
private lateinit var binding: DialogPasswordInputBinding
|
||||||
private var onConfirmListener: ((String) -> Unit)? = null
|
private var onConfirmListener: ((String) -> Unit)? = null
|
||||||
private var onDismissListener: (() -> Unit)? = null
|
private var onDismissListener: (() -> Unit)? = null
|
||||||
|
private var customTitle: String? = null
|
||||||
|
|
||||||
// 6个密码输入框数组
|
// 6个密码输入框数组
|
||||||
private lateinit var passwordEditTexts: Array<EditText>
|
private lateinit var passwordEditTexts: Array<EditText>
|
||||||
@@ -61,6 +62,11 @@ class PasswordInputDialog(context: Context) : Dialog(context) {
|
|||||||
|
|
||||||
setupPasswordInput()
|
setupPasswordInput()
|
||||||
|
|
||||||
|
// 设置标题(如果通过 setTitle 设置了自定义标题)
|
||||||
|
customTitle?.let {
|
||||||
|
binding.tvTitle.text = it
|
||||||
|
}
|
||||||
|
|
||||||
binding.ivClose.setOnClickListener {
|
binding.ivClose.setOnClickListener {
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
@@ -239,6 +245,14 @@ class PasswordInputDialog(context: Context) : Dialog(context) {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setTitle(title: String): PasswordInputDialog {
|
||||||
|
this.customTitle = title
|
||||||
|
if (::binding.isInitialized) {
|
||||||
|
binding.tvTitle.text = title
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
fun setOnDismissListener(listener: () -> Unit): PasswordInputDialog {
|
fun setOnDismissListener(listener: () -> Unit): PasswordInputDialog {
|
||||||
this.onDismissListener = listener
|
this.onDismissListener = listener
|
||||||
return this
|
return this
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
android:background="@color/white"
|
||||||
tools:context=".personal.LoginPasswordActivity">
|
tools:context=".personal.LoginPasswordActivity">
|
||||||
|
|
||||||
<!-- 标题栏 -->
|
<!-- 标题栏 -->
|
||||||
@@ -28,7 +29,6 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/password_management"
|
android:text="@string/password_management"
|
||||||
android:textColor="@color/black"
|
|
||||||
android:textSize="16dp"
|
android:textSize="16dp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -36,7 +36,6 @@
|
|||||||
android:id="@+id/change_password"
|
android:id="@+id/change_password"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:background="@color/white"
|
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingHorizontal="16dp">
|
android:paddingHorizontal="16dp">
|
||||||
@@ -45,7 +44,6 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/change_password"
|
android:text="@string/change_password"
|
||||||
android:textColor="@color/black"
|
|
||||||
android:textSize="16dp" />
|
android:textSize="16dp" />
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
@@ -58,7 +56,6 @@
|
|||||||
android:id="@+id/retrieve_password"
|
android:id="@+id/retrieve_password"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:background="@color/white"
|
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingHorizontal="16dp">
|
android:paddingHorizontal="16dp">
|
||||||
@@ -67,7 +64,6 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/retrieve_password"
|
android:text="@string/retrieve_password"
|
||||||
android:textColor="@color/black"
|
|
||||||
android:textSize="16dp" />
|
android:textSize="16dp" />
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:background="@color/message_bg"
|
android:background="@color/white"
|
||||||
tools:context=".personal.OperationPasswordActivity">
|
tools:context=".personal.OperationPasswordActivity">
|
||||||
|
|
||||||
<!-- 标题栏 -->
|
<!-- 标题栏 -->
|
||||||
@@ -44,8 +44,8 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/operation_password_switch"
|
android:text="@string/operation_password_switch"
|
||||||
android:textSize="14dp"/>
|
android:textSize="16dp" />
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/swOperationPassword"
|
android:id="@+id/swOperationPassword"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -57,65 +57,29 @@
|
|||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<!-- 分割线 -->
|
<LinearLayout
|
||||||
<View
|
android:id="@+id/change_password"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1px"
|
android:layout_height="60dp"
|
||||||
android:background="@color/gray_divider"/>
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
<!-- 内容区域 -->
|
<TextView
|
||||||
<ScrollView
|
android:layout_width="0dp"
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:layout_weight="1"
|
||||||
|
android:text="@string/change_password"
|
||||||
|
android:textSize="16dp" />
|
||||||
|
|
||||||
<!-- 密码输入框 -->
|
<ImageView
|
||||||
<EditText
|
android:layout_width="24dp"
|
||||||
android:id="@+id/etPassword"
|
android:layout_height="24dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_marginStart="12dp"
|
||||||
android:layout_height="56dp"
|
android:src="@drawable/right_back" />
|
||||||
android:background="@drawable/textinput_white_bg"
|
|
||||||
android:hint="@string/hint_operation_password"
|
|
||||||
android:inputType="numberPassword"
|
|
||||||
android:maxLength="6"
|
|
||||||
android:paddingHorizontal="16dp"
|
|
||||||
android:textColor="@color/black"
|
|
||||||
android:textColorHint="@color/gray"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
|
|
||||||
<!-- 确认密码输入框 -->
|
</LinearLayout>
|
||||||
<EditText
|
|
||||||
android:id="@+id/etConfirmPassword"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:background="@drawable/textinput_white_bg"
|
|
||||||
android:hint="@string/hint_confirm_password"
|
|
||||||
android:inputType="numberPassword"
|
|
||||||
android:maxLength="6"
|
|
||||||
android:paddingHorizontal="16dp"
|
|
||||||
android:textColor="@color/black"
|
|
||||||
android:textColorHint="@color/gray"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
|
|
||||||
<!-- 确定重设密码按钮 -->
|
|
||||||
<android.widget.Button
|
|
||||||
android:id="@+id/btnConfirmReset"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:layout_marginTop="32dp"
|
|
||||||
android:background="@drawable/rounded_blue_bg"
|
|
||||||
android:text="@string/confirm_reset_password_btn"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="16sp" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -324,6 +324,7 @@
|
|||||||
<string name="collect_face">采集人脸</string>
|
<string name="collect_face">采集人脸</string>
|
||||||
<string name="login_password">登录密码</string>
|
<string name="login_password">登录密码</string>
|
||||||
<string name="retrieve_password">找回密码</string>
|
<string name="retrieve_password">找回密码</string>
|
||||||
|
<string name="input_new_op_pwd">请输入新操作密码</string>|
|
||||||
<string name="operation_password">操作密码</string>
|
<string name="operation_password">操作密码</string>
|
||||||
<string name="enter_phone_number">请输入手机号</string>
|
<string name="enter_phone_number">请输入手机号</string>
|
||||||
<string name="enter_verification_code">请输入验证码</string>
|
<string name="enter_verification_code">请输入验证码</string>
|
||||||
@@ -440,6 +441,7 @@
|
|||||||
<string name="regenerate">重新生成</string>
|
<string name="regenerate">重新生成</string>
|
||||||
<string name="device_no">设备编号</string>
|
<string name="device_no">设备编号</string>
|
||||||
<string name="fw_version">固件版本</string>
|
<string name="fw_version">固件版本</string>
|
||||||
|
<string name="generate_invite_code">生成邀请码</string>
|
||||||
|
|
||||||
<!-- WiFi管理 -->
|
<!-- WiFi管理 -->
|
||||||
<string name="not_set">未设置</string>
|
<string name="not_set">未设置</string>
|
||||||
@@ -475,4 +477,15 @@
|
|||||||
<string name="max_add_11_users">最多添加11个用户</string>
|
<string name="max_add_11_users">最多添加11个用户</string>
|
||||||
<string name="linked_user_phone_label">手机号码:%s</string>
|
<string name="linked_user_phone_label">手机号码:%s</string>
|
||||||
<string name="linked_user_idcard_label">身份证号:%s</string>
|
<string name="linked_user_idcard_label">身份证号:%s</string>
|
||||||
|
<string name="direction_up">向上移动</string>
|
||||||
|
<string name="direction_down">向下移动</string>
|
||||||
|
<string name="direction_left">向左移动</string>
|
||||||
|
<string name="direction_right">向右移动</string>
|
||||||
|
|
||||||
|
<!-- 操作密码 -->
|
||||||
|
<string name="please_enable_operation_password_first">请先开启操作密码</string>
|
||||||
|
<string name="disable_operation_password_tip">确定要关闭操作密码吗?</string>
|
||||||
|
<string name="verify_failed">验证失败</string>
|
||||||
|
<string name="password_update_success">密码修改成功</string>
|
||||||
|
<string name="password_update_failed">密码修改失败</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -232,6 +232,7 @@
|
|||||||
<string name="use_smart_defense_app">Scan code to join via smart defense management APP</string>
|
<string name="use_smart_defense_app">Scan code to join via smart defense management APP</string>
|
||||||
<string name="cancel_invite">Cancel Invitation</string>
|
<string name="cancel_invite">Cancel Invitation</string>
|
||||||
<string name="regenerate">Regenerate</string>
|
<string name="regenerate">Regenerate</string>
|
||||||
|
<string name="generate_invite_code">Generate Invite Code</string>
|
||||||
|
|
||||||
<!-- Dialog -->
|
<!-- Dialog -->
|
||||||
<string name="tip">Tip</string>
|
<string name="tip">Tip</string>
|
||||||
@@ -308,6 +309,7 @@
|
|||||||
<string name="face_in_circle">Please align your face within the circular area</string>
|
<string name="face_in_circle">Please align your face within the circular area</string>
|
||||||
<string name="collect_face">Collect Face</string>
|
<string name="collect_face">Collect Face</string>
|
||||||
<string name="login_password">Login Password</string>
|
<string name="login_password">Login Password</string>
|
||||||
|
<string name="input_new_op_pwd">Enter new operation password</string>
|
||||||
<string name="enter_old_password">Enter old password</string>
|
<string name="enter_old_password">Enter old password</string>
|
||||||
<string name="confirm_reset_password">Confirm Reset Password</string>
|
<string name="confirm_reset_password">Confirm Reset Password</string>
|
||||||
<string name="retrieve_password">Retrieve Password</string>
|
<string name="retrieve_password">Retrieve Password</string>
|
||||||
@@ -485,4 +487,12 @@
|
|||||||
<string name="direction_down">Move Down</string>
|
<string name="direction_down">Move Down</string>
|
||||||
<string name="direction_left">Move Left</string>
|
<string name="direction_left">Move Left</string>
|
||||||
<string name="direction_right">Move Right</string>
|
<string name="direction_right">Move Right</string>
|
||||||
|
|
||||||
|
<!-- Operation Password -->
|
||||||
|
<string name="please_enable_operation_password_first">Please enable operation password first</string>
|
||||||
|
<string name="disable_operation_password_tip">Are you sure you want to disable operation password?</string>
|
||||||
|
<string name="verify_failed">Verification failed</string>
|
||||||
|
<string name="password_update_success">Password updated successfully</string>
|
||||||
|
<string name="password_update_failed">Failed to update password</string>
|
||||||
|
<string name="update_failed">Update failed</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user