IMChatUtil.kt 23.7 KB
Newer Older
1 2 3 4
package com.yidianling.im.helper

import android.annotation.SuppressLint
import android.content.Context
YKai committed
5 6
import androidx.core.content.ContextCompat
import androidx.appcompat.app.AppCompatActivity
7 8 9 10 11 12 13 14
import android.text.TextUtils
import android.view.View
import com.ydl.webview.H5Params
import com.ydl.webview.NewH5Activity
import com.ydl.ydlcommon.data.http.BaseAPIResponse
import com.ydl.ydlcommon.data.http.BaseResponse
import com.ydl.ydlcommon.data.http.RxUtils.applySchedulers
import com.ydl.ydlcommon.data.http.UpLoadLogUtils.upLoadLog
konghaorui committed
15
import com.ydl.ydlcommon.modular.ModularServiceManager
konghaorui committed
16 17
import com.ydl.ydlcommon.ui.LoadingDialogFragment
import com.ydl.ydlcommon.ui.LoadingDialogFragment.Companion.newInstance
18 19
import com.ydl.ydlcommon.utils.NetworkParamsUtils
import com.ydl.ydlcommon.utils.UserInfoCache
20
import com.ydl.ydlcommon.utils.log.AliYunLogConfig
21
import com.ydl.ydlcommon.utils.log.AliYunRichLogsHelper
22 23 24 25 26 27
import com.ydl.ydlcommon.utils.remind.HttpErrorUtils.Companion.handleError
import com.ydl.ydlcommon.view.dialog.CommonDialog
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.ToastUtil
import com.yidianling.im.R
import com.yidianling.im.api.bean.IMExpertBuild
konghaorui committed
28
import com.yidianling.im.bean.DoctorAssistantRespDtoBean
29 30 31 32 33 34
import com.yidianling.im.bean.GetExpert
import com.yidianling.im.bean.UserTypeBean
import com.yidianling.im.bridge.P2PCustomActionHandlerImpl
import com.yidianling.im.config.constants.ImConstants
import com.yidianling.im.http.ImRetrofitApi.Companion.getImJavaApi
import com.yidianling.im.http.ImRetrofitApi.Companion.getImRetrofitApi
35
import com.yidianling.im.router.ImIn
36 37 38
import com.yidianling.im.router.ImIn.isLogin
import com.yidianling.im.session.SessionHelper
import com.yidianling.im.ui.page.fragment.bean.ChatItemBean
konghaorui committed
39
import com.yidianling.uikit.business.session.fragment.YDLMessageFragment
40 41 42 43 44 45 46
import com.yidianling.uikit.business.session.helper.ChatStatusCacheHelper
import com.yidianling.uikit.custom.bridge.ActionHandlerStorage
import com.yidianling.uikit.custom.bridge.IP2PCustomActionHandler
import com.yidianling.uikit.custom.http.ServiceImpl.Companion.instance
import com.yidianling.uikit.custom.http.response.ChatStatusBean
import com.yidianling.uikit.custom.http.response.RecommendExpertBean
import com.yidianling.uikit.custom.widget.TitleBarBottom
konghaorui committed
47
import com.yidianling.user.api.service.IUserService
48 49 50 51 52 53
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException
import java.net.URLEncoder

/**
konghaorui committed
54
 * 私聊页面相关接口封装
55 56
 */
object IMChatUtil {
konghaorui committed
57
    private var loadingDialog: LoadingDialogFragment? = null
霍志良 committed
58 59 60
    private const val USER_TYPE_EXPERT=2//专家
    private const val USER_TYPE_ASSISTANT=3//助理
    private const val USER_TYPE_USER=1//用户
konghaorui committed
61 62 63
    /**
     * 接口数据请求完成回调
     */
64
    interface ChatDataRequestListener {
konghaorui committed
65
        fun onSuccess(expertInfo: IMExpertBuild)
66 67
    }

konghaorui committed
68 69 70 71
    /**
     * 客服专用
     */
    fun startKefuChat(context: AppCompatActivity?) {
72 73 74 75 76 77 78
        SessionHelper.startP2PSession(
            context,
            -1,
            ImConstants.KEFUXIAOYI,
            null,
            P2PCustomActionHandlerImpl(ImConstants.KEFUXIAOYI, "客服小壹", ImConstants.KEFUXIAOYI)
        )
79 80 81
    }

    /**
konghaorui committed
82
     * 私聊列表进入,后置数据请求
83 84 85 86 87
     *
     * @param context
     * @param chatItemBean
     */
    fun startChat(context: AppCompatActivity?, chatItemBean: ChatItemBean) {
88 89 90 91 92 93
        SessionHelper.startP2PSession(
            context,
            chatItemBean.utype,
            chatItemBean.toUid.toString(),
            null,
            P2PCustomActionHandlerImpl(chatItemBean)
94 95 96
        )
    }

konghaorui committed
97 98 99 100 101 102 103
    /**
     * 非私聊列表进入,前置数据请求
     *
     * @param context
     * @param toUid
     * @param isFromQingShu     用于判断是否从倾诉流程跳转私聊:1:是   其他:不是    从倾述流程跳转私聊,需要发送自定义消息
     */
104
    @SuppressLint("CheckResult")
konghaorui committed
105
    fun startChat(context: AppCompatActivity, toUid: String, isFromQingShu: Int) {
106 107 108
        if (!isLogin(context, true)) {
            return
        }
konghaorui committed
109 110 111 112 113 114
        if (loadingDialog == null) {
            loadingDialog = newInstance(null)
        }
        if (context.supportFragmentManager != null && !context.isDestroyed) {
            loadingDialog?.show(context.supportFragmentManager, null)
        }
115
        getImJavaApi().getUserType(toUid)
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ res: BaseResponse<UserTypeBean> ->
                if (res.code == 200 && res.data != null) {
                    if (res.data!!.chatEvent) { //和助理私聊需要打开常用语弹窗
                        ChatStatusCacheHelper.setStatusCache(
                            "chatEvent",
                            res.data!!.chatEvent
                        )
                    }
                    if (res.data!!.collectEvent) { //和助理私聊需要打开信息采集弹窗
                        ChatStatusCacheHelper.setStatusCache(
                            "collectEvent",
                            res.data!!.collectEvent
                        )
                    }
霍志良 committed
132
                    if (TextUtils.equals(res.data!!.userType, USER_TYPE_EXPERT.toString())) { //专家
133 134 135 136 137 138 139 140 141 142 143
                        //在uid用户类型确定为专家的情况下,根据uid调用接口判断是进入专家私聊还是助理私聊
                        getImJavaApi().getChatUid(toUid)
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe({ resp: BaseAPIResponse<DoctorAssistantRespDtoBean> ->
                                val bean = resp.data
                                val toUid = bean.chatUid
                                prepareChatData(context, toUid, object :
                                    ChatDataRequestListener {
                                    override fun onSuccess(expertInfo: IMExpertBuild) {
                                        startChatSession(toUid, expertInfo, isFromQingShu, context)
konghaorui committed
144
                                    }
145 146 147 148
                                })
                            }) { t: Throwable? ->
                                handleError(context, t!!)
                            }
konghaorui committed
149
                    } else {
150 151 152 153 154
                        prepareAssistantChatData(context, toUid, object : ChatDataRequestListener {
                            override fun onSuccess(expertInfo: IMExpertBuild) {
                                startChatSession(toUid, expertInfo, isFromQingShu, context)
                            }
                        })
155
                    }
156
                } else {
konghaorui committed
157 158
                    if (loadingDialog != null && loadingDialog!!.isVisible) {
                        loadingDialog?.dismissAllowingStateLoss()
159
                    }
160
                    ToastUtil.toastShort(res.msg)
161
                }
162 163 164 165 166 167 168
            }, { throwable: Throwable? ->
                if (loadingDialog != null && loadingDialog!!.isVisible) {
                    loadingDialog?.dismissAllowingStateLoss()
                }
                handleError(context, throwable!!)
            }
            )
169 170
    }

严久程 committed
171

172
    fun startChatCloseReplaceChat(context: AppCompatActivity, toUid: String) {
严久程 committed
173 174 175 176 177 178 179 180 181 182
        if (!isLogin(context, true)) {
            return
        }
        if (loadingDialog == null) {
            loadingDialog = newInstance(null)
        }
        if (context.supportFragmentManager != null && !context.isDestroyed) {
            loadingDialog?.show(context.supportFragmentManager, null)
        }
        prepareChatData(context, toUid, object :
183
            ChatDataRequestListener {
严久程 committed
184 185 186 187 188 189
            override fun onSuccess(expertInfo: IMExpertBuild) {
                startChatSession(toUid, expertInfo, 0, context)
            }
        })
    }

190
    /**
konghaorui committed
191
     * 开启聊天会话
192
     */
193 194 195 196 197 198
    private fun startChatSession(
        toUid: String,
        expertInfo: IMExpertBuild,
        isFromQingShu: Int,
        context: AppCompatActivity
    ) {
199
        AliYunRichLogsHelper.getInstance().sendRichLog(AliYunLogConfig.YUNXIN, "startChatSession  开启聊天会话")
konghaorui committed
200 201
        val p2PCustomActionHandlerImpl = P2PCustomActionHandlerImpl(toUid, expertInfo)
        p2PCustomActionHandlerImpl.isFromQingShu = isFromQingShu
202 203 204 205 206 207 208
        SessionHelper.startP2PSession(
            context,
            expertInfo.shareData.user_type,
            toUid,
            null,
            p2PCustomActionHandlerImpl
        )
konghaorui committed
209 210 211 212 213 214
    }

    //====================准备私聊数据====================
    /**
     * 初始化聊天数据
     */
215 216 217 218 219
    fun prepareChatData(
        context: AppCompatActivity,
        toUid: String,
        listener: ChatDataRequestListener
    ) {
konghaorui committed
220 221 222 223
        if (!isLogin(context, true)) {
            return
        }
        val dis = getImJavaApi().getUserType(toUid)
224 225 226 227 228 229 230 231 232 233 234 235
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ res: BaseResponse<UserTypeBean> ->
                if (res.code == 200 && res.data != null) {
                    if (res.data!!.chatEvent) { //和助理私聊需要打开常用语弹窗
                        ChatStatusCacheHelper.setStatusCache("chatEvent", res.data!!.chatEvent)
                    }
                    if (res.data!!.collectEvent) { //和助理私聊需要打开信息采集弹窗
                        ChatStatusCacheHelper.setStatusCache(
                            "collectEvent",
                            res.data!!.collectEvent
                        )
236
                    }
237 238 239 240 241 242 243
                    if (TextUtils.equals(res.data!!.userType, "2")) {
                        //接口返回值是专家,java接口
                        prepareExpertChatData(context, toUid, listener)
                    } else { //非专家 php接口
                        prepareAssistantChatData(context, toUid, listener)
                    }
                } else {
konghaorui committed
244 245 246
                    if (loadingDialog != null && loadingDialog!!.isVisible) {
                        loadingDialog?.dismissAllowingStateLoss()
                    }
247
                    ToastUtil.toastShort(res.msg)
248
                }
249 250 251 252 253 254 255
            }, { throwable: Throwable? ->
                if (loadingDialog != null && loadingDialog!!.isVisible) {
                    loadingDialog?.dismissAllowingStateLoss()
                }
                handleError(context, throwable!!)
            }
            )
256 257 258
    }

    /**
konghaorui committed
259
     * 专家私聊数据请求
260
     */
261 262 263 264 265
    fun prepareExpertChatData(
        context: AppCompatActivity,
        toUid: String?,
        listener: ChatDataRequestListener
    ) {
konghaorui committed
266
        val disposable = getImJavaApi().getPersonalChat(toUid!!)
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ resp: BaseResponse<IMExpertBuild> ->
                if (null != loadingDialog && loadingDialog?.isVisible!!) {
                    loadingDialog?.dismissAllowingStateLoss()
                }
                if (resp.code == 200) {
                    val expert = resp.data
                    UserInfoCache.getInstance().saveYDLUser(
                        expert.shareData.toUid,
                        expert.shareData.doctorName,
                        expert.shareData.cover
                    )
                    listener.onSuccess(expert)
                } else {
                    upLoadLog("consult/get-expert", resp.code, resp.msg)
                    if (resp.code == ImConstants.HTTP_CODE_UNLOGIN) {
刘鹏 committed
284
                        ImIn.loginByOneKeyLogin(context, true)
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
                        ToastUtil.toastShort(resp.msg)
                    } else if (resp.code == ImConstants.SILENCED_CODE) { //禁言
                        showSilencedDialog(context, resp.data.tips, resp.data.url)
                    } else {
                        ToastUtil.toastShort(resp.msg)
                    }
                }
            }
            ) { throwable: Throwable ->
                if (null != loadingDialog && loadingDialog!!.isVisible) {
                    loadingDialog?.dismissAllowingStateLoss()
                }
                handleError(context, throwable)
                if (throwable is HttpException) {
                    upLoadLog("consult/get-expert", throwable.code(), throwable.message!!)
                }
            }
    }

    /**
     * 助理私聊数据请求
     */
    fun prepareAssistantChatData(
        context: AppCompatActivity,
        toUid: String,
        listener: ChatDataRequestListener
    ) {
        val cmd = GetExpert(toUid.toInt(), 0)
        val disposable =
            getImRetrofitApi().getExpert(NetworkParamsUtils.getMaps(cmd))
315 316
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
konghaorui committed
317
                .subscribe({ resp: BaseResponse<IMExpertBuild> ->
318 319 320 321 322 323 324 325 326 327
                    if (null != loadingDialog && loadingDialog!!.isVisible) {
                        loadingDialog?.dismissAllowingStateLoss()
                    }
                    if (resp.code == 0) {
                        val expert = resp.data
                        UserInfoCache.getInstance().saveYDLUser(
                            expert.shareData.toUid,
                            expert.shareData.doctorName,
                            expert.shareData.cover
                        )
霍志良 committed
328
                        listener.onSuccess(expert)
329 330 331
                    } else {
                        upLoadLog("consult/get-expert", resp.code, resp.msg)
                        if (resp.code == ImConstants.HTTP_CODE_UNLOGIN) {
刘鹏 committed
332
                            ImIn.loginByOneKeyLogin(context, true)
333 334 335 336 337
                            ToastUtil.toastShort(resp.msg)
                        } else if (resp.code == ImConstants.SILENCED_CODE) { //禁言
                            showSilencedDialog(context, resp.data.tips, resp.data.url)
                        } else {
                            ToastUtil.toastShort(resp.msg)
338
                        }
339 340
                    }
                }
341
                ) { throwable: Throwable ->
342
                    if (null != loadingDialog && loadingDialog?.isVisible!!) {
konghaorui committed
343 344
                        loadingDialog?.dismissAllowingStateLoss()
                    }
345 346
                    handleError(context, throwable)
                    if (throwable is HttpException) {
347
                        upLoadLog("consult/get-expert", throwable.code(), throwable.message!!)
348 349 350 351
                    }
                }
    }

konghaorui committed
352 353 354
    //====================私聊页面 初始化操作====================
    /**
     * 初始化在线状态接口
355 356
     *
     * 只有专家显示在线、离线标识,其他用户Type隐藏在线、离线标识
konghaorui committed
357
     */
358 359 360 361 362 363
    fun initChatOnlineState(
        tb: TitleBarBottom,
        context: Context,
        toUid: String,
        messageFragment: YDLMessageFragment
    ) {
364 365 366 367
        val actionHandler = ActionHandlerStorage.getL(toUid)
        //获取私聊对方在线状态
        if (null != actionHandler) {
            val docInfo = actionHandler.info
368 369
            docInfo.doctorBriefInfoFeedbackRate
            if (null != docInfo && (ImConstants.KEFUXIAOYI == docInfo.toUid || "4108805" == docInfo.toUid)) { //小壹客服  不显示是否在线
370 371
                tb.setmMinTitleVisiable(View.GONE)
            } else {
konghaorui committed
372
                //对方是用户,自己是助理
刘鹏 committed
373 374 375
                if (actionHandler.userType == USER_TYPE_USER && ModularServiceManager.provide(
                        IUserService::class.java
                    )
霍志良 committed
376
                        .getUserInfo()?.user_type == USER_TYPE_ASSISTANT
377
                ) {
konghaorui committed
378 379 380 381
                    tb.setTitleTextRightIcon(R.drawable.user_info_icon) {
                        messageFragment.showUserInfoDialog()
                    }
                }
霍志良 committed
382
                if (actionHandler.userType == USER_TYPE_EXPERT) { // 专家
383
                    tb.setmMinTitleVisiable(View.VISIBLE)
384 385
                    // 调取接口获取专家状态
                    val dis = instance
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
                        .getDoctorChatStatus(actionHandler.info.toUid.toLong())
                        .compose(applySchedulers())
                        .subscribe(
                            { chatStatusBean: BaseAPIResponse<ChatStatusBean> ->
                                if (actionHandler != null) {
                                    val status = chatStatusBean.data.status
                                    actionHandler.setDoctorStatus(status)
                                    actionHandler.setDoctorBusyNum(chatStatusBean.data.busyTotal)
                                    //1.在线,2.离线,3.忙碌 4咨询中, 5倾述中  6咨询前准备
                                    if (status == 2) { //离线
                                        tb.setMinTitleText("离线")
                                        tb.setMinTitleColor(
                                            ContextCompat.getColor(
                                                context,
                                                R.color.platform_color_666666
                                            )
                                        )
                                        tb.setMinTitleDrawable(
                                            ContextCompat.getDrawable(
                                                context,
                                                R.drawable.im_background_chat_top_status_off_line
                                            )
                                        )
                                    } else if (status == 4 || status == 5) { //服务中
                                        tb.setMinTitleText("服务中")
                                        tb.setMinTitleColor(
                                            ContextCompat.getColor(
                                                context,
                                                R.color.platform_color_666666
                                            )
                                        )
                                        tb.setMinTitleDrawable(
                                            ContextCompat.getDrawable(
                                                context,
                                                R.drawable.im_background_chat_top_status_online_server
                                            )
                                        )
                                    } else { //在线  1,3,6..
                                        tb.setMinTitleText("在线")
                                        tb.setMinTitleColor(
                                            ContextCompat.getColor(
                                                context,
                                                R.color.platform_color_666666
                                            )
                                        )
                                        tb.setMinTitleDrawable(
                                            ContextCompat.getDrawable(
                                                context,
                                                R.drawable.im_background_chat_top_status_online
                                            )
                                        )
437
                                    }
438 439 440 441 442 443 444
                                    initSystemMessage(
                                        chatStatusBean.data.promptRule,
                                        status,
                                        toUid,
                                        actionHandler
                                    )
                                }
445
                            }
446 447 448
                        ) { throwable: Throwable ->
                            LogUtil.i("getDoctorChatStatus throwable:$throwable")
                        }
霍志良 committed
449
                } else if (actionHandler.userType == USER_TYPE_ASSISTANT) { // 助理
450
                    tb.setmMinTitleVisiable(View.GONE)
451 452
                    // 调取接口获取助理状态
                    instance.getAssistantChatStatus(
453
                        actionHandler.info.toUid.toLong()
454
                    )
455 456 457 458 459 460 461 462 463 464 465 466
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe({ res: BaseAPIResponse<Int> ->
                            if (actionHandler != null) {
                                if (res.data == 1) { //在线
                                    /*tb.setMinTitleText("在线")
                                    tb.setMinTitleColor(context.resources.getColor(R.color.platform_color_666666))
                                    tb.setMinTitleDrawable(context.resources.getDrawable(R.drawable.im_background_chat_top_status_online))*/
                                } else { //离线
                                    /* tb.setMinTitleText("离线")
                                     tb.setMinTitleColor(context.resources.getColor(R.color.platform_color_666666))
                                     tb.setMinTitleDrawable(context.resources.getDrawable(R.drawable.im_background_chat_top_status_off_line))*/
467 468
                                }
                            }
469 470
                        }
                        ) { throwable: Throwable? -> }
471 472 473 474 475 476 477 478 479
                } else {
                    tb.setmMinTitleVisiable(View.GONE)
                }
            }
        }
    }

    // promptRule 判断是否推荐专家  4,5直接不走文本提示和推荐逻辑,1,3不走推荐逻辑
    //初始化 根据专家在线状态来发送提示消息或者推荐消息
480 481 482 483 484 485
    private fun initSystemMessage(
        promptRule: Int,
        status: Int,
        toUid: String,
        actionHandler: IP2PCustomActionHandler
    ) {
486 487
        if (!(promptRule == 4 || promptRule == 5)) {
            val showExpertList = !(promptRule == 1 || promptRule == 3)
霍志良 committed
488
            if (actionHandler.userType == USER_TYPE_EXPERT && status == 2) { //当该专家离线时
489
                sendRecommendExpertListMessage(1, showExpertList, toUid, actionHandler)
霍志良 committed
490
            } else if (actionHandler.userType == USER_TYPE_EXPERT&& status >= 3) { //当该专家忙碌时
491 492 493 494 495 496 497 498 499
                sendRecommendExpertListMessage(2, showExpertList, toUid, actionHandler)
            }
        }
    }

    /**
     * 发送推荐专家列表
     */
    @SuppressLint("CheckResult")
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
    fun sendRecommendExpertListMessage(
        type: Int,
        showExpertList: Boolean,
        toUid: String,
        actionHandler: IP2PCustomActionHandler
    ) { // 调取接口获取推荐专家列表
        instance.getRecommendExpertList(
            actionHandler.info.toUid.toLong(),
            URLEncoder.encode(actionHandler.info.tag1),
            3
        )
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ res: BaseAPIResponse<ArrayList<RecommendExpertBean>> ->
                //发送推荐专家列表消息
                actionHandler.sendRecommendExpertListMessage(toUid, res.data, type, showExpertList)
            }, { throwable: Throwable -> ToastUtil.toastShort(throwable.toString()) })
517 518
    }

konghaorui committed
519 520 521
    //====================展示提示====================
    fun showSilencedDialog(context: Context, tips: String?, url: String?) {
        CommonDialog.create(context)
522 523 524 525 526 527 528 529 530 531 532
            .setMessage(tips)
            .setCancelAble(false)
            .setLeftOnclick(
                context.getString(R.string.im_details)
            ) {
                val realUrl = if (TextUtils.isEmpty(url)) ImConstants.HELP_URL else url!!
                val params = H5Params(realUrl, "")
                NewH5Activity.start(context, params)
            }
            .setRightClick(context.getString(R.string.im_approval), null)
            .show()
konghaorui committed
533
    }
534
}