2025-05-13 19:39:53 +08:00
< template >
2025-05-28 22:12:30 +08:00
< div class = "Navigation" >
2025-05-14 16:09:14 +08:00
< image
src = "../../../static/Navigationimg.png"
mode = "scaleToFill"
class = "Navigationimg"
/ >
2025-05-28 22:12:30 +08:00
< image
@ click = "Returnfunc"
src = "../../../static/Return.png"
mode = "scaleToFill"
class = "Return"
/ >
2025-05-14 16:09:14 +08:00
< / div >
2025-05-28 22:12:30 +08:00
< div class = "dingweizhibox" > < / div >
2025-05-13 19:39:53 +08:00
< div class = "chat" >
< div : class = "['tui-chat', !isPC && 'tui-chat-h5']" >
< div
v - if = "!currentConversationID"
: class = "['tui-chat-default', !isPC && 'tui-chat-h5-default']"
>
< slot / >
< / div >
2025-05-28 22:12:30 +08:00
< div v-if = "currentConversationID" :class="['tui-chat', !isPC && 'tui-chat-h5']" >
2025-05-13 19:39:53 +08:00
< ChatHeader
: class = " [
'tui-chat-header' ,
! isPC && 'tui-chat-H5-header' ,
isUniFrameWork && 'tui-chat-uniapp-header' ,
] "
: isGroup = "isGroup"
: headerExtensionList = "headerExtensionList"
@ closeChat = "closeChat"
@ openGroupManagement = "handleGroup"
/ >
< Forward @toggleMultipleSelectMode ="toggleMultipleSelectMode" / >
< MessageList
ref = "messageListRef"
: class = "['tui-chat-message-list', !isPC && 'tui-chat-h5-message-list']"
: isGroup = "isGroup"
: groupID = "groupID"
: isNotInGroup = "isNotInGroup"
: isMultipleSelectMode = "isMultipleSelectMode"
@ handleEditor = "handleEditor"
@ closeInputToolBar = "() => changeToolbarDisplayType('none')"
@ toggleMultipleSelectMode = "toggleMultipleSelectMode"
/ >
< div
v - if = "isNotInGroup"
: class = " {
'tui-chat-leave-group' : true ,
'tui-chat-leave-group-mobile' : isMobile ,
} "
>
{ { leaveGroupReasonText } }
< / div >
< MultipleSelectPanel
v - else - if = "isMultipleSelectMode"
@ oneByOneForwardMessage = "oneByOneForwardMessage"
@ mergeForwardMessage = "mergeForwardMessage"
@ toggleMultipleSelectMode = "toggleMultipleSelectMode"
/ >
< template v-else >
< MessageInputToolbar
v - if = "isInputToolbarShow"
: class = " [
'tui-chat-message-input-toolbar' ,
! isPC && 'tui-chat-h5-message-input-toolbar' ,
2025-05-28 22:12:30 +08:00
isUniFrameWork && 'tui-chat-uni-message-input-toolbar' ,
2025-05-13 19:39:53 +08:00
] "
: displayType = "inputToolbarDisplayType"
@ insertEmoji = "insertEmoji"
@ changeToolbarDisplayType = "changeToolbarDisplayType"
@ scrollToLatestMessage = "scrollToLatestMessage"
/ >
< MessageInput
ref = "messageInputRef"
: class = " [
'tui-chat-message-input' ,
! isPC && 'tui-chat-h5-message-input' ,
isUniFrameWork && 'tui-chat-uni-message-input' ,
isWeChat && 'tui-chat-wx-message-input' ,
] "
: enableAt = "featureConfig.InputMention"
: isMuted = "false"
: muteText = "TUITranslateService.t('TUIChat.您已被管理员禁言')"
: placeholder = "TUITranslateService.t('TUIChat.请输入消息')"
: inputToolbarDisplayType = "inputToolbarDisplayType"
@ changeToolbarDisplayType = "changeToolbarDisplayType"
/ >
< / template >
< / div >
<!-- Group Management -- >
< div
2025-05-28 22:12:30 +08:00
v - if = "
! isNotInGroup &&
! isApp &&
isUniFrameWork &&
isGroup &&
headerExtensionList . length > 0
"
2025-05-13 19:39:53 +08:00
class = "group-profile"
@ click = "handleGroup"
>
{ { headerExtensionList [ 0 ] . text } }
< / div >
< / div >
< / div >
< / template >
< script lang = "ts" setup >
2025-05-28 22:12:30 +08:00
import { ref , onMounted , onUnmounted , computed } from "../../adapter-vue" ;
2025-05-13 19:39:53 +08:00
import TUIChatEngine , {
TUITranslateService ,
TUIConversationService ,
TUIStore ,
StoreName ,
IMessageModel ,
IConversationModel ,
2025-05-28 22:12:30 +08:00
} from "@tencentcloud/chat-uikit-engine" ;
import TUICore , { TUIConstants , ExtensionInfo } from "@tencentcloud/tui-core" ;
import ChatHeader from "./chat-header/index.vue" ;
import MessageList from "./message-list/index.vue" ;
import MessageInput from "./message-input/index.vue" ;
import MultipleSelectPanel from "./mulitple-select-panel/index.vue" ;
import Forward from "./forward/index.vue" ;
import MessageInputToolbar from "./message-input-toolbar/index.vue" ;
import { isPC , isWeChat , isUniFrameWork , isMobile , isApp } from "../../utils/env" ;
import { ToolbarDisplayType } from "../../interface" ;
import TUIChatConfig from "./config" ;
2025-05-13 19:39:53 +08:00
// @Start uniapp use Chat only
2025-05-28 22:12:30 +08:00
import { onLoad , onUnload } from "@dcloudio/uni-app" ;
import { initChat , logout } from "./entry-chat-only.ts" ;
import { isEnabledMessageReadReceiptGlobal } from "./utils/utils" ;
import OfflinePushInfoManager from "./offlinePushInfoManager/index" ;
import { TUIChatService } from "@tencentcloud/chat-uikit-engine" ;
2025-05-30 22:04:45 +08:00
import { useCounterStore } from "@/stores/counter" ;
import request from "@/components/request" ;
import generateMsgId from "../../../components/generateMsgId.js" ;
const counter = useCounterStore ( ) ;
2025-05-14 16:09:14 +08:00
2025-05-28 22:12:30 +08:00
let myitem = ref ( ) ;
let youritem = ref ( ) ;
2025-05-30 22:04:45 +08:00
let MessageListinfo = ref ( ) ;
2025-05-13 19:39:53 +08:00
onLoad ( ( options ) => {
initChat ( options ) ;
2025-05-30 22:04:45 +08:00
myitem . value = JSON . parse ( options . myitem ) ;
youritem . value = JSON . parse ( options . youritem ) ;
counter . $patch ( { youritem : youritem . value } ) ;
setTimeout ( ( ) => {
sendCustomMessage ( myitem . value , youritem . value ) ;
} , 1000 ) ;
2025-05-13 19:39:53 +08:00
} ) ;
onUnload ( ( ) => {
// Whether logout is decided by yourself when the page is unloaded. The default is false.
2025-05-28 22:12:30 +08:00
logout ( false )
. then ( ( ) => {
// Handle success result from promise.then when you set true.
} )
. catch ( ( ) => {
// handle error
} ) ;
2025-05-13 19:39:53 +08:00
} ) ;
// @End uniapp use Chat only
2025-05-28 22:12:30 +08:00
const emits = defineEmits ( [ "closeChat" ] ) ;
2025-05-13 19:39:53 +08:00
const groupID = ref ( undefined ) ;
const isGroup = ref ( false ) ;
const isNotInGroup = ref ( false ) ;
const notInGroupReason = ref < number > ( ) ;
const currentConversationID = ref ( ) ;
const isMultipleSelectMode = ref ( false ) ;
2025-05-28 22:12:30 +08:00
const inputToolbarDisplayType = ref < ToolbarDisplayType > ( "none" ) ;
2025-05-13 19:39:53 +08:00
const messageInputRef = ref ( ) ;
const messageListRef = ref < InstanceType < typeof MessageList > > ( ) ;
const headerExtensionList = ref < ExtensionInfo [ ] > ( [ ] ) ;
const featureConfig = TUIChatConfig . getFeatureConfig ( ) ;
onMounted ( ( ) => {
TUIStore . watch ( StoreName . CONV , {
currentConversation : onCurrentConversationUpdate ,
} ) ;
} ) ;
onUnmounted ( ( ) => {
TUIStore . unwatch ( StoreName . CONV , {
currentConversation : onCurrentConversationUpdate ,
} ) ;
reset ( ) ;
} ) ;
2025-05-28 22:12:30 +08:00
//发送自定义消息
let currentConversation = ref ( ) ;
TUIStore . watch ( StoreName . CONV , {
currentConversation : ( conversation ) => {
currentConversation . value = conversation ;
} ,
} ) ;
function sendCustomMessage ( myitem , youritem ) {
2025-05-30 22:04:45 +08:00
const keyid = generateMsgId ( ) ;
2025-05-28 22:12:30 +08:00
const payload = {
data : JSON . stringify ( {
businessID : "pk" ,
2025-05-30 22:04:45 +08:00
keyid : keyid ,
myitem : counter . myitem . id ,
2025-06-03 22:12:34 +08:00
pkIdA : youritem . id ,
pkIdB : myitem . id ,
userIdA : youritem . senderId ,
userIdB : myitem . senderId ,
pkTime : youritem . pkTime ,
pkNumber : youritem . pkNumber ,
link : "https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/pk.png" ,
2025-05-30 22:04:45 +08:00
btnDisplay : true ,
2025-05-28 22:12:30 +08:00
} ) ,
description : "邀请参加PK" ,
extension : "邀请参加PK" ,
} ;
const options = {
to :
currentConversation ? . value ? . groupProfile ? . groupID ||
currentConversation ? . value ? . userProfile ? . userID ,
conversationType : currentConversation ? . value ? . type ,
payload ,
needReadReceipt : isEnabledMessageReadReceiptGlobal ( ) ,
} ;
const offlinePushInfoCreateParams = {
conversation : currentConversation . value ,
payload : options . payload ,
messageType : TUIChatEngine . TYPES . MSG _CUSTOM ,
} ;
const sendMessageOptions = {
offlinePushInfo : OfflinePushInfoManager . create ( offlinePushInfoCreateParams ) ,
} ;
2025-05-30 22:04:45 +08:00
TUIChatService . sendCustomMessage ( options , sendMessageOptions ) . then ( ( res ) => {
const messagein = request ( {
url : "chat/add" ,
method : "POST" ,
data : {
messageInfo : JSON . stringify ( res . data . message ) ,
keyId : keyid ,
} ,
userInfo : false ,
} ) ;
} ) ;
const messageList = request ( {
url : "pk/createPkRecord" ,
method : "POST" ,
data : {
pkIdA : youritem . id ,
pkIdB : myitem . id ,
userIdA : youritem . senderId ,
userIdB : myitem . senderId ,
pkTime : youritem . pkTime ,
2025-06-03 22:12:34 +08:00
pkNumber : youritem . pkNumber ,
2025-05-30 22:04:45 +08:00
status : 0 ,
} ,
userInfo : false ,
2025-05-28 22:12:30 +08:00
} ) ;
myitem . value = null ;
youritem . value = null ;
currentConversation . value = null ;
}
2025-05-30 22:04:45 +08:00
//`````````````````````````````````````````````````````````````````````标记
2025-05-13 19:39:53 +08:00
const isInputToolbarShow = computed < boolean > ( ( ) => {
2025-05-28 22:12:30 +08:00
return isUniFrameWork ? inputToolbarDisplayType . value !== "none" : true ;
2025-05-13 19:39:53 +08:00
} ) ;
const leaveGroupReasonText = computed < string > ( ( ) => {
2025-05-28 22:12:30 +08:00
let text = "" ;
2025-05-13 19:39:53 +08:00
switch ( notInGroupReason . value ) {
case 4 :
2025-05-28 22:12:30 +08:00
text = TUITranslateService . t ( "TUIChat.您已被管理员移出群聊" ) ;
2025-05-13 19:39:53 +08:00
break ;
case 5 :
2025-05-28 22:12:30 +08:00
text = TUITranslateService . t ( "TUIChat.该群聊已被解散" ) ;
2025-05-13 19:39:53 +08:00
break ;
case 8 :
2025-05-28 22:12:30 +08:00
text = TUITranslateService . t ( "TUIChat.您已退出该群聊" ) ;
2025-05-13 19:39:53 +08:00
break ;
default :
2025-05-28 22:12:30 +08:00
text = TUITranslateService . t ( "TUIChat.您已退出该群聊" ) ;
2025-05-13 19:39:53 +08:00
break ;
}
return text ;
} ) ;
const reset = ( ) => {
2025-05-28 22:12:30 +08:00
TUIConversationService . switchConversation ( "" ) ;
2025-05-13 19:39:53 +08:00
} ;
const closeChat = ( conversationID : string ) => {
2025-05-28 22:12:30 +08:00
emits ( "closeChat" , conversationID ) ;
2025-05-13 19:39:53 +08:00
reset ( ) ;
} ;
const insertEmoji = ( emojiObj : object ) => {
messageInputRef . value ? . insertEmoji ( emojiObj ) ;
} ;
const handleEditor = ( message : IMessageModel , type : string ) => {
if ( ! message || ! type ) return ;
switch ( type ) {
2025-05-28 22:12:30 +08:00
case "reference" :
2025-05-13 19:39:53 +08:00
// todo
break ;
2025-05-28 22:12:30 +08:00
case "reply" :
2025-05-13 19:39:53 +08:00
// todo
break ;
2025-05-28 22:12:30 +08:00
case "reedit" :
2025-05-13 19:39:53 +08:00
if ( message ? . payload ? . text ) {
messageInputRef ? . value ? . reEdit ( message ? . payload ? . text ) ;
}
break ;
default :
break ;
}
} ;
const handleGroup = ( ) => {
headerExtensionList . value [ 0 ] . listener . onClicked ( { groupID : groupID . value } ) ;
} ;
2025-05-28 22:12:30 +08:00
function Returnfunc ( ) {
2025-05-14 16:09:14 +08:00
uni . navigateBack ( {
2025-05-28 22:12:30 +08:00
delta : 1 ,
2025-05-14 16:09:14 +08:00
} ) ;
}
2025-05-13 19:39:53 +08:00
function changeToolbarDisplayType ( type : ToolbarDisplayType ) {
2025-05-28 22:12:30 +08:00
inputToolbarDisplayType . value = inputToolbarDisplayType . value === type ? "none" : type ;
if ( inputToolbarDisplayType . value !== "none" && isUniFrameWork ) {
uni . $emit ( "scroll-to-bottom" ) ;
2025-05-13 19:39:53 +08:00
}
}
function scrollToLatestMessage ( ) {
messageListRef . value ? . scrollToLatestMessage ( ) ;
}
function toggleMultipleSelectMode ( visible ? : boolean ) {
2025-05-28 22:12:30 +08:00
isMultipleSelectMode . value =
visible === undefined ? ! isMultipleSelectMode . value : visible ;
2025-05-13 19:39:53 +08:00
}
function mergeForwardMessage ( ) {
messageListRef . value ? . mergeForwardMessage ( ) ;
}
function oneByOneForwardMessage ( ) {
messageListRef . value ? . oneByOneForwardMessage ( ) ;
}
function updateUIUserNotInGroup ( conversation : IConversationModel ) {
if ( conversation ? . operationType > 0 ) {
headerExtensionList . value = [ ] ;
isNotInGroup . value = true ;
/ * *
* 4 - be removed from the group
* 5 - group is dismissed
* 8 - quit group
* /
notInGroupReason . value = conversation ? . operationType ;
} else {
isNotInGroup . value = false ;
notInGroupReason . value = undefined ;
}
}
function onCurrentConversationUpdate ( conversation : IConversationModel ) {
updateUIUserNotInGroup ( conversation ) ;
// return when currentConversation is null
if ( ! conversation ) {
return ;
}
// return when currentConversationID.value is the same as conversation.conversationID.
if ( currentConversationID . value === conversation ? . conversationID ) {
return ;
}
isGroup . value = false ;
let conversationType = TUIChatEngine . TYPES . CONV _C2C ;
const conversationID = conversation . conversationID ;
if ( conversationID . startsWith ( TUIChatEngine . TYPES . CONV _GROUP ) ) {
conversationType = TUIChatEngine . TYPES . CONV _GROUP ;
isGroup . value = true ;
2025-05-28 22:12:30 +08:00
groupID . value = conversationID . replace ( TUIChatEngine . TYPES . CONV _GROUP , "" ) ;
2025-05-13 19:39:53 +08:00
}
headerExtensionList . value = [ ] ;
isMultipleSelectMode . value = false ;
// Initialize chatType
TUIChatConfig . setChatType ( conversationType ) ;
// While converstaion change success, notify callkit and roomkit、or other components.
2025-05-28 22:12:30 +08:00
TUICore . notifyEvent (
TUIConstants . TUIChat . EVENT . CHAT _STATE _CHANGED ,
TUIConstants . TUIChat . EVENT _SUB _KEY . CHAT _OPENED ,
{ groupID : groupID . value }
) ;
2025-05-13 19:39:53 +08:00
// The TUICustomerServicePlugin plugin determines if the current conversation is a customer service conversation, then sets chatType and activates the conversation.
TUICore . callService ( {
serviceName : TUIConstants . TUICustomerServicePlugin . SERVICE . NAME ,
method : TUIConstants . TUICustomerServicePlugin . SERVICE . METHOD . ACTIVE _CONVERSATION ,
params : { conversationID : conversationID } ,
} ) ;
// When open chat in room, close main chat ui and reset theme.
if ( TUIChatConfig . getChatType ( ) === TUIConstants . TUIChat . TYPE . ROOM ) {
2025-05-28 22:12:30 +08:00
if (
TUIChatConfig . getFeatureConfig ( TUIConstants . TUIChat . FEATURE . InputVoice ) === true
) {
TUIChatConfig . setTheme ( "light" ) ;
currentConversationID . value = "" ;
2025-05-13 19:39:53 +08:00
return ;
}
}
// Get chat header extensions
if ( TUIChatConfig . getChatType ( ) === TUIConstants . TUIChat . TYPE . GROUP ) {
2025-05-28 22:12:30 +08:00
headerExtensionList . value = TUICore . getExtensionList (
TUIConstants . TUIChat . EXTENSION . CHAT _HEADER . EXT _ID
) ;
2025-05-13 19:39:53 +08:00
}
2025-05-28 22:12:30 +08:00
TUIStore . update ( StoreName . CUSTOM , "activeConversation" , conversationID ) ;
2025-05-13 19:39:53 +08:00
currentConversationID . value = conversationID ;
}
< / script >
< style scoped lang = "scss" src = "./style/index.scss" > < / style >
2025-05-14 16:09:14 +08:00
< style >
2025-05-28 22:12:30 +08:00
. dingweizhibox {
2025-05-14 16:09:14 +08:00
width : 100 % ;
height : 15 % ;
}
. Navigation {
width : 100 % ;
height : 10 % ;
position : fixed ;
top : 0 ;
left : 0 ;
z - index : 999 ;
display : flex ;
justify - content : center ;
align - items : center ;
}
. Navigationimg {
width : 100 % ;
height : 200 rpx ;
position : absolute ;
top : 0 ;
left : 0 ;
z - index : - 1 ;
}
. Navigation {
width : 100 % ;
height : 200 rpx ;
z - index : 999 ;
display : flex ;
justify - content : center ;
align - items : center ;
}
. Return {
width : 50 rpx ;
height : 50 rpx ;
position : absolute ;
top : 100 rpx ;
left : 40 rpx ;
z - index : 999 ;
}
< / style >