From 80837e39bf621baa1cfcbb4fa5235fb8920eb005 Mon Sep 17 00:00:00 2001 From: maxinyu Date: Wed, 13 May 2026 10:27:46 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=9F=E6=88=90=E4=BA=8C=E7=BB=B4=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 3 + .../adapter/LinkedUserAdapter.kt | 5 +- .../home/PersonalFragment.kt | 5 +- .../liveVideo/LinkedUserActivity.kt | 38 +++- .../liveVideo/SettingsActivity.kt | 4 +- .../personal/InvitationCodeActivity.kt | 191 ++++++++++++++++++ .../view/FamilySwitchDialog.kt | 2 +- app/src/main/res/drawable/add_img.png | Bin 0 -> 1303 bytes .../res/drawable/bg_radio_button_selector.xml | 21 ++ .../main/res/drawable/bg_white_rounded.xml | 6 + app/src/main/res/drawable/logo.png | Bin 0 -> 3332 bytes .../main/res/drawable/text_color_selector.xml | 5 + app/src/main/res/drawable/vx.png | Bin 0 -> 6736 bytes .../main/res/layout/dialog_expire_time.xml | 72 +++++++ .../res/layout/invitation_code_activity.xml | 172 ++++++++++++++++ app/src/main/res/layout/item_linked_user.xml | 1 + .../main/res/layout/linked_user_activity.xml | 12 +- .../res/layout/strike_position_activity.xml | 2 +- app/src/main/res/values-zh/strings.xml | 12 ++ app/src/main/res/values/strings.xml | 18 +- app/src/main/res/values/themes.xml | 7 + 21 files changed, 560 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/com/example/defenseapplication/personal/InvitationCodeActivity.kt create mode 100644 app/src/main/res/drawable/add_img.png create mode 100644 app/src/main/res/drawable/bg_radio_button_selector.xml create mode 100644 app/src/main/res/drawable/bg_white_rounded.xml create mode 100644 app/src/main/res/drawable/logo.png create mode 100644 app/src/main/res/drawable/text_color_selector.xml create mode 100644 app/src/main/res/drawable/vx.png create mode 100644 app/src/main/res/layout/dialog_expire_time.xml create mode 100644 app/src/main/res/layout/invitation_code_activity.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2051a5d..e80cc69 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,6 +25,9 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.DefenseApplication"> + diff --git a/app/src/main/java/com/example/defenseapplication/adapter/LinkedUserAdapter.kt b/app/src/main/java/com/example/defenseapplication/adapter/LinkedUserAdapter.kt index 3820287..49d3e03 100644 --- a/app/src/main/java/com/example/defenseapplication/adapter/LinkedUserAdapter.kt +++ b/app/src/main/java/com/example/defenseapplication/adapter/LinkedUserAdapter.kt @@ -14,6 +14,7 @@ data class LinkedUser( ) class LinkedUserAdapter( + private val deleteText: String, private val onItemClick: (LinkedUser, Int) -> Unit, private val onDeleteClick: (LinkedUser, Int) -> Unit ) : RecyclerView.Adapter() { @@ -43,6 +44,7 @@ class LinkedUserAdapter( } override fun onBindViewHolder(holder: LinkedUserViewHolder, position: Int) { + holder.bind(items[position], position) } @@ -58,7 +60,8 @@ class LinkedUserAdapter( binding.tvPhone.text = "手机号码:${item.phone}" binding.tvIdCard.text = "身份证号:${item.idCard}" binding.tvTime.text = item.time - + //设置删除按钮的文字 + binding.tvDeleteAction.text = deleteText binding.llContent.setOnClickListener { onItemClick(item, position) } 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 a74256a..78a85d7 100644 --- a/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt +++ b/app/src/main/java/com/example/defenseapplication/home/PersonalFragment.kt @@ -50,10 +50,13 @@ class PersonalFragment : Fragment() { binding.itemSwitchFamily.setOnClickListener { showFamilySwitchDialog() } + //用户管理点击事件跳转关联用户页面 binding.itemUserManage.setOnClickListener { - val intent= Intent(requireContext(), LinkedUserActivity::class.java) + val intent = Intent(requireContext(), LinkedUserActivity::class.java) + intent.putExtra(LinkedUserActivity.EXTRA_MODE, LinkedUserActivity.MODE_PERSONAL) startActivity(intent) } + // 密码管理点击事件 binding.itemPwdManage.setOnClickListener { val intent= Intent(requireContext(), PasswordManagementActivity::class.java) startActivity(intent) 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 8d4387f..ae260ac 100644 --- a/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt @@ -2,6 +2,7 @@ package com.example.defenseapplication.liveVideo import android.content.Intent import android.os.Bundle +import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager @@ -18,10 +19,14 @@ class LinkedUserActivity : AppCompatActivity() { private lateinit var binding: LinkedUserActivityBinding private lateinit var adapter: LinkedUserAdapter private val userList = mutableListOf() + private var mode: Int = MODE_SETTINGS companion object { const val REQUEST_CODE_SEARCH = 1001 const val EXTRA_SEARCH_RESULT = "search_result" + const val EXTRA_MODE = "extra_mode" + const val MODE_SETTINGS = 0 + const val MODE_PERSONAL = 1 } override fun onCreate(savedInstanceState: Bundle?) { @@ -29,6 +34,8 @@ class LinkedUserActivity : AppCompatActivity() { binding = LinkedUserActivityBinding.inflate(layoutInflater) setContentView(binding.root) + mode = intent.getIntExtra(EXTRA_MODE, MODE_SETTINGS) + ImmersionBar.with(this) .statusBarDarkFont(true) .titleBar(binding.topBar) @@ -37,10 +44,13 @@ class LinkedUserActivity : AppCompatActivity() { initView() initData() initListener() + setupModeUI() } private fun initView() { + val deleteText = if (mode == MODE_SETTINGS) getString(R.string.unlink) else getString(R.string.delete) adapter = LinkedUserAdapter( + deleteText = deleteText, onItemClick = { user, position -> val intent = Intent(this, UserDetailsActivity::class.java).apply { putExtra("name", user.name) @@ -131,11 +141,16 @@ class LinkedUserActivity : AppCompatActivity() { currentSwipeHeld = true val dialog = CustomDialogFragmentText() - dialog.setTitle("解除关联") - dialog.setMessage("确定要解除与 ${user.name} 的关联吗?") + if (mode == MODE_SETTINGS) { + dialog.setTitle(getString(R.string.tip)) + dialog.setMessage(getString(R.string.unlink_confirm_message)) + } else { + dialog.setTitle(getString(R.string.tip)) + dialog.setMessage(getString(R.string.confirm_delete_user)) + } dialog.setShowInput(false) - dialog.setPositiveText("确定") - dialog.setNegativeText("取消") + dialog.setPositiveText(getString(R.string.confirm)) + dialog.setNegativeText(getString(R.string.cancel)) dialog.setOnConfirmListener { userList.removeAt(position) adapter.removeItem(position) @@ -185,6 +200,21 @@ class LinkedUserActivity : AppCompatActivity() { val intent = Intent(this, AddLinkedUserActivity::class.java) startActivity(intent) } + + binding.fabAdd.setOnClickListener { + val intent = Intent(this, com.example.defenseapplication.personal.InvitationCodeActivity::class.java) + startActivity(intent) + } + } + + private fun setupModeUI() { + if (mode == MODE_SETTINGS) { + binding.btnAddLinkedUser.visibility = View.VISIBLE + binding.fabAdd.visibility = View.GONE + } else { + binding.btnAddLinkedUser.visibility = View.GONE + binding.fabAdd.visibility = View.VISIBLE + } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { diff --git a/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt b/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt index 00bd7b4..2d40e8f 100644 --- a/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt @@ -74,9 +74,11 @@ class SettingsActivity : BaseActivity() { val intent = Intent(this, DeviceInfoActivity::class.java) startActivity(intent) } + // 关联用户 binding.itemRelatedUsers.setOnClickListener { val intent = Intent(this, LinkedUserActivity::class.java) - startActivity( intent) + intent.putExtra(LinkedUserActivity.EXTRA_MODE, LinkedUserActivity.MODE_SETTINGS) + startActivity( intent) } binding.itemWifiManage.setOnClickListener { val intent = Intent(this, WiFiManagementActivity::class.java) diff --git a/app/src/main/java/com/example/defenseapplication/personal/InvitationCodeActivity.kt b/app/src/main/java/com/example/defenseapplication/personal/InvitationCodeActivity.kt new file mode 100644 index 0000000..08201ff --- /dev/null +++ b/app/src/main/java/com/example/defenseapplication/personal/InvitationCodeActivity.kt @@ -0,0 +1,191 @@ +package com.example.defenseapplication.personal + +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.os.Bundle + +import android.view.LayoutInflater +import android.view.View +import android.widget.RadioButton +import android.widget.RadioGroup +import androidx.appcompat.app.AppCompatActivity +import com.google.android.material.bottomsheet.BottomSheetDialog +import androidx.core.content.ContextCompat +import com.example.defenseapplication.R +import com.example.defenseapplication.databinding.DialogExpireTimeBinding +import com.example.defenseapplication.databinding.InvitationCodeActivityBinding +import com.google.zxing.BarcodeFormat +import com.google.zxing.EncodeHintType +import com.google.zxing.qrcode.QRCodeWriter +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel +import com.gyf.immersionbar.ImmersionBar +import java.util.Hashtable + +//邀请码页面 +class InvitationCodeActivity : AppCompatActivity() { + + private lateinit var binding: InvitationCodeActivityBinding + private var expireTimeInMillis: Long = 24 * 60 * 60 * 1000 // 默认24小时 + private var selectedExpireOption: Int = 0 // 0: 24h, 1: 7d,默认选中24h + + companion object { + const val EXPIRE_24H = 24 * 60 * 60 * 1000L + const val EXPIRE_7D = 7 * 24 * 60 * 60 * 1000L + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = InvitationCodeActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + + ImmersionBar.with(this) + .statusBarDarkFont(true) + .titleBar(binding.topBar) + .init() + + initListener() + // 默认显示时效为24h + binding.tvExpireTime.text = getString(R.string.expire_24h) + // 默认显示灰色占位区域,二维码不可见 + hideQrCode() + } + + private fun initListener() { + binding.ivBack.setOnClickListener { + finish() + } + + binding.llExpireTime.setOnClickListener { + showExpireTimeDialog() + } + + binding.llWechatShare.setOnClickListener { + // 微信分享功能 + shareToWeChat() + } + } + + private fun showExpireTimeDialog() { + val dialogBinding = DialogExpireTimeBinding.inflate(LayoutInflater.from(this)) + + val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog) + dialog.setContentView(dialogBinding.root) + + // 设置选中状态 + when (selectedExpireOption) { + 0 -> dialogBinding.rb24h.isChecked = true + 1 -> dialogBinding.rb7d.isChecked = true + } + + dialogBinding.radioGroup.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.rb24h -> selectedExpireOption = 0 + R.id.rb7d -> selectedExpireOption = 1 + } + } + + dialogBinding.tvCancel.setOnClickListener { + dialog.dismiss() + } + + dialogBinding.tvConfirm.setOnClickListener { + when (selectedExpireOption) { + 0 -> { + expireTimeInMillis = EXPIRE_24H + binding.tvExpireTime.text = getString(R.string.expire_24h) + } + 1 -> { + expireTimeInMillis = EXPIRE_7D + binding.tvExpireTime.text = getString(R.string.expire_7d) + } + } + // 选择后显示二维码并生成 + showQrCode() + generateQRCode() + dialog.dismiss() + } + + dialog.show() + } + + private fun hideQrCode() { + // 隐藏二维码,显示灰色占位区域 + binding.ivQrCode.visibility = View.GONE + binding.ivQrLogo.visibility = View.GONE + binding.vQrPlaceholder.visibility = View.VISIBLE + } + + private fun showQrCode() { + // 显示二维码,隐藏灰色占位区域 + binding.vQrPlaceholder.visibility = View.GONE + binding.ivQrCode.visibility = View.VISIBLE + binding.ivQrLogo.visibility = View.VISIBLE + } + + private fun generateQRCode() { + val content = generateInviteCode() + val qrBitmap = createQRCodeWithLogo(content, 400, 400) + binding.ivQrCode.setImageBitmap(qrBitmap) + } + + private fun generateInviteCode(): String { + // 生成包含邀请信息的JSON字符串 + val timestamp = System.currentTimeMillis() + val expireTime = timestamp + expireTimeInMillis + return "{\"type\":\"invite\",\"code\":\"INV${timestamp}\",\"expire\":$expireTime}" + } + + private fun createQRCodeWithLogo(content: String, width: Int, height: Int): Bitmap? { + return try { + val hints = Hashtable() + hints[EncodeHintType.CHARACTER_SET] = "UTF-8" + hints[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.H + + val writer = QRCodeWriter() + val bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints) + + val qrBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) + val canvas = Canvas(qrBitmap) + + // 绘制白色背景 + canvas.drawColor(Color.WHITE) + + // 绘制二维码 + val paint = Paint(Paint.ANTI_ALIAS_FLAG) + paint.color = Color.BLACK + + val cellWidth = width.toFloat() / bitMatrix.width + val cellHeight = height.toFloat() / bitMatrix.height + + for (x in 0 until bitMatrix.width) { + for (y in 0 until bitMatrix.height) { + if (bitMatrix.get(x, y)) { + canvas.drawRect( + x * cellWidth, + y * cellHeight, + (x + 1) * cellWidth, + (y + 1) * cellHeight, + paint + ) + } + } + } + + qrBitmap + } catch (e: Exception) { + e.printStackTrace() + null + } + } + + private fun shareToWeChat() { + // 微信分享实现 + // 这里需要集成微信SDK + } + + override fun onDestroy() { + super.onDestroy() + } +} diff --git a/app/src/main/java/com/example/defenseapplication/view/FamilySwitchDialog.kt b/app/src/main/java/com/example/defenseapplication/view/FamilySwitchDialog.kt index 0567437..ea92540 100644 --- a/app/src/main/java/com/example/defenseapplication/view/FamilySwitchDialog.kt +++ b/app/src/main/java/com/example/defenseapplication/view/FamilySwitchDialog.kt @@ -47,7 +47,7 @@ class FamilySwitchDialog( val familyList = listOf( FamilyItem("1", context.getString(R.string.my_family)), - FamilyItem("2", context.getString(R.string.zhangsan_family)) + FamilyItem("2", "张三的家庭") ) adapter = FamilySwitchAdapter(familyList) { familyItem -> diff --git a/app/src/main/res/drawable/add_img.png b/app/src/main/res/drawable/add_img.png new file mode 100644 index 0000000000000000000000000000000000000000..47134ad757225fc7a1cf81ef22384d22db60afdf GIT binary patch literal 1303 zcmV+y1?c*TP)2(yO`3^aZ!AS!6~skhK`h8_6jxH*>f*f+&|O9FQd;yvQ1nu9!3(v;%LUOz zq2RsLWF^5B%`QS^VL|C4_)n=9x;2yEv+tYvNz-PMGflS5g!5(2ob&xW?@Z>LX)PJW z=bP2Tb}@fCUCe)I7YhZuR9J`oYnSp(*9z!k40Ene{}?dAGEE-UkGWZcwOG?6exQKK(pS$|s!>L=S=fHHS=MCj zK?VB?NEP!hTcTEQWeyEWH0pWQWNk9^%WZ{CGSE_LS&0hu35y-oIBS!EEMYl&!tvHA zB})iWu!C+&frU)HKz0e>!()l{v66$k@;gDvLMF29oU^(HuzXFZ#^*|8-+%L696e6R zM7EtvY?lE0_UYFUyPvBK%0+6k9%B&H5x`wg$s57Uke%s7Qr0skWc`s7GLuXWnQdD* z8OiDm1p?A`;&t4nk!@0UrBZSyZ4yVAS8wP88OiD=as}XJN{fEU9~}2%n-$FDYzs&= zk}p8n$lh(3_+}be$;=vU0T_6WCvh^L+4BCdI2I>(kM$VYExTzw0X1mea7+#WR%Ex( z$;5I)U8+)(p(JaaVn4>W~bw`_r9Onf*cjoagRs z4B|S@K!Bcd`)1$YJ)98}`}An%m&v|KOc}Y&D10wH1p)qv;ZYmXjfZ`zA5;34)9|Y6}8n!^qcj+HBP2$F1uF?dQt>UW5qyCNUfJdJtpS z*|0>*FA~=e*s+o6&b^MA5GDEwHZtM=d}4;~;$l51Th2u5Yjn`u!MJ<_Sd-n7$4~tM z=*zIUwaaAZDum})K8qVY?m(NlEufmHe}aL|x;N%($Vz5nwgt#zPyd5W@Eix?U`o_E zGLzL6fL_IEo`teVyE4K;+n=?nw5?i|-(jJS5huu4aT;g+ut0#E!o#fPU4LTOBX`v! z-(Qp?<%`1Id)RzIJQ>OA4Ri!x!1;UgJsj3xxCZ$X2;yyjk#HawODieTv*>oKsy-A zmoqp2j^i{R!1*$YjqKgY&83!^n>8fYy;P!JXfqe!r@$^)$<8l2iTXWQXJ19}OE5Iw z!R&|tTx_|-9L!b8o?L9d4VZ-oUeN{kp?CqTX6HX}vhx|oYTk{t?u=-?1gZ;wy9WD@ ztB7lYzFgy+>!Z&whOx}yznJ-{qa1Gl00960fC(}o00006Nkl + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_white_rounded.xml b/app/src/main/res/drawable/bg_white_rounded.xml new file mode 100644 index 0000000..9cf9a8d --- /dev/null +++ b/app/src/main/res/drawable/bg_white_rounded.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/logo.png b/app/src/main/res/drawable/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c3977b7315ae7fb764489765f6019709967d5f59 GIT binary patch literal 3332 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 O0000 + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/vx.png b/app/src/main/res/drawable/vx.png new file mode 100644 index 0000000000000000000000000000000000000000..ebeb0656e6262bc5b7476f9fa4b474098577b0e2 GIT binary patch literal 6736 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 m|6vQ_?*IS*21!IgR09CT + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/invitation_code_activity.xml b/app/src/main/res/layout/invitation_code_activity.xml new file mode 100644 index 0000000..2ded2b2 --- /dev/null +++ b/app/src/main/res/layout/invitation_code_activity.xml @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_linked_user.xml b/app/src/main/res/layout/item_linked_user.xml index 1c23c42..75cbd8a 100644 --- a/app/src/main/res/layout/item_linked_user.xml +++ b/app/src/main/res/layout/item_linked_user.xml @@ -16,6 +16,7 @@ app:layout_constraintTop_toTopOf="parent"> - + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/strike_position_activity.xml b/app/src/main/res/layout/strike_position_activity.xml index 554d5be..3b42b14 100644 --- a/app/src/main/res/layout/strike_position_activity.xml +++ b/app/src/main/res/layout/strike_position_activity.xml @@ -85,7 +85,7 @@ android:layout_width="match_parent" android:layout_height="40dp" android:layout_margin="16dp" - android:layout_marginBottom="20dp" + android:layout_marginBottom="40dp" android:background="@drawable/rounded_blue_bg" android:text="@string/submit" android:textColor="@color/white" diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index d06a73f..bfa0d2c 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -398,4 +398,16 @@ 密码错误 未设置操作密码 确认重置 + 用户状态 + 联系人姓名 + 身份证号 + MAC地址 + 邀请码 + 邀请码有效期 + 二维码邀请 + 邀请二维码24小时内有效,仅可接受一次;手动撤销或重新生成将使原邀请二维码失效 + 其他邀请方式 + 微信好友 + 24小时 + 7天 \ 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 67c3766..608cd6d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -103,8 +103,6 @@ Add User Admin Member - Ordinary Member - Zhang San Family Phone Number Enter nickname @@ -244,10 +242,6 @@ Please scan the QR code on the device or manual - 用户状态 - 联系人姓名 - 身份证号 - MAC地址 Workshop Parents Home Smart Hanging Defense @@ -408,4 +402,16 @@ Please enter new password Please re-enter new password Confirm Reset + User Status + Contact Name + ID Card Number + MAC Address + Invite Code + Invite Code Expiry + QR Code Scan Invite + Invite QR code is valid for 24 hours; can only be accepted once; manual revocation or regenerating will invalidate the previous invite QR code + Other Invite Methods + WeChat Friend + 24h + 7d \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 9b74115..7cebb25 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -19,4 +19,11 @@ @anim/slide_up @anim/slide_down + + \ No newline at end of file