diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e5e7a63..98d8b11 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -25,6 +25,24 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DefenseApplication">
+
+
+
+
+
+
@@ -57,12 +75,7 @@
android:exported="false" />
-
-
-
-
-
+ android:exported="false" />
@@ -86,7 +99,13 @@
android:exported="false" />
+ android:exported="true">
+
+
+
+
+
+
diff --git a/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt b/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt
index 91cde94..a74256a 100644
--- a/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt
+++ b/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt
@@ -9,6 +9,8 @@ import android.view.ViewGroup
import com.bumptech.glide.Glide
import com.example.defenseapplication.R
import com.example.defenseapplication.databinding.PersonalFragmentBinding
+import com.example.defenseapplication.liveVideo.LinkedUserActivity
+import com.example.defenseapplication.personal.PasswordManagementActivity
import com.example.defenseapplication.personal.PersonalProfileActivity
import com.example.defenseapplication.utils.LanguageUtil
import com.example.defenseapplication.view.FamilySwitchDialog
@@ -48,6 +50,14 @@ class PersonalFragment : Fragment() {
binding.itemSwitchFamily.setOnClickListener {
showFamilySwitchDialog()
}
+ binding.itemUserManage.setOnClickListener {
+ val intent= Intent(requireContext(), LinkedUserActivity::class.java)
+ startActivity(intent)
+ }
+ binding.itemPwdManage.setOnClickListener {
+ val intent= Intent(requireContext(), PasswordManagementActivity::class.java)
+ startActivity(intent)
+ }
return binding.root
}
diff --git a/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt b/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt
index da1edc6..8d4387f 100644
--- a/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt
+++ b/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt
@@ -42,7 +42,13 @@ class LinkedUserActivity : AppCompatActivity() {
private fun initView() {
adapter = LinkedUserAdapter(
onItemClick = { user, position ->
-
+ val intent = Intent(this, UserDetailsActivity::class.java).apply {
+ putExtra("name", user.name)
+ putExtra("phone", user.phone)
+ putExtra("idCard", user.idCard)
+ putExtra("time", user.time)
+ }
+ startActivity(intent)
},
onDeleteClick = { user, position ->
showUnlinkDialog(user, position)
diff --git a/app/src/main/java/com/example/defenseapplication/liveVideo/UserDetailsActivity.kt b/app/src/main/java/com/example/defenseapplication/liveVideo/UserDetailsActivity.kt
new file mode 100644
index 0000000..0a47377
--- /dev/null
+++ b/app/src/main/java/com/example/defenseapplication/liveVideo/UserDetailsActivity.kt
@@ -0,0 +1,87 @@
+package com.example.defenseapplication.liveVideo
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import com.example.defenseapplication.R
+import com.example.defenseapplication.databinding.UserDetailsActivityBinding
+import com.example.defenseapplication.view.CustomDialogFragmentText
+import com.gyf.immersionbar.ImmersionBar
+
+//用户详情页面
+class UserDetailsActivity : AppCompatActivity() {
+ private lateinit var binding: UserDetailsActivityBinding
+
+ private lateinit var userName: String
+ private lateinit var phone: String
+ private lateinit var idCard: String
+ private lateinit var time: String
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = UserDetailsActivityBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ .titleBar(binding.topBar)
+ .init()
+
+ initData()
+ initView()
+ initListener()
+ }
+
+ private fun initData() {
+ userName = intent.getStringExtra("name") ?: ""
+ phone = intent.getStringExtra("phone") ?: ""
+ idCard = intent.getStringExtra("idCard") ?: ""
+ time = intent.getStringExtra("time") ?: ""
+ }
+
+ private fun initView() {
+ binding.tvContactName.text = userName
+ binding.tvPhone.text = phone
+ binding.tvIdCard.text = idCard
+ binding.tvMacAddress.text = "AA:BB:CC:DD:EE:FF"
+ }
+
+ private fun initListener() {
+ binding.ivBack.setOnClickListener {
+ finish()
+ }
+
+ binding.swUserStatus.setOnCheckedChangeListener { _, isChecked ->
+ when (isChecked) {
+ true -> {
+ // 打开开关业务逻辑
+ }
+ false -> {
+ // 关闭开关业务逻辑
+ }
+ }
+ }
+
+ binding.btnDelete.setOnClickListener {
+ showDeleteDialog()
+ }
+ }
+
+
+ private fun showDeleteDialog() {
+ val dialog = CustomDialogFragmentText()
+ dialog.setTitle(getString(R.string.tip))
+ dialog.setMessage(getString(R.string.confirm_delete_user))
+ dialog.setShowInput(false)
+ dialog.setPositiveText(getString(R.string.confirm))
+ dialog.setNegativeText(getString(R.string.cancel))
+ dialog.setOnConfirmListener {
+ finish()
+ // if(){
+ // ToastUtils.showSuccess(this, getString(R.string.wifi_connection_success)
+ // }else{
+ // ToastUtils.showError(this, getString(R.string.wifi_connection_failed))
+ // }
+ }
+ dialog.show(supportFragmentManager, "DeleteUserDialog")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/defenseapplication/personal/FaceManagementActivity.kt b/app/src/main/java/com/example/defenseapplication/personal/FaceManagementActivity.kt
new file mode 100644
index 0000000..dcf8533
--- /dev/null
+++ b/app/src/main/java/com/example/defenseapplication/personal/FaceManagementActivity.kt
@@ -0,0 +1,35 @@
+package com.example.defenseapplication.personal
+
+import android.content.Intent
+import android.os.Bundle
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+import com.example.defenseapplication.R
+import com.example.defenseapplication.databinding.FaceManagementActivityBinding
+import com.example.defenseapplication.databinding.LoginPasswordActivityBinding
+import com.example.defenseapplication.login.FaceVerificationActivity
+import com.gyf.immersionbar.ImmersionBar
+
+//人脸管理页面
+class FaceManagementActivity : AppCompatActivity() {
+ private lateinit var binding: FaceManagementActivityBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = FaceManagementActivityBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ .titleBar(binding.topBar)
+ .init()
+
+ binding.ivBack.setOnClickListener {
+ finish()
+ }
+ binding.faceManagement.setOnClickListener {
+ startActivity(Intent(this, FaceVerificationActivity::class.java))
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/defenseapplication/personal/LoginPasswordActivity.kt b/app/src/main/java/com/example/defenseapplication/personal/LoginPasswordActivity.kt
new file mode 100644
index 0000000..c3f7117
--- /dev/null
+++ b/app/src/main/java/com/example/defenseapplication/personal/LoginPasswordActivity.kt
@@ -0,0 +1,30 @@
+package com.example.defenseapplication.personal
+
+import android.os.Bundle
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+import com.example.defenseapplication.R
+import com.example.defenseapplication.databinding.LoginPasswordActivityBinding
+import com.example.defenseapplication.databinding.PasswordManagementActivityBinding
+import com.gyf.immersionbar.ImmersionBar
+
+//登录密码
+class LoginPasswordActivity : AppCompatActivity() {
+ private lateinit var binding: LoginPasswordActivityBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = LoginPasswordActivityBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ .titleBar(binding.topBar)
+ .init()
+
+ binding.ivBack.setOnClickListener {
+ finish()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/defenseapplication/personal/OperationPasswordActivity.kt b/app/src/main/java/com/example/defenseapplication/personal/OperationPasswordActivity.kt
new file mode 100644
index 0000000..4e11807
--- /dev/null
+++ b/app/src/main/java/com/example/defenseapplication/personal/OperationPasswordActivity.kt
@@ -0,0 +1,80 @@
+package com.example.defenseapplication.personal
+
+import android.os.Bundle
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.blankj.utilcode.util.SPUtils
+import com.example.defenseapplication.R
+import com.example.defenseapplication.databinding.OperationPasswordActivityBinding
+import com.gyf.immersionbar.ImmersionBar
+
+//操作密码
+class OperationPasswordActivity : AppCompatActivity() {
+
+ private lateinit var binding: OperationPasswordActivityBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = OperationPasswordActivityBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ .titleBar(binding.topBar)
+ .init()
+
+ initListener()
+ }
+
+ private fun initListener() {
+ binding.ivBack.setOnClickListener {
+ finish()
+ }
+
+ binding.swOperationPassword.setOnCheckedChangeListener { _, isChecked ->
+ when (isChecked) {
+ true -> {
+ binding.etPassword.isEnabled = true
+ binding.etConfirmPassword.isEnabled = true
+ binding.btnConfirmReset.isEnabled = true
+ Toast.makeText(this, getString(R.string.operation_password_enabled), Toast.LENGTH_SHORT).show()
+ }
+ false -> {
+ binding.etPassword.isEnabled = false
+ binding.etConfirmPassword.isEnabled = false
+ binding.btnConfirmReset.isEnabled = false
+ SPUtils.getInstance().remove("operation_password")
+ Toast.makeText(this, getString(R.string.operation_password_disabled), Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
+ binding.btnConfirmReset.setOnClickListener {
+ 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
+ }
+
+ SPUtils.getInstance().put("operation_password", password)
+ Toast.makeText(this, getString(R.string.operation_success), Toast.LENGTH_SHORT).show()
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/defenseapplication/personal/PasswordManagementActivity.kt b/app/src/main/java/com/example/defenseapplication/personal/PasswordManagementActivity.kt
new file mode 100644
index 0000000..a9ad9d2
--- /dev/null
+++ b/app/src/main/java/com/example/defenseapplication/personal/PasswordManagementActivity.kt
@@ -0,0 +1,75 @@
+package com.example.defenseapplication.personal
+
+import android.content.Intent
+import android.os.Bundle
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.example.defenseapplication.R
+import com.example.defenseapplication.databinding.PasswordManagementActivityBinding
+import com.example.defenseapplication.view.PasswordInputDialog
+import com.blankj.utilcode.util.SPUtils
+import com.gyf.immersionbar.ImmersionBar
+//密码管理
+class PasswordManagementActivity : AppCompatActivity() {
+
+ private lateinit var binding: PasswordManagementActivityBinding
+ private lateinit var passwordDialog: PasswordInputDialog
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = PasswordManagementActivityBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ .titleBar(binding.topBar)
+ .init()
+
+ binding.ivBack.setOnClickListener {
+ finish()
+ }
+
+ binding.loginPassword.setOnClickListener {
+ startActivity(Intent(this, LoginPasswordActivity::class.java))
+ }
+
+ binding.retrievePassword.setOnClickListener {
+ startActivity(Intent(this, RetrievePasswordActivity::class.java))
+ }
+
+ binding.operationPassword.setOnClickListener {
+ showPasswordDialog()
+ }
+ }
+
+ private fun showPasswordDialog() {
+ passwordDialog = PasswordInputDialog(this).apply {
+ setOnConfirmListener { inputPassword ->
+ val savedPassword = SPUtils.getInstance().getString("operation_password", "111111")
+ if (savedPassword.isEmpty()) {
+ Toast.makeText(this@PasswordManagementActivity, getString(R.string.operation_password_not_set), Toast.LENGTH_SHORT).show()
+ dismiss()
+ return@setOnConfirmListener
+ }
+ if (inputPassword == savedPassword) {
+ startActivity(Intent(this@PasswordManagementActivity, OperationPasswordActivity::class.java))
+ dismiss()
+ } else {
+ showError(getString(R.string.password_error))
+ clearPassword()
+ }
+ }
+ setOnDismissListener {
+ // Dialog dismissed
+ }
+ }
+ passwordDialog.show()
+ }
+
+ override fun onDestroy() {
+ if (::passwordDialog.isInitialized) {
+ passwordDialog.dismiss()
+ }
+ super.onDestroy()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/defenseapplication/personal/RetrievePasswordActivity.kt b/app/src/main/java/com/example/defenseapplication/personal/RetrievePasswordActivity.kt
new file mode 100644
index 0000000..a1a7029
--- /dev/null
+++ b/app/src/main/java/com/example/defenseapplication/personal/RetrievePasswordActivity.kt
@@ -0,0 +1,126 @@
+package com.example.defenseapplication.personal
+
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.example.defenseapplication.R
+import com.example.defenseapplication.databinding.RetrievePasswordActivityBinding
+import com.gyf.immersionbar.ImmersionBar
+
+//找回密码页面
+class RetrievePasswordActivity : AppCompatActivity() {
+
+ private lateinit var binding: RetrievePasswordActivityBinding
+ private var countDownTimer: CountDownTimer? = null
+ private var isCountingDown = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = RetrievePasswordActivityBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ ImmersionBar.with(this)
+ .statusBarDarkFont(true)
+ .titleBar(binding.topBar)
+ .init()
+
+ initListener()
+ }
+
+ private fun initListener() {
+ binding.ivBack.setOnClickListener {
+ finish()
+ }
+
+ binding.btnGetCode.setOnClickListener {
+ val phoneNumber = binding.etPhoneNumber.text.toString()
+
+ if (phoneNumber.isEmpty()) {
+ Toast.makeText(this, getString(R.string.enter_phone_number), Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ if (phoneNumber.length != 11) {
+ Toast.makeText(this, getString(R.string.phone_format_invalid), Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ startCountdown()
+ Toast.makeText(this, String.format(getString(R.string.code_sent_to), phoneNumber), Toast.LENGTH_SHORT).show()
+ }
+
+ binding.btnConfirmReset.setOnClickListener {
+ val phoneNumber = binding.etPhoneNumber.text.toString()
+ val verificationCode = binding.etVerificationCode.text.toString()
+ val newPassword = binding.etNewPassword.text.toString()
+ val confirmPassword = binding.etConfirmPassword.text.toString()
+
+ if (phoneNumber.isEmpty()) {
+ Toast.makeText(this, getString(R.string.enter_phone_number), Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ if (phoneNumber.length != 11) {
+ Toast.makeText(this, getString(R.string.phone_format_invalid), Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ if (verificationCode.isEmpty()) {
+ Toast.makeText(this, getString(R.string.enter_verification_code_pls), Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ if (verificationCode.length != 6) {
+ Toast.makeText(this, getString(R.string.verification_code_error), Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ if (newPassword.isEmpty()) {
+ Toast.makeText(this, getString(R.string.password_cannot_empty), Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ if (newPassword.length < 6 || newPassword.length > 20) {
+ Toast.makeText(this, getString(R.string.password_requirement), Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ if (confirmPassword.isEmpty()) {
+ Toast.makeText(this, getString(R.string.enter_password_again), Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ if (newPassword != confirmPassword) {
+ Toast.makeText(this, getString(R.string.password_mismatch), Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ Toast.makeText(this, getString(R.string.reset_success), Toast.LENGTH_SHORT).show()
+ finish()
+ }
+ }
+
+ private fun startCountdown() {
+ isCountingDown = true
+ binding.btnGetCode.isEnabled = false
+
+ countDownTimer = object : CountDownTimer(60000, 1000) {
+ override fun onTick(millisUntilFinished: Long) {
+ val seconds = millisUntilFinished / 1000
+ binding.btnGetCode.text = String.format(getString(R.string.countdown_retry), seconds)
+ }
+
+ override fun onFinish() {
+ isCountingDown = false
+ binding.btnGetCode.isEnabled = true
+ binding.btnGetCode.text = getString(R.string.get_verification_code)
+ }
+ }.start()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ countDownTimer?.cancel()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/defenseapplication/view/PasswordInputDialog.kt b/app/src/main/java/com/example/defenseapplication/view/PasswordInputDialog.kt
new file mode 100644
index 0000000..c6e6d22
--- /dev/null
+++ b/app/src/main/java/com/example/defenseapplication/view/PasswordInputDialog.kt
@@ -0,0 +1,127 @@
+package com.example.defenseapplication.view
+
+import android.app.Dialog
+import android.content.Context
+import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
+import android.view.Gravity
+import android.view.LayoutInflater
+import android.view.View
+import android.view.WindowManager
+import android.widget.EditText
+import com.example.defenseapplication.R
+import com.example.defenseapplication.databinding.DialogPasswordInputBinding
+
+class PasswordInputDialog(context: Context) : Dialog(context) {
+
+ private lateinit var binding: DialogPasswordInputBinding
+ private var onConfirmListener: ((String) -> Unit)? = null
+ private var onDismissListener: (() -> Unit)? = null
+
+ init {
+ initView()
+ }
+
+ private fun initView() {
+ binding = DialogPasswordInputBinding.inflate(LayoutInflater.from(context))
+ setContentView(binding.root)
+
+ window?.apply {
+ setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
+ val params = attributes
+ params.gravity = Gravity.CENTER
+ params.width = WindowManager.LayoutParams.MATCH_PARENT
+ params.height = WindowManager.LayoutParams.WRAP_CONTENT
+ params.horizontalMargin = 40f
+ attributes = params
+ }
+
+ setupPasswordInput()
+
+ binding.btnCancel.setOnClickListener {
+ dismiss()
+ }
+
+ binding.btnConfirm.setOnClickListener {
+ val password = getPassword()
+ if (password.length == 6) {
+ onConfirmListener?.invoke(password)
+ dismiss()
+ }
+ }
+ }
+
+ private fun setupPasswordInput() {
+ val editTexts = listOf(
+ binding.etPassword1,
+ binding.etPassword2,
+ binding.etPassword3,
+ binding.etPassword4,
+ binding.etPassword5,
+ binding.etPassword6
+ )
+
+ editTexts.forEachIndexed { index, editText ->
+ editText.setOnKeyListener { _, _, _ ->
+ if (editText.text.isNotEmpty()) {
+ if (index < editTexts.size - 1) {
+ editTexts[index + 1].requestFocus()
+ } else {
+ editText.clearFocus()
+ }
+ }
+ false
+ }
+
+ editText.setOnFocusChangeListener { v, hasFocus ->
+ if (hasFocus) {
+ (v as EditText).setSelection((v.text?.length ?: 0))
+ }
+ }
+ }
+ }
+
+ private fun getPassword(): String {
+ return binding.etPassword1.text.toString() +
+ binding.etPassword2.text.toString() +
+ binding.etPassword3.text.toString() +
+ binding.etPassword4.text.toString() +
+ binding.etPassword5.text.toString() +
+ binding.etPassword6.text.toString()
+ }
+
+ fun setOnConfirmListener(listener: (String) -> Unit): PasswordInputDialog {
+ this.onConfirmListener = listener
+ return this
+ }
+
+ fun setOnDismissListener(listener: () -> Unit): PasswordInputDialog {
+ this.onDismissListener = listener
+ return this
+ }
+
+ fun showError(message: String) {
+ binding.tvError.text = message
+ binding.tvError.visibility = View.VISIBLE
+ }
+
+ fun clearError() {
+ binding.tvError.visibility = View.GONE
+ binding.tvError.text = ""
+ }
+
+ fun clearPassword() {
+ binding.etPassword1.text?.clear()
+ binding.etPassword2.text?.clear()
+ binding.etPassword3.text?.clear()
+ binding.etPassword4.text?.clear()
+ binding.etPassword5.text?.clear()
+ binding.etPassword6.text?.clear()
+ binding.etPassword1.requestFocus()
+ }
+
+ override fun dismiss() {
+ super.dismiss()
+ onDismissListener?.invoke()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/btn_selector_cyan.xml b/app/src/main/res/drawable/btn_selector_cyan.xml
new file mode 100644
index 0000000..dd34181
--- /dev/null
+++ b/app/src/main/res/drawable/btn_selector_cyan.xml
@@ -0,0 +1,15 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/password_input_bg.xml b/app/src/main/res/drawable/password_input_bg.xml
new file mode 100644
index 0000000..ddae5b6
--- /dev/null
+++ b/app/src/main/res/drawable/password_input_bg.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_password_input.xml b/app/src/main/res/layout/dialog_password_input.xml
new file mode 100644
index 0000000..56ef5b7
--- /dev/null
+++ b/app/src/main/res/layout/dialog_password_input.xml
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/face_management_activity.xml b/app/src/main/res/layout/face_management_activity.xml
new file mode 100644
index 0000000..8aeef78
--- /dev/null
+++ b/app/src/main/res/layout/face_management_activity.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/login_password_activity.xml b/app/src/main/res/layout/login_password_activity.xml
new file mode 100644
index 0000000..babe93a
--- /dev/null
+++ b/app/src/main/res/layout/login_password_activity.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/operation_password_activity.xml b/app/src/main/res/layout/operation_password_activity.xml
new file mode 100644
index 0000000..22f5aa6
--- /dev/null
+++ b/app/src/main/res/layout/operation_password_activity.xml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/password_management_activity.xml b/app/src/main/res/layout/password_management_activity.xml
new file mode 100644
index 0000000..caf31bf
--- /dev/null
+++ b/app/src/main/res/layout/password_management_activity.xml
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/retrieve_password_activity.xml b/app/src/main/res/layout/retrieve_password_activity.xml
new file mode 100644
index 0000000..c55df2f
--- /dev/null
+++ b/app/src/main/res/layout/retrieve_password_activity.xml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_details_activity.xml b/app/src/main/res/layout/user_details_activity.xml
new file mode 100644
index 0000000..18f15f3
--- /dev/null
+++ b/app/src/main/res/layout/user_details_activity.xml
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
index bff8784..ce90154 100644
--- a/app/src/main/res/values-zh/strings.xml
+++ b/app/src/main/res/values-zh/strings.xml
@@ -174,6 +174,7 @@
中文
English
关联用户
+ 用户详情
搜索
搜索预设文案
添加关联用户
@@ -249,6 +250,7 @@
操作失败
网络不可用
请检查网络连接
+ 确定删除该用户吗?
识别模式
@@ -305,7 +307,9 @@
人脸采集
请将人脸放入圆形区域内
采集人脸
+ 登录密码
找回密码
+ 操作密码
请输入手机号
请输入验证码
发送验证码
@@ -375,4 +379,21 @@
修改手机号
手机号格式不正确
验证并绑定
+ 操作密码开关
+ 请输入6位数字密码
+ 请确认密码
+ 操作密码已开启
+ 操作密码已关闭
+ 密码必须为6位数字
+ 请确认密码
+ 确定重设密码
+ 获取验证码
+ 请输入手机号
+ 请输入验证码
+ 请输入新密码
+ 请再次输入新密码
+ 请输入旧密码
+ 密码错误
+ 未设置操作密码
+ 确认重置
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 7fcf1d7..c3b18d5 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -18,5 +18,6 @@
#F3F3F3
#111111
#E8F7F7
+ #E5E5E5
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3fee377..701ed3d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -166,6 +166,7 @@
Chinese
English
Linked user
+ User Details
search
Search preset text
Add linked user
@@ -224,6 +225,7 @@
Operation failed
Network unavailable
Please check your network connection
+ Are you sure to delete this user?
Recognition Mode
@@ -242,6 +244,10 @@
Please scan the QR code on the device or manual
+ 用户状态
+ 联系人姓名
+ 身份证号
+ MAC地址
Workshop
Parents Home
Smart Hanging Defense
@@ -290,7 +296,12 @@
Face Collection
Please align your face within the circular area
Collect Face
+ Login Password
+ Enter old password
+ Confirm Reset Password
Retrieve Password
+ Operation Password
+
Enter phone number
Enter verification code
Send Code
@@ -380,4 +391,19 @@
Verification code sent to %s
Login successful
Login successful
+ Operation Password Switch
+ Please enter a 6-digit numeric password
+ Please confirm your password
+ Operation password enabled
+ Operation password disabled
+ Password must be 6 digits
+ Please confirm your password
+ Password error
+ Operation password not set
+ Get Verification Code
+ Please enter your phone number
+ Please enter verification code
+ Please enter new password
+ Please re-enter new password
+ Confirm Reset
\ No newline at end of file