Files
uniapp-im-shop/stores/user.js
cbb 20ccbf1f14 注释搜索:主播发送消息
观看列表只能主播跟管理员查看
2026-02-10 17:49:33 +08:00

462 lines
12 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { 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 * 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'
// #endif
// #ifdef H5
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 { navigateTo } from '@/utils/router'
import { sendCallMsg } from '../utils/call-user'
export const useUserStore = defineStore('user', () => {
const { clearToken } = useTokenStore()
const { showDialog, showToast } = useUI()
const userInfo = ref(
getUserInfoData() ? JSON?.parse(getUserInfoData()) : {}
)
/** 用户字体大小 */
const fontSizeData = ref(getFontSize())
/** 腾讯 IM 存储数据 */
const tencentUserSig = ref(getSig() ? JSON?.parse(getSig()) : {})
/** 用户积分数 */
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 startTimer = () => {
stopTimer() // 先停止之前的计时器
timer.value = setInterval(() => {
callDuration.value++
}, 1000)
}
/** 停止通话计时 */
const stopTimer = () => {
if (timer.value) {
clearInterval(timer.value)
timer.value = null
}
}
/** 重置时间 */
const resetTime = () => {
callDuration.value = 0
}
/** 通话模式更新 */
const updateCallMode = mode => {
callMode.value = mode
}
/**
* 获取用户信息(可从缓存或接口)
*/
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
}
/**
* 设置用户信息
*/
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 (loading = true) => {
const res = await getUserIntegral(loading)
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`
})
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
}
//连接融云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'
})
}
}
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
)
})
}
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)
}
/**
* 清除用户信息(退出登录)
*/
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
}
})