diff --git a/TUIKit/components/TUIChat/message-input-toolbar/call-view/index.vue b/TUIKit/components/TUIChat/message-input-toolbar/call-view/index.vue index 027abd6..37f1736 100644 --- a/TUIKit/components/TUIChat/message-input-toolbar/call-view/index.vue +++ b/TUIKit/components/TUIChat/message-input-toolbar/call-view/index.vue @@ -1,102 +1,112 @@ - \ No newline at end of file + diff --git a/TUIKit/components/TUIChat/message-list/message-elements/message-custom.vue b/TUIKit/components/TUIChat/message-list/message-elements/message-custom.vue index bc1c412..bc22c1b 100644 --- a/TUIKit/components/TUIChat/message-list/message-elements/message-custom.vue +++ b/TUIKit/components/TUIChat/message-list/message-elements/message-custom.vue @@ -151,6 +151,25 @@ + + @@ -165,7 +184,7 @@ computed, reactive } from '../../../../adapter-vue' - import { + import TUIChatEngine, { TUITranslateService, IMessageModel } from '@tencentcloud/chat-uikit-engine-lite' @@ -177,6 +196,7 @@ import unopenedEnvelope from '../../../../assets/icon/unopened-envelope.svg' import kaiEnvelope from '../../../../assets/icon/kai-unopened-envelope.svg' import { navigateTo } from '../../../../../utils/router' + import { useUserStore } from '../../../../../stores/user' interface Props { messageItem: IMessageModel @@ -187,6 +207,8 @@ (key: 'claim'): void } + const { updateCallMode } = useUserStore() + const emits = defineEmits() const props = withDefaults(defineProps(), { @@ -230,6 +252,32 @@ return JSON.parse(props.messageItem.payload.data) }) + /** 点击拨打音视频电话 */ + const onCall = () => { + if (props.messageItem.flow === 'out') { + if ( + goodsData.value.businessID === CHAT_MSG_CUSTOM_TYPE.VOICE_CALL + ) { + updateCallMode('0') + navigateTo('/pages/room/incom', { + type: 'call', + userID: goodsData.value.userID, + mediaType: 'audio', + callType: 'out' + }) + } else { + uni.setStorageSync('room-parameters', { + callType: 'out', + mediaType: 'video', + targetId: goodsData.value.userID, + callSelect: 'single' + }) + updateCallMode('1') + navigateTo('/pages/room/room') + } + } + } + /** 点击商品详情 */ const onGoods = () => { navigateTo('/pages/mall/detail', { productId: goodsData.value.id }) @@ -467,4 +515,12 @@ } } } + + .call-box { + display: flex; + align-items: center; + .call-text { + margin-right: 10rpx; + } + } diff --git a/TUIKit/components/TUIConversation/conversation-list/index.vue b/TUIKit/components/TUIConversation/conversation-list/index.vue index 5cc06bf..0b74f68 100644 --- a/TUIKit/components/TUIConversation/conversation-list/index.vue +++ b/TUIKit/components/TUIConversation/conversation-list/index.vue @@ -404,6 +404,20 @@ return `[直播信息]:${data.title}` } } + if (data.businessID === CHAT_MSG_CUSTOM_TYPE.VOICE_CALL) { + if (isText) { + return `${text[0]}:[语音通话]` + } else { + return `[语音通话]` + } + } + if (data.businessID === CHAT_MSG_CUSTOM_TYPE.VIDEO_CALL) { + if (isText) { + return `${text[0]}:[视频通话]` + } else { + return `[视频通话]` + } + } if (data.content === 'Create Group' && item.type === 'GROUP') { return `${item.getLastMessage('text')?.split(':')[0]}:创建群聊` } diff --git a/TUIKit/constant.ts b/TUIKit/constant.ts index 3ce9379..3afe941 100644 --- a/TUIKit/constant.ts +++ b/TUIKit/constant.ts @@ -23,7 +23,11 @@ export const CHAT_MSG_CUSTOM_TYPE = { /** 商品详情 */ GOODS: "goods", /** 直播 */ - LIVE: "live" + LIVE: "live", + /** 语音通话 */ + VOICE_CALL: "voiceCall", + /** 视频通话 */ + VIDEO_CALL: "videoCall", }; export const DIALOG_CONTENT = { diff --git a/composables/useAuthUser.js b/composables/useAuthUser.js index 49421c1..51d803f 100644 --- a/composables/useAuthUser.js +++ b/composables/useAuthUser.js @@ -11,6 +11,9 @@ export const useAuthUser = () => { // 响应式状态(state & getters) const { + callMode, + callUserId, + callDuration, imEngine, userInfo, tencentUserSig, @@ -20,6 +23,9 @@ export const useAuthUser = () => { const { token } = storeToRefs(tokenStore) return { + callMode, + callUserId, + callDuration, imEngine, integralData, userInfo, diff --git a/pages/room/incom.vue b/pages/room/incom.vue index 0c88030..faa3631 100644 --- a/pages/room/incom.vue +++ b/pages/room/incom.vue @@ -1,472 +1,527 @@ - - + + \ No newline at end of file + /* 响应式调整 */ + @media (max-height: 600px) { + .incoming-controls { + padding: 40rpx 30rpx 80rpx !important; + } + } + diff --git a/stores/user.js b/stores/user.js index 3055200..57cb170 100644 --- a/stores/user.js +++ b/stores/user.js @@ -1,419 +1,461 @@ +import { defineStore } from 'pinia' import { - defineStore -} from 'pinia' -import { - getToken, - getUserInfoData, - setUserInfoData, - removeUserInfoData, - getSig, - setSig, - removeSig, - getFontSize, - setFontSize, - removeFontSize + getToken, + getUserInfoData, + setUserInfoData, + removeUserInfoData, + getSig, + setSig, + removeSig, + getFontSize, + setFontSize, + removeFontSize } from '@/utils/storage' // #ifdef APP-PLUS -import { - useLoginState -} from '@/uni_modules/tuikit-atomic-x/state/LoginState' +import { useLoginState } from '@/uni_modules/tuikit-atomic-x/state/LoginState' import * as CallLib from '@/uni_modules/RongCloud-CallWrapper/lib/index' import RCIMIWEngine from '@/uni_modules/RongCloud-IMWrapper-V2/js_sdk/RCIMEngine' -import { - reasonDeal, - errorDeal, - imCode -} from '@/utils/code.js' +import { reasonDeal, errorDeal, imCode } from '@/utils/code.js' // #endif // #ifdef H5 -import { - useLoginState -} from 'tuikit-atomicx-vue3' +import { useLoginState } from 'tuikit-atomicx-vue3' // #endif -import { - useTokenStore -} from './token' -import { - getUserData, - userLogout, - updateUserData -} from '@/api' -import { - ref -} from 'vue' -import { - useUI -} from '@/utils/use-ui' -import { - reLaunch -} from '@/utils/router' -import { - getTencentUserSig -} from '@/api' -import { - TUILogin -} from '@tencentcloud/tui-core-lite' -import { - TUIChatEngine -} from '@tencentcloud/chat-uikit-engine-lite' -import { - getUserIntegral -} from '@/api/my-index' -import { - removeFriendList, - removeGroupList -} from '../utils/storage' -import { - getRongYunLoginInfo -} from '../api' -import permision from "@/js_sdk/wa-permission/permission.js" +import { useTokenStore } from './token' +import { getUserData, userLogout, updateUserData } from '@/api' +import { ref } from 'vue' +import { useUI } from '@/utils/use-ui' +import { reLaunch } from '@/utils/router' +import { getTencentUserSig } from '@/api' +import { TUILogin } from '@tencentcloud/tui-core-lite' +import { TUIChatEngine } from '@tencentcloud/chat-uikit-engine-lite' +import { getUserIntegral } from '@/api/my-index' +import { removeFriendList, removeGroupList } from '../utils/storage' +import { getRongYunLoginInfo } from '../api' +import permision from '@/js_sdk/wa-permission/permission.js' import { navigateTo } from '@/utils/router' +import { sendCallMsg } from '../utils/call-user' export const useUserStore = defineStore('user', () => { - const { - clearToken - } = useTokenStore() - const { - showDialog, - showToast - } = useUI() + const { clearToken } = useTokenStore() + const { showDialog, showToast } = useUI() - const userInfo = ref( - getUserInfoData() ? JSON?.parse(getUserInfoData()) : {} - ) - /** 用户字体大小 */ - const fontSizeData = ref(getFontSize()) + const userInfo = ref( + getUserInfoData() ? JSON?.parse(getUserInfoData()) : {} + ) + /** 用户字体大小 */ + const fontSizeData = ref(getFontSize()) - /** 腾讯 IM 存储数据 */ - const tencentUserSig = ref(getSig() ? JSON?.parse(getSig()) : {}) + /** 腾讯 IM 存储数据 */ + const tencentUserSig = ref(getSig() ? JSON?.parse(getSig()) : {}) - /** 用户积分数 */ - const integralData = ref(0) - /** 融云 IM 引擎 */ - const imEngine = ref(null) + /** 用户积分数 */ + const integralData = ref(0) + /** 融云 IM 引擎 */ + const imEngine = ref(null) + /** 发起通话用户id */ + const callUserId = ref('') + /** 通话时长(秒) */ + const callDuration = ref(0) + /** 通话模式 0:语音通话 1:视频通话 */ + const callMode = ref('0') + /** 通话计时器 */ + const timer = ref(null) - /** - * 获取用户信息(可从缓存或接口) - */ - const fetchUserInfo = async () => { - // 尝试从本地缓存读取 - const cachedToken = getToken() - const cachedUserInfo = getUserInfoData() - const cachedSig = getSig() + /** 开始通话计时 */ + const startTimer = () => { + stopTimer() // 先停止之前的计时器 + timer.value = setInterval(() => { + callDuration.value++ + }, 1000) + } - if (cachedToken && cachedUserInfo) { - userInfo.value = JSON.parse(cachedUserInfo) - tencentUserSig.value = JSON.parse(cachedSig) - loginTencentIM() - return - } - await getIntegral() - const res = await getUserData() - await setUserInfo(res.data) - loginTencentIM() - return - } + /** 停止通话计时 */ + const stopTimer = () => { + if (timer.value) { + clearInterval(timer.value) + timer.value = null + } + } - /** - * 设置用户信息 - */ - const setUserInfo = async data => { - const res = await getTencentUserSig() - const ryData = await getRongYunLoginInfo() - const IM_DATA = { - ...res.data, - ...ryData.data - } - tencentUserSig.value = IM_DATA - userInfo.value = data - setUserInfoData(data) - setSig(IM_DATA) - } + /** 重置时间 */ + const resetTime = () => { + callDuration.value = 0 + } + /** 通话模式更新 */ + const updateCallMode = mode => { + callMode.value = mode + } - /** 获取用户积分 */ - const getIntegral = async () => { - const res = await getUserIntegral() - integralData.value = res.data.availablePoints - } + /** + * 获取用户信息(可从缓存或接口) + */ + const fetchUserInfo = async () => { + // 尝试从本地缓存读取 + const cachedToken = getToken() + const cachedUserInfo = getUserInfoData() + const cachedSig = getSig() - /** - * 登录腾讯 IM - */ - const loginTencentIM = async () => { - await refreshUserInfo() - await TUILogin.login({ - SDKAppID: tencentUserSig.value.sdkappID, - userID: tencentUserSig.value.userId, - userSig: tencentUserSig.value.userSig, - framework: `vue3` - }) + if (cachedToken && cachedUserInfo) { + userInfo.value = JSON.parse(cachedUserInfo) + tencentUserSig.value = JSON.parse(cachedSig) + loginTencentIM() + return + } + await getIntegral() + const res = await getUserData() + await setUserInfo(res.data) + loginTencentIM() + return + } - await TUIChatEngine.login({ - SDKAppID: tencentUserSig.value.sdkappID, - userID: tencentUserSig.value.userId, - userSig: tencentUserSig.value.userSig, - useUploadPlugin: true // 使用文件上传插件 - }) - // #ifdef H5 - await useLoginState().login({ - SDKAppID: tencentUserSig.value.sdkappID, - userID: tencentUserSig.value.userId, - userSig: tencentUserSig.value.userSig - }) - // #endif + /** + * 设置用户信息 + */ + const setUserInfo = async data => { + const res = await getTencentUserSig() + const ryData = await getRongYunLoginInfo() + const IM_DATA = { + ...res.data, + ...ryData.data + } + tencentUserSig.value = IM_DATA + userInfo.value = data + setUserInfoData(data) + setSig(IM_DATA) + } - // #ifdef APP-PLUS - await useLoginState().login({ - sdkAppID: tencentUserSig.value.sdkappID, - userID: tencentUserSig.value.userId, - userSig: tencentUserSig.value.userSig - }) - console.log(tencentUserSig.value.appKey, '====') - await connectIM() - // #endif - } + /** 获取用户积分 */ + const getIntegral = async () => { + const res = await getUserIntegral() + integralData.value = res.data.availablePoints + } - //连接融云IM - const connectIM = async () => { - let options = {} - imEngine.value = await RCIMIWEngine.create(tencentUserSig.value.appKey, options) - imEngine.value.setOnConnectedListener((res) => { - if (res.code != 0) { - uni.hideLoading(); - // uni.showToast({ - // title: 'OnCon:' + res.code, - // icon: 'error' - // }) - console.log("连接已存在"); - // return - } - //连接成功 - CallLib.init({}); - console.log('call.init') - uni.hideLoading(); - uni.showToast({ - title: res.userId - }); - if (uni.getSystemInfoSync().platform === 'android') { - permision.requestAndroidPermission('android.permission.CAMERA'); - permision.requestAndroidPermission('android.permission.RECORD_AUDIO'); - } - onAllListeners() - }); - let code = await imEngine.value.connect(tencentUserSig.value.ryToken, 10) - if (code != 0) { - uni.hideLoading(); - uni.showToast({ - title: 'connect:' + code, - icon: 'error' - }) - } - } - - function onAllListeners () { - CallLib.onCallReceived( (res)=> { - console.log(res) - console.log("Engine:OnCallReceived=>"+"监听通话呼入, 目标id=>", res.data.targetId); - if (res.data.targetId) { - // let url = res.data.mediaType == 0 ? "" : "/pages/room/room" - uni.setStorageSync('room-parameters', { - callType: 'in', - mediaType: res.data.mediaType === 0 ? 'audio' : 'video' - }); - uni.showToast({ - title:"有通话呼入该跳转了"+res.data.targetId, - duration:3000 - }) - navigateTo("/pages/room/incom", { - type: res.data.extra, - callType: 'in', - mediaType: res.data.mediaType == 0 ? "audio" : "video", - userID: res.data.mine.userId // 对方的用户id - }) - } - }); - CallLib.onCallDisconnected((res)=>{ - console.log(res) - console.log("Engine:OnCallDisconnected=>"+"通话挂断/拒绝, 挂断原因=>", res.data.reason); - // 重新渲染视频视图 - // uni.$emit('OnCallDisconnected'); - uni.showToast({ - title:reasonDeal(res.data.reason), - error:"error", - icon:'none', - duration:2000 - }) - goback() - }); - CallLib.onCallConnected((res)=>{ - console.log(res) - console.log("Engine:OnCallConnected=>"+"已建立通话通话接通时,通过回调 onCallConnected 通知当前 call 的详细信息", res); - }); - CallLib.onRemoteUserInvited((res)=>{ - console.log("Engine:OnRemoteUserInvited=>"+"通话中的某一个参与者,邀请好友加入通话 ,远端Id为=>", res.data.userId); - uni.$emit('OnCallConnected'); - }) - CallLib.onRemoteUserJoined((res)=>{ - console.log("Engine:OnRemoteUserJoined=>"+"主叫端拨出电话,被叫端收到请求后,加入通话,对端Id为=>", res.data.userId); - uni.$emit('OnCallConnected'); - }) - CallLib.onRemoteUserLeft((res)=>{ - console.log("Engine:OnRemoteUserLeft=>"+"远端用户挂断(群聊触发),远端Id为=>", res.data.reason); - uni.$emit('OnCallConnected'); - uni.showToast({ - title:reasonDeal(res.data.reason), - error:"error", - icon:'none', - duration:2000 - }) - }) - CallLib.onCallOutgoing((res)=>{ - console.log('电话已拨出 主叫端拨出电话后,通过回调 onCallOutgoing 通知当前 call 的详细信息') - }) - CallLib.onRemoteUserRinging((res)=>{ - console.log('被叫端正在振铃,主叫端拨出电话,被叫端收到请求,发出振铃响应时,回调 onRemoteUserRingin,对端Id为=>', res.data.userId) - }) - CallLib.onError((res)=>{ - console.log('通话过程中,发生异常') - uni.showToast({ - title:errorDeal(res.data.reason), - error:"error", - icon:'none', - duration:2000 - }); - goback() - }) - CallLib.onRemoteUserMediaTypeChanged((res)=>{ - console.log('当通话中的某一个参与者切换通话类型,例如由 audio 切换至 video,回调 onMediaTypeChanged,切换媒体类型的Id为=>',res.data.user.userId); - }) - } - - function goback () { - const pages = getCurrentPages() - console.log('pages: ',pages); - if (pages.length > 1) { - console.log("走返回"); - uni.showToast({ - title:"走返回", - duration:3000 - }) - uni.navigateBack({ - delta: 1 - }) - const currentPage = pages[pages.length - 1] - const prevPage = pages[pages.length - 2] - - // 判断上一页是否是 tabBar 页面 - // const isPrevPageTabBar = isTabBarPage(currentPage.route) - // if(!isPrevPageTabBar){ - - // } - } - } - - // 判断页面是否是 tabBar 页面 - function isTabBarPage(route) { - // 这里根据你的 pages.json 配置来判断 - const tabBarPages = [ - 'TUIKit/components/TUIConversation/index', - 'TUIKit/components/TUIContact/index', - 'pages/discover/discover', - 'pages/my-index/my-index' - ] - - // 判断路由是否在 tabBar 页面列表中 - return tabBarPages.includes(route) - } + /** + * 登录腾讯 IM + */ + const loginTencentIM = async () => { + await refreshUserInfo() + await TUILogin.login({ + SDKAppID: tencentUserSig.value.sdkappID, + userID: tencentUserSig.value.userId, + userSig: tencentUserSig.value.userSig, + framework: `vue3` + }) - /** - * 清除用户信息(退出登录) - */ - const clearUserInfo = async () => { - const show = await showDialog('提示', '确定要退出登录吗?') - if (show) { - await logout() - } - } + await TUIChatEngine.login({ + SDKAppID: tencentUserSig.value.sdkappID, + userID: tencentUserSig.value.userId, + userSig: tencentUserSig.value.userSig, + useUploadPlugin: true // 使用文件上传插件 + }) + // #ifdef H5 + await useLoginState().login({ + SDKAppID: tencentUserSig.value.sdkappID, + userID: tencentUserSig.value.userId, + userSig: tencentUserSig.value.userSig + }) + // #endif - /** - * 退出登录(不带提示) - */ - const logout = async () => { - if (!userInfo.value) return - try { - userInfo.value = null + // #ifdef APP-PLUS + await useLoginState().login({ + sdkAppID: tencentUserSig.value.sdkappID, + userID: tencentUserSig.value.userId, + userSig: tencentUserSig.value.userSig + }) + console.log(tencentUserSig.value.appKey, '====') + await connectIM() + // #endif + } - await userLogout() - await TUILogin.logout() - await TUIChatEngine.logout() - // #ifdef APP-PLUS - removeFriendList() - removeGroupList() - await useLoginState().logout() - // #endif - // #ifdef H5 - await useLoginState().logout() - // #endif - clearAllUserInfo() - await showToast('退出登录成功', 'success') - reLaunch('/pages/login/login') - } catch (error) { - clearAllUserInfo() - await showToast('退出登录成功', 'success') - reLaunch('/pages/login/login') - } - } + //连接融云IM + const connectIM = async () => { + let options = {} + imEngine.value = await RCIMIWEngine.create( + tencentUserSig.value.appKey, + options + ) + imEngine.value.setOnConnectedListener(res => { + if (res.code != 0) { + uni.hideLoading() + // uni.showToast({ + // title: 'OnCon:' + res.code, + // icon: 'error' + // }) + console.log('连接已存在') + // return + } + //连接成功 + CallLib.init({}) + console.log('call.init') + uni.hideLoading() + // uni.showToast({ + // title: res.userId + // }) + console.log('登录成功') + if (uni.getSystemInfoSync().platform === 'android') { + permision.requestAndroidPermission('android.permission.CAMERA') + permision.requestAndroidPermission( + 'android.permission.RECORD_AUDIO' + ) + } + onAllListeners() + }) + let code = await imEngine.value.connect( + tencentUserSig.value.ryToken, + 10 + ) + if (code != 0) { + uni.hideLoading() + uni.showToast({ + title: 'connect:' + code, + icon: 'error' + }) + } + } - /** 清空所有用户缓存 */ - const clearAllUserInfo = async () => { - userInfo.value = null - tencentUserSig.value = null - fontSizeData.value = 26 - clearToken() - removeUserInfoData() - removeSig() - removeFontSize() - } + function onAllListeners() { + CallLib.onCallReceived(res => { + console.log(res) + console.log( + 'Engine:OnCallReceived=>' + '监听通话呼入, 目标id=>', + res.data.targetId + ) + if (res.data.targetId) { + // let url = res.data.mediaType == 0 ? "" : "/pages/room/room" + uni.setStorageSync('room-parameters', { + callType: 'in', + mediaType: res.data.mediaType === 0 ? 'audio' : 'video' + }) + uni.showToast({ + title: '有通话呼入该跳转了' + res.data.targetId, + duration: 3000 + }) + navigateTo('/pages/room/incom', { + type: res.data.extra, + callType: 'in', + mediaType: res.data.mediaType == 0 ? 'audio' : 'video', + userID: res.data.mine.userId // 对方的用户id + }) + } + }) + CallLib.onCallDisconnected(res => { + console.log(res) + console.log( + 'Engine:OnCallDisconnected=>' + '通话挂断/拒绝, 挂断原因=>', + res.data.reason + ) + console.log('=====通话用户id', callUserId.value) + sendCallMsg(res.data.reason) + // 重新渲染视频视图 + // uni.$emit('OnCallDisconnected'); + uni.showToast({ + title: reasonDeal(res.data.reason), + error: 'error', + icon: 'none', + duration: 2000 + }) + goback() + }) + CallLib.onCallConnected(res => { + console.log(res) + console.log( + 'Engine:OnCallConnected=>' + + '已建立通话通话接通时,通过回调 onCallConnected 通知当前 call 的详细信息', + res + ) + }) + CallLib.onRemoteUserInvited(res => { + console.log( + 'Engine:OnRemoteUserInvited=>' + + '通话中的某一个参与者,邀请好友加入通话 ,远端Id为=>', + res.data.userId + ) + uni.$emit('OnCallConnected') + }) + CallLib.onRemoteUserJoined(res => { + console.log( + 'Engine:OnRemoteUserJoined=>' + + '主叫端拨出电话,被叫端收到请求后,加入通话,对端Id为=>', + res.data.userId + ) + uni.$emit('OnCallConnected') + }) + CallLib.onRemoteUserLeft(res => { + console.log( + 'Engine:OnRemoteUserLeft=>' + + '远端用户挂断(群聊触发),远端Id为=>', + res.data.reason + ) + uni.$emit('OnCallConnected') + uni.showToast({ + title: reasonDeal(res.data.reason), + error: 'error', + icon: 'none', + duration: 2000 + }) + }) + CallLib.onCallOutgoing(res => { + console.log( + '电话已拨出 主叫端拨出电话后,通过回调 onCallOutgoing 通知当前 call 的详细信息' + ) + }) + CallLib.onRemoteUserRinging(res => { + console.log( + '被叫端正在振铃,主叫端拨出电话,被叫端收到请求,发出振铃响应时,回调 onRemoteUserRingin,对端Id为=>', + res.data.userId + ) + }) + CallLib.onError(res => { + console.log('通话过程中,发生异常') + uni.showToast({ + title: errorDeal(res.data.reason), + error: 'error', + icon: 'none', + duration: 2000 + }) + goback() + }) + CallLib.onRemoteUserMediaTypeChanged(res => { + console.log( + '当通话中的某一个参与者切换通话类型,例如由 audio 切换至 video,回调 onMediaTypeChanged,切换媒体类型的Id为=>', + res.data.user.userId + ) + }) + } - /** 刷新用户信息(如用户信息被修改) */ - const refreshUserInfo = async () => { - const res = await getUserData() - await getIntegral() - await setUserInfoData(res.data) - userInfo.value = res.data - } + function goback() { + const pages = getCurrentPages() + console.log('pages: ', pages) + if (pages.length > 1) { + console.log('走返回') + uni.showToast({ + title: '走返回', + duration: 3000 + }) + uni.navigateBack({ + delta: 1 + }) + const currentPage = pages[pages.length - 1] + const prevPage = pages[pages.length - 2] - /** - * 更新部分用户信息(例如昵称、头像) - */ - const updateUserInfo = async partialData => { - if (!userInfo.value) return - await updateUserData(partialData) - await refreshUserInfo() - } + // 判断上一页是否是 tabBar 页面 + // const isPrevPageTabBar = isTabBarPage(currentPage.route) + // if(!isPrevPageTabBar){ - /** 更新字体大小 */ - const updateFontSize = async fontSize => { - fontSizeData.value = fontSize - setFontSize(fontSize) - } + // } + } + } - return { - imEngine, - userInfo, - integralData, - tencentUserSig, - fontSizeData, - getIntegral, - clearAllUserInfo, - updateFontSize, - logout, - refreshUserInfo, - fetchUserInfo, - loginTencentIM, - setUserInfo, - clearUserInfo, - updateUserInfo - } -}) \ No newline at end of file + // 判断页面是否是 tabBar 页面 + function isTabBarPage(route) { + // 这里根据你的 pages.json 配置来判断 + const tabBarPages = [ + 'TUIKit/components/TUIConversation/index', + 'TUIKit/components/TUIContact/index', + 'pages/discover/discover', + 'pages/my-index/my-index' + ] + + // 判断路由是否在 tabBar 页面列表中 + return tabBarPages.includes(route) + } + + /** + * 清除用户信息(退出登录) + */ + const clearUserInfo = async () => { + const show = await showDialog('提示', '确定要退出登录吗?') + if (show) { + await logout() + } + } + + /** + * 退出登录(不带提示) + */ + const logout = async () => { + if (!userInfo.value) return + try { + userInfo.value = null + + await userLogout() + await TUILogin.logout() + await TUIChatEngine.logout() + // #ifdef APP-PLUS + removeFriendList() + removeGroupList() + await useLoginState().logout() + // #endif + // #ifdef H5 + await useLoginState().logout() + // #endif + clearAllUserInfo() + await showToast('退出登录成功', 'success') + reLaunch('/pages/login/login') + } catch (error) { + clearAllUserInfo() + await showToast('退出登录成功', 'success') + reLaunch('/pages/login/login') + } + } + + /** 清空所有用户缓存 */ + const clearAllUserInfo = async () => { + userInfo.value = null + tencentUserSig.value = null + fontSizeData.value = 26 + clearToken() + removeUserInfoData() + removeSig() + removeFontSize() + } + + /** 刷新用户信息(如用户信息被修改) */ + const refreshUserInfo = async () => { + const res = await getUserData() + await getIntegral() + await setUserInfoData(res.data) + userInfo.value = res.data + } + + /** + * 更新部分用户信息(例如昵称、头像) + */ + const updateUserInfo = async partialData => { + if (!userInfo.value) return + await updateUserData(partialData) + await refreshUserInfo() + } + + /** 更新字体大小 */ + const updateFontSize = async fontSize => { + fontSizeData.value = fontSize + setFontSize(fontSize) + } + + return { + callUserId, + callDuration, + imEngine, + userInfo, + integralData, + tencentUserSig, + fontSizeData, + callMode, + startTimer, + stopTimer, + updateCallMode, + resetTime, + getIntegral, + clearAllUserInfo, + updateFontSize, + logout, + refreshUserInfo, + fetchUserInfo, + loginTencentIM, + setUserInfo, + clearUserInfo, + updateUserInfo + } +}) diff --git a/utils/call-user.js b/utils/call-user.js new file mode 100644 index 0000000..d7105de --- /dev/null +++ b/utils/call-user.js @@ -0,0 +1,59 @@ +import TUIChatEngine, { + TUIChatService +} from '@tencentcloud/chat-uikit-engine-lite' +import { CHAT_MSG_CUSTOM_TYPE } from '../TUIKit/constant' +import { useAuthUser } from '../composables/useAuthUser' +import { useUserStore } from '../stores/user' + +/** 格式化时间显示 */ +const formatTime = date => { + const minutes = Math.floor(date / 60) + const seconds = date % 60 + return `${minutes.toString().padStart(2, '0')}:${seconds + .toString() + .padStart(2, '0')}` +} + +/** 通话消息发送 */ +export const sendCallMsg = async state => { + const { resetTime, stopTimer } = useUserStore() + const { callUserId, callMode, callDuration, tencentUserSig } = + useAuthUser() + const to = callUserId.value + const userID = tencentUserSig.value.userId + if (to !== userID) { + let title = '' + if ([0, 11].includes(state)) { + title = { 0: '已挂断', 11: '对方已拒绝' }[state] + } else { + title = `通话时长 ${formatTime(callDuration.value)}` + } + + const payload = { + data: JSON.stringify({ + businessID: + callMode.value == 0 + ? CHAT_MSG_CUSTOM_TYPE.VOICE_CALL + : CHAT_MSG_CUSTOM_TYPE.VIDEO_CALL, + title, + userID: to + }), + description: title, + extension: title + } + const options = { + to, + payload, + conversationType: TUIChatEngine.TYPES.CONV_C2C, + needReadReceipt: false + } + resetTime() + await TUIChatService.sendCustomMessage(options) + } else { + resetTime() + } + + if (callMode.value == 1) { + stopTimer() + } +}