From f61d8c90c9787acb00d7c4337497e660f69768c1 Mon Sep 17 00:00:00 2001 From: zhanglei <350328959@qq.com> Date: Tue, 4 Aug 2026 17:27:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(emergency):=20=E6=96=B0=E5=A2=9E=E5=BA=94?= =?UTF-8?q?=E6=80=A5=E5=B0=B1=E5=8C=BB=E7=BE=A4=E8=81=8A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 工作台新增"应急就医"入口,支持多工单选择弹窗 - 新增应急就医相关 API:参与工单列表、群成员增减、专家/员工搜索 - 群聊页面集成侧边导航抽屉(DrawerLayout),展示群成员并支持添加/移除 - 新增添加成员页面(AddMemberActivity),支持搜索专家和员工 - InputActionSetting 扩展:新增结束会话、结束问诊名称、评价等控制字段 - IMManager.startGroupChat 支持传入 InputActionSetting 定制输入区行为 - TUIUtils 新增 WORK_TYPE_EMERGENCY 类型常量 - 新增 ParamedicOperateHelper 统一管理应急群聊操作回调 Co-Authored-By: Claude Opus 4.7 --- .../xjjk/healthexpertclient/MyApplication.kt | 22 +- .../xjjk/healthexpertclient/bean/PageBean.kt | 12 + .../bean/emergency/GroupInfo.kt | 15 + .../bean/emergency/GroupMemberBean.kt | 10 + .../data/api/WorkbenchApi.kt | 41 +++ .../data/repository/WorkbenchRepository.kt | 52 ++++ .../xjjk/healthexpertclient/ext/IMManager.kt | 9 +- .../ui/im/utils/IMInputActionSettingUtils.kt | 19 ++ .../ui/workbench/adapter/GroupInfoAdapter.kt | 117 ++++++++ .../workbench/fragment/WorkbenchFragment.kt | 197 ++++++++++++- .../workbench/viewmodel/WorkbenchViewModel.kt | 33 +++ .../healthexpertclient/utils/TUIUtils.java | 10 + .../icon_consult_emergency.png | Bin 0 -> 2808 bytes .../layout/fragment_workbench.xml | 54 +++- .../res/drawable/bg_dept_badge_selected.xml | 5 + .../res/drawable/bg_dept_badge_unselected.xml | 5 + .../res/drawable/bg_emergency_close_btn.xml | 4 + .../res/drawable/bg_emergency_confirm_btn.xml | 5 + .../res/drawable/bg_emergency_dialog_card.xml | 5 + .../drawable/bg_emergency_item_selected.xml | 8 + .../drawable/bg_emergency_item_unselected.xml | 8 + .../main/res/drawable/ic_emergency_clock.xml | 19 ++ .../main/res/drawable/ic_emergency_close.xml | 12 + .../res/drawable/ic_emergency_location.xml | 15 + .../drawable/ic_emergency_radio_selected.xml | 16 ++ .../ic_emergency_radio_unselected.xml | 7 + .../res/layout/dialog_group_info_list.xml | 96 +++++++ app/src/main/res/layout/item_group_info.xml | 122 ++++++++ app/src/main/res/values/colors.xml | 12 + app/src/main/res/values/strings.xml | 1 + .../com/btpj/lib_base/data/local/IpManager.kt | 9 +- system/tuichat/src/main/AndroidManifest.xml | 4 + .../tuikit/tuichat/TUIChatConstants.java | 2 + .../qcloud/tuikit/tuichat/bean/ChatInfo.java | 19 ++ .../tuikit/tuichat/bean/EmployeeBean.java | 67 +++++ .../tuikit/tuichat/bean/ExpertBean.java | 112 ++++++++ .../qcloud/tuikit/tuichat/bean/GroupInfo.java | 16 +- .../tuikit/tuichat/bean/GroupMember.java | 109 +++++++ .../tuikit/tuichat/bean/GroupMemberBean.java | 76 +++++ .../classicui/event/CustomMessageEvent.kt | 9 + .../tuichat/classicui/event/IMChatEvent.java | 79 ++++++ .../OnParamedicOperateListener.java | 70 +++++ .../classicui/page/AddMemberActivity.java | 267 ++++++++++++++++++ .../classicui/page/AddMemberAdapter.java | 126 +++++++++ .../classicui/page/AddMemberViewModel.java | 68 +++++ .../classicui/page/TUIBaseChatActivity.java | 143 +++++++++- .../classicui/page/TUIBaseChatFragment.java | 69 +++++ .../classicui/page/TUIGroupChatActivity.java | 90 +++++- .../classicui/page/TUIGroupChatFragment.java | 231 +++++++++++++-- .../classicui/setting/ChatLayoutSetting.java | 15 +- .../classicui/setting/InputActionSetting.java | 56 ++++ .../tuichat/classicui/widget/ChatView.java | 21 +- .../widget/GroupMemberNavAdapter.java | 100 +++++++ .../interfaces/FileBaseUrlListener.java | 5 + .../interfaces/IMInputViewActionListener.java | 2 + .../tuichat/presenter/FileBaseUrlHelper.java | 31 ++ .../presenter/ParamedicOperateHelper.java | 74 +++++ .../tuichat/util/ChatMessageParser.java | 6 + .../res/drawable-xxhdpi/chat_phone_call.png | Bin 0 -> 7157 bytes .../res/drawable-xxhdpi/default_user_icon.png | Bin 0 -> 11706 bytes .../res/drawable-xxhdpi/ic_plus_circle.png | Bin 0 -> 3139 bytes .../res/drawable-xxhdpi/ic_update_circle.png | Bin 0 -> 1107 bytes .../res/drawable/bg_add_member_button.xml | 9 + .../src/main/res/drawable/bg_gray_round_8.xml | 6 + .../main/res/drawable/bg_phone_call_btn.xml | 7 + .../res/drawable/bg_phone_call_dialog.xml | 7 + .../res/drawable/bg_tab_selected_white.xml | 6 + .../main/res/drawable/bg_theme_round_24.xml | 6 + .../res/drawable/bg_update_member_button.xml | 9 + .../src/main/res/drawable/checkbox_custom.xml | 5 + .../src/main/res/drawable/ic_check_circle.xml | 14 + .../main/res/drawable/ic_circle_stroke.xml | 11 + .../src/main/res/drawable/ic_clear.xml | 14 + .../src/main/res/drawable/ic_phone_call.xml | 10 + .../main/res/drawable/ic_phone_call_close.xml | 9 + .../src/main/res/drawable/ic_search.xml | 15 + .../src/main/res/drawable/selector_tab_bg.xml | 14 + .../main/res/layout/activity_add_member.xml | 140 +++++++++ .../layout/chat_activity_with_navigation.xml | 20 ++ .../res/layout/chat_navigation_header.xml | 66 +++++ .../src/main/res/layout/dialog_phone_call.xml | 87 ++++++ .../src/main/res/layout/item_add_member.xml | 85 ++++++ .../main/res/layout/item_group_member_nav.xml | 75 +++++ system/tuichat/src/main/res/values/colors.xml | 6 + .../tuichat/src/main/res/values/strings.xml | 16 ++ .../pages/StartGroupMemberSelectActivity.java | 1 + .../layout/contact_selecable_adapter_item.xml | 29 +- .../src/main/res/values/strings.xml | 1 + .../tencent/qcloud/tuicore/TUIConstants.java | 3 + 89 files changed, 3409 insertions(+), 69 deletions(-) create mode 100644 app/src/main/java/com/xjjk/healthexpertclient/bean/PageBean.kt create mode 100644 app/src/main/java/com/xjjk/healthexpertclient/bean/emergency/GroupInfo.kt create mode 100644 app/src/main/java/com/xjjk/healthexpertclient/bean/emergency/GroupMemberBean.kt create mode 100644 app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/adapter/GroupInfoAdapter.kt create mode 100644 app/src/main/res-workbench/drawable-xxhdpi/icon_consult_emergency.png create mode 100644 app/src/main/res/drawable/bg_dept_badge_selected.xml create mode 100644 app/src/main/res/drawable/bg_dept_badge_unselected.xml create mode 100644 app/src/main/res/drawable/bg_emergency_close_btn.xml create mode 100644 app/src/main/res/drawable/bg_emergency_confirm_btn.xml create mode 100644 app/src/main/res/drawable/bg_emergency_dialog_card.xml create mode 100644 app/src/main/res/drawable/bg_emergency_item_selected.xml create mode 100644 app/src/main/res/drawable/bg_emergency_item_unselected.xml create mode 100644 app/src/main/res/drawable/ic_emergency_clock.xml create mode 100644 app/src/main/res/drawable/ic_emergency_close.xml create mode 100644 app/src/main/res/drawable/ic_emergency_location.xml create mode 100644 app/src/main/res/drawable/ic_emergency_radio_selected.xml create mode 100644 app/src/main/res/drawable/ic_emergency_radio_unselected.xml create mode 100644 app/src/main/res/layout/dialog_group_info_list.xml create mode 100644 app/src/main/res/layout/item_group_info.xml create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/EmployeeBean.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/ExpertBean.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupMember.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupMemberBean.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/event/CustomMessageEvent.kt create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/event/IMChatEvent.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/interfaces/OnParamedicOperateListener.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberActivity.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberAdapter.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberViewModel.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/widget/GroupMemberNavAdapter.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/interfaces/FileBaseUrlListener.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/presenter/FileBaseUrlHelper.java create mode 100644 system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/presenter/ParamedicOperateHelper.java create mode 100644 system/tuichat/src/main/res/drawable-xxhdpi/chat_phone_call.png create mode 100644 system/tuichat/src/main/res/drawable-xxhdpi/default_user_icon.png create mode 100644 system/tuichat/src/main/res/drawable-xxhdpi/ic_plus_circle.png create mode 100644 system/tuichat/src/main/res/drawable-xxhdpi/ic_update_circle.png create mode 100644 system/tuichat/src/main/res/drawable/bg_add_member_button.xml create mode 100644 system/tuichat/src/main/res/drawable/bg_gray_round_8.xml create mode 100644 system/tuichat/src/main/res/drawable/bg_phone_call_btn.xml create mode 100644 system/tuichat/src/main/res/drawable/bg_phone_call_dialog.xml create mode 100644 system/tuichat/src/main/res/drawable/bg_tab_selected_white.xml create mode 100644 system/tuichat/src/main/res/drawable/bg_theme_round_24.xml create mode 100644 system/tuichat/src/main/res/drawable/bg_update_member_button.xml create mode 100644 system/tuichat/src/main/res/drawable/checkbox_custom.xml create mode 100644 system/tuichat/src/main/res/drawable/ic_check_circle.xml create mode 100644 system/tuichat/src/main/res/drawable/ic_circle_stroke.xml create mode 100644 system/tuichat/src/main/res/drawable/ic_clear.xml create mode 100644 system/tuichat/src/main/res/drawable/ic_phone_call.xml create mode 100644 system/tuichat/src/main/res/drawable/ic_phone_call_close.xml create mode 100644 system/tuichat/src/main/res/drawable/ic_search.xml create mode 100644 system/tuichat/src/main/res/drawable/selector_tab_bg.xml create mode 100644 system/tuichat/src/main/res/layout/activity_add_member.xml create mode 100644 system/tuichat/src/main/res/layout/chat_activity_with_navigation.xml create mode 100644 system/tuichat/src/main/res/layout/chat_navigation_header.xml create mode 100644 system/tuichat/src/main/res/layout/dialog_phone_call.xml create mode 100644 system/tuichat/src/main/res/layout/item_add_member.xml create mode 100644 system/tuichat/src/main/res/layout/item_group_member_nav.xml diff --git a/app/src/main/java/com/xjjk/healthexpertclient/MyApplication.kt b/app/src/main/java/com/xjjk/healthexpertclient/MyApplication.kt index 49692ef..472992d 100644 --- a/app/src/main/java/com/xjjk/healthexpertclient/MyApplication.kt +++ b/app/src/main/java/com/xjjk/healthexpertclient/MyApplication.kt @@ -56,14 +56,22 @@ class MyApplication : BaseApp() { DataStoreManager.initialize(this) DebuggerUtils.checkDebuggableInNotDebugModel(this) TUIChatConfigs.getConfigs().imInputViewActionListener = - IMInputViewActionListener { workType, workId -> - var activity = CustomActivityManager.getInstance().currentActivity() - if(activity is AppCompatActivity){ - activity?.showLoading() + object : IMInputViewActionListener { + override fun finishAction(workType: Int, workId: String) { + var activity = CustomActivityManager.getInstance().currentActivity() + if(activity is AppCompatActivity){ + activity?.showLoading() + } + appViewModel.finishIMChat(workType, workId, finallyCall = { + hideLoading() + }) + } + + override fun appraiseAction(chatId: String, workType: Int, workId: String) { + } + + override fun finishActivityToGuidanceHome(workType: Int) { } - appViewModel.finishIMChat(workType, workId, finallyCall = { - hideLoading() - }) } registerActivityLifecycleCallbacks(AdjustLifecycleCallbacks()) } diff --git a/app/src/main/java/com/xjjk/healthexpertclient/bean/PageBean.kt b/app/src/main/java/com/xjjk/healthexpertclient/bean/PageBean.kt new file mode 100644 index 0000000..de64d1a --- /dev/null +++ b/app/src/main/java/com/xjjk/healthexpertclient/bean/PageBean.kt @@ -0,0 +1,12 @@ +package com.xjjk.healthexpertclient.bean + +/** + * 通用分页数据包装类(MyBatis-Plus 风格) + */ +data class PageBean( + val records: List?, + val total: Int = 0, + val size: Int = 0, + val current: Int = 0, + val pages: Int = 0 +) diff --git a/app/src/main/java/com/xjjk/healthexpertclient/bean/emergency/GroupInfo.kt b/app/src/main/java/com/xjjk/healthexpertclient/bean/emergency/GroupInfo.kt new file mode 100644 index 0000000..26f58c5 --- /dev/null +++ b/app/src/main/java/com/xjjk/healthexpertclient/bean/emergency/GroupInfo.kt @@ -0,0 +1,15 @@ +package com.xjjk.healthexpertclient.bean.emergency + +data class GroupInfo( + val orderId: String, + val sessionId: String, + val salvageUserName: String, + val salvageUserSex: String, + val salvageUserAvatar: String, + val salvageUserAge: Int, + val salvageUserMobile: String, + val orgName: String, + val deptName: String, + val orderStatus: String, + val initTime: String +) diff --git a/app/src/main/java/com/xjjk/healthexpertclient/bean/emergency/GroupMemberBean.kt b/app/src/main/java/com/xjjk/healthexpertclient/bean/emergency/GroupMemberBean.kt new file mode 100644 index 0000000..616081c --- /dev/null +++ b/app/src/main/java/com/xjjk/healthexpertclient/bean/emergency/GroupMemberBean.kt @@ -0,0 +1,10 @@ +package com.xjjk.healthexpertclient.bean.emergency + +/** + * 应急群组成员信息 + */ +data class GroupMemberBean( + val userId: String, + val userName: String = "", + val userAvatar: String = "" +) diff --git a/app/src/main/java/com/xjjk/healthexpertclient/data/api/WorkbenchApi.kt b/app/src/main/java/com/xjjk/healthexpertclient/data/api/WorkbenchApi.kt index 305b5e0..b17885f 100644 --- a/app/src/main/java/com/xjjk/healthexpertclient/data/api/WorkbenchApi.kt +++ b/app/src/main/java/com/xjjk/healthexpertclient/data/api/WorkbenchApi.kt @@ -1,6 +1,8 @@ package com.xjjk.healthexpertclient.data.api import com.btpj.lib_base.data.bean.ApiResponse +import com.tencent.qcloud.tuikit.tuichat.bean.EmployeeBean +import com.tencent.qcloud.tuikit.tuichat.bean.ExpertBean import com.xjjk.healthexpertclient.bean.AppUpdateBean import com.xjjk.healthexpertclient.bean.workbench.ArchivesDetailResultBean import com.xjjk.healthexpertclient.bean.workbench.AudioVideoCallBean @@ -11,6 +13,9 @@ import com.xjjk.healthexpertclient.bean.workbench.HealthInfoBean import com.xjjk.healthexpertclient.bean.workbench.MessageBean import com.xjjk.healthexpertclient.bean.workbench.PhysicalExaminationReportBean import com.xjjk.healthexpertclient.bean.workbench.RefuseReasonBean +import com.xjjk.healthexpertclient.bean.PageBean +import com.xjjk.healthexpertclient.bean.emergency.GroupInfo +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMemberBean import com.xjjk.healthexpertclient.bean.workbench.WorkBenchConsultNumBean import okhttp3.RequestBody import retrofit2.http.Body @@ -136,4 +141,40 @@ interface WorkbenchApi { */ @GET("/health-system/version/getSysVersionDetailByPackageName") suspend fun getAppUpdateInfo(@QueryMap params: MutableMap): ApiResponse + + /** + * 当前登录人参与的应急工单列表 + */ + @GET("/health-emergency/api/emergency/order/myParticipatedOrders") + suspend fun getParticipatedOrders(): ApiResponse> + + /** + * 实际群成员列表 + */ + @GET("/health-emergency/api/emergency/order/getActualGroupMemberList") + suspend fun getActualGroupMemberList(@QueryMap params: MutableMap): ApiResponse> + + /** + * 邀请进群 + */ + @POST("/health-emergency/api/emergency/addGroupUser") + suspend fun addGroupUser(@Body requestBody: RequestBody): ApiResponse + + /** + * 移除群成员 + */ + @POST("/health-emergency/api/emergency/removeGroupUser") + suspend fun removeGroupUser(@Body requestBody: RequestBody): ApiResponse + + /** + * 搜索专家(专业人员) + */ + @GET("/health-emergency/api/emergency/order/searchExpert") + suspend fun searchExpert(@QueryMap params: MutableMap): ApiResponse> + + /** + * 搜索员工 + */ + @GET("/health-emergency/api/emergency/order/searchEmployee") + suspend fun searchEmployee(@QueryMap params: MutableMap): ApiResponse> } \ No newline at end of file diff --git a/app/src/main/java/com/xjjk/healthexpertclient/data/repository/WorkbenchRepository.kt b/app/src/main/java/com/xjjk/healthexpertclient/data/repository/WorkbenchRepository.kt index 540b9ec..fa4e49d 100644 --- a/app/src/main/java/com/xjjk/healthexpertclient/data/repository/WorkbenchRepository.kt +++ b/app/src/main/java/com/xjjk/healthexpertclient/data/repository/WorkbenchRepository.kt @@ -7,6 +7,11 @@ import com.btpj.lib_base.http.RetrofitManager import com.btpj.lib_base.http.RetrofitManager.toRequestBody import com.xjjk.healthexpertclient.BuildConfig import com.xjjk.healthexpertclient.bean.AppUpdateBean +import com.xjjk.healthexpertclient.bean.PageBean +import com.xjjk.healthexpertclient.bean.emergency.GroupInfo +import com.tencent.qcloud.tuikit.tuichat.bean.EmployeeBean +import com.tencent.qcloud.tuikit.tuichat.bean.ExpertBean +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMemberBean import com.xjjk.healthexpertclient.bean.workbench.ArchivesDetailResultBean import com.xjjk.healthexpertclient.bean.workbench.AudioVideoCallBean import com.xjjk.healthexpertclient.bean.workbench.CheckRecordUserInfoBean @@ -190,4 +195,51 @@ object WorkbenchRepository : BaseRepository() { params["packageName"] = BuildConfig.APPLICATION_ID return apiCall { service.getAppUpdateInfo(params) } } + + suspend fun getParticipatedOrders(): ApiResponse> { + return apiCall { service.getParticipatedOrders() } + } + + suspend fun getActualGroupMemberList(sessionId: String): ApiResponse> { + val map = mutableMapOf() + map["sessionId"] = sessionId + return apiCall { service.getActualGroupMemberList(map) } + } + + suspend fun addGroupUser(groupId: String, memberList: List, memberType: Int): ApiResponse { + val map = mutableMapOf() + map["groupId"] = groupId + map["memberList"] = memberList + map["memberType"] = memberType + return apiCall { service.addGroupUser(map.toJson().toRequestBody()) } + } + + suspend fun removeGroupUser(groupId: String, memberList: List): ApiResponse { + val map = mutableMapOf() + map["groupId"] = groupId + map["memberList"] = memberList + return apiCall { service.removeGroupUser(map.toJson().toRequestBody()) } + } + + suspend fun searchExpert(realname: String, centerId: String, excludeSessionId: String, pageNo: Int, pageSize: Int): ApiResponse> { + val map = mutableMapOf() + map["realname"] = realname + map["centerId"] = centerId + map["excludeSessionId"] = excludeSessionId + map["pageNo"] = pageNo + map["pageSize"] = pageSize + return apiCall { service.searchExpert(map) } + } + + suspend fun searchEmployee(realname: String, orgCode: String, workNo: String, phone: String, excludeSessionId: String, pageNo: Int, pageSize: Int): ApiResponse> { + val map = mutableMapOf() + map["realname"] = realname + map["orgCode"] = orgCode + map["workNo"] = workNo + map["phone"] = phone + map["excludeSessionId"] = excludeSessionId + map["pageNo"] = pageNo + map["pageSize"] = pageSize + return apiCall { service.searchEmployee(map) } + } } \ No newline at end of file diff --git a/app/src/main/java/com/xjjk/healthexpertclient/ext/IMManager.kt b/app/src/main/java/com/xjjk/healthexpertclient/ext/IMManager.kt index c754b9f..381b094 100644 --- a/app/src/main/java/com/xjjk/healthexpertclient/ext/IMManager.kt +++ b/app/src/main/java/com/xjjk/healthexpertclient/ext/IMManager.kt @@ -19,6 +19,7 @@ import com.tencent.qcloud.tuikit.tuicallkit.TUICallKit import com.tencent.qcloud.tuikit.tuicallkit.base.Constants import com.tencent.qcloud.tuikit.tuicallkit.config.OfflinePushInfoConfig import com.tencent.qcloud.tuikit.tuichat.bean.WorkBean +import com.tencent.qcloud.tuikit.tuichat.classicui.setting.InputActionSetting import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -111,13 +112,13 @@ fun Context.startC2CChat(chatId: String, groupName: String, workBean: WorkBean? } } -fun Context.startGroupChat(groupId: String, groupName: String = "", workBean: WorkBean? = null) { +fun Context.startGroupChat(groupId: String, groupName: String = "", workBean: WorkBean? = null, + inputActionSetting: InputActionSetting? = null) { if (TUILogin.isUserLogined()) { - // TUIUtils.createGroup("VHMQIUMM", "android测试组", V2TIMConversation.V2TIM_GROUP) - TUIUtils.startChat(groupId, groupName, V2TIMConversation.V2TIM_GROUP, workBean) + TUIUtils.startChat(groupId, groupName, V2TIMConversation.V2TIM_GROUP, workBean, inputActionSetting) } else { loginIm(successCall = { - TUIUtils.startChat(groupId, groupName, V2TIMConversation.V2TIM_GROUP, workBean) + TUIUtils.startChat(groupId, groupName, V2TIMConversation.V2TIM_GROUP, workBean, inputActionSetting) }) } } diff --git a/app/src/main/java/com/xjjk/healthexpertclient/ui/im/utils/IMInputActionSettingUtils.kt b/app/src/main/java/com/xjjk/healthexpertclient/ui/im/utils/IMInputActionSettingUtils.kt index e640af8..c2696fe 100644 --- a/app/src/main/java/com/xjjk/healthexpertclient/ui/im/utils/IMInputActionSettingUtils.kt +++ b/app/src/main/java/com/xjjk/healthexpertclient/ui/im/utils/IMInputActionSettingUtils.kt @@ -1,5 +1,6 @@ package com.xjjk.healthexpertclient.ui.im.utils +import com.xjjk.healthexpertclient.BuildConfig import com.tencent.qcloud.tuikit.tuichat.classicui.setting.InputActionSetting object IMInputActionSettingUtils { @@ -26,4 +27,22 @@ object IMInputActionSettingUtils { inputActionSetting.isDisableMedicalExaminationReport = true inputActionSetting.isDisableSendMessage = false } + + /** + * 应急求助IM功能配置 + */ + fun createEmergencySetting(): InputActionSetting { + var inputActionSetting = InputActionSetting() + inputActionSetting.isDisableAudioCall = true + inputActionSetting.isDisableVideoCall = false + inputActionSetting.isDisableArchives = true + inputActionSetting.isDisableMedicalExaminationReport = true + inputActionSetting.isDisableSendMessage = false + inputActionSetting.isDisableFinishName = true + inputActionSetting.isDisableEvaluate = true + inputActionSetting.isDisableFinishSession = true + inputActionSetting.packageName = BuildConfig.APPLICATION_ID + InputActionSetting.setsInstance(inputActionSetting) + return inputActionSetting + } } \ No newline at end of file diff --git a/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/adapter/GroupInfoAdapter.kt b/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/adapter/GroupInfoAdapter.kt new file mode 100644 index 0000000..07bdb7b --- /dev/null +++ b/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/adapter/GroupInfoAdapter.kt @@ -0,0 +1,117 @@ +package com.xjjk.healthexpertclient.ui.workbench.adapter + +import android.content.res.ColorStateList +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView +import com.xjjk.healthexpertclient.R +import com.xjjk.healthexpertclient.bean.emergency.GroupInfo +import com.xjjk.healthexpertclient.databinding.ItemGroupInfoBinding + +/** + * 急救工单选择适配器,支持单选 + */ +class GroupInfoAdapter( + private val items: List, + private val onSelectionChanged: (Int) -> Unit +) : RecyclerView.Adapter() { + + /** 当前选中位置,-1 表示无选中 */ + var selectedPosition = -1 + private set + + /** 获取当前选中的工单 */ + val selectedItem: GroupInfo? + get() = if (selectedPosition in items.indices) items[selectedPosition] else null + + /** 选中主色 */ + private var colorPrimary = 0 + /** 未选中灰色 */ + private var colorGray = 0 + private var colorDark = 0 + private var colorBody = 0 + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val binding = ItemGroupInfoBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + if (colorPrimary == 0) { + colorPrimary = ContextCompat.getColor(parent.context, R.color.emergency_primary) + colorGray = ContextCompat.getColor(parent.context, R.color.emergency_text_gray) + colorDark = ContextCompat.getColor(parent.context, R.color.emergency_text_dark) + colorBody = ContextCompat.getColor(parent.context, R.color.emergency_text_body) + } + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(items[position], position == selectedPosition) + } + + override fun getItemCount(): Int = items.size + + inner class ViewHolder(private val binding: ItemGroupInfoBinding) : + RecyclerView.ViewHolder(binding.root) { + + private var currentPosition = -1 + + init { + binding.rootItem.setOnClickListener { + val oldPos = selectedPosition + if (oldPos == currentPosition) { + // 取消选中 + selectedPosition = -1 + notifyItemChanged(currentPosition) + onSelectionChanged(-1) + } else { + selectedPosition = currentPosition + notifyItemChanged(oldPos) + notifyItemChanged(currentPosition) + onSelectionChanged(currentPosition) + } + } + } + + fun bind(groupInfo: GroupInfo, isSelected: Boolean) { + currentPosition = adapterPosition + val ctx = binding.root.context + + // 姓名 + binding.tvUserName.text = groupInfo.salvageUserName + + // 部门标签 + binding.tvDeptName.text = groupInfo.deptName + + // 地址 + binding.tvOrgName.text = groupInfo.orgName + + // 时间 + binding.tvInitTime.text = "求助时间:${groupInfo.initTime}" + + if (isSelected) { + // 选中态 + binding.rootItem.setBackgroundResource(R.drawable.bg_emergency_item_selected) + binding.ivRadio.setImageResource(R.drawable.ic_emergency_radio_selected) + + binding.tvDeptName.setTextColor(colorPrimary) + binding.tvDeptName.setBackgroundResource(R.drawable.bg_dept_badge_selected) + + binding.tvInitTime.setTextColor(colorPrimary) + binding.ivLocation.imageTintList = ColorStateList.valueOf(colorPrimary) + binding.ivClock.imageTintList = ColorStateList.valueOf(colorPrimary) + } else { + // 未选中态 + binding.rootItem.setBackgroundResource(R.drawable.bg_emergency_item_unselected) + binding.ivRadio.setImageResource(R.drawable.ic_emergency_radio_unselected) + + binding.tvDeptName.setTextColor(colorGray) + binding.tvDeptName.setBackgroundResource(R.drawable.bg_dept_badge_unselected) + + binding.tvInitTime.setTextColor(colorGray) + binding.ivLocation.imageTintList = ColorStateList.valueOf(colorGray) + binding.ivClock.imageTintList = ColorStateList.valueOf(colorGray) + } + } + } +} diff --git a/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/fragment/WorkbenchFragment.kt b/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/fragment/WorkbenchFragment.kt index 89ba4b1..d907c46 100644 --- a/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/fragment/WorkbenchFragment.kt +++ b/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/fragment/WorkbenchFragment.kt @@ -3,17 +3,29 @@ package com.xjjk.healthexpertclient.ui.workbench.fragment import android.os.Bundle import android.os.SystemClock import android.view.View +import android.app.Dialog +import android.graphics.Color +import android.graphics.Rect +import android.graphics.drawable.ColorDrawable +import android.view.WindowManager +import androidx.core.util.Consumer import androidx.fragment.app.activityViewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.btpj.lib_base.data.local.DataStoreManager import com.btpj.lib_base.ext.initColors import com.btpj.lib_base.ext.loadCircle +import com.btpj.lib_base.utils.ToastUtil import com.buddy.kredit.android.base.BaseFragment import com.xjjk.healthexpertclient.R +import com.xjjk.healthexpertclient.bean.emergency.GroupInfo import com.xjjk.healthexpertclient.bean.mine.DoctorBean +import com.xjjk.healthexpertclient.data.repository.WorkbenchRepository +import com.xjjk.healthexpertclient.databinding.DialogGroupInfoListBinding import com.xjjk.healthexpertclient.databinding.FragmentWorkbenchBinding import com.xjjk.healthexpertclient.event.WorkbenchEvent import com.xjjk.healthexpertclient.ext.loginIm @@ -24,14 +36,24 @@ import com.xjjk.healthexpertclient.ext.startSimulateUserActivity import com.xjjk.healthexpertclient.ui.im.utils.IMInputActionSettingUtils import com.xjjk.healthexpertclient.ui.main.viewmodel.MainViewModel import com.xjjk.healthexpertclient.ui.workbench.ConsultRecordActivity +import com.xjjk.healthexpertclient.ui.workbench.adapter.GroupInfoAdapter import com.xjjk.healthexpertclient.ui.workbench.viewmodel.WorkbenchViewModel import com.xjjk.healthexpertclient.utils.CommonUtils import com.xjjk.healthexpertclient.utils.TUIUtils import com.xjjk.healthexpertclient.utils.orEmptyDefault import com.xjjk.healthexpertclient.utils.orNullDefault +import com.tencent.qcloud.tuikit.tuichat.bean.EmployeeBean +import com.tencent.qcloud.tuikit.tuichat.bean.ExpertBean +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMemberBean import com.tencent.qcloud.tuikit.tuichat.bean.WorkBean +import com.tencent.qcloud.tuikit.tuichat.classicui.interfaces.OnParamedicOperateListener +import com.tencent.qcloud.tuikit.tuichat.presenter.ParamedicOperateHelper +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withTimeoutOrNull import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode @@ -43,12 +65,93 @@ class WorkbenchFragment : } private val mainViewModel by activityViewModels() + private val paramedicOperateListener = object : OnParamedicOperateListener { + override fun getActualGroupMemberList(sessionId: String): List? { + return runBlocking(Dispatchers.IO) { + try { + val deferred = async { + WorkbenchRepository.getActualGroupMemberList(sessionId) + } + val response = withTimeoutOrNull(10000L) { deferred.await() } + ?: return@runBlocking emptyList() + response.takeIf { it.success }?.result ?: emptyList() + } catch (e: Exception) { + emptyList() + } + } + } + + override fun addGroupUser( + groupId: String, + memberList: List, + memberType: Int, + callback: Consumer + ) { + mViewModel.addGroupUser(groupId, memberList, memberType) { success -> + callback.accept(success) + } + } + + override fun removeGroupUser(groupId: String, memberList: List) { + mViewModel.removeGroupUser(groupId, memberList) + } + + override fun searchExpert( + realname: String?, + centerId: String?, + excludeSessionId: String?, + pageNo: Int, + pageSize: Int + ): List? { + return runBlocking(Dispatchers.IO) { + try { + val deferred = async { + WorkbenchRepository.searchExpert( + realname ?: "", centerId ?: "", excludeSessionId ?: "", pageNo, pageSize + ) + } + val response = withTimeoutOrNull(10000L) { deferred.await() } + ?: return@runBlocking emptyList() + response.takeIf { it.success }?.result?.records ?: emptyList() + } catch (e: Exception) { + emptyList() + } + } + } + + override fun searchEmployee( + realname: String?, + orgCode: String?, + workNo: String?, + phone: String?, + excludeSessionId: String?, + pageNo: Int, + pageSize: Int + ): List? { + return runBlocking(Dispatchers.IO) { + try { + val deferred = async { + WorkbenchRepository.searchEmployee( + realname ?: "", orgCode ?: "", workNo ?: "", phone ?: "", + excludeSessionId ?: "", pageNo, pageSize + ) + } + val response = withTimeoutOrNull(10000L) { deferred.await() } + ?: return@runBlocking emptyList() + response.takeIf { it.success }?.result?.records ?: emptyList() + } catch (e: Exception) { + emptyList() + } + } + } + } + var time: Long = 3000 var mCount = 5 var mLastTime = 0L var mHits = LongArray(mCount) override fun initView(view: View, savedInstanceState: Bundle?) { -// setToolBarRightText(getString(R.string.doctor_homepage_message)) + ParamedicOperateHelper.getInstance().setListener(paramedicOperateListener) mBinding.swipeRefresh.initColors() mBinding.swipeRefresh.setOnRefreshListener(this@WorkbenchFragment) } @@ -101,6 +204,7 @@ class WorkbenchFragment : clImageTextConsultLay, clAudioVideoConsultLay, clAssistantConsultLay, + clAssistanceEmergencyLay, layImageTextConsultStatus.llLeftLay, layImageTextConsultStatus.llCenterLay, layImageTextConsultStatus.llRightLay, @@ -151,6 +255,36 @@ class WorkbenchFragment : requireContext().startGroupChat(it.groupId, getString(R.string.title_assistant_consult), WorkBean(it.id, TUIUtils.WORK_TYPE_ASSISTANT)) }) } + clAssistanceEmergencyLay -> { + mViewModel.getParticipatedOrders { result -> + if (result.records.isNullOrEmpty()) { + ToastUtil.showShort(requireContext(), "暂无参与的应急就医工单") + + } else if (result.records.size == 1) { + mViewModel.getActualGroupMemberList(result.records[0].sessionId) { groupMemberBeans -> + val setting = IMInputActionSettingUtils.createEmergencySetting() + requireContext().startGroupChat( + result.records[0].sessionId, + getString(R.string.title_paramedic_group), + WorkBean(result.records[0].orderId, TUIUtils.WORK_TYPE_EMERGENCY), + setting + ) + } + } else { + showChatListDialog(result.records!!) { groupInfo -> + mViewModel.getActualGroupMemberList(groupInfo.sessionId) { groupMemberBeans -> + val setting = IMInputActionSettingUtils.createEmergencySetting() + requireContext().startGroupChat( + groupInfo.sessionId, + getString(R.string.title_paramedic_group), + WorkBean(groupInfo.orderId, TUIUtils.WORK_TYPE_EMERGENCY), + setting + ) + } + } + } + } + } toolbarLay.tvRight -> { startMessageListActivity(requireContext()) } @@ -169,6 +303,67 @@ class WorkbenchFragment : } } } + /** + * 展示应急工单选择Dialog + */ + private fun showChatListDialog( + records: List, + onChatSelected: (GroupInfo) -> Unit + ) { + context?.let { ctx -> + val dialog = Dialog(ctx) + val binding = DialogGroupInfoListBinding.inflate(layoutInflater) + + val adapter = GroupInfoAdapter(records) { selectedPos -> + val hasSelection = selectedPos >= 0 + binding.tvConfirm.isEnabled = hasSelection + binding.tvConfirm.alpha = if (hasSelection) 1.0f else 0.4f + } + + binding.rvGroupList.layoutManager = LinearLayoutManager(ctx) + binding.rvGroupList.adapter = adapter.apply { + binding.tvConfirm.isEnabled = false + binding.tvConfirm.alpha = 0.4f + } + + val spacing = ctx.resources.getDimensionPixelSize(R.dimen.dp_12) + binding.rvGroupList.addItemDecoration(object : RecyclerView.ItemDecoration() { + override fun getItemOffsets( + outRect: Rect, + view: View, + parent: RecyclerView, + state: RecyclerView.State + ) { + outRect.bottom = spacing + } + }) + + binding.tvConfirm.setOnClickListener { + adapter.selectedItem?.let { item -> + onChatSelected(item) + dialog.dismiss() + } + } + + binding.ivClose.setOnClickListener { dialog.dismiss() } + binding.flRoot.setOnClickListener { dialog.dismiss() } + + dialog.setContentView(binding.root) + dialog.setCanceledOnTouchOutside(true) + dialog.setCancelable(true) + + dialog.window?.let { window -> + window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + window.decorView.setBackgroundColor(Color.TRANSPARENT) + window.setLayout( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT + ) + } + dialog.show() + } + } + @Subscribe(threadMode = ThreadMode.MAIN) fun onEvent(event: WorkbenchEvent) { onRefresh() diff --git a/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/viewmodel/WorkbenchViewModel.kt b/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/viewmodel/WorkbenchViewModel.kt index 32ae4c6..24b36a4 100644 --- a/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/viewmodel/WorkbenchViewModel.kt +++ b/app/src/main/java/com/xjjk/healthexpertclient/ui/workbench/viewmodel/WorkbenchViewModel.kt @@ -6,8 +6,11 @@ import com.btpj.lib_base.base.BaseViewModel import com.btpj.lib_base.ext.handleRequest import com.btpj.lib_base.ext.launch import com.btpj.lib_base.utils.DateUtil +import com.xjjk.healthexpertclient.bean.PageBean +import com.xjjk.healthexpertclient.bean.emergency.GroupInfo import com.xjjk.healthexpertclient.bean.workbench.WorkBenchConsultNumBean import com.xjjk.healthexpertclient.data.repository.WorkbenchRepository +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMemberBean import com.tencent.imsdk.v2.V2TIMConversation import com.tencent.imsdk.v2.V2TIMConversationListFilter import com.tencent.imsdk.v2.V2TIMConversationListener @@ -121,4 +124,34 @@ class WorkbenchViewModel: BaseViewModel() { }) }) } + + fun getParticipatedOrders(successCall: (PageBean) -> Unit){ + launch(false, { + handleRequest(WorkbenchRepository.getParticipatedOrders(), successBlock = { + it.result?.let { result -> successCall.invoke(result) } + }) + }) + } + + fun getActualGroupMemberList(sessionId: String, successCall: (List) -> Unit){ + launch(false, { + handleRequest(WorkbenchRepository.getActualGroupMemberList(sessionId), successBlock = { + it.result?.let { result -> successCall.invoke(result) } + }) + }) + } + + fun addGroupUser(groupId: String, memberList: List, memberType: Int, successCall: (Boolean) -> Unit){ + launch(false, { + handleRequest(WorkbenchRepository.addGroupUser(groupId, memberList, memberType), successBlock = { + successCall.invoke(it.success) + }) + }) + } + + fun removeGroupUser(groupId: String, memberList: List){ + launch(false, { + handleRequest(WorkbenchRepository.removeGroupUser(groupId, memberList), successBlock = {}) + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/xjjk/healthexpertclient/utils/TUIUtils.java b/app/src/main/java/com/xjjk/healthexpertclient/utils/TUIUtils.java index 427d5fb..3346966 100644 --- a/app/src/main/java/com/xjjk/healthexpertclient/utils/TUIUtils.java +++ b/app/src/main/java/com/xjjk/healthexpertclient/utils/TUIUtils.java @@ -16,6 +16,7 @@ import com.tencent.qcloud.tuicore.TUICore; import com.tencent.qcloud.tuicore.interfaces.TUILoginConfig; import com.tencent.qcloud.tuicore.util.TUIBuild; import com.tencent.qcloud.tuikit.tuichat.bean.WorkBean; +import com.tencent.qcloud.tuikit.tuichat.classicui.setting.InputActionSetting; import java.util.Locale; @@ -23,6 +24,7 @@ import java.util.Locale; public class TUIUtils { public static final int WORK_TYPE_IMAGE_TEXT_CONSULT = 2; public static final int WORK_TYPE_ASSISTANT = 3; + public static final int WORK_TYPE_EMERGENCY = 4; public static final String TAG = TUIUtils.class.getSimpleName(); public static void startActivity(String activityName, Bundle param) { @@ -30,6 +32,11 @@ public class TUIUtils { } public static void startChat(String chatId, String chatName, int chatType, WorkBean workBean) { + startChat(chatId, chatName, chatType, workBean, null); + } + + public static void startChat(String chatId, String chatName, int chatType, WorkBean workBean, + InputActionSetting inputActionSetting) { Bundle bundle = new Bundle(); bundle.putString(TUIConstants.TUIChat.CHAT_ID, chatId); if(!TextUtils.isEmpty(chatId)){ @@ -38,6 +45,9 @@ public class TUIUtils { } bundle.putInt(TUIConstants.TUIChat.CHAT_TYPE, chatType); bundle.putSerializable(TUIConstants.TUIChat.WORK_BEAN, workBean); + if (inputActionSetting != null) { + bundle.putSerializable("inputActionSetting", inputActionSetting); + } if (chatType == V2TIMConversation.V2TIM_C2C) { TUICore.startActivity(TUIConstants.TUIChat.C2C_CHAT_ACTIVITY_NAME, bundle); } else if (chatType == V2TIMConversation.V2TIM_GROUP) { diff --git a/app/src/main/res-workbench/drawable-xxhdpi/icon_consult_emergency.png b/app/src/main/res-workbench/drawable-xxhdpi/icon_consult_emergency.png new file mode 100644 index 0000000000000000000000000000000000000000..c35a3c6cd8ed1c5bca84ea6e54cd7f4d9b6a4203 GIT binary patch literal 2808 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 KMNUMnLSTaKmRlVF literal 0 HcmV?d00001 diff --git a/app/src/main/res-workbench/layout/fragment_workbench.xml b/app/src/main/res-workbench/layout/fragment_workbench.xml index d9a1d32..b4ecdd6 100644 --- a/app/src/main/res-workbench/layout/fragment_workbench.xml +++ b/app/src/main/res-workbench/layout/fragment_workbench.xml @@ -323,7 +323,7 @@ app:layout_constraintTop_toBottomOf="@+id/cl_audio_video_consult_lay" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" - app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintBottom_toTopOf="@+id/cl_assistance_emergency_lay" android:background="@drawable/rectangle_round_corner10_white" android:elevation="@dimen/dp_3" android:layout_marginHorizontal="@dimen/dp_15" @@ -394,6 +394,58 @@ app:layout_constraintTop_toBottomOf="@+id/tv_assistant_consult_title" android:text="@string/doctor_homepage_assistant_consult_explain" /> + + + + + + + + diff --git a/app/src/main/res/drawable/bg_dept_badge_selected.xml b/app/src/main/res/drawable/bg_dept_badge_selected.xml new file mode 100644 index 0000000..092e1da --- /dev/null +++ b/app/src/main/res/drawable/bg_dept_badge_selected.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/bg_dept_badge_unselected.xml b/app/src/main/res/drawable/bg_dept_badge_unselected.xml new file mode 100644 index 0000000..0d21655 --- /dev/null +++ b/app/src/main/res/drawable/bg_dept_badge_unselected.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/bg_emergency_close_btn.xml b/app/src/main/res/drawable/bg_emergency_close_btn.xml new file mode 100644 index 0000000..c5e68ca --- /dev/null +++ b/app/src/main/res/drawable/bg_emergency_close_btn.xml @@ -0,0 +1,4 @@ + + + diff --git a/app/src/main/res/drawable/bg_emergency_confirm_btn.xml b/app/src/main/res/drawable/bg_emergency_confirm_btn.xml new file mode 100644 index 0000000..461bf60 --- /dev/null +++ b/app/src/main/res/drawable/bg_emergency_confirm_btn.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/bg_emergency_dialog_card.xml b/app/src/main/res/drawable/bg_emergency_dialog_card.xml new file mode 100644 index 0000000..a8ae65b --- /dev/null +++ b/app/src/main/res/drawable/bg_emergency_dialog_card.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/bg_emergency_item_selected.xml b/app/src/main/res/drawable/bg_emergency_item_selected.xml new file mode 100644 index 0000000..dc1c306 --- /dev/null +++ b/app/src/main/res/drawable/bg_emergency_item_selected.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_emergency_item_unselected.xml b/app/src/main/res/drawable/bg_emergency_item_unselected.xml new file mode 100644 index 0000000..f763ee4 --- /dev/null +++ b/app/src/main/res/drawable/bg_emergency_item_unselected.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_emergency_clock.xml b/app/src/main/res/drawable/ic_emergency_clock.xml new file mode 100644 index 0000000..769e61c --- /dev/null +++ b/app/src/main/res/drawable/ic_emergency_clock.xml @@ -0,0 +1,19 @@ + + + + diff --git a/app/src/main/res/drawable/ic_emergency_close.xml b/app/src/main/res/drawable/ic_emergency_close.xml new file mode 100644 index 0000000..563c85d --- /dev/null +++ b/app/src/main/res/drawable/ic_emergency_close.xml @@ -0,0 +1,12 @@ + + + diff --git a/app/src/main/res/drawable/ic_emergency_location.xml b/app/src/main/res/drawable/ic_emergency_location.xml new file mode 100644 index 0000000..a666090 --- /dev/null +++ b/app/src/main/res/drawable/ic_emergency_location.xml @@ -0,0 +1,15 @@ + + + + diff --git a/app/src/main/res/drawable/ic_emergency_radio_selected.xml b/app/src/main/res/drawable/ic_emergency_radio_selected.xml new file mode 100644 index 0000000..226186d --- /dev/null +++ b/app/src/main/res/drawable/ic_emergency_radio_selected.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_emergency_radio_unselected.xml b/app/src/main/res/drawable/ic_emergency_radio_unselected.xml new file mode 100644 index 0000000..8005b40 --- /dev/null +++ b/app/src/main/res/drawable/ic_emergency_radio_unselected.xml @@ -0,0 +1,7 @@ + + + + diff --git a/app/src/main/res/layout/dialog_group_info_list.xml b/app/src/main/res/layout/dialog_group_info_list.xml new file mode 100644 index 0000000..e05c8ff --- /dev/null +++ b/app/src/main/res/layout/dialog_group_info_list.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_group_info.xml b/app/src/main/res/layout/item_group_info.xml new file mode 100644 index 0000000..ddc25ac --- /dev/null +++ b/app/src/main/res/layout/item_group_info.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f5af710..98bc23f 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -111,6 +111,7 @@ #FF00B0FF #66000000 #21BEBD + #1A21BEBD #EFEFEF #E0E0E0 @@ -122,4 +123,15 @@ #16C716 #21BEBD + + #0F2EB8B2 + #802EB8B2 + #E6E6EA + #EAECFA + #252535 + #394356 + #77859E + #2EB8B2 + #F1F5F9 + \ 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 99018ff..b1ecda1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -28,6 +28,7 @@ 擅长病种 体检详情 全科医生 + 应急求助 位置 消息 选择位置 diff --git a/lib_base/src/main/java/com/btpj/lib_base/data/local/IpManager.kt b/lib_base/src/main/java/com/btpj/lib_base/data/local/IpManager.kt index 54c2295..a186984 100644 --- a/lib_base/src/main/java/com/btpj/lib_base/data/local/IpManager.kt +++ b/lib_base/src/main/java/com/btpj/lib_base/data/local/IpManager.kt @@ -20,8 +20,11 @@ object IpManager { /** 常用的IP */ private const val DEBUG_DEFAULT_IP_ADDRESS_REMOTE = "http://cqyt.dev.yg.dt.io/" // 开发环境 - private const val TEST_DEFAULT_IP_ADDRESS_REMOTE = "https://xjgateway.mcrm.vip:8888/" // 测试环境 -// private const val PRODUCT_DEFAULT_IP_ADDRESS_REMOTE = "https://api.xjygjk.com/" // 线上环境 +// private const val TEST_DEFAULT_IP_ADDRESS_REMOTE = "https://xjgateway.mcrm.vip:8888/" // 测试环境 +// private const val TEST_DEFAULT_IP_ADDRESS_REMOTE = "https://xjxc-api.mcrm.vip:8888/" // 测试环境 + private const val TEST_DEFAULT_IP_ADDRESS_REMOTE = "https://xj-api.yixiong-tech.com:8081/" + + // private const val PRODUCT_DEFAULT_IP_ADDRESS_REMOTE = "https://api.xjygjk.com/" // 线上环境 private const val PRODUCT_DEFAULT_IP_ADDRESS_REMOTE = "https://api-jkglpt.iosp.ydpt.tech/" // 线上环境 private const val DEBUG_H5_ADDRESS_REMOTE = "http://cms.dev.yg.dt.io" // 开发环境 @@ -34,7 +37,7 @@ object IpManager { private const val KEY_DEFAULT_IP_AND_PORT = "data_default_ip_and_port" private lateinit var dataStore: DataStoreUtils - val baseUrlType: BaseUrlType = BaseUrlType.PRODUCT + val baseUrlType: BaseUrlType = BaseUrlType.TEST fun initialize(context: Context?) { if (context == null) { Log.w(TAG, "initialize: context is null") diff --git a/system/tuichat/src/main/AndroidManifest.xml b/system/tuichat/src/main/AndroidManifest.xml index 60652a2..0f0e3e1 100644 --- a/system/tuichat/src/main/AndroidManifest.xml +++ b/system/tuichat/src/main/AndroidManifest.xml @@ -44,6 +44,10 @@ android:screenOrientation="portrait" android:windowSoftInputMode="adjustNothing|stateHidden"/> + + diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/TUIChatConstants.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/TUIChatConstants.java index 142ba25..01f5eef 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/TUIChatConstants.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/TUIChatConstants.java @@ -38,6 +38,8 @@ public class TUIChatConstants { public static final int GET_MESSAGE_LOCATE = 3; public static final String CHAT_INFO = "chatInfo"; + public static final String WEEK_STATE = "weekState"; + public static final String CHAT_IS_LIAISON_USER = "chat_is_liaison_user"; public static final String MESSAGE_BEAN = "messageBean"; diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/ChatInfo.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/ChatInfo.java index 6ecac01..ae8df43 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/ChatInfo.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/ChatInfo.java @@ -194,4 +194,23 @@ public class ChatInfo implements Serializable { public void setInputActionSetting(InputActionSetting inputActionSetting) { this.inputActionSetting = inputActionSetting; } + + private String autoSendMessage; + private String consultantId; + + public String getAutoSendMessage() { + return autoSendMessage; + } + + public void setAutoSendMessage(String autoSendMessage) { + this.autoSendMessage = autoSendMessage; + } + + public String getConsultantId() { + return consultantId; + } + + public void setConsultantId(String consultantId) { + this.consultantId = consultantId; + } } diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/EmployeeBean.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/EmployeeBean.java new file mode 100644 index 0000000..71e6d9d --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/EmployeeBean.java @@ -0,0 +1,67 @@ +package com.tencent.qcloud.tuikit.tuichat.bean; + +public class EmployeeBean { + private String userId; + private String realname; + private String avatar; + private String orgCode; + private String orgName; + private String deptName; + private String phone; + private String workNo; + public void setUserId(String userId) { + this.userId = userId; + } + public String getUserId() { + return userId; + } + + public void setRealname(String realname) { + this.realname = realname; + } + public String getRealname() { + return realname; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + public String getAvatar() { + return avatar; + } + + public void setOrgCode(String orgCode) { + this.orgCode = orgCode; + } + public String getOrgCode() { + return orgCode; + } + + public void setOrgName(String orgName) { + this.orgName = orgName; + } + public String getOrgName() { + return orgName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + public String getDeptName() { + return deptName; + } + + public void setPhone(String phone) { + this.phone = phone; + } + public String getPhone() { + return phone; + } + + public void setWorkNo(String workNo) { + this.workNo = workNo; + } + public String getWorkNo() { + return workNo; + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/ExpertBean.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/ExpertBean.java new file mode 100644 index 0000000..5b1163f --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/ExpertBean.java @@ -0,0 +1,112 @@ +package com.tencent.qcloud.tuikit.tuichat.bean; + +public class ExpertBean { + private String userId; + private String realname; + private String avatar; + private String type; + private String centerId; + private String post; + private String post_dictText; + private String school; + private String edu; + private String goodAt; + private String deptName; + private String phone; + + public String getPost_dictText() { + return post_dictText; + } + + public void setPost_dictText(String post_dictText) { + this.post_dictText = post_dictText; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getRealname() { + return realname; + } + + public void setRealname(String realname) { + this.realname = realname; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getCenterId() { + return centerId; + } + + public void setCenterId(String centerId) { + this.centerId = centerId; + } + + public String getPost() { + return post; + } + + public void setPost(String post) { + this.post = post; + } + + public String getSchool() { + return school; + } + + public void setSchool(String school) { + this.school = school; + } + + public String getEdu() { + return edu; + } + + public void setEdu(String edu) { + this.edu = edu; + } + + public String getGoodAt() { + return goodAt; + } + + public void setGoodAt(String goodAt) { + this.goodAt = goodAt; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupInfo.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupInfo.java index 35bc028..b66876f 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupInfo.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupInfo.java @@ -21,7 +21,7 @@ public class GroupInfo extends ChatInfo { private int memberCount; private String groupName; private String notice; - private List memberDetails = new ArrayList<>(); + private List memberDetails = new ArrayList<>(); private int joinType; private String owner; private boolean messageReceiveOption; @@ -125,7 +125,7 @@ public class GroupInfo extends ChatInfo { * * @return */ - public List getMemberDetails() { + public List getMemberDetails() { return memberDetails; } @@ -136,7 +136,7 @@ public class GroupInfo extends ChatInfo { * * @param memberDetails */ - public void setMemberDetails(List memberDetails) { + public void setMemberDetails(List memberDetails) { this.memberDetails = memberDetails; } @@ -223,4 +223,14 @@ public class GroupInfo extends ChatInfo { setMessageReceiveOption(infoResult.getGroupInfo().getRecvOpt() == V2TIMMessage.V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE ? true : false); return this; } + + private boolean initiateVideoCall; + + public boolean isInitiateVideoCall() { + return initiateVideoCall; + } + + public void setInitiateVideoCall(boolean initiateVideoCall) { + this.initiateVideoCall = initiateVideoCall; + } } diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupMember.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupMember.java new file mode 100644 index 0000000..0b0b0cd --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupMember.java @@ -0,0 +1,109 @@ +package com.tencent.qcloud.tuikit.tuichat.bean; + +import java.util.ArrayList; +import java.util.List; + +/** + * 群成员信息扩展类,在 GroupMemberInfo 基础上补充 GroupMemberBean 中的业务字段 + */ +public class GroupMember extends GroupMemberInfo { + + private String orderId; + private String userId; + private String userName; + private String avatar; + private String phone; + private int isGroupMember; + private int isSelf; + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public int getIsGroupMember() { + return isGroupMember; + } + + public void setIsGroupMember(int isGroupMember) { + this.isGroupMember = isGroupMember; + } + + public int getIsSelf() { + return isSelf; + } + + public void setIsSelf(int isSelf) { + this.isSelf = isSelf; + } + + /** + * 将 GroupMemberBean 转换为 GroupMember + */ + public static GroupMember convertFromBean(GroupMemberBean bean) { + if (bean == null) { + return null; + } + GroupMember member = new GroupMember(); + // 映射到父类字段 + member.setAccount(bean.getUserId()); + member.setMemberType(bean.getMemberType()); + // 映射到自身扩展字段 + member.setOrderId(bean.getOrderId()); + member.setUserId(bean.getUserId()); + member.setUserName(bean.getUserName()); + member.setAvatar(bean.getAvatar()); + member.setPhone(bean.getPhone()); + member.setIsGroupMember(bean.getIsGroupMember()); + member.setIsSelf(bean.getIsSelf()); + return member; + } + + /** + * 批量将 List 转换为 List + */ + public static List convertFromBeanList(List beans) { + List members = new ArrayList<>(); + if (beans != null) { + for (GroupMemberBean bean : beans) { + members.add(convertFromBean(bean)); + } + } + return members; + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupMemberBean.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupMemberBean.java new file mode 100644 index 0000000..7fa1887 --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/bean/GroupMemberBean.java @@ -0,0 +1,76 @@ +package com.tencent.qcloud.tuikit.tuichat.bean; + +public class GroupMemberBean { + private String orderId; + private String userId; + private String userName; + private String avatar; + private String phone; + private int isGroupMember; + private int memberType; + private int isSelf; + + public int getIsSelf() { + return isSelf; + } + + public void setIsSelf(int isSelf) { + this.isSelf = isSelf; + } + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public int getIsGroupMember() { + return isGroupMember; + } + + public void setIsGroupMember(int isGroupMember) { + this.isGroupMember = isGroupMember; + } + + public int getMemberType() { + return memberType; + } + + public void setMemberType(int memberType) { + this.memberType = memberType; + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/event/CustomMessageEvent.kt b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/event/CustomMessageEvent.kt new file mode 100644 index 0000000..99726a3 --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/event/CustomMessageEvent.kt @@ -0,0 +1,9 @@ +package com.tencent.qcloud.tuikit.tuichat.classicui.event + +/** + * @author nanfeifei + * @time 2023/7/5 14:32 + * @description + */ +class CustomMessageEvent(var chatId: String, var messageJson: String) { +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/event/IMChatEvent.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/event/IMChatEvent.java new file mode 100644 index 0000000..8698475 --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/event/IMChatEvent.java @@ -0,0 +1,79 @@ +package com.tencent.qcloud.tuikit.tuichat.classicui.event; + +public class IMChatEvent { + public int type;//0 医生卡片 1 仅提示message信息 2聊天头像id + public String doctor; + public String message = ""; + public long time; + + //新疆项目新增字段 + public String groupId = ""; + public String fromAccount = "";//小助手id + public String toAccount = "";//当前登录用户id + public String msgId = ""; + + + public String getMessage() { + return message == null ? "" : message; + } + + public void setMessage(String message) { + this.message = message; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getDoctor() { + return doctor == null ? "" : doctor; + } + + public void setDoctor(String doctor) { + this.doctor = doctor; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public String getGroupId() { + return groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public String getFromAccount() { + return fromAccount; + } + + public void setFromAccount(String fromAccount) { + this.fromAccount = fromAccount; + } + + public String getToAccount() { + return toAccount; + } + + public void setToAccount(String toAccount) { + this.toAccount = toAccount; + } + + public String getMsgId() { + return msgId; + } + + public void setMsgId(String msgId) { + this.msgId = msgId; + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/interfaces/OnParamedicOperateListener.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/interfaces/OnParamedicOperateListener.java new file mode 100644 index 0000000..2a1994b --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/interfaces/OnParamedicOperateListener.java @@ -0,0 +1,70 @@ +package com.tencent.qcloud.tuikit.tuichat.classicui.interfaces; + +import androidx.core.util.Consumer; + +import com.tencent.qcloud.tuikit.tuichat.bean.EmployeeBean; +import com.tencent.qcloud.tuikit.tuichat.bean.ExpertBean; +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMemberBean; + +import java.util.List; + +/** + * 急救调度相关操作的对外接口。 + * 由宿主 App(如 EmergencyFragment)实现并注册到 {@link com.tencent.qcloud.tuikit.tuichat.presenter.ParamedicOperateHelper}, + * 供 tuichat 模块反向调用宿主能力(加成员、查专家/员工、移除成员等)。 + */ +public interface OnParamedicOperateListener { + + /** + * 获取指定会话(群组)当前实际成员列表。 + * + * @param sessionId 群组会话 ID + * @return 成员列表,可能为空,但不为 null + */ + List getActualGroupMemberList(String sessionId); + + /** + * 邀请一批用户加入指定群组。操作为异步执行,结果通过 callback 回传。 + * + * @param groupId 目标群组 ID + * @param memberList 待加入成员的 userId 列表 + * @param memberType 成员类型,由业务侧约定语义 + * @param callback 操作结果回调:true 表示服务器侧写入成功;false 表示失败(含网络异常、业务错误等)。 + * 回调触发线程不限定,调用方需自行切回主线程操作 UI。不允许传 null。 + */ + void addGroupUser(String groupId, List memberList, int memberType, Consumer callback); + + /** + * 按条件检索专家。 + * + * @param realname 真实姓名关键字,可空 + * @param centerId 中心 ID,可空 + * @param excludeSessionId 需排除的会话 ID(避免重复添加),可空 + * @param pageNo 页码 + * @param pageSize 每页条数 + * @return 专家列表,可能为空 + */ + List searchExpert(String realname, String centerId, String excludeSessionId, int pageNo, int pageSize); + + /** + * 按条件检索员工。 + * + * @param realname 真实姓名关键字,可空 + * @param orgCode 机构编码,可空 + * @param workNo 工号,可空 + * @param phone 电话,可空 + * @param excludeSessionId 需排除的会话 ID,可空 + * @param pageNo 页码 + * @param pageSize 每页条数 + * @return 员工列表,可能为空 + */ + List searchEmployee(String realname, String orgCode, String workNo, String phone, String excludeSessionId, int pageNo, int pageSize); + + /** + * 从指定群组移除一批成员。当前为 fire-and-forget,无回调。 + * + * @param groupId 目标群组 ID + * @param memberList 待移除成员的 userId 列表 + */ + void removeGroupUser(String groupId, List memberList); +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberActivity.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberActivity.java new file mode 100644 index 0000000..5c1211a --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberActivity.java @@ -0,0 +1,267 @@ +package com.tencent.qcloud.tuikit.tuichat.classicui.page; + +import android.app.Activity; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.tabs.TabLayout; +import com.tencent.qcloud.tuicore.component.activities.BaseLightActivity; +import com.tencent.qcloud.tuikit.tuichat.R; +import com.tencent.qcloud.tuikit.tuichat.bean.EmployeeBean; +import com.tencent.qcloud.tuikit.tuichat.bean.ExpertBean; + +import java.util.ArrayList; +import java.util.List; + +public class AddMemberActivity extends BaseLightActivity { + + public static final int REQUEST_CODE_ADD_MEMBER = 12; + public static final String EXTRA_SELECTED_USER_IDS = "extra_selected_user_ids"; + + private static final int TAB_EMPLOYEE = 0; + private static final int TAB_EXPERT = 1; + private LinearLayout llBack; + private TabLayout tabLayout; + private EditText etSearch; + private RecyclerView rvMembers; + private TextView tvConfirm; + private TextView tvSearchAction; + + private AddMemberViewModel viewModel; + private AddMemberAdapter expertAdapter; + private AddMemberAdapter employeeAdapter; + private int currentTab = TAB_EMPLOYEE; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_add_member); + + viewModel = new ViewModelProvider(this).get(AddMemberViewModel.class); + + initViews(); + initAdapters(); + initObservers(); + initListeners(); + + viewModel.loadExperts(""); + viewModel.loadEmployees(""); + } + + private void initViews() { + llBack = findViewById(R.id.ll_back); + tabLayout = findViewById(R.id.tab_layout); + etSearch = findViewById(R.id.et_search); + rvMembers = findViewById(R.id.rv_members); + tvConfirm = findViewById(R.id.tv_confirm); + tvSearchAction = findViewById(R.id.tv_search_action); + + rvMembers.setLayoutManager(new LinearLayoutManager(this)); + rvMembers.setHasFixedSize(false); + + tabLayout.addTab(tabLayout.newTab().setText(R.string.add_member_tab_employee)); + tabLayout.addTab(tabLayout.newTab().setText(R.string.add_member_tab_expert)); + + setupSearchBox(); + } + + private void setupSearchBox() { + etSearch.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_search, 0, 0, 0); + + etSearch.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + @Override + public void afterTextChanged(Editable s) { + updateClearIconVisibility(s.length() > 0); + } + }); + + etSearch.setOnEditorActionListener((v, actionId, event) -> { + if (actionId == EditorInfo.IME_ACTION_SEARCH + || (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER + && event.getAction() == KeyEvent.ACTION_DOWN)) { + onSearch(v.getText().toString().trim()); + return true; + } + return false; + }); + + etSearch.setOnTouchListener((v, event) -> { + if (event.getAction() != MotionEvent.ACTION_UP) { + return false; + } + Drawable clearIcon = etSearch.getCompoundDrawables()[2]; + if (clearIcon == null) { + return false; + } + int iconWidth = clearIcon.getIntrinsicWidth(); + int rightEdge = etSearch.getWidth() - etSearch.getPaddingRight(); + int leftEdge = rightEdge - iconWidth; + float touchX = event.getX(); + if (touchX >= leftEdge && touchX <= rightEdge) { + etSearch.setText(""); + if (currentTab == TAB_EXPERT) { + viewModel.loadExperts(""); + } else { + viewModel.loadEmployees(""); + } + return true; + } + return false; + }); + } + + private void updateClearIconVisibility(boolean hasText) { + etSearch.setCompoundDrawablesWithIntrinsicBounds( + R.drawable.ic_search, 0, + hasText ? R.drawable.ic_clear : 0, 0); + } + + protected void onSearch(String keyword) { + if (currentTab == TAB_EXPERT) { + viewModel.loadExperts(keyword); + } else { + viewModel.loadEmployees(keyword); + } + } + + private void initAdapters() { + expertAdapter = new AddMemberAdapter<>(new AddMemberAdapter.ItemBinder() { + @Override + public String getUserId(@NonNull ExpertBean item) { + return item.getUserId(); + } + @Override + public String getDisplayName(@NonNull ExpertBean item) { + return item.getRealname(); + } + @Override + public String getDeptName(@NonNull ExpertBean item) { + return item.getDeptName(); + } + @Override + public String getAvatar(@NonNull ExpertBean item) { + return item.getAvatar(); + } + @Override + public String getPost(@NonNull ExpertBean item) { + return item.getPost_dictText(); + } + }); + expertAdapter.setOnItemClickListener((item, position) -> onItemClicked(item.getUserId())); + + employeeAdapter = new AddMemberAdapter<>(new AddMemberAdapter.ItemBinder() { + @Override + public String getUserId(@NonNull EmployeeBean item) { + return item.getUserId(); + } + @Override + public String getDisplayName(@NonNull EmployeeBean item) { + return item.getRealname(); + } + @Override + public String getDeptName(@NonNull EmployeeBean item) { + return item.getDeptName(); + } + @Override + public String getAvatar(@NonNull EmployeeBean item) { + return item.getAvatar(); + } + @Override + public String getPost(@NonNull EmployeeBean item) { + return null; + } + }); + employeeAdapter.setOnItemClickListener((item, position) -> onItemClicked(item.getUserId())); + + rvMembers.setAdapter(employeeAdapter); + } + + private void initObservers() { + viewModel.getExpertsLiveData().observe(this, this::applyExpertData); + viewModel.getEmployeesLiveData().observe(this, this::applyEmployeeData); + } + + private void initListeners() { + llBack.setOnClickListener(v -> finish()); + + tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { + @Override + public void onTabSelected(TabLayout.Tab tab) { + int position = tab.getPosition(); + currentTab = position; + if (position == TAB_EXPERT) { + rvMembers.setAdapter(expertAdapter); + expertAdapter.setSelectedIds(viewModel.getSelectedUserIds()); + } else if (position == TAB_EMPLOYEE) { + rvMembers.setAdapter(employeeAdapter); + employeeAdapter.setSelectedIds(viewModel.getSelectedUserIds()); + } + } + @Override + public void onTabUnselected(TabLayout.Tab tab) {} + @Override + public void onTabReselected(TabLayout.Tab tab) {} + }); + + tvSearchAction.setOnClickListener(v -> onSearch(etSearch.getText().toString().trim())); + tvConfirm.setOnClickListener(v -> onConfirm()); + } + + private void onItemClicked(String userId) { + viewModel.toggleSelected(userId); + refreshSelectionUi(); + } + + private void applyExpertData(List experts) { + expertAdapter.setData(experts); + expertAdapter.setSelectedIds(viewModel.getSelectedUserIds()); + } + + private void applyEmployeeData(List employees) { + employeeAdapter.setData(employees); + employeeAdapter.setSelectedIds(viewModel.getSelectedUserIds()); + } + + private void refreshSelectionUi() { + int count = viewModel.getSelectedCount(); + tvConfirm.setText(count > 0 ? getString(R.string.add_member_confirm) + " (" + count + ")" : getString(R.string.add_member_confirm)); + if (currentTab == TAB_EXPERT) { + expertAdapter.setSelectedIds(viewModel.getSelectedUserIds()); + } else { + employeeAdapter.setSelectedIds(viewModel.getSelectedUserIds()); + } + } + + private void onConfirm() { + ArrayList selected = viewModel.snapshotSelectedUserIds(); + if (selected.isEmpty()) { + Toast.makeText(this, R.string.add_member_empty, Toast.LENGTH_SHORT).show(); + return; + } + Intent data = new Intent(); + data.putStringArrayListExtra(EXTRA_SELECTED_USER_IDS, selected); + setResult(Activity.RESULT_OK, data); + finish(); + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberAdapter.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberAdapter.java new file mode 100644 index 0000000..39af3a8 --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberAdapter.java @@ -0,0 +1,126 @@ +package com.tencent.qcloud.tuikit.tuichat.classicui.page; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.tencent.qcloud.tuicore.component.imageEngine.impl.GlideEngine; +import com.tencent.qcloud.tuikit.tuichat.R; +import com.tencent.qcloud.tuikit.tuichat.presenter.FileBaseUrlHelper; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class AddMemberAdapter extends RecyclerView.Adapter { + + private final List data = new ArrayList<>(); + private final ItemBinder binder; + private final Set selectedIds = new HashSet<>(); + private OnItemClickListener itemClickListener; + + public AddMemberAdapter(@NonNull ItemBinder binder) { + this.binder = binder; + } + + public void setData(List items) { + data.clear(); + if (items != null) { + data.addAll(items); + } + notifyDataSetChanged(); + } + + public void setSelectedIds(Set ids) { + selectedIds.clear(); + if (ids != null) { + selectedIds.addAll(ids); + } + notifyDataSetChanged(); + } + + public void setOnItemClickListener(OnItemClickListener listener) { + this.itemClickListener = listener; + } + + @NonNull + @Override + public MemberViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View itemView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_add_member, parent, false); + return new MemberViewHolder(itemView); + } + + @Override + public void onBindViewHolder(@NonNull MemberViewHolder holder, int position) { + T item = data.get(position); + if (item == null) { + return; + } + final String userId = binder.getUserId(item); + String name = binder.getDisplayName(item); + String dept = binder.getDeptName(item); + String avatar = binder.getAvatar(item); + String post = binder.getPost(item); + + holder.tvName.setText(name); + holder.tvDept.setText(dept == null ? "" : dept); + holder.tvPost.setText(post == null ? "" : post); + String avatarFullPath = FileBaseUrlHelper.getInstance().getIconBaseUrl() + avatar; + GlideEngine.loadUserCircleIcon(holder.ivAvatar, avatarFullPath, R.drawable.default_user_icon); + + boolean checked = userId != null && selectedIds.contains(userId); + holder.cbSelect.setChecked(checked); + + holder.itemView.setOnClickListener(v -> { + if (itemClickListener != null) { + int adapterPosition = holder.getBindingAdapterPosition(); + if (adapterPosition == RecyclerView.NO_POSITION) { + return; + } + itemClickListener.onItemClick(item, adapterPosition); + } + }); + } + + @Override + public int getItemCount() { + return data.size(); + } + + static class MemberViewHolder extends RecyclerView.ViewHolder { + ImageView ivAvatar; + TextView tvName; + TextView tvDept; + TextView tvPost; + CheckBox cbSelect; + + MemberViewHolder(@NonNull View itemView) { + super(itemView); + ivAvatar = itemView.findViewById(R.id.iv_avatar); + tvName = itemView.findViewById(R.id.tv_name); + tvDept = itemView.findViewById(R.id.tv_dept); + cbSelect = itemView.findViewById(R.id.cb_select); + tvPost = itemView.findViewById(R.id.tv_post); + } + } + + public interface ItemBinder { + String getUserId(@NonNull T item); + String getDisplayName(@NonNull T item); + String getDeptName(@NonNull T item); + String getAvatar(@NonNull T item); + String getPost(@NonNull T item); + } + + public interface OnItemClickListener { + void onItemClick(@NonNull T item, int position); + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberViewModel.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberViewModel.java new file mode 100644 index 0000000..1004bb6 --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/AddMemberViewModel.java @@ -0,0 +1,68 @@ +package com.tencent.qcloud.tuikit.tuichat.classicui.page; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +import com.tencent.qcloud.tuikit.tuichat.bean.EmployeeBean; +import com.tencent.qcloud.tuikit.tuichat.bean.ExpertBean; +import com.tencent.qcloud.tuikit.tuichat.presenter.ParamedicOperateHelper; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class AddMemberViewModel extends ViewModel { + + private final MutableLiveData> expertsLiveData = new MutableLiveData<>(); + private final MutableLiveData> employeesLiveData = new MutableLiveData<>(); + private final Set selectedUserIds = new HashSet<>(); + + public LiveData> getExpertsLiveData() { + return expertsLiveData; + } + + public LiveData> getEmployeesLiveData() { + return employeesLiveData; + } + + public Set getSelectedUserIds() { + return Collections.unmodifiableSet(selectedUserIds); + } + + public boolean isSelected(String userId) { + return userId != null && selectedUserIds.contains(userId); + } + + public boolean toggleSelected(String userId) { + if (userId == null) { + return false; + } + if (selectedUserIds.contains(userId)) { + selectedUserIds.remove(userId); + return false; + } + selectedUserIds.add(userId); + return true; + } + + public int getSelectedCount() { + return selectedUserIds.size(); + } + + public ArrayList snapshotSelectedUserIds() { + return new ArrayList<>(selectedUserIds); + } + + public void loadExperts(String searchKey) { + List experts = ParamedicOperateHelper.getInstance().searchExpert(searchKey, "", "", 1, 10); + expertsLiveData.postValue(experts); + } + + public void loadEmployees(String searchKey) { + List employees = ParamedicOperateHelper.getInstance().searchEmployee(searchKey, "", "", "", "", 1, 50); + employeesLiveData.postValue(employees); + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIBaseChatActivity.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIBaseChatActivity.java index bf7dd73..03d8de2 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIBaseChatActivity.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIBaseChatActivity.java @@ -1,46 +1,99 @@ package com.tencent.qcloud.tuikit.tuichat.classicui.page; +import static com.tencent.qcloud.tuikit.tuichat.TUIChatConstants.CHAT_IS_LIAISON_USER; + import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; +import android.view.View; +import android.widget.TextView; import androidx.annotation.Nullable; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.navigation.NavigationView; import com.tencent.imsdk.v2.V2TIMGroupAtInfo; import com.tencent.imsdk.v2.V2TIMMessage; import com.tencent.qcloud.tuicore.TUIConstants; import com.tencent.qcloud.tuicore.TUICore; import com.tencent.qcloud.tuicore.TUILogin; import com.tencent.qcloud.tuicore.component.activities.BaseLightActivity; +import com.tencent.qcloud.tuicore.util.SPUtils; import com.tencent.qcloud.tuicore.util.ToastUtil; import com.tencent.qcloud.tuikit.tuichat.R; import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo; import com.tencent.qcloud.tuikit.tuichat.bean.DraftInfo; import com.tencent.qcloud.tuikit.tuichat.bean.GroupInfo; +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMember; +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMemberBean; import com.tencent.qcloud.tuikit.tuichat.bean.GroupMemberInfo; import com.tencent.qcloud.tuikit.tuichat.bean.WorkBean; import com.tencent.qcloud.tuikit.tuichat.bean.message.TUIMessageBean; +import com.tencent.qcloud.tuikit.tuichat.classicui.event.CustomMessageEvent; import com.tencent.qcloud.tuikit.tuichat.classicui.setting.InputActionSetting; +import com.tencent.qcloud.tuikit.tuichat.config.TUIChatConfigs; +import com.tencent.qcloud.tuikit.tuichat.presenter.ParamedicOperateHelper; import com.tencent.qcloud.tuikit.tuichat.util.ChatMessageBuilder; +import com.tencent.qcloud.tuikit.tuichat.util.ChatMessageParser; import com.tencent.qcloud.tuikit.tuichat.util.TUIChatLog; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.ArrayList; import java.util.HashMap; import java.util.List; public abstract class TUIBaseChatActivity extends BaseLightActivity { private static final String TAG = TUIBaseChatActivity.class.getSimpleName(); + private int mWirkState = -1; public InputActionSetting inputActionSetting; + private DrawerLayout drawerLayout; + public TextView tvTitle; + /** 右侧抽屉中的群成员列表,供子类(如 TUIGroupChatActivity)绑定 Adapter */ + public RecyclerView rvMembers; + public TextView tvAddMember; + public TextView tvUpdateMember; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { TUIChatLog.i(TAG, "onCreate " + this); super.onCreate(savedInstanceState); - setContentView(R.layout.chat_activity); + setContentView(R.layout.chat_activity_with_navigation); + drawerLayout = findViewById(R.id.drawer_layout); + NavigationView navigationView = findViewById(R.id.nav_view_right); + View headerView = navigationView.getHeaderView(0); + tvTitle = headerView.findViewById(R.id.tv_title); + rvMembers = headerView.findViewById(R.id.rv_members); + tvAddMember = headerView.findViewById(R.id.tv_add_member); + tvUpdateMember = headerView.findViewById(R.id.tv_update_member); + chat(getIntent()); } + public void openDrawer() { + if (drawerLayout != null) { + drawerLayout.openDrawer(GravityCompat.END); + } + } + + public boolean closeDrawer() { + if (drawerLayout != null && drawerLayout.isDrawerOpen(GravityCompat.END)) { + drawerLayout.closeDrawer(GravityCompat.END); + return true; + } + return false; + } + + public int getmWirkState() { + return mWirkState; + } + @Override protected void onNewIntent(Intent intent) { TUIChatLog.i(TAG, "onNewIntent"); @@ -48,12 +101,47 @@ public abstract class TUIBaseChatActivity extends BaseLightActivity { chat(intent); } + @Override + protected void onStart() { + super.onStart(); + if (!EventBus.getDefault().isRegistered(this)) { + EventBus.getDefault().register(this); + } + } + @Override protected void onResume() { TUIChatLog.i(TAG, "onResume"); super.onResume(); } + @Override + protected void onStop() { + super.onStop(); + if (!EventBus.getDefault().isRegistered(this)) { + EventBus.getDefault().unregister(this); + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(CustomMessageEvent event) { + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + @Override + public void onBackPressed() { + if (!closeDrawer()) { + if (mWirkState != -1) { + TUIChatConfigs.getConfigs().getImInputViewActionListener().finishActivityToGuidanceHome(mWirkState); + } + super.onBackPressed(); + } + } + private void chat(Intent intent) { Bundle bundle = intent.getExtras(); TUIChatLog.i(TAG, "bundle: " + bundle + " intent: " + intent); @@ -62,11 +150,16 @@ public abstract class TUIBaseChatActivity extends BaseLightActivity { finish(); return; } - if(inputActionSetting == null){ - inputActionSetting = InputActionSetting.createInstance().copy(); + if (inputActionSetting == null) { + InputActionSetting fromIntent = (InputActionSetting) intent.getSerializableExtra("inputActionSetting"); + if (fromIntent != null) { + inputActionSetting = fromIntent; + } else { + inputActionSetting = InputActionSetting.createInstance().copy(); + } } + startVideoCall(intent); ChatInfo chatInfo = getChatInfo(intent); - chatInfo.setInputActionSetting(inputActionSetting); TUIChatLog.i(TAG, "start chatActivity chatInfo: " + chatInfo); if (chatInfo != null) { @@ -85,6 +178,8 @@ public abstract class TUIBaseChatActivity extends BaseLightActivity { super.onActivityResult(requestCode, resultCode, data); if (resultCode == 3 && data != null) { if (requestCode == 11) { + ArrayList stringList2 = data.getStringArrayListExtra("user_namecard_select"); + ChatMessageParser.setSelectName(stringList2); List stringList = data.getStringArrayListExtra("list"); if (stringList != null && !stringList.isEmpty()) { String[] stringArray = stringList.toArray(new String[]{}); @@ -101,6 +196,12 @@ public abstract class TUIBaseChatActivity extends BaseLightActivity { } + /** + * 添加成员回传结果处理:由子类(如 TUIGroupChatActivity)实现具体逻辑 + */ + protected void onAddMemberResult(ArrayList selectedUserIds) { + } + private ChatInfo getChatInfo(Intent intent) { int chatType = intent.getIntExtra(TUIConstants.TUIChat.CHAT_TYPE, ChatInfo.TYPE_INVALID); ChatInfo chatInfo; @@ -125,7 +226,13 @@ public abstract class TUIBaseChatActivity extends BaseLightActivity { chatInfo.setLocateMessage(messageInfo); chatInfo.setAtInfoList((List) intent.getSerializableExtra(TUIConstants.TUIChat.AT_INFO_LIST)); chatInfo.setFaceUrl(intent.getStringExtra(TUIConstants.TUIChat.FACE_URL)); - chatInfo.setWorkBean((WorkBean) intent.getSerializableExtra(TUIConstants.TUIChat.WORK_BEAN)); + chatInfo.setAutoSendMessage(intent.getStringExtra(TUIConstants.TUIChat.AUTO_SEND_MESSAGE)); + chatInfo.setConsultantId(intent.getStringExtra(TUIConstants.TUIChat.CONSULTANT_ID)); + WorkBean woekBean = (WorkBean) intent.getSerializableExtra(TUIConstants.TUIChat.WORK_BEAN); + chatInfo.setWorkBean(woekBean); + if (woekBean != null) { + mWirkState = woekBean.getWorkState(); + } if (chatType == ChatInfo.TYPE_GROUP) { GroupInfo groupInfo = (GroupInfo) chatInfo; groupInfo.setGroupName(intent.getStringExtra(TUIConstants.TUIChat.GROUP_NAME)); @@ -136,11 +243,35 @@ public abstract class TUIBaseChatActivity extends BaseLightActivity { groupInfo.setNotice(intent.getStringExtra(TUIConstants.TUIChat.NOTICE)); groupInfo.setOwner(intent.getStringExtra(TUIConstants.TUIChat.OWNER)); groupInfo.setMemberDetails((List) intent.getSerializableExtra(TUIConstants.TUIChat.MEMBER_DETAILS)); + List list = ParamedicOperateHelper.getInstance().getActualGroupMemberList(chatInfo.getId()); + if (list != null && !list.isEmpty()) { + groupInfo.setMemberDetails(GroupMember.convertFromBeanList(list)); + } } - if (TextUtils.isEmpty(chatInfo.getId())) { return null; } return chatInfo; } + + /** + * 跳转视频通话 + */ + private void startVideoCall(Intent intent) { + Boolean initiateVideoCall = intent.getBooleanExtra(TUIConstants.TUIChat.INITIATE_VIDEO_CALL, false); + if (!initiateVideoCall) { + return; + } + String groupId = intent.getStringExtra(TUIConstants.TUIChat.CHAT_ID); + List userIDs = intent.getStringArrayListExtra(TUIConstants.TUICalling.PARAM_NAME_USERIDS); + if (userIDs == null || userIDs.isEmpty()) { + return; + } + HashMap hashMap = new HashMap<>(); + hashMap.put(TUIConstants.TUICalling.PARAM_NAME_GROUPID, groupId); + hashMap.put(TUIConstants.TUICalling.PARAM_NAME_USERIDS, userIDs.toArray(new String[]{})); + hashMap.put(TUIConstants.TUICalling.PARAM_NAME_TYPE, TUIConstants.TUICalling.TYPE_VIDEO); + TUICore.callService(TUIConstants.TUICalling.SERVICE_NAME, + TUIConstants.TUICalling.METHOD_NAME_CALL, hashMap); + } } diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIBaseChatFragment.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIBaseChatFragment.java index 3dba30a..5bb6d94 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIBaseChatFragment.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIBaseChatFragment.java @@ -22,6 +22,8 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import com.tencent.imsdk.v2.V2TIMMessage; import com.tencent.qcloud.tuicore.TUIConfig; import com.tencent.qcloud.tuicore.TUIConstants; @@ -33,22 +35,30 @@ import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback; import com.tencent.qcloud.tuicore.util.ToastUtil; import com.tencent.qcloud.tuikit.tuichat.R; import com.tencent.qcloud.tuikit.tuichat.TUIChatConstants; +import com.tencent.qcloud.tuikit.tuichat.TUIChatService; import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo; import com.tencent.qcloud.tuikit.tuichat.bean.message.CallingMessageBean; import com.tencent.qcloud.tuikit.tuichat.bean.message.LocationMessageBean; import com.tencent.qcloud.tuikit.tuichat.bean.message.TUIMessageBean; +import com.tencent.qcloud.tuikit.tuichat.classicui.event.CustomMessageEvent; import com.tencent.qcloud.tuikit.tuichat.classicui.setting.ChatLayoutSetting; +import com.tencent.qcloud.tuikit.tuichat.classicui.setting.InputActionSetting; import com.tencent.qcloud.tuikit.tuichat.component.AudioPlayer; import com.tencent.qcloud.tuikit.tuichat.classicui.interfaces.OnItemClickListener; import com.tencent.qcloud.tuikit.tuichat.classicui.widget.ChatView; import com.tencent.qcloud.tuikit.tuichat.classicui.widget.input.InputView; import com.tencent.qcloud.tuikit.tuichat.classicui.widget.message.MessageRecyclerView; +import com.tencent.qcloud.tuikit.tuichat.config.TUIChatConfigs; import com.tencent.qcloud.tuikit.tuichat.presenter.ChatPresenter; import com.tencent.qcloud.tuikit.tuichat.util.ChatMessageBuilder; import com.tencent.qcloud.tuikit.tuichat.util.DataStoreUtil; import com.tencent.qcloud.tuikit.tuichat.util.TUIChatLog; import com.tencent.qcloud.tuikit.tuichat.util.TUIChatUtils; +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -86,6 +96,17 @@ public class TUIBaseChatFragment extends BaseFragment { return baseView; } + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + if (!EventBus.getDefault().isRegistered(this)) { + EventBus.getDefault().register(this); + } + } + + protected void finishEvent(){ + } + protected void initView() { chatView = baseView.findViewById(R.id.chat_layout); chatView.setFragment(TUIBaseChatFragment.this); @@ -97,6 +118,7 @@ public class TUIBaseChatFragment extends BaseFragment { public void onClick(View view) { InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(chatView.getWindowToken(), 0); + finishEvent(); getActivity().finish(); } }); @@ -267,6 +289,10 @@ public class TUIBaseChatFragment extends BaseFragment { String messageJson = data.getStringExtra(ChatLayoutSetting.KEY_CUSTOM_MESSAGE); if (ChatLayoutSetting.RESULT_CODE_LOCATION == resultCode) { sendLocationMessage(messageJson); + } else if (ChatLayoutSetting.RESULT_CODE_ARCHIVES == resultCode) { + sendCustomMessage(messageJson); + } else if (ChatLayoutSetting.RESULT_CODE_MEDICAL_EXAMINATION_REPORT == resultCode) { + sendCustomMessage(messageJson); } } } @@ -319,6 +345,49 @@ public class TUIBaseChatFragment extends BaseFragment { public ChatPresenter getPresenter() { return null; } + public InputActionSetting getInputActionSetting(){ + return null; + } + + @Override + public void onStart() { + super.onStart(); + TUIChatLog.e(TAG, "onStart"); + if (!EventBus.getDefault().isRegistered(this)) { + EventBus.getDefault().register(this); + } + } + + @Override + public void onStop() { + super.onStop(); + TUIChatLog.e(TAG, "onStop"); + if (!EventBus.getDefault().isRegistered(this)) { + EventBus.getDefault().unregister(this); + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + public void onMessageEvent(CustomMessageEvent customMessageEvent) { + if (customMessageEvent == null) { + return; + } + if (isVisible() && customMessageEvent.getChatId().equals(getChatInfo().getId())) { + sendCustomMessage(customMessageEvent.getMessageJson()); + } + } + + public void sendCustomMessage(String messageJson) { + if (chatView != null && !TextUtils.isEmpty(messageJson)) { + JsonObject tuiMessageObj = new Gson().fromJson(messageJson, JsonObject.class); + TUIChatLog.i(TAG, "customMessageEvent msgContent:" + new Gson().toJson(tuiMessageObj)); + JsonElement extensionJson = tuiMessageObj.get("extension"); + String extension = extensionJson == null ? TUIChatService.getAppContext().getString(R.string.custom_msg) : extensionJson.getAsString(); + TUIMessageBean info = ChatMessageBuilder.buildCustomMessage(messageJson, extension + , extension.getBytes()); + chatView.sendMessage(info, false); + } + } protected void initChatViewBackground() { if (getChatInfo() == null) { diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIGroupChatActivity.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIGroupChatActivity.java index 8e5294e..54c7285 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIGroupChatActivity.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIGroupChatActivity.java @@ -1,21 +1,38 @@ package com.tencent.qcloud.tuikit.tuichat.classicui.page; +import static com.tencent.qcloud.tuicore.util.ToastUtil.toastShortMessage; +import static com.tencent.qcloud.tuikit.tuichat.classicui.page.AddMemberActivity.EXTRA_SELECTED_USER_IDS; + +import android.content.Intent; import android.os.Bundle; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearLayoutManager; + import com.tencent.qcloud.tuicore.util.ToastUtil; import com.tencent.qcloud.tuikit.tuichat.R; import com.tencent.qcloud.tuikit.tuichat.TUIChatConstants; import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo; import com.tencent.qcloud.tuikit.tuichat.bean.GroupInfo; +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMember; +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMemberBean; +import com.tencent.qcloud.tuikit.tuichat.bean.message.TipsMessageBean; +import com.tencent.qcloud.tuikit.tuichat.classicui.widget.ChatView; +import com.tencent.qcloud.tuikit.tuichat.classicui.widget.GroupMemberNavAdapter; import com.tencent.qcloud.tuikit.tuichat.presenter.GroupChatPresenter; +import com.tencent.qcloud.tuikit.tuichat.presenter.ParamedicOperateHelper; import com.tencent.qcloud.tuikit.tuichat.util.TUIChatLog; import com.tencent.qcloud.tuikit.tuichat.util.TUIChatUtils; +import java.util.List; + public class TUIGroupChatActivity extends TUIBaseChatActivity { private static final String TAG = TUIGroupChatActivity.class.getSimpleName(); private TUIGroupChatFragment chatFragment; private GroupChatPresenter presenter; + private GroupInfo groupInfo; + private GroupMemberNavAdapter adapter; @Override public void initChat(ChatInfo chatInfo) { @@ -25,15 +42,84 @@ public class TUIGroupChatActivity extends TUIBaseChatActivity { TUIChatLog.e(TAG, "init group chat failed , chatInfo = " + chatInfo); ToastUtil.toastShortMessage("init group chat failed."); } - GroupInfo groupInfo = (GroupInfo) chatInfo; + groupInfo = (GroupInfo) chatInfo; chatFragment = new TUIGroupChatFragment(); Bundle bundle = new Bundle(); bundle.putSerializable(TUIChatConstants.CHAT_INFO, groupInfo); + bundle.putSerializable("inputActionSetting", inputActionSetting); + bundle.putInt(TUIChatConstants.WEEK_STATE, getmWirkState()); chatFragment.setArguments(bundle); presenter = new GroupChatPresenter(); presenter.initListener(); chatFragment.setPresenter(presenter); getSupportFragmentManager().beginTransaction().replace(R.id.empty_view, chatFragment).commitAllowingStateLoss(); + + if (tvTitle != null) { + tvTitle.setText(String.format("群成员 (%d)", groupInfo.getMemberCount())); + } + + // 绑定群成员列表 Adapter,数据来源于 GroupInfo.memberDetails + if (rvMembers != null) { + rvMembers.setLayoutManager(new LinearLayoutManager(this)); + adapter = new GroupMemberNavAdapter(); + List memberList = (List) groupInfo.getMemberDetails(); + adapter.setMembers(memberList); + rvMembers.setAdapter(adapter); + } + if (tvAddMember != null) { + tvAddMember.setOnClickListener(v -> { + // 跳转添加成员页面 + Intent intent = new Intent(TUIGroupChatActivity.this, AddMemberActivity.class); + intent.putExtra(TUIChatConstants.GROUP_ID, groupInfo.getId()); + startActivityForResult(intent, AddMemberActivity.REQUEST_CODE_ADD_MEMBER); + }); + } + if (tvUpdateMember != null) { + tvUpdateMember.setOnClickListener(v -> { + List list = ParamedicOperateHelper.getInstance() + .getActualGroupMemberList(groupInfo.getId()); + runOnUiThread(() -> { + adapter.setMembers(GroupMember.convertFromBeanList(list)); + tvTitle.setText(String.format("群成员 (%d)", list.size())); + toastShortMessage("群成员已更新"); + }); + }); + } + + // OnGroupTipsListener:群成员加入时自动刷新列表 + ChatView.OnGroupTipsListener onGroupTipsListener = new ChatView.OnGroupTipsListener() { + @Override + public void onGroupJoin(TipsMessageBean message) { + List list = ParamedicOperateHelper.getInstance() + .getActualGroupMemberList(groupInfo.getId()); + runOnUiThread(() -> { + adapter.setMembers(GroupMember.convertFromBeanList(list)); + tvTitle.setText(String.format("群成员 (%d)", list.size())); + }); + } + }; + chatFragment.setOnGroupTipsListener(onGroupTipsListener); } -} \ No newline at end of file + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == AddMemberActivity.REQUEST_CODE_ADD_MEMBER && resultCode == RESULT_OK) { + if (data != null) { + List memberList = (List) data.getSerializableExtra(EXTRA_SELECTED_USER_IDS); + if (memberList != null && !memberList.isEmpty() && adapter != null && groupInfo != null) { + ParamedicOperateHelper.getInstance().addGroupUser(groupInfo.getId(), memberList, 0, success -> { + if (!success) { + runOnUiThread(() -> ToastUtil.toastShortMessage("添加群成员失败")); + return; + } + List list = ParamedicOperateHelper.getInstance() + .getActualGroupMemberList(groupInfo.getId()); + runOnUiThread(() -> adapter.setMembers(GroupMember.convertFromBeanList(list))); + }); + } + } + } + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIGroupChatFragment.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIGroupChatFragment.java index bae69ff..5ec3e29 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIGroupChatFragment.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/page/TUIGroupChatFragment.java @@ -1,29 +1,61 @@ package com.tencent.qcloud.tuikit.tuichat.classicui.page; +import android.app.Dialog; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; import android.os.Bundle; +import android.text.TextUtils; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.TextView; import androidx.annotation.Nullable; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import com.tencent.imsdk.v2.V2TIMMessage; import com.tencent.qcloud.tuicore.TUIConstants; import com.tencent.qcloud.tuicore.TUICore; +import com.tencent.qcloud.tuicore.TUILogin; +import com.tencent.qcloud.tuicore.component.imageEngine.impl.GlideEngine; +import com.tencent.qcloud.tuicore.component.interfaces.IUIKitCallback; +import com.tencent.qcloud.tuikit.tuichat.R; import com.tencent.qcloud.tuikit.tuichat.TUIChatConstants; +import com.tencent.qcloud.tuikit.tuichat.TUIChatService; import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo; import com.tencent.qcloud.tuikit.tuichat.bean.GroupInfo; +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMember; +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMemberInfo; import com.tencent.qcloud.tuikit.tuichat.bean.message.TUIMessageBean; import com.tencent.qcloud.tuikit.tuichat.classicui.interfaces.OnItemClickListener; +import com.tencent.qcloud.tuikit.tuichat.classicui.setting.InputActionSetting; +import com.tencent.qcloud.tuikit.tuichat.classicui.widget.ChatView; +import com.tencent.qcloud.tuikit.tuichat.config.TUIChatConfigs; +import com.tencent.qcloud.tuikit.tuichat.presenter.FileBaseUrlHelper; import com.tencent.qcloud.tuikit.tuichat.presenter.GroupChatPresenter; +import com.tencent.qcloud.tuikit.tuichat.util.ChatMessageBuilder; import com.tencent.qcloud.tuikit.tuichat.util.TUIChatLog; -import com.tencent.qcloud.tuikit.tuichat.util.TUIChatUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; public class TUIGroupChatFragment extends TUIBaseChatFragment { private static final String TAG = TUIGroupChatFragment.class.getSimpleName(); private GroupChatPresenter presenter; private GroupInfo groupInfo; + private InputActionSetting inputActionSetting; + private int mWeekState = -1; + private ChatView.OnGroupTipsListener cachedGroupTipsListener; @Nullable @Override @@ -35,7 +67,9 @@ public class TUIGroupChatFragment extends TUIBaseChatFragment { if (bundle == null) { return baseView; } + mWeekState = bundle.getInt(TUIChatConstants.WEEK_STATE); groupInfo = (GroupInfo) bundle.getSerializable(TUIChatConstants.CHAT_INFO); + inputActionSetting = (InputActionSetting) bundle.getSerializable("inputActionSetting"); if (groupInfo == null) { return baseView; } @@ -44,17 +78,30 @@ public class TUIGroupChatFragment extends TUIBaseChatFragment { return baseView; } + @Override + protected void finishEvent() { + if (mWeekState != -1) { + TUIChatConfigs.getConfigs().getImInputViewActionListener().finishActivityToGuidanceHome(mWeekState); + } + super.finishEvent(); + } + + public void setOnGroupTipsListener(ChatView.OnGroupTipsListener listener){ + // 始终缓存 listener,避免因 commitAllowingStateLoss() 异步导致的时序问题 + this.cachedGroupTipsListener = listener; + } + @Override protected void initView() { super.initView(); chatView.setPresenter(presenter); presenter.setGroupInfo(groupInfo); chatView.setChatInfo(groupInfo); + autoSendMessage(); chatView.getMessageLayout().setOnItemClickListener(new OnItemClickListener() { @Override public void onMessageLongClick(View view, int position, TUIMessageBean messageBean) { // 因为adapter中第一条为加载条目,位置需减1 - // Because the first entry in the adapter is the load entry, the position needs to be decremented by 1 chatView.getMessageLayout().showItemPopMenu(position - 1, messageBean, view); } @@ -63,14 +110,13 @@ public class TUIGroupChatFragment extends TUIBaseChatFragment { if (null == messageBean) { return; } - //当前项目不需要跳转个人信息 -// ChatInfo info = new ChatInfo(); -// info.setId(messageBean.getSender()); -// -// Bundle bundle = new Bundle(); -// bundle.putString(TUIConstants.TUIChat.CHAT_ID, info.getId()); -// TUICore.startActivity("FriendProfileActivity", bundle); - + String id = messageBean.getSender(); + for (GroupMemberInfo groupMemberInfo : groupInfo.getMemberDetails()) { + if (groupMemberInfo.getAccount().equals(id)) { + showPhoneCallDialog((GroupMember) groupMemberInfo); + break; + } + } } @Override @@ -86,7 +132,7 @@ public class TUIGroupChatFragment extends TUIBaseChatFragment { return; } int messageType = messageInfo.getMsgType(); - if (messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT){ + if (messageType == V2TIMMessage.V2TIM_ELEM_TYPE_TEXT) { chatView.getInputLayout().appendText(messageInfo.getV2TIMMessage().getTextElem().getText()); } else { TUIChatLog.e(TAG, "error type: " + messageType); @@ -105,21 +151,23 @@ public class TUIGroupChatFragment extends TUIBaseChatFragment { } }); - chatView.getTitleBar().setOnRightClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (TUIChatUtils.isTopicGroup(groupInfo.getId())) { - Bundle bundle = new Bundle(); - bundle.putString(TUIConstants.TUICommunity.TOPIC_ID, groupInfo.getId()); - TUICore.startActivity(getContext(), "TopicInfoActivity", bundle); - } else { - Bundle bundle = new Bundle(); - bundle.putString(TUIChatConstants.Group.GROUP_ID, groupInfo.getId()); - bundle.putString(TUIConstants.TUIChat.CHAT_BACKGROUND_URI, mChatBackgroundThumbnailUrl); - TUICore.startActivity(getContext(), "GroupInfoActivity", bundle); - } + chatView.getTitleBar().setOnRightClickListener(view -> { + // 打开右侧抽屉 + TUIGroupChatActivity activity = (TUIGroupChatActivity) getActivity(); + if (activity != null) { + activity.openDrawer(); } }); + + titleBar.getRightGroup().setVisibility(View.VISIBLE); + titleBar.getRightTitle().setVisibility(View.GONE); + titleBar.getRightIcon().setVisibility(View.VISIBLE); + titleBar.getRightIcon().setImageResource(R.drawable.chat_title_bar_more_menu_lively); + + // 应用缓存的 OnGroupTipsListener,解决 Activity 中提前设置 listener 的时序问题 + if (cachedGroupTipsListener != null && chatView != null) { + chatView.setOnGroupTipsListener(cachedGroupTipsListener); + } } public void setPresenter(GroupChatPresenter presenter) { @@ -135,4 +183,139 @@ public class TUIGroupChatFragment extends TUIBaseChatFragment { public ChatInfo getChatInfo() { return groupInfo; } + + @Override + public InputActionSetting getInputActionSetting() { + return inputActionSetting; + } + + private void autoSendMessage() { + String message = groupInfo.getAutoSendMessage(); + if (TextUtils.isEmpty(message)) { + return; + } + JsonObject tuiMessageObj = new Gson().fromJson(message, JsonObject.class); + JsonElement extensionJson = tuiMessageObj.get("extension"); + String extension = extensionJson == null ? TUIChatService.getAppContext().getString(R.string.custom_msg) : extensionJson.getAsString(); + TUIMessageBean info = ChatMessageBuilder.buildCustomMessage(message, extension + , extension.getBytes()); + chatView.sendMessage(info, false); + + } + + /** + * 显示电话拨打弹窗 + */ + private void showPhoneCallDialog(GroupMember groupMember) { + if (groupMember == null || getActivity() == null) { + return; + } + String phone = groupMember.getPhone(); + + Dialog dialog = new Dialog(getActivity()); + dialog.setContentView(R.layout.dialog_phone_call); + + Window window = dialog.getWindow(); + if (window != null) { + // 背景透明,使用布局自身的圆角白色背景 + window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + WindowManager.LayoutParams params = window.getAttributes(); + params.width = WindowManager.LayoutParams.WRAP_CONTENT; + params.height = WindowManager.LayoutParams.WRAP_CONTENT; + params.gravity = Gravity.CENTER; + window.setAttributes(params); + } + dialog.setCancelable(true); + dialog.setCanceledOnTouchOutside(true); + + // 绑定视图 + ImageView ivAvatar = dialog.findViewById(R.id.iv_avatar); + ImageView ivClose = dialog.findViewById(R.id.iv_close); + TextView tvName = dialog.findViewById(R.id.tv_name); + TextView tvPhone = dialog.findViewById(R.id.tv_phone); + View btnCall = dialog.findViewById(R.id.btn_call); + View btnCancel = dialog.findViewById(R.id.btn_cancel); + + // 头像加载(圆形) + String avatar = FileBaseUrlHelper.getInstance().getIconBaseUrl() + groupMember.getAvatar(); + GlideEngine.loadUserCircleIcon(ivAvatar, avatar, R.drawable.default_user_icon); + // 姓名 + String name = groupMember.getUserName(); + if (groupMember.getIsSelf() == 1) { + name = "我"; + } + tvName.setText(name); + // 电话号码占位 + tvPhone.setText(phone); + + // 关闭按钮与取消按钮 + ivClose.setOnClickListener(v -> dialog.dismiss()); + btnCancel.setOnClickListener(v -> dialog.dismiss()); + + // 拨打电话:拉起系统拨号界面 + btnCall.setOnClickListener(v -> { + try { + Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phone)); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } catch (Exception e) { + TUIChatLog.e(TAG, "拉起系统拨号失败: " + e.getMessage()); + } + dialog.dismiss(); + }); + + dialog.show(); + } + + /** + * 发起视频通话 + */ + private void initiateVideoCall() { + presenter.loadGroupMembers(groupInfo.getId(), new IUIKitCallback>() { + @Override + public void onSuccess(List data) { + startVideoCall(data); + } + }); + } + + /** + * 跳转视频通话 + */ + private void startVideoCall(List data) { + if (data == null || data.isEmpty()) { + return; + } + data = filterMember(data); + HashMap hashMap = new HashMap<>(); + hashMap.put(TUIConstants.TUICalling.PARAM_NAME_GROUPID, groupInfo.getId()); + hashMap.put(TUIConstants.TUICalling.PARAM_NAME_USERIDS, getMembersAccount(data).toArray(new String[]{})); + hashMap.put(TUIConstants.TUICalling.PARAM_NAME_TYPE, TUIConstants.TUICalling.TYPE_VIDEO); + TUICore.callService(TUIConstants.TUICalling.SERVICE_NAME, + TUIConstants.TUICalling.METHOD_NAME_CALL, hashMap); + } + + private List filterMember(List list) { + for (int i = list.size() - 1; i >= 0; i--) { + if (TUILogin.getUserId().equals(list.get(i).getAccount())) { + list.remove(i); + } + if ("000000".equals(list.get(i).getAccount())) { + list.remove(i); + } + } + return list; + } + + private List getMembersAccount(List mMembers) { + if (mMembers.size() == 0) { + return new ArrayList<>(); + } + + List friendIdList = new ArrayList<>(); + for (int i = 0; i < mMembers.size(); i++) { + friendIdList.add(mMembers.get(i).getAccount()); + } + return friendIdList; + } } diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/setting/ChatLayoutSetting.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/setting/ChatLayoutSetting.java index 1e05218..6979a80 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/setting/ChatLayoutSetting.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/setting/ChatLayoutSetting.java @@ -61,7 +61,7 @@ public class ChatLayoutSetting { } } - public void customizeChatLayout(final ChatView layout) { + public void customizeChatLayout(final ChatView layout, InputActionSetting inputActionSetting) { // //====== NoticeLayout使用范例 ======// //====== NoticeLayout example======// @@ -187,6 +187,13 @@ public class ChatLayoutSetting { //====== InputLayout使用范例 ======// //====== InputLayout example ======// final InputView inputView = layout.getInputLayout(); + InputActionSetting mInputActionSetting = inputActionSetting; + if (mInputActionSetting == null){ + mInputActionSetting = InputActionSetting.getsInstance(); + if (mInputActionSetting == null) { + mInputActionSetting = new InputActionSetting(); + } + } // // TODO 隐藏音频输入的入口,可以打开下面代码测试 // // To hide the entrance of audio input, you can open the following code to test @@ -220,7 +227,7 @@ public class ChatLayoutSetting { //隐藏音频通话 inputView.disableAudioCall(true); //隐藏视频通话 - inputView.disableVideoCall(true); + inputView.disableVideoCall(mInputActionSetting.isDisableVideoCall()); // 增加名片 InputMoreActionUnit businessCardUnit = new InputMoreActionUnit() { @@ -291,7 +298,9 @@ public class ChatLayoutSetting { actionClick(layout, endConsultUnit.getActionId()); } }); - inputView.addAction(endConsultUnit); + if(!mInputActionSetting.isDisableFinishSession()){ + inputView.addAction(endConsultUnit); + } // 评价 InputMoreActionUnit evaluationUnit = new InputMoreActionUnit() { }; diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/setting/InputActionSetting.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/setting/InputActionSetting.java index fddbd66..48c8419 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/setting/InputActionSetting.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/setting/InputActionSetting.java @@ -26,6 +26,43 @@ public class InputActionSetting implements Serializable { private boolean disableAudioCall = false; private boolean disableVideoCall = false; private boolean disableSendMessage = false; + private boolean disableFinishSession = false; + public boolean disableFinishName = false; + public String packageName=""; + public String CurrentResourceHost=""; + public boolean disableEvaluate = false; + + public String getCurrentResourceHost() { + return CurrentResourceHost == null ? "" : CurrentResourceHost; + } + + public void setCurrentResourceHost(String currentResourceHost) { + CurrentResourceHost = currentResourceHost; + } + + public String getPackageName() { + return packageName == null ? "" : packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public static InputActionSetting getsInstance() { + return sInstance; + } + + public static void setsInstance(InputActionSetting sInstance) { + InputActionSetting.sInstance = sInstance; + } + + public boolean isDisableEvaluate() { + return disableEvaluate; + } + + public void setDisableEvaluate(boolean disableEvaluate) { + this.disableEvaluate = disableEvaluate; + } public boolean isDisableVideoRecord() { return disableVideoRecord; @@ -74,6 +111,23 @@ public class InputActionSetting implements Serializable { public void setDisableSendMessage(boolean disableSendMessage) { this.disableSendMessage = disableSendMessage; } + + public boolean isDisableFinishSession() { + return disableFinishSession; + } + + public void setDisableFinishSession(boolean disableFinishSession) { + this.disableFinishSession = disableFinishSession; + } + + public boolean isDisableFinishName() { + return disableFinishName; + } + + public void setDisableFinishName(boolean disableFinishName) { + this.disableFinishName = disableFinishName; + } + public InputActionSetting copy(){ InputActionSetting inputActionSetting = new InputActionSetting(); inputActionSetting.setDisableArchives(disableArchives); @@ -82,6 +136,8 @@ public class InputActionSetting implements Serializable { inputActionSetting.setDisableVideoCall(disableVideoCall); inputActionSetting.setDisableVideoRecord(disableVideoRecord); inputActionSetting.setDisableMedicalExaminationReport(disableMedicalExaminationReport); + inputActionSetting.setDisableFinishSession(disableFinishSession); + inputActionSetting.setDisableFinishName(disableFinishName); return inputActionSetting; } } diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/widget/ChatView.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/widget/ChatView.java index a7d569b..7e76177 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/widget/ChatView.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/widget/ChatView.java @@ -51,6 +51,7 @@ import com.tencent.qcloud.tuikit.tuichat.bean.MessageTyping; import com.tencent.qcloud.tuikit.tuichat.bean.ReplyPreviewBean; import com.tencent.qcloud.tuikit.tuichat.bean.message.ReplyMessageBean; import com.tencent.qcloud.tuikit.tuichat.bean.message.SystemMessageBean; +import com.tencent.qcloud.tuikit.tuichat.bean.message.TipsMessageBean; import com.tencent.qcloud.tuikit.tuichat.bean.message.TUIMessageBean; import com.tencent.qcloud.tuikit.tuichat.classicui.setting.InputActionSetting; import com.tencent.qcloud.tuikit.tuichat.component.AudioPlayer; @@ -148,6 +149,7 @@ public class ChatView extends LinearLayout implements IChatLayout { private boolean isSupportTyping = false; private ChatPresenter presenter; + private OnGroupTipsListener onGroupTipsListener; ChatLayoutSetting chatLayoutSetting; public ChatView(Context context) { @@ -261,6 +263,15 @@ public class ChatView extends LinearLayout implements IChatLayout { public void setFragment(Fragment fragment) { this.fragment = fragment; } + + public interface OnGroupTipsListener { + void onGroupJoin(TipsMessageBean message); + } + + public void setOnGroupTipsListener(OnGroupTipsListener onGroupTipsListener) { + this.onGroupTipsListener = onGroupTipsListener; + } + private void initGroupAtInfoLayout() { if (mChatInfo != null) { List groupAtInfos = mChatInfo.getAtInfoList(); @@ -458,6 +469,14 @@ public class ChatView extends LinearLayout implements IChatLayout { goneInputLayout(); } } + + if (message instanceof TipsMessageBean) { + TipsMessageBean tips = (TipsMessageBean) message; + if (tips.getTipType() == TipsMessageBean.MSG_TYPE_GROUP_JOIN + && onGroupTipsListener != null) { + onGroupTipsListener.onGroupJoin(tips); + } + } } @Override @@ -923,7 +942,7 @@ public class ChatView extends LinearLayout implements IChatLayout { mMessageRecyclerView.setAdapter(mAdapter); } chatLayoutSetting = new ChatLayoutSetting(getContext()); - chatLayoutSetting.customizeChatLayout(this); + chatLayoutSetting.customizeChatLayout(this,inputActionSetting); initListener(); resetForwardState(""); if(inputActionSetting != null&&inputActionSetting.isDisableSendMessage()){ diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/widget/GroupMemberNavAdapter.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/widget/GroupMemberNavAdapter.java new file mode 100644 index 0000000..24ac237 --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/classicui/widget/GroupMemberNavAdapter.java @@ -0,0 +1,100 @@ +package com.tencent.qcloud.tuikit.tuichat.classicui.widget; + +import android.content.Intent; +import android.net.Uri; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.tencent.qcloud.tuicore.component.imageEngine.impl.GlideEngine; +import com.tencent.qcloud.tuikit.tuichat.R; +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMember; +import com.tencent.qcloud.tuikit.tuichat.presenter.FileBaseUrlHelper; +import com.tencent.qcloud.tuikit.tuichat.util.TUIChatLog; + +import java.util.ArrayList; +import java.util.List; + +/** + * NavigationView 右侧抽屉中群成员列表的适配器。 + */ +public class GroupMemberNavAdapter extends RecyclerView.Adapter { + + private final List members = new ArrayList<>(); + + public void setMembers(List data) { + members.clear(); + if (data != null) { + members.addAll(data); + } + notifyDataSetChanged(); + } + + @NonNull + @Override + public MemberViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View itemView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_group_member_nav, parent, false); + return new MemberViewHolder(itemView); + } + + @Override + public void onBindViewHolder(@NonNull MemberViewHolder holder, int position) { + GroupMember member = members.get(position); + if (member == null) { + return; + } + String avatar = FileBaseUrlHelper.getInstance().getIconBaseUrl() + member.getAvatar(); + GlideEngine.loadUserCircleIcon(holder.ivAvatar, avatar, R.drawable.default_user_icon); + String name = member.getUserName(); + if (member.getIsSelf() == 1) { + name = "我"; + } + holder.tvName.setText(name); + String type = "员工"; + if (member.getMemberType() == 1) { + type = "专业人员"; + } else if (member.getMemberType() == 2) { + type = "员工"; + } else if (member.getMemberType() == 0) { + type = "操作人员"; + } else if (member.getMemberType() == -1) { + type = "发起人"; + } + holder.tvType.setText(type); + holder.ivCall.setOnClickListener(v -> { + try { + Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + member.getPhone())); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + v.getContext().startActivity(intent); + } catch (Exception e) { + TUIChatLog.e("GroupMemberNavAdapter", "拉起系统拨号失败: " + e.getMessage()); + } + }); + } + + @Override + public int getItemCount() { + return members.size(); + } + + static class MemberViewHolder extends RecyclerView.ViewHolder { + ImageView ivAvatar; + ImageView ivCall; + TextView tvName; + TextView tvType; + + MemberViewHolder(@NonNull View itemView) { + super(itemView); + ivAvatar = itemView.findViewById(R.id.iv_avatar); + tvName = itemView.findViewById(R.id.tv_name); + tvType = itemView.findViewById(R.id.tv_type); + ivCall = itemView.findViewById(R.id.iv_call); + } + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/interfaces/FileBaseUrlListener.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/interfaces/FileBaseUrlListener.java new file mode 100644 index 0000000..d0d0954 --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/interfaces/FileBaseUrlListener.java @@ -0,0 +1,5 @@ +package com.tencent.qcloud.tuikit.tuichat.interfaces; + +public interface FileBaseUrlListener { + String getIconBaseUrl(); +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/interfaces/IMInputViewActionListener.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/interfaces/IMInputViewActionListener.java index 9de93c0..711e53c 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/interfaces/IMInputViewActionListener.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/interfaces/IMInputViewActionListener.java @@ -6,4 +6,6 @@ package com.tencent.qcloud.tuikit.tuichat.interfaces; */ public interface IMInputViewActionListener { void finishAction(int workType, String workId); + void appraiseAction(String chatId, int workType, String workId); + void finishActivityToGuidanceHome(int workType); } diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/presenter/FileBaseUrlHelper.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/presenter/FileBaseUrlHelper.java new file mode 100644 index 0000000..0b2a235 --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/presenter/FileBaseUrlHelper.java @@ -0,0 +1,31 @@ +package com.tencent.qcloud.tuikit.tuichat.presenter; + +import com.tencent.qcloud.tuikit.tuichat.interfaces.FileBaseUrlListener; + +public class FileBaseUrlHelper { + private FileBaseUrlListener listener; + private static FileBaseUrlHelper instance; + + public void setListener(FileBaseUrlListener listener) { + this.listener = listener; + } + + private FileBaseUrlHelper() { + // 私有构造 + } + + public static synchronized FileBaseUrlHelper getInstance() { + if (instance == null) { + instance = new FileBaseUrlHelper(); + } + return instance; + } + + public String getIconBaseUrl() { + if (listener != null) { + return listener.getIconBaseUrl(); + } else { + return null; + } + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/presenter/ParamedicOperateHelper.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/presenter/ParamedicOperateHelper.java new file mode 100644 index 0000000..9731cac --- /dev/null +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/presenter/ParamedicOperateHelper.java @@ -0,0 +1,74 @@ +package com.tencent.qcloud.tuikit.tuichat.presenter; + +import androidx.core.util.Consumer; + +import com.tencent.qcloud.tuikit.tuichat.bean.EmployeeBean; +import com.tencent.qcloud.tuikit.tuichat.bean.ExpertBean; +import com.tencent.qcloud.tuikit.tuichat.bean.GroupMemberBean; +import com.tencent.qcloud.tuikit.tuichat.classicui.interfaces.OnParamedicOperateListener; + +import java.util.List; + +public class ParamedicOperateHelper { + private OnParamedicOperateListener listener; + private static ParamedicOperateHelper instance; + + public void setListener(OnParamedicOperateListener listener) { + this.listener = listener; + } + + private ParamedicOperateHelper() { + // 私有构造 + } + + public static synchronized ParamedicOperateHelper getInstance() { + if (instance == null) { + instance = new ParamedicOperateHelper(); + } + return instance; + } + + public List getActualGroupMemberList(String sessionId) { + if (listener != null) { + return listener.getActualGroupMemberList(sessionId); + } + return null; + } + + + /** + * 邀请成员加入群组。操作异步执行,结果通过 callback 回传。 + * + * @param groupId 目标群组 ID + * @param memberList 待加入成员的 userId 列表 + * @param memberType 成员类型 + * @param callback 结果回调;当未注册 listener 时直接回调 false,避免调用方无限等待 + */ + public void addGroupUser(String groupId, List memberList, int memberType, Consumer callback) { + if (listener != null) { + listener.addGroupUser(groupId, memberList, memberType, callback); + } else if (callback != null) { + callback.accept(false); + } + } + + public List searchExpert(String realname, String centerId, String excludeSessionId, int pageNo, int pageSize) { + if (listener != null) { + return listener.searchExpert(realname, centerId, excludeSessionId, pageNo, pageSize); + } + return null; + } + + public List searchEmployee(String realname, String orgCode, String workNo, String phone, String excludeSessionId, int pageNo, int pageSize) { + if (listener != null) { + return listener.searchEmployee(realname, orgCode, workNo, phone, excludeSessionId, pageNo, pageSize); + } + return null; + } + + public void removeGroupUser(String groupId, List memberList) { + if (listener != null) { + listener.removeGroupUser(groupId, memberList); + } + } +} diff --git a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/util/ChatMessageParser.java b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/util/ChatMessageParser.java index 10cf2b7..7d9fed3 100644 --- a/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/util/ChatMessageParser.java +++ b/system/tuichat/src/main/java/com/tencent/qcloud/tuikit/tuichat/util/ChatMessageParser.java @@ -46,6 +46,12 @@ import java.util.Map; public class ChatMessageParser { private static final String TAG = ChatMessageParser.class.getSimpleName(); + private static ArrayList mSelectName = new ArrayList(); + + public static void setSelectName(ArrayList list) { + mSelectName.clear(); + mSelectName.addAll(list); + } public static TUIMessageBean parseMessage(V2TIMMessage v2TIMMessage) { System.out.println("聊天消息接受"+v2TIMMessage); diff --git a/system/tuichat/src/main/res/drawable-xxhdpi/chat_phone_call.png b/system/tuichat/src/main/res/drawable-xxhdpi/chat_phone_call.png new file mode 100644 index 0000000000000000000000000000000000000000..91c7244464958d74bff7a3a08d9119795f4539a2 GIT binary patch literal 7157 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 literal 0 HcmV?d00001 diff --git a/system/tuichat/src/main/res/drawable-xxhdpi/default_user_icon.png b/system/tuichat/src/main/res/drawable-xxhdpi/default_user_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..68bb06fa7179743cfd8b054e5344d163845c56a3 GIT binary patch literal 11706 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 Qy#N3J07*qoM6N<$f*GQ0K>z>% literal 0 HcmV?d00001 diff --git a/system/tuichat/src/main/res/drawable-xxhdpi/ic_plus_circle.png b/system/tuichat/src/main/res/drawable-xxhdpi/ic_plus_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..ba75131abd01da5a41afa1c2eb95d3b77138d9d0 GIT binary patch literal 3139 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 literal 0 HcmV?d00001 diff --git a/system/tuichat/src/main/res/drawable-xxhdpi/ic_update_circle.png b/system/tuichat/src/main/res/drawable-xxhdpi/ic_update_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..a05c0af416b909b535322ec86a186b7be413e41b GIT binary patch literal 1107 zcmV-Z1g!gsP)g5QjVJyV(IfRJr66c1BEE=tPft&M{6=gf;Oy+|I*K9}v!nzn26G=DAA4Mu!oUi1 za&qDjxD%C3JPl)oxCSfY;R{h%0LkCtTv^Tl8z*vba1bI=&5{X@h+JTqAf(Ga`Bh|} zzI z&(FS;fYo$Fq>aU=R?M6T;#c#j!x2Gby$!1%6+++s<_ zB0fGouA|98VRElkSU}d`B(EE;D-}Xn)k(5La|Urj?wK@WiU}ZjM?~(i84Ox^@-bN= zQWO)wfG^SK38KmONWLyxf?Buv7yq4%nIgXcl26aZh?=y63Ti$JR{Iv`%4!M;c!}m` z;*!q3R1A}DPfr*dTSto=TuG2AfH8GYJ$YhAbhKm(5XvN0lV)8+eqyU=k%ub@G6k@l zZQKnuhT3mX`(4>Gta^=AZ_>QLvdAsq0cT@lsQn+?s{Jfj6^qU6%H#?67$1{cfG?l3 zFrbr-|8fvwB1A>FGAXZo0%91z5?)FI!0!|$)uEJ4O4;Lb#!3O-fxUoT^ZyCZ&BC!6 z2EgS`$#aNg32=n zA-5`r+1JU6%SVXUKtNYgloBvygq41wUxjX7o={(Cjv@KX@=*+Ij+_GS*c0xyW}h7H zagKbl@C+1FNPx}+%UWYFU$#U#zQ*M1hqY|73JFjcFtZk`fVxk=#;%Q5Sb(x_&@wDZ zzE7MQ&84gpptas+LwU5%u_P{~)WUBJU%7AifYqj%WI$|ZS?RnvTqqD|ux>0E61NVY)N7mx<7&_HbR6yN_QBljP9nhLWjq zIS2PwZrU^p0#>0Sc*W}y_=?K~2(CeWeh+8|v_nkqTa<`}x4Crq-NY}z?|qW5=S^NQ zu)^qu6TT{w$T5CnNc + + + + + diff --git a/system/tuichat/src/main/res/drawable/bg_gray_round_8.xml b/system/tuichat/src/main/res/drawable/bg_gray_round_8.xml new file mode 100644 index 0000000..e758f61 --- /dev/null +++ b/system/tuichat/src/main/res/drawable/bg_gray_round_8.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/system/tuichat/src/main/res/drawable/bg_phone_call_btn.xml b/system/tuichat/src/main/res/drawable/bg_phone_call_btn.xml new file mode 100644 index 0000000..fca7405 --- /dev/null +++ b/system/tuichat/src/main/res/drawable/bg_phone_call_btn.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/system/tuichat/src/main/res/drawable/bg_phone_call_dialog.xml b/system/tuichat/src/main/res/drawable/bg_phone_call_dialog.xml new file mode 100644 index 0000000..23bf50a --- /dev/null +++ b/system/tuichat/src/main/res/drawable/bg_phone_call_dialog.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/system/tuichat/src/main/res/drawable/bg_tab_selected_white.xml b/system/tuichat/src/main/res/drawable/bg_tab_selected_white.xml new file mode 100644 index 0000000..cc9eccc --- /dev/null +++ b/system/tuichat/src/main/res/drawable/bg_tab_selected_white.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/system/tuichat/src/main/res/drawable/bg_theme_round_24.xml b/system/tuichat/src/main/res/drawable/bg_theme_round_24.xml new file mode 100644 index 0000000..fba2a3f --- /dev/null +++ b/system/tuichat/src/main/res/drawable/bg_theme_round_24.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/system/tuichat/src/main/res/drawable/bg_update_member_button.xml b/system/tuichat/src/main/res/drawable/bg_update_member_button.xml new file mode 100644 index 0000000..d676e80 --- /dev/null +++ b/system/tuichat/src/main/res/drawable/bg_update_member_button.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/system/tuichat/src/main/res/drawable/checkbox_custom.xml b/system/tuichat/src/main/res/drawable/checkbox_custom.xml new file mode 100644 index 0000000..d88bbc3 --- /dev/null +++ b/system/tuichat/src/main/res/drawable/checkbox_custom.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/system/tuichat/src/main/res/drawable/ic_check_circle.xml b/system/tuichat/src/main/res/drawable/ic_check_circle.xml new file mode 100644 index 0000000..f4bdfab --- /dev/null +++ b/system/tuichat/src/main/res/drawable/ic_check_circle.xml @@ -0,0 +1,14 @@ + + + + diff --git a/system/tuichat/src/main/res/drawable/ic_circle_stroke.xml b/system/tuichat/src/main/res/drawable/ic_circle_stroke.xml new file mode 100644 index 0000000..aac1e08 --- /dev/null +++ b/system/tuichat/src/main/res/drawable/ic_circle_stroke.xml @@ -0,0 +1,11 @@ + + + diff --git a/system/tuichat/src/main/res/drawable/ic_clear.xml b/system/tuichat/src/main/res/drawable/ic_clear.xml new file mode 100644 index 0000000..99e1f44 --- /dev/null +++ b/system/tuichat/src/main/res/drawable/ic_clear.xml @@ -0,0 +1,14 @@ + + + + diff --git a/system/tuichat/src/main/res/drawable/ic_phone_call.xml b/system/tuichat/src/main/res/drawable/ic_phone_call.xml new file mode 100644 index 0000000..34ee0b5 --- /dev/null +++ b/system/tuichat/src/main/res/drawable/ic_phone_call.xml @@ -0,0 +1,10 @@ + + + diff --git a/system/tuichat/src/main/res/drawable/ic_phone_call_close.xml b/system/tuichat/src/main/res/drawable/ic_phone_call_close.xml new file mode 100644 index 0000000..9b5c846 --- /dev/null +++ b/system/tuichat/src/main/res/drawable/ic_phone_call_close.xml @@ -0,0 +1,9 @@ + + + diff --git a/system/tuichat/src/main/res/drawable/ic_search.xml b/system/tuichat/src/main/res/drawable/ic_search.xml new file mode 100644 index 0000000..9d64dbb --- /dev/null +++ b/system/tuichat/src/main/res/drawable/ic_search.xml @@ -0,0 +1,15 @@ + + + + diff --git a/system/tuichat/src/main/res/drawable/selector_tab_bg.xml b/system/tuichat/src/main/res/drawable/selector_tab_bg.xml new file mode 100644 index 0000000..2253e63 --- /dev/null +++ b/system/tuichat/src/main/res/drawable/selector_tab_bg.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/system/tuichat/src/main/res/layout/activity_add_member.xml b/system/tuichat/src/main/res/layout/activity_add_member.xml new file mode 100644 index 0000000..8669fbe --- /dev/null +++ b/system/tuichat/src/main/res/layout/activity_add_member.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/tuichat/src/main/res/layout/chat_activity_with_navigation.xml b/system/tuichat/src/main/res/layout/chat_activity_with_navigation.xml new file mode 100644 index 0000000..b970c46 --- /dev/null +++ b/system/tuichat/src/main/res/layout/chat_activity_with_navigation.xml @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/system/tuichat/src/main/res/layout/chat_navigation_header.xml b/system/tuichat/src/main/res/layout/chat_navigation_header.xml new file mode 100644 index 0000000..9be87e6 --- /dev/null +++ b/system/tuichat/src/main/res/layout/chat_navigation_header.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + diff --git a/system/tuichat/src/main/res/layout/dialog_phone_call.xml b/system/tuichat/src/main/res/layout/dialog_phone_call.xml new file mode 100644 index 0000000..0fcae38 --- /dev/null +++ b/system/tuichat/src/main/res/layout/dialog_phone_call.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/tuichat/src/main/res/layout/item_add_member.xml b/system/tuichat/src/main/res/layout/item_add_member.xml new file mode 100644 index 0000000..2df2f9f --- /dev/null +++ b/system/tuichat/src/main/res/layout/item_add_member.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/tuichat/src/main/res/layout/item_group_member_nav.xml b/system/tuichat/src/main/res/layout/item_group_member_nav.xml new file mode 100644 index 0000000..77856da --- /dev/null +++ b/system/tuichat/src/main/res/layout/item_group_member_nav.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/system/tuichat/src/main/res/values/colors.xml b/system/tuichat/src/main/res/values/colors.xml index d929aea..89f9735 100644 --- a/system/tuichat/src/main/res/values/colors.xml +++ b/system/tuichat/src/main/res/values/colors.xml @@ -59,4 +59,10 @@ #4A4A4A #F19927 + + #F2F3F5 + #252535 + #808080 + #77849E + #B6B6B6 \ No newline at end of file diff --git a/system/tuichat/src/main/res/values/strings.xml b/system/tuichat/src/main/res/values/strings.xml index 876ce2b..f2b9769 100644 --- a/system/tuichat/src/main/res/values/strings.xml +++ b/system/tuichat/src/main/res/values/strings.xml @@ -263,4 +263,20 @@ 去完善 服务评价 + + + 拨打电话 + 取消 + + + 返回 + 选择联系人 + 邀请专家 + 邀请员工 + 已选择 0 人 + 确定 + 暂无数据 + 搜索联系人 + 搜索 + diff --git a/system/tuicontact/src/main/java/com/tencent/qcloud/tuikit/tuicontact/classicui/pages/StartGroupMemberSelectActivity.java b/system/tuicontact/src/main/java/com/tencent/qcloud/tuikit/tuicontact/classicui/pages/StartGroupMemberSelectActivity.java index 3f3ce15..b9cf4c6 100644 --- a/system/tuicontact/src/main/java/com/tencent/qcloud/tuikit/tuicontact/classicui/pages/StartGroupMemberSelectActivity.java +++ b/system/tuicontact/src/main/java/com/tencent/qcloud/tuikit/tuicontact/classicui/pages/StartGroupMemberSelectActivity.java @@ -85,6 +85,7 @@ public class StartGroupMemberSelectActivity extends BaseLightActivity { limit = getIntent().getIntExtra(TUIContactConstants.Selection.LIMIT, Integer.MAX_VALUE); alreadySelectedList = getIntent().getStringArrayListExtra(TUIContactConstants.Selection.SELECTED_LIST); mTitleBar = findViewById(R.id.group_create_title_bar); + mTitleBar.setTitle(getString(R.string.select_group_member), ITitleBarLayout.Position.MIDDLE); mTitleBar.setTitle(getResources().getString(com.tencent.qcloud.tuicore.R.string.sure), ITitleBarLayout.Position.RIGHT); mTitleBar.getRightIcon().setVisibility(View.GONE); mTitleBar.setOnRightClickListener(new View.OnClickListener() { diff --git a/system/tuicontact/src/main/res/layout/contact_selecable_adapter_item.xml b/system/tuicontact/src/main/res/layout/contact_selecable_adapter_item.xml index ed0f0ce..4757f41 100644 --- a/system/tuicontact/src/main/res/layout/contact_selecable_adapter_item.xml +++ b/system/tuicontact/src/main/res/layout/contact_selecable_adapter_item.xml @@ -16,12 +16,13 @@ android:paddingLeft="15.36dp"> @@ -30,24 +31,24 @@ android:layout_width="45dp" android:layout_height="@dimen/contact_avatar_width"> - + + android:elevation="4dp" + android:visibility="gone" /> @@ -62,13 +63,13 @@ android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerInParent="true" - android:singleLine="true" - android:ellipsize="end" - android:textSize="17.28sp" - android:lineHeight="23.04sp" android:clickable="false" + android:ellipsize="end" android:focusable="false" + android:lineHeight="23.04sp" + android:singleLine="true" android:textColor="@color/black_font_color" + android:textSize="17.28sp" tools:text="@string/default_friend" /> Edit Group Name Add Member + 选择群成员 Group Joining Method Prohibited from Joining Admin Approval diff --git a/system/tuicore/src/main/java/com/tencent/qcloud/tuicore/TUIConstants.java b/system/tuicore/src/main/java/com/tencent/qcloud/tuicore/TUIConstants.java index 4038559..885cc45 100644 --- a/system/tuicore/src/main/java/com/tencent/qcloud/tuicore/TUIConstants.java +++ b/system/tuicore/src/main/java/com/tencent/qcloud/tuicore/TUIConstants.java @@ -113,6 +113,9 @@ public final class TUIConstants { public static final String FACE_URL_LIST = "faceUrlList"; /*当下公司业务传输数据使用*/ public static final String WORK_BEAN = "workBean"; + public static final String INITIATE_VIDEO_CALL = "initiateVideoCall"; + public static final String AUTO_SEND_MESSAGE = "autoSendMessage"; + public static final String CONSULTANT_ID = "consultantId"; public static final String JOIN_TYPE = "joinType"; public static final String MEMBER_COUNT = "memberCount"; public static final String RECEIVE_OPTION = "receiveOption";