Bläddra i källkod

feat: welcome补充

DoggyZhang 3 veckor sedan
förälder
incheckning
23eca5bbde

+ 2 - 0
app/src/main/java/com/adealink/weparty/module/im/Router.kt

@@ -33,6 +33,8 @@ interface IM {
             const val EXTRA_CHAT_DRAFT_TIME = "extra_chat_draft_time"
 
             const val EXTRA_CHAT_PLAYMATE_ID = "extra_chat_category_id"
+
+            const val EXTRA_CHAT_SOURCE = "extra_chat_source"
         }
     }
 

+ 5 - 0
app/src/main/java/com/adealink/weparty/module/im/data/Constants.kt

@@ -0,0 +1,5 @@
+package com.adealink.weparty.module.im.data
+
+enum class SessionSource(val source: String) {
+    USER_PUSH("user_push");
+}

+ 16 - 0
app/src/main/java/com/adealink/weparty/module/playmate/IPlaymateService.kt

@@ -1,6 +1,7 @@
 package com.adealink.weparty.module.playmate
 
 import androidx.lifecycle.ViewModelStoreOwner
+import com.adealink.frame.base.Rlt
 import com.adealink.weparty.aab.IService
 import com.adealink.weparty.module.playmate.viewmodel.IPlaymateDetailViewModel
 import com.adealink.weparty.module.playmate.viewmodel.IPlaymateViewModel
@@ -10,4 +11,19 @@ interface IPlaymateService : IService<IPlaymateService> {
     fun getPlaymateViewModel(owner: ViewModelStoreOwner): IPlaymateViewModel?
 
     fun getPlaymateDetailViewModel(owner: ViewModelStoreOwner): IPlaymateDetailViewModel?
+
+    /**
+     * 上报欢迎回复
+     */
+    fun reportWelcomeReply(uid:String)
+
+    /**
+     * 上报UserPush私聊消耗
+     */
+    fun reportUserPushChat(uid: String)
+
+    /**
+     * UserPush私聊是否可用
+     */
+    suspend fun isUserPushChatAvailable(uid: String): Rlt<Boolean>
 }

+ 24 - 0
app/src/main/java/com/adealink/weparty/module/playmate/PlaymateModule.kt

@@ -2,6 +2,8 @@ package com.adealink.weparty.module.playmate
 
 import androidx.lifecycle.ViewModelStoreOwner
 import com.adealink.frame.aab.BaseDynamicModule
+import com.adealink.frame.aab.constant.AABModuleNotInitError
+import com.adealink.frame.base.Rlt
 import com.adealink.weparty.R
 import com.adealink.weparty.module.playmate.viewmodel.IPlaymateDetailViewModel
 import com.adealink.weparty.module.playmate.viewmodel.IPlaymateViewModel
@@ -30,6 +32,16 @@ object PlaymateModule : BaseDynamicModule<IPlaymateService>(IPlaymateService::cl
                 return null
             }
 
+            override fun reportWelcomeReply(uid: String) {
+            }
+
+            override fun reportUserPushChat(uid: String) {
+            }
+
+            override suspend fun isUserPushChatAvailable(uid: String): Rlt<Boolean> {
+                return Rlt.Failed(AABModuleNotInitError())
+            }
+
             override fun onLogout() {
             }
         }
@@ -43,6 +55,18 @@ object PlaymateModule : BaseDynamicModule<IPlaymateService>(IPlaymateService::cl
         return getService().getPlaymateDetailViewModel(owner)
     }
 
+    override fun reportWelcomeReply(uid: String) {
+        getService().reportWelcomeReply(uid)
+    }
+
+    override fun reportUserPushChat(uid: String) {
+        getService().reportUserPushChat(uid)
+    }
+
+    override suspend fun isUserPushChatAvailable(uid: String): Rlt<Boolean> {
+        return getService().isUserPushChatAvailable(uid)
+    }
+
     override fun onLogout() {
         getService().onLogout()
     }

+ 1 - 0
app/src/main/res/values-in/strings.xml

@@ -384,4 +384,5 @@
     <string name="common_resubmit">Kirim Ulang</string>
     <string name="common_reject_reason">Alasan Penolakan</string>
     <string name="common_copy_success">Disalin</string>
+    <string name="playmate_user_push_chat_limit">Batas chat harian telah tercapai.</string>
 </resources>

+ 1 - 0
app/src/main/res/values-zh/strings.xml

@@ -384,4 +384,5 @@
     <string name="common_resubmit">重新提交</string>
     <string name="common_reject_reason">拒绝原因</string>
     <string name="common_copy_success">已复制</string>
+    <string name="playmate_user_push_chat_limit">今日私聊次数已达到上限</string>
 </resources>

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -391,4 +391,5 @@
     <string name="common_under_review_desc">Due to high application volume, we estimate a response within one week.</string>
     <string name="common_reject_reason">Reason for rejection</string>
     <string name="common_copy_success">Copied</string>
+    <string name="playmate_user_push_chat_limit">Daily chat limit reached.</string>
 </resources>

+ 11 - 1
module/im/src/main/java/com/adealink/weparty/im/constant/Error.kt

@@ -3,11 +3,14 @@ package com.adealink.weparty.im.constant
 import com.adealink.frame.aab.util.getCompatString
 import com.adealink.frame.base.IError
 import com.adealink.weparty.im.R
+import com.adealink.weparty.R as APP_R
 
 const val IM_IN_BLACKLIST = 120001 //对方把你拉黑
 
 const val IM_USER_NOT_FIND = 120002 //用户不存在
 
+const val IM_USER_CHAT_LIMIT = 120003 //私信限制
+
 
 /**
  * http状态码不是成功状态错误
@@ -19,4 +22,11 @@ class InBlackError(override val msg: String = getCompatString(R.string.im_send_m
  * http状态码不是成功状态错误
  */
 class UserNotFindError(override val msg: String = getCompatString(R.string.im_send_msg_error_user_not_find)) :
-    IError(serverCode = IM_USER_NOT_FIND)
+    IError(serverCode = IM_USER_NOT_FIND)
+
+
+/**
+ * 私聊限制
+ */
+class ChatLimitError(override val msg: String = getCompatString(APP_R.string.playmate_user_push_chat_limit)) :
+    IError(serverCode = IM_USER_CHAT_LIMIT)

+ 16 - 1
module/im/src/main/java/com/adealink/weparty/im/session/comp/SessionBottomComp.kt

@@ -11,7 +11,11 @@ import com.adealink.weparty.im.databinding.LayoutSessionBottomBarBinding
 import com.adealink.weparty.im.session.comp.input.InputAction
 import com.adealink.weparty.im.session.comp.input.InputState
 import com.adealink.weparty.im.session.comp.viewmodel.SessionInputViewModel
+import com.adealink.weparty.module.im.IM
+import com.adealink.weparty.module.im.data.SessionSource
 import com.adealink.weparty.module.im.data.sendIMMessageLD
+import com.adealink.weparty.module.playmate.PlaymateModule
+import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean
 import com.tencent.qcloud.tuikit.tuichat.bean.ChatInfo
 import com.tencent.qcloud.tuikit.tuichat.presenter.ChatPresenter
 
@@ -72,11 +76,22 @@ class SessionBottomComp(
                 }
 
                 is Rlt.Success -> {
-                    sendIMMessageLD.postValue(rlt.data)
+                    val data = rlt.data
+                    onSendMessageSuccess(data)
                 }
             }
         }
 
     }
 
+    private fun onSendMessageSuccess(message: TUIMessageBean?) {
+        //来源:用户推荐
+        val source = activity?.intent?.getStringExtra(IM.Session.EXTRA_CHAT_SOURCE)
+        if (SessionSource.USER_PUSH.source == source) {
+            chatInfo?.id?.let { uid ->
+                PlaymateModule.reportUserPushChat(uid)
+            }
+        }
+    }
+
 }

+ 28 - 0
module/im/src/main/java/com/adealink/weparty/im/session/comp/viewmodel/SessionInputViewModel.kt

@@ -11,7 +11,9 @@ import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
 import com.adealink.frame.mvvm.viewmodel.BaseViewModel
 import com.adealink.weparty.commonui.toast.util.debugToast
 import com.adealink.weparty.im.R
+import com.adealink.weparty.im.constant.ChatLimitError
 import com.adealink.weparty.im.constant.IM_IN_BLACKLIST
+import com.adealink.weparty.im.constant.IM_USER_CHAT_LIMIT
 import com.adealink.weparty.im.constant.IM_USER_NOT_FIND
 import com.adealink.weparty.im.constant.InBlackError
 import com.adealink.weparty.im.constant.UserNotFindError
@@ -19,6 +21,10 @@ import com.adealink.weparty.im.session.comp.input.InputAction
 import com.adealink.weparty.im.session.comp.input.InputMachineTransaction
 import com.adealink.weparty.im.session.comp.input.InputState
 import com.adealink.weparty.im.session.comp.input.SessionInputMachine
+import com.adealink.weparty.im.session.mesasge.PlaymateSayWelcomeTextMessageBean
+import com.adealink.weparty.im.session.mesasge.PlaymateSayWelcomeVoiceMessageBean
+import com.adealink.weparty.module.im.data.sendIMMessageLD
+import com.adealink.weparty.module.playmate.PlaymateModule
 import com.tencent.qcloud.tuicore.TUIConstants
 import com.tencent.qcloud.tuikit.timcommon.bean.TUIMessageBean
 import com.tencent.qcloud.tuikit.timcommon.component.interfaces.IUIKitCallback
@@ -27,6 +33,7 @@ import com.tencent.qcloud.tuikit.tuichat.component.progress.ProgressPresenter
 import com.tencent.qcloud.tuikit.tuichat.presenter.ChatPresenter
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.suspendCancellableCoroutine
+import com.adealink.weparty.R as APP_R
 
 
 data class SessionInputState(
@@ -129,6 +136,8 @@ class SessionInputViewModel : BaseViewModel() {
         callback: IUIKitCallback<TUIMessageBean>?
     ): String? {
         return suspendCancellableCoroutine { continuation ->
+            val lastMessage = presenter.loadedMessageList?.lastOrNull()
+
             presenter.sendMessage(
                 message,
                 retry,
@@ -137,6 +146,8 @@ class SessionInputViewModel : BaseViewModel() {
                     override fun onSuccess(data: TUIMessageBean?) {
                         callback?.onSuccess(data)
                         sendMessageResultLD.send(Rlt.Success(data))
+                        sendIMMessageLD.postValue(message)
+                        onSendMessageSuccess(lastMessage, message)
                     }
 
                     override fun onError(module: String?, errCode: Int, errMsg: String?) {
@@ -151,6 +162,10 @@ class SessionInputViewModel : BaseViewModel() {
                         } else if (errCode == IM_USER_NOT_FIND) {
                             errorMessage = getCompatString(R.string.im_send_msg_error_user_not_find)
                             error = UserNotFindError()
+                        } else if (errCode == IM_USER_CHAT_LIMIT) {
+                            errorMessage =
+                                getCompatString(APP_R.string.playmate_user_push_chat_limit)
+                            error = ChatLimitError()
                         }
                         callback?.onError(errCode, errorMessage, message)
                         sendMessageResultLD.send(Rlt.Failed(error))
@@ -169,6 +184,19 @@ class SessionInputViewModel : BaseViewModel() {
         }
     }
 
+    private fun onSendMessageSuccess(lastMessage: TUIMessageBean?, sendMessage: TUIMessageBean) {
+        val uid = chatInfo?.id
+        if (uid.isNullOrEmpty() || lastMessage == null) {
+            return
+        }
+        if (lastMessage is PlaymateSayWelcomeTextMessageBean
+            || lastMessage is PlaymateSayWelcomeVoiceMessageBean
+        ) {
+            //上一条消息是陪玩欢迎消息
+            PlaymateModule.reportWelcomeReply(uid)
+        }
+    }
+
     fun sendPhotoVideoMessage(original: Uri?, transcodeUri: Uri? = null) {
         presenter?.sendPhotoVideoMessages(original, transcodeUri)
     }

+ 1 - 0
module/im/src/main/res/values/strings.xml

@@ -46,4 +46,5 @@
     <string name="im_order_go_voice">Go voice</string>
     <string name="im_create_order_title">Order now mark a voice call</string>
     <string name="im_call_return_by_no_in_service">No ongoing orders, unable to call</string>
+    <string name="im_chat_limit_error">Chat limit</string>
 </resources>

+ 35 - 0
module/playmate/src/main/java/com/adealink/weparty/playmate/PlaymateServiceImpl.kt

@@ -2,16 +2,26 @@ package com.adealink.weparty.playmate
 
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.ViewModelStoreOwner
+import com.adealink.frame.base.Rlt
 import com.adealink.frame.spi.RegisterService
+import com.adealink.weparty.App
 import com.adealink.weparty.module.playmate.IPlaymateService
 import com.adealink.weparty.module.playmate.viewmodel.IPlaymateDetailViewModel
 import com.adealink.weparty.module.playmate.viewmodel.IPlaymateViewModel
+import com.adealink.weparty.playmate.data.PlaymateUserPushQuotaReq
+import com.adealink.weparty.playmate.datasource.remote.PlaymateHttpService
 import com.adealink.weparty.playmate.detail.viewmodel.PlaymateDetailViewModel
+import com.adealink.weparty.playmate.stat.UserPushSendMessageEvent
+import com.adealink.weparty.playmate.stat.WelcomeReplyEvent
 import com.adealink.weparty.playmate.viewmodel.PlaymateViewModel
 
 @RegisterService(IPlaymateService::class)
 class PlaymateServiceImpl : IPlaymateService {
 
+    private val playmateHttpService by lazy {
+        App.instance.networkService.getHttpService(PlaymateHttpService::class.java)
+    }
+
     override fun getService(): IPlaymateService {
         return this
     }
@@ -24,6 +34,31 @@ class PlaymateServiceImpl : IPlaymateService {
         return ViewModelProvider(owner)[PlaymateDetailViewModel::class.java]
     }
 
+    override fun reportWelcomeReply(uid: String) {
+        WelcomeReplyEvent().apply {
+            this.uid to uid
+        }.send()
+    }
+
+    override fun reportUserPushChat(uid: String) {
+        UserPushSendMessageEvent().apply {
+            this.uid to uid
+        }.send()
+    }
+
+    override suspend fun isUserPushChatAvailable(uid: String): Rlt<Boolean> {
+        return when (val rlt =
+            playmateHttpService.getUserPushChatQuota(PlaymateUserPushQuotaReq(uid))) {
+            is Rlt.Failed -> {
+                rlt
+            }
+
+            is Rlt.Success -> {
+                Rlt.Success(rlt.data.data?.isQuotaAvailable() ?: false)
+            }
+        }
+    }
+
     override fun onLogout() {
 
     }

+ 21 - 0
module/playmate/src/main/java/com/adealink/weparty/playmate/data/PlaymateData.kt

@@ -132,3 +132,24 @@ data class UpdateWelcomeReq(
     @SerializedName("voiceUrl") val voice: String? = null,
     @SerializedName("voiceDuration") val duration: Int? = null,
 )
+
+data class WelcomeReplayReq(
+    @SerializedName("userNo") val uid: String
+)
+
+data class ReportUserPushChatReq(
+    @SerializedName("userNo") val uid: String
+)
+
+data class PlaymateUserPushQuotaReq(
+    @SerializedName("userNo") val uid: String
+)
+
+data class PlaymateUserPushQuotaRes(
+    @SerializedName("userQuotaCount") val userQuotaCount: Int,
+    @SerializedName("playmateQuotaCount") val playmateQuotaCount: Int
+) {
+    fun isQuotaAvailable(): Boolean {
+        return userQuotaCount > 0 && playmateQuotaCount > 0
+    }
+}

+ 13 - 0
module/playmate/src/main/java/com/adealink/weparty/playmate/datasource/remote/PlaymateHttpService.kt

@@ -16,6 +16,9 @@ import com.adealink.weparty.playmate.data.PlaymateCategoryRes
 import com.adealink.weparty.playmate.data.PlaymateDetailReq
 import com.adealink.weparty.playmate.data.PlaymateListReq
 import com.adealink.weparty.playmate.data.PlaymateListRes
+import com.adealink.weparty.playmate.data.PlaymateUserPushQuotaReq
+import com.adealink.weparty.playmate.data.PlaymateUserPushQuotaRes
+import com.adealink.weparty.playmate.data.ReportUserPushChatReq
 import com.adealink.weparty.playmate.data.SetupBusinessTimeReq
 import com.adealink.weparty.playmate.data.SkillSettingListReq
 import com.adealink.weparty.playmate.data.SkillSettingListRes
@@ -27,6 +30,7 @@ import com.adealink.weparty.playmate.data.UserPlaymateCategoryReq
 import com.adealink.weparty.playmate.data.UserPlaymateCategoryRes
 import com.adealink.weparty.playmate.data.UserPushListRes
 import com.adealink.weparty.playmate.data.WelcomeListRes
+import com.adealink.weparty.playmate.data.WelcomeReplayReq
 import retrofit2.http.Body
 import retrofit2.http.POST
 
@@ -95,4 +99,13 @@ interface PlaymateHttpService {
     @POST("playmate/autoWelcome/switch")
     suspend fun enableAutoWelcome(@Body req: EnableAutoWelcomeReq): Rlt<Res<Any>>
 
+    @POST("playmate/welcome/reply/submit")
+    suspend fun userWelcomeReplyReq(@Body req: WelcomeReplayReq): Rlt<Res<Any>>
+
+    @POST("playmate/push/chat/submit")
+    suspend fun reportUserPushChat(@Body req: ReportUserPushChatReq): Rlt<Res<Any>>
+
+    @POST("playmate/push/chat/quota")
+    suspend fun getUserPushChatQuota(@Body req: PlaymateUserPushQuotaReq): Rlt<Res<PlaymateUserPushQuotaRes>>
+
 }

+ 34 - 0
module/playmate/src/main/java/com/adealink/weparty/playmate/stat/UserPushSendMessageEvent.kt

@@ -0,0 +1,34 @@
+package com.adealink.weparty.playmate.stat
+
+import com.adealink.frame.log.Log
+import com.adealink.frame.statistics.BaseStatEvent
+import com.adealink.frame.statistics.CommonEventKey
+import com.adealink.frame.statistics.CommonEventValue
+import com.adealink.frame.statistics.IEventValue
+import com.adealink.weparty.App
+import com.adealink.weparty.module.playmate.data.TAG_PLAYMATE_EVENT
+import com.adealink.weparty.playmate.data.ReportUserPushChatReq
+import com.adealink.weparty.playmate.datasource.remote.PlaymateHttpService
+import kotlinx.coroutines.launch
+
+class UserPushSendMessageEvent : BaseStatEvent("") {
+
+    override val action: IEventValue = CommonEventValue.Action.EMPTY
+    private val playmateHttpService by lazy {
+        App.instance.networkService.getHttpService(PlaymateHttpService::class.java)
+    }
+
+    val uid = Param(CommonEventKey.UID)
+    override fun send() {
+        launch {
+            val uid = uid.value as? String ?: return@launch
+            Log.d(TAG_PLAYMATE_EVENT, "report user push send message, uid:${uid}")
+            playmateHttpService.reportUserPushChat(ReportUserPushChatReq(uid))
+        }
+    }
+
+    override fun toString(): String {
+        return "UserPushSendMessageEvent(uid:${uid})"
+    }
+
+}

+ 34 - 0
module/playmate/src/main/java/com/adealink/weparty/playmate/stat/WelcomeReplyEvent.kt

@@ -0,0 +1,34 @@
+package com.adealink.weparty.playmate.stat
+
+import com.adealink.frame.log.Log
+import com.adealink.frame.statistics.BaseStatEvent
+import com.adealink.frame.statistics.CommonEventKey
+import com.adealink.frame.statistics.CommonEventValue
+import com.adealink.frame.statistics.IEventValue
+import com.adealink.weparty.App
+import com.adealink.weparty.module.playmate.data.TAG_PLAYMATE_EVENT
+import com.adealink.weparty.playmate.data.WelcomeReplayReq
+import com.adealink.weparty.playmate.datasource.remote.PlaymateHttpService
+import kotlinx.coroutines.launch
+
+class WelcomeReplyEvent : BaseStatEvent("") {
+
+    override val action: IEventValue = CommonEventValue.Action.EMPTY
+    private val playmateHttpService by lazy {
+        App.instance.networkService.getHttpService(PlaymateHttpService::class.java)
+    }
+
+    val uid = Param(CommonEventKey.UID)
+    override fun send() {
+        launch {
+            val uid = uid.value as? String ?: return@launch
+            Log.d(TAG_PLAYMATE_EVENT, "report welcome reply, uid:${uid}")
+            playmateHttpService.userWelcomeReplyReq(WelcomeReplayReq(uid))
+        }
+    }
+
+    override fun toString(): String {
+        return "WelcomeReplyEvent(uid:${uid})"
+    }
+
+}

+ 28 - 3
module/playmate/src/main/java/com/adealink/weparty/playmate/userpush/UserPushFragment.kt

@@ -1,8 +1,10 @@
 package com.adealink.weparty.playmate.userpush
 
 import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.lifecycleScope
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
+import com.adealink.frame.base.Rlt
 import com.adealink.frame.base.fastLazy
 import com.adealink.frame.mvvm.view.viewBinding
 import com.adealink.frame.router.Router
@@ -13,8 +15,11 @@ import com.adealink.weparty.commonui.ext.show
 import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
 import com.adealink.weparty.commonui.recycleview.itemdecoration.VerticalSpaceItemDecoration
 import com.adealink.weparty.commonui.toast.util.showFailedToast
+import com.adealink.weparty.commonui.toast.util.showToast
 import com.adealink.weparty.module.im.IM
+import com.adealink.weparty.module.im.data.SessionSource
 import com.adealink.weparty.module.im.data.sendIMMessageLD
+import com.adealink.weparty.module.playmate.PlaymateModule
 import com.adealink.weparty.module.profile.Profile
 import com.adealink.weparty.playmate.R
 import com.adealink.weparty.playmate.databinding.FragmentUserPushBinding
@@ -24,6 +29,7 @@ import com.adealink.weparty.playmate.userpush.viewmodel.UserPushViewModel
 import com.adealink.weparty.playmate.viewmodel.PlaymateViewModelFactory
 import com.scwang.smart.refresh.layout.api.RefreshLayout
 import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
+import kotlinx.coroutines.launch
 import com.adealink.weparty.R as APP_R
 
 class UserPushFragment : BaseFragment(R.layout.fragment_user_push) {
@@ -106,9 +112,28 @@ class UserPushFragment : BaseFragment(R.layout.fragment_user_push) {
 
     private fun goSession(uid: String) {
         val act = activity ?: return
-        Router.build(act, IM.Session.PATH)
-            .putExtra(IM.Session.EXTRA_CHAT_ID, uid)
-            .start()
+        lifecycleScope.launch {
+            this@UserPushFragment.showLoading()
+            val rlt = PlaymateModule.isUserPushChatAvailable(uid)
+            this@UserPushFragment.dismissLoading()
+            when (rlt) {
+                is Rlt.Failed -> {
+                    showFailedToast(rlt)
+                }
+
+                is Rlt.Success -> {
+                    val available = rlt.data
+                    if (available) {
+                        Router.build(act, IM.Session.PATH)
+                            .putExtra(IM.Session.EXTRA_CHAT_ID, uid)
+                            .putExtra(IM.Session.EXTRA_CHAT_SOURCE, SessionSource.USER_PUSH.source)
+                            .start()
+                    } else {
+                        showToast(APP_R.string.playmate_user_push_chat_limit)
+                    }
+                }
+            }
+        }
     }
 
 }