diff --git a/app/src/main/java/com/example/defenseapplication/MyApplication.kt b/app/src/main/java/com/example/defenseapplication/MyApplication.kt index a21c273..44bc787 100644 --- a/app/src/main/java/com/example/defenseapplication/MyApplication.kt +++ b/app/src/main/java/com/example/defenseapplication/MyApplication.kt @@ -6,6 +6,7 @@ import bean.LoginBean import com.blankj.utilcode.util.Utils import com.example.defenseapplication.bean.BaseInfo import com.example.defenseapplication.utils.ApiConfig +import com.example.defenseapplication.utils.LanguageHeaderManager import com.example.defenseapplication.utils.LanguageUtil import com.example.defenseapplication.utils.UserinfoUtil import com.google.gson.Gson diff --git a/app/src/main/java/com/example/defenseapplication/adapter/AddLinkedUserAdapter.kt b/app/src/main/java/com/example/defenseapplication/adapter/AddLinkedUserAdapter.kt index c13e848..4b6ec3e 100644 --- a/app/src/main/java/com/example/defenseapplication/adapter/AddLinkedUserAdapter.kt +++ b/app/src/main/java/com/example/defenseapplication/adapter/AddLinkedUserAdapter.kt @@ -1,25 +1,36 @@ package com.example.defenseapplication.adapter +import android.graphics.Color import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import com.example.defenseapplication.R import com.example.defenseapplication.databinding.ItemAddLinkedUserBinding -data class UserItem(val name: String, val phone: String) +data class UserItem(val name: String, val phone: String, val userId: String = "") class AddLinkedUserAdapter( private val data: List, private val selectedIds: MutableSet, - private val onItemClick: (String, Boolean) -> Unit + private val selectedUserIdMap: MutableMap, + private val onItemClick: (String, Boolean, String?) -> Unit ) : RecyclerView.Adapter() { inner class ViewHolder(val binding: ItemAddLinkedUserBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(item: UserItem) { binding.tvUserName.text = "${item.name}-${item.phone}" - binding.cbSelect.isChecked = selectedIds.contains(item.phone) - binding.cbSelect.setOnClickListener { - val isChecked = binding.cbSelect.isChecked - onItemClick(item.phone, isChecked) + val isChecked = selectedIds.contains(item.phone) + binding.cbSelect.isChecked = isChecked + binding.cbSelect.setOnCheckedChangeListener { _, checked -> + if (checked) { + binding.cbSelect.buttonTintList = android.content.res.ColorStateList.valueOf(Color.parseColor("#09C2BD")) + } else { + binding.cbSelect.buttonTintList = null + } + onItemClick(item.phone, checked, item.userId) + } + if (isChecked) { + binding.cbSelect.buttonTintList = android.content.res.ColorStateList.valueOf(Color.parseColor("#09C2BD")) } } } 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 129e74f..774ac16 100644 --- a/app/src/main/java/com/example/defenseapplication/adapter/LinkedUserAdapter.kt +++ b/app/src/main/java/com/example/defenseapplication/adapter/LinkedUserAdapter.kt @@ -56,10 +56,10 @@ class LinkedUserAdapter( ) : RecyclerView.ViewHolder(binding.root) { fun bind(item: LinkedUser, position: Int) { + binding.tvPhone.text ="手机号码:${item.phone}" + binding.tvIdCard.text ="身份证号:${item.idCard}" binding.llContent.translationX = 0f binding.tvUserName.text = item.name - binding.tvPhone.text = "手机号码:${item.phone}" - binding.tvIdCard.text = "身份证号:${item.idCard}" binding.tvTime.text = item.time //设置删除按钮的文字 binding.tvDeleteAction.text = deleteText diff --git a/app/src/main/java/com/example/defenseapplication/bean/AddDeviceUserRequest.kt b/app/src/main/java/com/example/defenseapplication/bean/AddDeviceUserRequest.kt new file mode 100644 index 0000000..029ca04 --- /dev/null +++ b/app/src/main/java/com/example/defenseapplication/bean/AddDeviceUserRequest.kt @@ -0,0 +1,8 @@ +package com.example.defenseapplication.bean + +data class AddDeviceUserRequest( + val deviceId: String, + val deviceNo: String? = null, + val deviceName: String? = null, + val userId: String +) \ No newline at end of file diff --git a/app/src/main/java/com/example/defenseapplication/bean/DeviceUserBean.kt b/app/src/main/java/com/example/defenseapplication/bean/DeviceUserBean.kt index 7514ff1..35b57ad 100644 --- a/app/src/main/java/com/example/defenseapplication/bean/DeviceUserBean.kt +++ b/app/src/main/java/com/example/defenseapplication/bean/DeviceUserBean.kt @@ -1,9 +1,9 @@ package com.example.defenseapplication.bean data class DeviceUserBean( - val createDept: String? = null, //创建部门 - val createBy: String? = null, //创建人 - val updateBy: String? = null, //更新者 + val createDept: Int ? = null, //创建部门 + val createBy: Int? = null, //创建人 + val updateBy: Int? = null, //更新者 val updateTime: String? = null, //更新时间 val paramskeykey: String? = null, val deviceId: String? = null, // 设备 ID diff --git a/app/src/main/java/com/example/defenseapplication/bean/FamilyMembersBean.kt b/app/src/main/java/com/example/defenseapplication/bean/FamilyMembersBean.kt new file mode 100644 index 0000000..20e7e04 --- /dev/null +++ b/app/src/main/java/com/example/defenseapplication/bean/FamilyMembersBean.kt @@ -0,0 +1,20 @@ +package com.example.defenseapplication.bean + +data class FamilyMembersBean( + val id: String? = null, // ID + val parentId: String? = null, // 家长 id + val parentName: String? = null, // 家长昵称 + val userId: String? = null, // 成员 id + val nickName: String? = null, // 成员昵称 + val idCard: String? = null, // 身份证号 + val phonenumber: String? = null, // 手机号码 + val status: String? = null, // 账号状态(0 正常 1 停用) + val role: String? = null, // 角色 + val createTime: String? = null, // 创建时间 + val inviteCode: String? = null, // 邀请码 + val createDept: Int? = null, // 创建部门 + val createBy: Int? = null, // 创建人 + val updateBy: Int? = null, // 更新者 + val updateTime: String? = null, // 更新时间 + val paramskeykey: String? = null +) \ No newline at end of file diff --git a/app/src/main/java/com/example/defenseapplication/liveVideo/AddLinkedUserActivity.kt b/app/src/main/java/com/example/defenseapplication/liveVideo/AddLinkedUserActivity.kt index 091b6ae..5ce64ce 100644 --- a/app/src/main/java/com/example/defenseapplication/liveVideo/AddLinkedUserActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/liveVideo/AddLinkedUserActivity.kt @@ -3,16 +3,27 @@ package com.example.defenseapplication.liveVideo import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import com.example.defenseapplication.R import com.example.defenseapplication.adapter.AddLinkedUserAdapter import com.example.defenseapplication.adapter.UserItem +import com.example.defenseapplication.bean.AddDeviceUserRequest +import com.example.defenseapplication.bean.FamilyMembersBean import com.example.defenseapplication.databinding.AddLinkedUserActivityBinding +import com.example.defenseapplication.utils.DeviceIdEvent +import com.example.defenseapplication.utils.DeviceUserUpdateEvent +import com.example.defenseapplication.utils.RetrofitNetwork import com.gyf.immersionbar.ImmersionBar -//添加关联用户 +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + class AddLinkedUserActivity : AppCompatActivity() { private lateinit var binding: AddLinkedUserActivityBinding private val selectedPhoneSet = mutableSetOf() + private val userItemList = mutableListOf() + private val selectedUserIdMap = mutableMapOf() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -26,36 +37,112 @@ class AddLinkedUserActivity : AppCompatActivity() { initRecyclerView() initListener() + fetchFamilyMembers() } private fun initRecyclerView() { - val mockData = listOf( - UserItem("王五", "13566666666"), - UserItem("赵六", "15733333333") - ) - binding.rvAddLinkedUser.layoutManager = LinearLayoutManager(this) binding.rvAddLinkedUser.adapter = - AddLinkedUserAdapter(mockData, selectedPhoneSet) { phone, isChecked -> + AddLinkedUserAdapter(userItemList, selectedPhoneSet, selectedUserIdMap) { phone, isChecked, userId -> if (isChecked) { selectedPhoneSet.add(phone) + userId?.let { selectedUserIdMap[phone] = it } } else { selectedPhoneSet.remove(phone) + selectedUserIdMap.remove(phone) } } } + private fun fetchFamilyMembers() { + lifecycleScope.launch { + try { + val response = RetrofitNetwork.getNetworkService().getFamilyMembers() + withContext(Dispatchers.Main) { + if (response.code == 200) { + if (response.data != null && response.data.isNotEmpty()) { + updateFamilyMemberList(response.data) + } else { + Toast.makeText(this@AddLinkedUserActivity, "暂无家庭成员数据", Toast.LENGTH_SHORT).show() + } + } else { + Toast.makeText(this@AddLinkedUserActivity, "请求失败: ${response.msg}", Toast.LENGTH_SHORT).show() + } + } + } catch (e: Exception) { + android.util.Log.e("AddLinkedUserActivity", "网络请求异常", e) + withContext(Dispatchers.Main) { + Toast.makeText(this@AddLinkedUserActivity, "网络请求失败: ${e.message}", Toast.LENGTH_SHORT).show() + } + } + } + } + + private fun updateFamilyMemberList(familyMembersList: List) { + userItemList.clear() + familyMembersList.forEach { member -> + userItemList.add( + UserItem( + name = member.nickName ?: member.parentName ?: "未知用户", + phone = member.phonenumber ?: "", + userId = member.userId ?: "" + ) + ) + } + binding.rvAddLinkedUser.adapter?.notifyDataSetChanged() + } + private fun initListener() { binding.btnAddLinkedUser.setOnClickListener { if (selectedPhoneSet.isEmpty()) { Toast.makeText(this, getString(R.string.please_select_at_least_one_user), Toast.LENGTH_SHORT).show() } else { - val message = getString(R.string.selected_users_voice, selectedPhoneSet.size) - Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + addDeviceUser() } } binding.ivBack.setOnClickListener { finish() } } + + private fun addDeviceUser() { + val deviceId = DeviceIdEvent.getDeviceId() + if (deviceId.isNullOrEmpty()) { + Toast.makeText(this, "设备ID为空", Toast.LENGTH_SHORT).show() + return + } + + lifecycleScope.launch { + var successCount = 0 + for ((phone, userId) in selectedUserIdMap) { + try { + val request = AddDeviceUserRequest( + deviceId = deviceId, + userId = userId + ) + val response = RetrofitNetwork.getNetworkService().addDeviceUser(request) + withContext(Dispatchers.Main) { + if (response.code == 200) { + successCount++ + } else { + Toast.makeText(this@AddLinkedUserActivity, "添加用户 $phone 失败: ${response.msg}", Toast.LENGTH_SHORT).show() + } + } + } catch (e: Exception) { + e.printStackTrace() + withContext(Dispatchers.Main) { + Toast.makeText(this@AddLinkedUserActivity, "添加用户 $phone 失败: 网络错误", Toast.LENGTH_SHORT).show() + } + } + } + + withContext(Dispatchers.Main) { + if (successCount > 0) { + Toast.makeText(this@AddLinkedUserActivity, "成功添加 $successCount 个用户", Toast.LENGTH_SHORT).show() + DeviceUserUpdateEvent.notifyUpdate() + finish() + } + } + } + } } \ No newline at end of file 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 2c9aa64..800e955 100644 --- a/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt @@ -15,8 +15,10 @@ import com.example.defenseapplication.adapter.LinkedUser import com.example.defenseapplication.adapter.LinkedUserAdapter import com.example.defenseapplication.bean.DeleteDeviceUserRequest import com.example.defenseapplication.bean.DeviceUserBean +import com.example.defenseapplication.bean.FamilyMembersBean import com.example.defenseapplication.databinding.LinkedUserActivityBinding import com.example.defenseapplication.utils.DeviceIdEvent +import com.example.defenseapplication.utils.DeviceUserUpdateEvent import com.example.defenseapplication.utils.RetrofitNetwork import com.example.defenseapplication.view.CustomDialogFragmentText import com.gyf.immersionbar.ImmersionBar @@ -55,6 +57,18 @@ class LinkedUserActivity : AppCompatActivity() { initData() initListener() setupModeUI() + DeviceUserUpdateEvent.addListener(deviceUserUpdateListener) + } + + private val deviceUserUpdateListener = object : DeviceUserUpdateEvent.DeviceUserUpdateListener { + override fun onDeviceUserUpdated() { + fetchUserList() + } + } + + override fun onDestroy() { + super.onDestroy() + DeviceUserUpdateEvent.removeListener(deviceUserUpdateListener) } private fun initView() { @@ -222,22 +236,29 @@ class LinkedUserActivity : AppCompatActivity() { } private fun initData() { - fetchDeviceUserList() + fetchUserList() } - private fun fetchDeviceUserList() { - val deviceId = DeviceIdEvent.getDeviceId() - if (deviceId.isNullOrEmpty()) { - Toast.makeText(this, "设备 ID 为空", Toast.LENGTH_SHORT).show() - return - } - + private fun fetchUserList() { lifecycleScope.launch { try { - val response = RetrofitNetwork.getNetworkService().getDeviceUserList(deviceId) + val response = if (mode == MODE_SETTINGS) { + val deviceId = DeviceIdEvent.getDeviceId() + if (deviceId.isNullOrEmpty()) { + Toast.makeText(this@LinkedUserActivity, "设备 ID 为空", Toast.LENGTH_SHORT).show() + return@launch + } + RetrofitNetwork.getNetworkService().getDeviceUserList(deviceId) + } else { + RetrofitNetwork.getNetworkService().getFamilyMembers() + } withContext(Dispatchers.Main) { if (response.code == 200 && response.data != null) { - updateDeviceUserList(response.data) + if (mode == MODE_SETTINGS) { + updateDeviceUserList(response.data as List) + } else { + updateFamilyMembersList(response.data as List) + } } else { Toast.makeText(this@LinkedUserActivity, response.msg, Toast.LENGTH_SHORT).show() } @@ -267,14 +288,29 @@ class LinkedUserActivity : AppCompatActivity() { adapter.submitList(userList) } + private fun updateFamilyMembersList(familyMembersList: List) { + userList.clear() + familyMembersList.forEach { member -> + userList.add( + LinkedUser( + userId = member.userId ?: "", + name = member.nickName ?: member.parentName ?: "未知用户", + phone = member.phonenumber ?: "", + idCard = member.idCard ?: "", + time = member.createTime ?: "" + ) + ) + } + adapter.submitList(userList) + } + private fun initListener() { binding.ivBack.setOnClickListener { finish() } binding.searchLayout.setOnClickListener { - val intent = Intent(this, LinkedUserSearchActivity::class.java) - startActivityForResult(intent, REQUEST_CODE_SEARCH) + } binding.btnAddLinkedUser.setOnClickListener { diff --git a/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserSearchActivity.kt b/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserSearchActivity.kt deleted file mode 100644 index d341a7c..0000000 --- a/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserSearchActivity.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.example.defenseapplication.liveVideo - - -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import androidx.recyclerview.widget.LinearLayoutManager -import com.example.defenseapplication.databinding.LinkedUserSearchActivityBinding -import com.gyf.immersionbar.ImmersionBar - -//搜索 -class LinkedUserSearchActivity : AppCompatActivity() { - - private lateinit var binding: LinkedUserSearchActivityBinding - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = LinkedUserSearchActivityBinding.inflate(layoutInflater) - setContentView(binding.root) - - ImmersionBar.with(this) - .statusBarDarkFont(true) - .titleBar(binding.topBar) - .init() - - initListener() - initData() - } - - private fun initListener() { - binding.ivBack.setOnClickListener { - finish() - } - - binding.btnSearch.setOnClickListener { - initData() - } - } - - private fun initData() { - val searchText = binding.etSearch.text.toString().trim() - - binding.rvSearchResult.layoutManager = LinearLayoutManager(this) - - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/defenseapplication/utils/ApiConfig.kt b/app/src/main/java/com/example/defenseapplication/utils/ApiConfig.kt index 5d17302..1df4bce 100644 --- a/app/src/main/java/com/example/defenseapplication/utils/ApiConfig.kt +++ b/app/src/main/java/com/example/defenseapplication/utils/ApiConfig.kt @@ -163,19 +163,17 @@ object ApiConfig { val requestBuilder = chain.request().newBuilder() val token = authToken val langHeader = LanguageHeaderManager.getLanguageHeaderValue() + + // 添加必要的请求头 + requestBuilder.header("clientid", "428a8310cd442757ae699df5d894f051") + requestBuilder.header("content-language", langHeader) + + // 如果有 token,添加 Authorization 头 if (token.isNotBlank()) { Log.d("ApiConfig", buildAuthorizationValue(token)) requestBuilder.header("Authorization", buildAuthorizationValue(token)) - requestBuilder.header("clientid", "428a8310cd442757ae699df5d894f051") - requestBuilder.header("content-language", langHeader) } - requestBuilder -// .header("Client-Toc", "Y") -// .header("Accept-Language", LanguageHelper.getLanguageServiceStr(BrightApp.getInstance())) -// .header("model", "Android") -// .header("X-App-Version", AppUtils.getAppVersionName()) - chain.proceed(requestBuilder.build()) } diff --git a/app/src/main/java/com/example/defenseapplication/utils/ApiService.kt b/app/src/main/java/com/example/defenseapplication/utils/ApiService.kt index 6b9ae6d..ed60bc4 100644 --- a/app/src/main/java/com/example/defenseapplication/utils/ApiService.kt +++ b/app/src/main/java/com/example/defenseapplication/utils/ApiService.kt @@ -8,8 +8,10 @@ import com.example.defenseapplication.bean.GetCodeBean import bean.LoginBean import bean.LoginRequest import bean.RegisterRequest +import com.example.defenseapplication.bean.AddDeviceUserRequest import com.example.defenseapplication.bean.DeleteBean import com.example.defenseapplication.bean.DeleteDeviceUserRequest +import com.example.defenseapplication.bean.FamilyMembersBean import com.example.defenseapplication.bean.MessageGroup import com.example.defenseapplication.bean.SwitchFamilyRequest import retrofit2.http.Body @@ -104,5 +106,29 @@ interface ApiService { @POST("/app/deleteDeviceUser") suspend fun deleteDeviceUser(@Body request: DeleteDeviceUserRequest): GetCodeBean + /** + * 查看家庭成员表 + */ + @GET("/app/familyMembers/list") + suspend fun getFamilyMembers( + @Query("createDept") createDept: Long? = null, + @Query("createBy") createBy: Long? = null, + @Query("createTime") createTime: String? = null, + @Query("updateBy") updateBy: Long? = null, + @Query("updateTime") updateTime: String? = null, + @Query("params.key.key") paramsKey: String? = null, + @Query("id") id: Long? = null, + @Query("parentId") parentId: Long? = null, + @Query("parentName") parentName: String? = null, + @Query("userId") userId: Long? = null, + @Query("status") status: String? = null + ): GetCodeBean> + + /** + * 添加设备关联用户 + */ + @POST("/app/addDeviceUser") + suspend fun addDeviceUser(@Body request: AddDeviceUserRequest): GetCodeBean + } diff --git a/app/src/main/java/com/example/defenseapplication/utils/DeviceUserUpdateEvent.kt b/app/src/main/java/com/example/defenseapplication/utils/DeviceUserUpdateEvent.kt new file mode 100644 index 0000000..2c2ea55 --- /dev/null +++ b/app/src/main/java/com/example/defenseapplication/utils/DeviceUserUpdateEvent.kt @@ -0,0 +1,23 @@ +package com.example.defenseapplication.utils + +object DeviceUserUpdateEvent { + private val listeners = mutableListOf() + + interface DeviceUserUpdateListener { + fun onDeviceUserUpdated() + } + + fun addListener(listener: DeviceUserUpdateListener) { + if (!listeners.contains(listener)) { + listeners.add(listener) + } + } + + fun removeListener(listener: DeviceUserUpdateListener) { + listeners.remove(listener) + } + + fun notifyUpdate() { + listeners.forEach { it.onDeviceUserUpdated() } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/defenseapplication/utils/LanguageHeaderManager.kt b/app/src/main/java/com/example/defenseapplication/utils/LanguageHeaderManager.kt index e0477a9..048209d 100644 --- a/app/src/main/java/com/example/defenseapplication/utils/LanguageHeaderManager.kt +++ b/app/src/main/java/com/example/defenseapplication/utils/LanguageHeaderManager.kt @@ -1,3 +1,5 @@ +package com.example.defenseapplication.utils + import android.content.Context import androidx.core.content.edit @@ -6,7 +8,7 @@ enum class AppLanguage(val code: String) { SIMPLIFIED_CHINESE("zh_CN"), TRADITIONAL_CHINESE("zh_TW") } -//语言枚举与管理器 + object LanguageHeaderManager { private const val PREF_NAME = "app_lang_pref" private const val KEY_LANGUAGE = "selected_language" diff --git a/app/src/main/res/layout/add_linked_user_activity.xml b/app/src/main/res/layout/add_linked_user_activity.xml index 7a95740..c32e020 100644 --- a/app/src/main/res/layout/add_linked_user_activity.xml +++ b/app/src/main/res/layout/add_linked_user_activity.xml @@ -6,6 +6,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" + android:background="@color/bg_gray" tools:context=".liveVideo.AddLinkedUserActivity"> diff --git a/app/src/main/res/layout/linked_user_search_activity.xml b/app/src/main/res/layout/linked_user_search_activity.xml deleted file mode 100644 index c852a9d..0000000 --- a/app/src/main/res/layout/linked_user_search_activity.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file