diff --git a/App.vue b/App.vue
index 7722c59..c14e36f 100644
--- a/App.vue
+++ b/App.vue
@@ -1,72 +1,219 @@
+ /* common css for page */
+ // uni-page-body,
+ // html,
+ // body,
+ // page {
+ // width: 100% !important;
+ // height: 100% !important;
+ // overflow: hidden;
+ // }
+
\ No newline at end of file
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 3379516..027abd6 100644
--- a/TUIKit/components/TUIChat/message-input-toolbar/call-view/index.vue
+++ b/TUIKit/components/TUIChat/message-input-toolbar/call-view/index.vue
@@ -1,106 +1,102 @@
-
-
-
+
+
-
+
-
+
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
index 47bb6d0..7acf74e 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,6 +1,6 @@
{
"name" : "密谈IM",
- "appid" : "__UNI__D40A151",
+ "appid" : "__UNI__BE00EFC",
"description" : "",
"versionName" : "1.1.3",
"versionCode" : 112,
@@ -112,27 +112,13 @@
}
},
"nativePlugins" : {
- "RongCloud-Beauty" : {
- "__plugin_info__" : {
- "name" : "RCUniBeauty",
- "description" : "融云基础版美颜插件,服务于 RCUniRtc 或 RCUniCall",
- "platforms" : "Android,iOS",
- "url" : "https://ext.dcloud.net.cn/plugin?id=7982",
- "android_package_name" : "",
- "ios_bundle_id" : "",
- "isCloud" : true,
- "bought" : 1,
- "pid" : "7982",
- "parameters" : {}
- }
- },
"RongCloud-Call" : {
"__plugin_info__" : {
"name" : "RCUniCall",
"description" : "融云实时音视频 SDK uni 原生插件",
"platforms" : "Android,iOS",
"url" : "https://ext.dcloud.net.cn/plugin?id=6372",
- "android_package_name" : "uni.app.UNI9EFDC69WWCC",
+ "android_package_name" : "uni.app.UNI9EFDC69",
"ios_bundle_id" : "",
"isCloud" : true,
"bought" : 1,
@@ -146,7 +132,7 @@
"description" : "融云即时通讯 SDK uni 原生插件V2",
"platforms" : "Android,iOS",
"url" : "https://ext.dcloud.net.cn/plugin?id=9227",
- "android_package_name" : "uni.app.UNI9EFDC69WWCC",
+ "android_package_name" : "uni.app.UNI9EFDC69",
"ios_bundle_id" : "",
"isCloud" : true,
"bought" : 1,
diff --git a/pages.json b/pages.json
index d201486..0d0d889 100644
--- a/pages.json
+++ b/pages.json
@@ -444,14 +444,14 @@
{
"path": "pages/room/room",
"style": {
- "navigationBarTitleText": "拨打电话",
+ "navigationBarTitleText": "拨打视频",
"navigationStyle": "custom"
}
},
{
"path": "pages/room/incom",
"style": {
- "navigationBarTitleText": "拨打视频",
+ "navigationBarTitleText": "拨打电话",
"navigationStyle": "custom"
}
},
diff --git a/pages/room/incom.vue b/pages/room/incom.vue
index 73a14fb..fc2668c 100644
--- a/pages/room/incom.vue
+++ b/pages/room/incom.vue
@@ -1,395 +1,379 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
- {{ callerInfo?.nick || callerInfo?.userID }}
-
-
- {{ callState === 'call' ? '呼叫中,等待对方接受邀请...' : '对话中...' }}
-
- {{ mediaType === 'audio' ? "语音通话" : "视频通话" }}
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ {{ callerInfo?.nick || callerInfo?.userID }}
+
+
+ {{ callState === 'call' ? '呼叫中,等待对方接受邀请...' : '对话中...' }}
+
+ {{ mediaType === 'audio' ? "语音通话" : "视频通话" }}
- {{ callState === 'call' || callState == 'dialogue' ? "挂断" : "拒绝" }}
-
-
-
-
+
+
+
+
+
+
+ {{ callState === 'call' || callState == 'dialogue' ? "挂断" : "拒绝" }}
+
+
+
+
+
+
+ 接听
+
- 接听
-
-
diff --git a/pages/room/room.nvue b/pages/room/room.nvue
index f010f5e..c939d28 100644
--- a/pages/room/room.nvue
+++ b/pages/room/room.nvue
@@ -150,24 +150,16 @@
},
onUnload() {
call.hangup()
- // this.removeAllListeners()
},
onHide() {
const session = call.getCurrentCallSession()
if (session) {
call.hangup()
}
- // this.removeAllListeners()
+ uni.$off('OnCallDisconnected')
+ uni.$off('OnCallConnected')
},
methods: {
- removeAllListeners(){
- //移除监听-接收到通话呼入
- call.removeRemoteUserJoinedListener();
- // 移除监听-通话已结束
- call.removeCallDisconnectedListener();
- // 移除监听-通话出现错误的回调
- call.removeErrorListener();
- },
changeMediaType() {
if (this.mediaTypeCur == 'video') {
this.mediaTypeCur = 'audio'
@@ -284,9 +276,9 @@
hangup() {
this.isSelf = true
call.hangup()
- uni.navigateBack({
- delta: 1
- })
+ // uni.navigateBack({
+ // delta: 1
+ // })
},
accept() {
call.accept()
@@ -324,12 +316,61 @@
)
}
},
-
onCallConnected() {
let context = this
console.log('oncallconnected接收了')
+ console.log('call: ',call);
+ // 使用 Promise 确保 call 对象完全初始化
+ this.initializeCall(call)
+ .then(() => {
+ this.processCallSession()
+ })
+ .catch(error => {
+ console.error('初始化通话失败:', error)
+ })
+ },
+ async initializeCall(callObj) {
+ // 等待 call 对象就绪
+ await this.waitForCallReady(callObj)
+
+ // 设置扬声器
+ if (callObj.enableSpeaker && typeof callObj.enableSpeaker === 'function') {
+ try {
+ callObj.enableSpeaker(true)
+ } catch (error) {
+ console.warn('设置扬声器失败:', error)
+ }
+ }
+
+ return callObj
+ },
+
+ waitForCallReady(callObj, timeout = 2000) {
+ return new Promise((resolve, reject) => {
+ const startTime = Date.now()
+
+ const check = () => {
+ const now = Date.now()
+
+ if (callObj &&
+ callObj.enableSpeaker &&
+ callObj.getCurrentCallSession &&
+ typeof callObj.getCurrentCallSession === 'function') {
+ resolve(callObj)
+ } else if (now - startTime > timeout) {
+ reject(new Error('call 对象初始化超时'))
+ } else {
+ setTimeout(check, 50)
+ }
+ }
+
+ check()
+ })
+ },
+
+ processCallSession(){
+ // call.enableSpeaker(true)
this.mediaTypeCur = this.mediaType
- call.enableSpeaker(true)
this.currentCallSession = call.getCurrentCallSession()
this.callWay = this.currentCallSession.callType
this.users = this.currentCallSession.users
@@ -347,6 +388,7 @@
) {
//视频是两个的时候
if (this.currentCallSession.users.length <= 2) {
+ console.log("视频是两个的时候");
setTimeout(() => {
this.systemInfoSync(
this.currentCallSession.mine.userId,
@@ -397,6 +439,7 @@
}
}
},
+
systemInfoSync(userId, ref, isZOrderOnTop) {
switch (uni.getSystemInfoSync().platform) {
case 'android':
diff --git a/stores/user.js b/stores/user.js
index 2d4296b..b08c09d 100644
--- a/stores/user.js
+++ b/stores/user.js
@@ -1,326 +1,302 @@
-import { defineStore } from 'pinia'
import {
- getToken,
- getUserInfoData,
- setUserInfoData,
- removeUserInfoData,
- getSig,
- setSig,
- removeSig,
- getFontSize,
- setFontSize,
- removeFontSize
+ defineStore
+} from 'pinia'
+import {
+ 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 {
+ 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"
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)
- /**
- * 获取用户信息(可从缓存或接口)
- */
- const fetchUserInfo = async () => {
- // 尝试从本地缓存读取
- const cachedToken = getToken()
- const cachedUserInfo = getUserInfoData()
- const cachedSig = getSig()
+ /**
+ * 获取用户信息(可从缓存或接口)
+ */
+ const fetchUserInfo = async () => {
+ // 尝试从本地缓存读取
+ const cachedToken = getToken()
+ const cachedUserInfo = getUserInfoData()
+ const cachedSig = getSig()
- 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
- }
+ 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 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 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 getIntegral = async () => {
- const res = await getUserIntegral()
- integralData.value = res.data.availablePoints
- }
+ /** 获取用户积分 */
+ const getIntegral = async () => {
+ const res = await getUserIntegral()
+ integralData.value = res.data.availablePoints
+ }
- /**
- * 登录腾讯 IM
- */
- const loginTencentIM = async () => {
- await refreshUserInfo()
- await TUILogin.login({
- SDKAppID: tencentUserSig.value.sdkappID,
- userID: tencentUserSig.value.userId,
- userSig: tencentUserSig.value.userSig,
- framework: `vue3`
- })
+ /**
+ * 登录腾讯 IM
+ */
+ const loginTencentIM = async () => {
+ await refreshUserInfo()
+ await TUILogin.login({
+ SDKAppID: tencentUserSig.value.sdkappID,
+ userID: tencentUserSig.value.userId,
+ userSig: tencentUserSig.value.userSig,
+ framework: `vue3`
+ })
- 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
+ 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
- // #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
- // #ifdef APP-PLUS
- // CallLib.init({})
- CallLib.onCallReceived(res => {
- console.log(
- 'Engine:OnCallReceived=>' + '监听通话呼入, 目标id=>',
- res.data
- )
- console.log('res: ',res.data);
- 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'
+ // #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
+ }
+
+ //连接融云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
});
- uni.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(
- 'Engine:OnCallDisconnected=>' + '挂断成功, 挂断原因=>',
- res.data.reason
- )
- uni.navigateBack()
- })
-
- CallLib.onError(res => {
- console.log('通话过程中,发生异常,异常原因=>', res.data.reason)
- uni.navigateBack()
- })
-
-
- // #endif
- }
+ if (uni.getSystemInfoSync().platform === 'android') {
+ permision.requestAndroidPermission('android.permission.CAMERA');
+ permision.requestAndroidPermission('android.permission.RECORD_AUDIO');
+ }
+ });
+ let code = await imEngine.value.connect(tencentUserSig.value.ryToken, 10)
+ if (code != 0) {
+ uni.hideLoading();
+ uni.showToast({
+ title: 'connect:' + code,
+ icon: 'error'
+ })
+ }
+ }
- //连接融云IM
- const connectIM = async () => {
- const options = {
- naviServer: ''
- }
- 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'
- })
- return
- }
- //连接成功
- CallLib.init({})
- console.log('call.init')
- // this.libPage = true;
- // this.loginUserId = res.userId;
- uni.hideLoading()
- console.log('登录成功')
- })
- const callback = {
- onDatabaseOpened: res => {
- console.log('数据库打开')
- },
- onConnected: res => {
- console.log(res)
- if (res.code === 0) {
- // uni.showToast({
- // title: '连接成功',
- // icon: 'none'
- // })
- console.log('连接成功')
- } else if (res.code === 34001) {
- // uni.showToast({
- // title: '连接已存在,不需要再连接',
- // icon: 'none'
- // })
- console.log('连接已存在,不需要再连接')
- }
-
- }
- }
- let code = await imEngine.value.connect(
- tencentUserSig.value.ryToken,
- 10,
- callback
- )
- if (code != 0) {
- uni.hideLoading()
- uni.showToast({
- title: 'connect:' + code,
- icon: 'error'
- })
- }
- }
+ /**
+ * 清除用户信息(退出登录)
+ */
+ const clearUserInfo = async () => {
+ const show = await showDialog('提示', '确定要退出登录吗?')
+ if (show) {
+ await logout()
+ }
+ }
- /**
- * 清除用户信息(退出登录)
- */
- const clearUserInfo = async () => {
- const show = await showDialog('提示', '确定要退出登录吗?')
- if (show) {
- await logout()
- }
- }
+ /**
+ * 退出登录(不带提示)
+ */
+ const logout = async () => {
+ if (!userInfo.value) return
+ try {
+ userInfo.value = null
- /**
- * 退出登录(不带提示)
- */
- 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')
+ }
+ }
- 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 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 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 updateUserInfo = async partialData => {
- if (!userInfo.value) return
- await updateUserData(partialData)
- await refreshUserInfo()
- }
+ /** 更新字体大小 */
+ const updateFontSize = async fontSize => {
+ fontSizeData.value = fontSize
+ setFontSize(fontSize)
+ }
- /** 更新字体大小 */
- 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
- }
-})
+ return {
+ imEngine,
+ userInfo,
+ integralData,
+ tencentUserSig,
+ fontSizeData,
+ getIntegral,
+ clearAllUserInfo,
+ updateFontSize,
+ logout,
+ refreshUserInfo,
+ fetchUserInfo,
+ loginTencentIM,
+ setUserInfo,
+ clearUserInfo,
+ updateUserInfo
+ }
+})
\ No newline at end of file