操作密码弹窗修改2

This commit is contained in:
2026-06-02 16:45:31 +08:00
parent a1b9acb2a6
commit 5822e562de
9 changed files with 261 additions and 314 deletions

View File

@@ -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" />

View File

@@ -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() {

View File

@@ -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()
})
}
} }

View File

@@ -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()
}
} }

View File

@@ -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

View File

@@ -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"

View File

@@ -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,7 +44,7 @@
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"
@@ -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>

View File

@@ -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>

View File

@@ -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>