Commit e7d97607 by wxl

fix bugs

parent 954c43df
import { useNetSocketStore } from "any-hooks/communication/useNetSocketStore";
import { useInjector, useRequest } from "vue-vulcan"; import { useInjector, useRequest } from "vue-vulcan";
import { useAuthData } from "./useAuthData"; import { useAuthData } from "./useAuthData";
export function useLogOut() { export function useLogOut() {
const [, request] = useRequest<any>('/loginOut', { auto: false }); const [, request] = useRequest<any>('/loginOut', { auto: false });
const { setAuth } = useInjector(useAuthData); const { setAuth } = useInjector(useAuthData);
const { close } = useInjector(useNetSocketStore)
const submitLogOut = (data: {login_id: string}) => { const submitLogOut = (data: {login_id: string}) => {
return request(data).then( _ => setAuth(null)); return request(data).then( _ => {
setAuth(null);
close();
});
} }
return { submitLogOut } return { submitLogOut }
......
...@@ -3,6 +3,8 @@ import { reactive } from "vue"; ...@@ -3,6 +3,8 @@ import { reactive } from "vue";
import { useInjector, useRequest } from "vue-vulcan"; import { useInjector, useRequest } from "vue-vulcan";
import { useAuthData } from "./useAuthData"; import { useAuthData } from "./useAuthData";
let LOGIN_STATE = false
export function useLogin() { export function useLogin() {
const loginData = reactive({ const loginData = reactive({
login_id: '', login_id: '',
...@@ -16,11 +18,17 @@ export function useLogin() { ...@@ -16,11 +18,17 @@ export function useLogin() {
const submitLogin = () => { const submitLogin = () => {
return request({...loginData, peer_id}) return request({...loginData, peer_id})
.then( data => {setAuth(data); return data} ) .then( data => {
LOGIN_STATE = true;
setAuth(data);
return data
} )
} }
return { return {
loginData, loginData,
LOGIN_STATE,
submitLogin submitLogin
} }
} }
import { AgoraAppStore, AgoraSdkClient, StreamType } from "any-hooks/types/agora"; import { AgoraAppStore, AgoraSdkClient, StreamType } from "any-hooks/types/agora";
import { onMounted, watch } from "vue"; import { watch } from "vue";
import { useInjector, useState } from "vue-vulcan"; import { useInjector, useState } from "vue-vulcan";
import { AGORA_APP_SDK } from "../communication/token"; import { AGORA_APP_SDK } from "../communication/token";
......
...@@ -13,7 +13,9 @@ export function useSocket<S = any>() { ...@@ -13,7 +13,9 @@ export function useSocket<S = any>() {
const brokenTime = ref(0); const brokenTime = ref(0);
if(customeSocket) ws = customeSocket; if(customeSocket) ws = customeSocket;
let initUrl: string;
const connect = (url?: string) => { const connect = (url?: string) => {
initUrl = url;
if(customeSocket) { if(customeSocket) {
ws.connect(url) ws.connect(url)
} else { } else {
...@@ -26,10 +28,9 @@ export function useSocket<S = any>() { ...@@ -26,10 +28,9 @@ export function useSocket<S = any>() {
brokenTime.value = 0; brokenTime.value = 0;
socketSettings.heartData && startHeartConnect(); socketSettings.heartData && startHeartConnect();
} ); } );
ws.addEventListener('close', () => {setStatus('closed'); reconnect(url);}); ws.addEventListener('close', () => {setStatus('closed');});
ws.addEventListener('error', () => { ws.addEventListener('error', () => {
setStatus('onerror'); setStatus('onerror');
reconnect(url);
}); });
} }
...@@ -40,15 +41,16 @@ export function useSocket<S = any>() { ...@@ -40,15 +41,16 @@ export function useSocket<S = any>() {
} }
// 重连功能 // 重连功能
const limit = socketSettings.retryLimit || 5; const limit = socketSettings.retryLimit || 100;
const reconnect = (url: string) => { const reconnect = () => {
if(!initUrl) return;
console.log('开始重连') console.log('开始重连')
brokenTime.value ++; brokenTime.value ++;
if(brokenTime.value > limit) { if(brokenTime.value > limit) {
ws.close(); ws.close();
} else { } else {
setStatus('reconnect'); setStatus('reconnect');
setTimeout( () => connect(url), brokenTime.value*1000 ); setTimeout( () => connect(initUrl), brokenTime.value*1000 );
} }
} }
...@@ -56,8 +58,12 @@ export function useSocket<S = any>() { ...@@ -56,8 +58,12 @@ export function useSocket<S = any>() {
currentMsg, currentMsg,
status, status,
connect, connect,
reconnect,
startHeartConnect, startHeartConnect,
send: ws.send, send: ws.send,
close: ws.close close: () => {
setStatus('closed');
ws.close();
}
} }
} }
...@@ -39,22 +39,24 @@ export function useCallCenter() { ...@@ -39,22 +39,24 @@ export function useCallCenter() {
} }
}) })
}) })
//12S后若本地用户仍处于主动呼叫状态,则自动挂断 //8S后若本地用户仍处于主动呼叫状态,则自动挂断
setTimeout(() => { setTimeout(() => {
if(myCallState.value === 'calling') hangup(); if(myCallState.value === 'calling') hangup();
}, 12000) }, 18000)
} }
/** 回应呼叫功能 */ /** 回应呼叫功能 */
const answerCaller = (subFlag: AnyRemoteSubFlag) => { const answerCaller = (subFlag: AnyRemoteSubFlag, user?: UserData) => {
if(subFlag === 'Connect') { if(subFlag === 'Connect') {
setCallState('call_accepted'); setCallState('call_accepted');
getTokenByChannel(caller.value.channel); getTokenByChannel(caller.value.channel);
updateMembers(caller.value.members, 'join') updateMembers(caller.value.members, 'join');
}; };
const target = user || caller.value
sendMsg({ sendMsg({
toID: caller.value.id, toID: target.id,
toName: caller.value.nickname, toName: target.nickname,
msgMainFlag: 'CallAnswer', msgMainFlag: 'CallAnswer',
msgSubFlag: subFlag msgSubFlag: subFlag
}) })
...@@ -68,11 +70,23 @@ export function useCallCenter() { ...@@ -68,11 +70,23 @@ export function useCallCenter() {
switch(msg.msgSubFlag) { switch(msg.msgSubFlag) {
case 'Request': case 'Request':
// 本地呼叫状态为free时,变更为being_called;不为free,则发送繁忙的回应。 // 本地呼叫状态为free时,变更为being_called;不为free,则发送繁忙的回应。
myCallState.value === 'free' ? setCallState('being_called') : answerCaller('Busying'); console.log(`${currentMsg.value.fromName}呼叫,我目前的状态${myCallState.value}`)
if(myCallState.value === 'free') {
setCallState('being_called');
setCaller({
id: msg.fromID,
nickname: msg.fromName,
action: msg.msgSubFlag,
channel: msg.channelID,
members: msg.msgData?.members || []
})
} else{
answerCaller('Busying', {id: msg.fromID, nickname: msg.fromName});
}
//10S秒后若本地用户仍然处于被呼叫状态,则自动发出繁忙恢复,且将状态恢复为free //10S秒后若本地用户仍然处于被呼叫状态,则自动发出繁忙恢复,且将状态恢复为free
setTimeout( () => { setTimeout( () => {
if(myCallState.value === 'being_called'){ if(myCallState.value === 'being_called'){
answerCaller('Busying'); answerCaller('Busying', {id: currentMsg.value.fromID, nickname: currentMsg.value.fromName});
setCallState('free'); setCallState('free');
} }
}, 10000) }, 10000)
...@@ -80,16 +94,17 @@ export function useCallCenter() { ...@@ -80,16 +94,17 @@ export function useCallCenter() {
case 'Hangup': case 'Hangup':
//对方中断呼叫,则将呼叫状态改为free //对方中断呼叫,则将呼叫状态改为free
setCallState('free'); setCallState('free');
break;
}
setCaller({ setCaller({
id: currentMsg.value.fromID, id: msg.fromID,
nickname: currentMsg.value.fromName, nickname: msg.fromName,
action: msg.msgSubFlag, action: msg.msgSubFlag,
channel: msg.channelID, channel: msg.channelID,
members: msg.msgData?.members || [] members: msg.msgData?.members || []
}) })
break;
}
}) })
// 监听呼叫目标的回应 // 监听呼叫目标的回应
watch(currentMsg, msg => { watch(currentMsg, msg => {
......
...@@ -20,9 +20,9 @@ interface MeetingMember { ...@@ -20,9 +20,9 @@ interface MeetingMember {
} }
} }
/** 会议中心功能, 该功能在呼叫功能生效后使用,此模块会将其他即时交互模块集中到一起,如:音视频通讯模块、文本聊天模块、白板标注模块等 */ /** 会议中心功能, 该功能在呼叫功能生效后使用,此模块会将其他即时交互模块集中到一起,如:音视频通讯模块、文本聊天模块等(目前只有音视频通讯) */
export function useMeetingCenter() { export function useMeetingCenter() {
const { hangup, myCallState } = useInjector(useCallCenter); const {hangup, myCallState} = useInjector(useCallCenter);
const {streamList, localPushurl, voiceMute, mode, stopVideoConference, switchLocalMicState, switchVideoOrAudio} = useInjector(useVideoConference); const {streamList, localPushurl, voiceMute, mode, stopVideoConference, switchLocalMicState, switchVideoOrAudio} = useInjector(useVideoConference);
/** 离开会议(分两步:1.挂断当前呼叫, 2.停止音视频功能) */ /** 离开会议(分两步:1.挂断当前呼叫, 2.停止音视频功能) */
......
import { onMounted } from "@vue/runtime-core";
import { useAuthData } from "any-hooks/auth/useAuthData"; import { useAuthData } from "any-hooks/auth/useAuthData";
import { useSocket } from "any-hooks/common/useSocket"; import { useSocket } from "any-hooks/common/useSocket";
import { AnyRemoteSocketMessage, SocketSettings } from "any-hooks/types/socket"; import { AnyRemoteSocketMessage, SocketSettings } from "any-hooks/types/socket";
...@@ -19,11 +20,18 @@ export function useNetSocketStore() { ...@@ -19,11 +20,18 @@ export function useNetSocketStore() {
const { authData } = useInjector(useAuthData); const { authData } = useInjector(useAuthData);
const [ netState, setNetState ] = useState<NetStates>(0); const [ netState, setNetState ] = useState<NetStates>(0);
const { baseUrl } = useInjector<SocketSettings>(SOCKET_SETTINGS, 'optional'); const { baseUrl } = useInjector<SocketSettings>(SOCKET_SETTINGS, 'optional');
const { connect, send, currentMsg, startHeartConnect, status } = useSocket<AnyRemoteSocketMessage>(); const { connect, reconnect, send, close, currentMsg, startHeartConnect, status } = useSocket<AnyRemoteSocketMessage>();
const [deviceCode, setDevice] = useState(null, {key: 'device', storage: 'custome'})
onMounted(() => {
if(!deviceCode.value) {
setDevice(new Date().getTime())
}
})
const initConnect = (data: UserData) => { const initConnect = (data: UserData) => {
connect( connect(
`${baseUrl}?fromID=${data.id}&fromName=${data.nickname}&signID=SA&companyID=${data.company_id}` `${baseUrl}?fromID=${data.id}&fromName=${data.nickname}&signID=${deviceCode.value}&companyID=${data.company_id}`
) )
startHeartConnect({ startHeartConnect({
fromID: authData.value.id, fromID: authData.value.id,
...@@ -46,6 +54,8 @@ export function useNetSocketStore() { ...@@ -46,6 +54,8 @@ export function useNetSocketStore() {
sendMsg, sendMsg,
setNetState, setNetState,
initConnect, initConnect,
reconnect,
close,
currentMsg, currentMsg,
netState, netState,
status status
......
...@@ -19,10 +19,9 @@ export function useVideoConference() { ...@@ -19,10 +19,9 @@ export function useVideoConference() {
localPushurl, localPushurl,
} = useAgoraClient(); } = useAgoraClient();
/** 监听频道模块,频道被创建后自动将agora的音视频通讯功能载入频道 */ /** 监听频道模块,频道被创建、更新后自动将agora的音视频通讯功能载入频道 */
watch(currentChannel, channel => { watch(currentChannel, channel => {
if(!channel) return; if(!channel) return;
console.log('频道变化', channel, authData.value.peer_id)
joinChannelWithAgora( joinChannelWithAgora(
channel.agora_token, channel.agora_token,
channel.channel_id, channel.channel_id,
...@@ -57,8 +56,9 @@ export function useVideoConference() { ...@@ -57,8 +56,9 @@ export function useVideoConference() {
setMode(mode.value === 'video' ? 'audio' : 'video'); setMode(mode.value === 'video' ? 'audio' : 'video');
} }
/** 停止音视频通讯功能 */
const stopVideoConference = () => { const stopVideoConference = () => {
setVoiceMute(false); setVoiceMute(false); //将麦克风、音视频状态重置
setMode('video'); setMode('video');
clearChannel(); clearChannel();
leaveChannelWithAgora(); leaveChannelWithAgora();
......
import { UserData } from "../types/user"; import { UserData, WorkGroupData } from "../types/user";
import { useInjector, useRequest, useState } from "vue-vulcan"; import { useInjector, useRequest, useState } from "vue-vulcan";
import { computed, watch} from "vue"; import { computed, watch} from "vue";
import { useAuthData } from "../auth/useAuthData"; import { useAuthData } from "../auth/useAuthData";
import { useNetSocketStore } from "any-hooks/communication/useNetSocketStore"; import { useNetSocketStore } from "any-hooks/communication/useNetSocketStore";
import { Subject } from "rxjs";
import { debounceTime } from "rxjs/operators";
export function useContacts() { export function useContacts() {
const { authData } = useInjector(useAuthData); const { authData } = useInjector(useAuthData);
const [ userList, getUserList ] = useRequest<UserData[]>('/getUserList', { auto: false }); const [ userList, getUserList ] = useRequest<UserData[]>('/getUserList', { auto: false });
const { currentMsg } = useInjector(useNetSocketStore); const { currentMsg, status } = useInjector(useNetSocketStore);
const [groups, requestGroups] = useRequest<WorkGroupData[]>('/getWorkGroupList');
const [keyword, setKeyWord] = useState(''); const [keyword, setKeyWord] = useState('');
const contacts = computed( () => { const contacts = computed( () => {
...@@ -15,6 +18,10 @@ export function useContacts() { ...@@ -15,6 +18,10 @@ export function useContacts() {
.filter( item => item.nickname.includes(keyword.value)) .filter( item => item.nickname.includes(keyword.value))
}); });
const filterGroups = computed( () => {
return groups.value?.filter(item => item.title.includes(keyword.value))
})
const roleContacts = computed( () => { const roleContacts = computed( () => {
const contactHome = {} as {[props: string]: UserData[]} const contactHome = {} as {[props: string]: UserData[]}
contacts.value?.forEach( item => { contacts.value?.forEach( item => {
...@@ -42,17 +49,28 @@ export function useContacts() { ...@@ -42,17 +49,28 @@ export function useContacts() {
} }
// 监听socket的home类型消息 实时更新contacts联系人数据 // 监听socket的home类型消息 实时更新contacts联系人数据
const req$ = new Subject();
req$
.pipe(debounceTime(500))
.subscribe( _ => getUserList())
watch(currentMsg, msg => { watch(currentMsg, msg => {
if(msg.msgMainFlag !== 'Home') return; if(msg.msgMainFlag !== 'Home') return;
if(msg.msgSubFlag === 'UpdateUserList') getUserList(); if(msg.msgSubFlag === 'UpdateUserList') req$.next();
})
watch(status, val => {
if(val === 'opening') req$.next();
}) })
return { return {
contacts, contacts,
freeContacts, freeContacts,
roleContacts, roleContacts,
setKeyWord,
keyword, keyword,
groups,
filterGroups,
requestGroups,
setKeyWord,
getUserList, getUserList,
getContactById, getContactById,
getContactsByGroup, getContactsByGroup,
......
...@@ -16,8 +16,8 @@ export interface SocketSettings { ...@@ -16,8 +16,8 @@ export interface SocketSettings {
export type ConnectStatus = 'ready' | 'opening' | 'onerror' | 'closed' | 'reconnect'; export type ConnectStatus = 'ready' | 'opening' | 'onerror' | 'closed' | 'reconnect';
export type AnyRemoteMainFlag = 'Heart' | 'Login' | 'Broadcast' | 'Home' | 'CallOffer' | 'CallAnswer' | 'ChannelChat' | 'NotifyUpdateUserList' | 'SetAtts'; export type AnyRemoteMainFlag = 'Heart' | 'Login' | 'Broadcast' | 'Home' | 'CallOffer' | 'CallAnswer' | 'ChannelChat' | 'NotifyUpdateUserList' | 'SetAtts' | 'Login';
export type AnyRemoteSubFlag = 'Request' | 'Busying' | 'Connect' | 'Hangup' | 'UpdateUserList'; export type AnyRemoteSubFlag = 'Request' | 'Busying' | 'Connect' | 'Hangup' | 'UpdateUserList' | 'OtherLoginIn';
export interface AnyRemoteSocketMessage { export interface AnyRemoteSocketMessage {
fromID?: string; fromID?: string;
......
...@@ -6,7 +6,7 @@ export interface UserData { ...@@ -6,7 +6,7 @@ export interface UserData {
avatar?: string; avatar?: string;
permission?: string; permission?: string;
token?: string; token?: string;
is_signin?: '1' | '2'; is_signin?: '1' | '0';
is_calling?: '1' | '0'; is_calling?: '1' | '0';
group_name?: string; group_name?: string;
diy_group?: string; diy_group?: string;
......
...@@ -27,7 +27,7 @@ export default { ...@@ -27,7 +27,7 @@ export default {
}, },
{ {
"pagePath": "pages/mine/index", "pagePath": "pages/mine/index",
"text": "我的", "text": "个人中心",
"iconPath": "assets/user_center.png", "iconPath": "assets/user_center.png",
"selectedIconPath": "assets/user_center_a.png" "selectedIconPath": "assets/user_center_a.png"
} }
......
import './app.less'; import './app.less';
import { authorize, getCurrentInstance } from '@tarojs/taro'; import { authorize } from '@tarojs/taro';
import { createApp } from 'vue'; import { createApp } from 'vue';
import { useCustomeRequest } from './hooks/http/useCustomeRequest'; import { useCustomeRequest } from './hooks/http/useCustomeRequest';
import { useProviders } from 'vue-vulcan'; import { useProviders } from 'vue-vulcan';
...@@ -24,9 +24,6 @@ import MeetingBar from './components/mini-meeting-bar.vue'; ...@@ -24,9 +24,6 @@ import MeetingBar from './components/mini-meeting-bar.vue';
import { useVideoConference } from 'any-hooks/communication/useVideoConference'; import { useVideoConference } from 'any-hooks/communication/useVideoConference';
const App = createApp({ const App = createApp({
onShow () {
console.log('show a ')
},
setup() { setup() {
/* 提供全局配置类hook */ /* 提供全局配置类hook */
useProviders( useProviders(
...@@ -57,8 +54,8 @@ const App = createApp({ ...@@ -57,8 +54,8 @@ const App = createApp({
authorize({ scope: 'scope.camera' }); authorize({ scope: 'scope.camera' });
useAuthCheck(); useAuthCheck();
useCallerListener(); useCallerListener(); //全局监听呼叫消息,并执行相应的处理逻辑:提示、页面跳转等
useSocketHandle(); useSocketHandle(); //全局监听socket的主要状态
} }
}) })
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
:autoPauseIfOpenNative="false" :autoPauseIfOpenNative="false"
:backgroundMute="true" :backgroundMute="true"
waitingImage="https://webdemo.agora.io/away.png" waitingImage="https://webdemo.agora.io/away.png"
v-show="mode==='video' && !stream.videoPause" v-show="mode === 'video' && !stream.videoPause"
/> />
<view class="cover" v-if="contact"> <view class="cover" v-if="contact">
<text class="name">{{contact.nickname}}</text> <text class="name">{{contact.nickname}}</text>
......
...@@ -13,7 +13,7 @@ export function useHttpIntercept(): HttpIntercept { ...@@ -13,7 +13,7 @@ export function useHttpIntercept(): HttpIntercept {
reqs.data.token = token; reqs.data.token = token;
reqs.data.company_id = company_id; reqs.data.company_id = company_id;
return new Promise( (resolve, reject) => { return new Promise( (resolve, reject) => {
if(token || reqs.path.includes('login')) { if(token || reqs.path.includes('login') || reqs.path.includes('CallStatus')) {
resolve(reqs) resolve(reqs)
} else { } else {
reject(`the http request ${reqs.path} need token`) reject(`the http request ${reqs.path} need token`)
...@@ -28,6 +28,14 @@ export function useHttpIntercept(): HttpIntercept { ...@@ -28,6 +28,14 @@ export function useHttpIntercept(): HttpIntercept {
} }
const responseIntercept = (res: HttpResponse) => { const responseIntercept = (res: HttpResponse) => {
switch(res.status) {
case 404:
showToast({title:'网络错误,请稍后再试'});
break;
case 504:
showToast({title:'服务器响应超时,请稍后重试'});
break;
}
return new Promise( resolve => { return new Promise( resolve => {
if(checkResData(res.data)) { if(checkResData(res.data)) {
resolve(res.data.data) resolve(res.data.data)
......
...@@ -30,7 +30,8 @@ export function useCustomeSocket(): CustomeSocket<AnyRemoteSocketMessage> { ...@@ -30,7 +30,8 @@ export function useCustomeSocket(): CustomeSocket<AnyRemoteSocketMessage> {
}, },
close() { close() {
closeSocket() closeSocket()
} },
removeEventListener() {}
} }
} }
......
import { navigateTo, showModal } from "@tarojs/taro"; import { hideLoading, navigateTo, showLoading, showModal, showToast } from "@tarojs/taro";
import { watch } from "@vue/runtime-core"; import { onMounted, watch } from "@vue/runtime-core";
import { useAuthData } from "any-hooks/auth/useAuthData"; import { useAuthData } from "any-hooks/auth/useAuthData";
import { useLogOut } from "any-hooks/auth/useLogOut"; import { useLogOut } from "any-hooks/auth/useLogOut";
import { useNetSocketStore } from "any-hooks/communication/useNetSocketStore"; import { useNetSocketStore } from "any-hooks/communication/useNetSocketStore";
import { useInjector, useRequest } from "vue-vulcan"; import { useInjector, useRequest } from "vue-vulcan";
export function useSocketHandle() { export function useSocketHandle() {
const { status, initConnect } = useInjector(useNetSocketStore); const { status, initConnect, reconnect, close, currentMsg } = useInjector(useNetSocketStore);
const { authData } = useInjector(useAuthData); const { authData } = useInjector(useAuthData);
const [,requestAuthState] = useRequest<{is_signin: '1' | '0'}>('/getUserCallStatus', {auto: false}); const [,requestAuthState] = useRequest<any>('/getUserCallStatus', {auto: false});
const { submitLogOut } = useLogOut(); const { submitLogOut } = useLogOut();
watch(authData, data => { onMounted(() => {
if(!data) return; console.log('handle', authData)
requestAuthState({user_id: data.id}) if(authData.value) {
requestAuthState({user_id: authData.value.id})
.then(res => { .then(res => {
if(res.callState === '1') {
showToast({title: '当前用户处于通话状态, 无法覆盖登录'});
return;
}
if(res.is_signin === '0') { if(res.is_signin === '0') {
initConnect(data) initConnect(authData.value)
} else { } else {
showModal({ showModal({
title:'当前账号已在线,是否确认登陆?', title:'当前账号已在线,是否确认登录?',
success: e => { success: e => {
if(e.confirm){ if(e.confirm){
initConnect(data); initConnect(authData.value);
} else if(e.cancel){ } else if(e.cancel){
submitLogOut({login_id: data.id}).then(_ => navigateTo({url: '/pages/login/index'})); submitLogOut({login_id: authData.value.id}).then(_ => navigateTo({url: '/pages/login/index'}));
}
} }
})
} }
}) })
} }
}) })
watch(status, val => {
switch(val) {
case 'reconnect':
showLoading({title: '重连中...'});
break;
case 'opening':
hideLoading();
break;
case 'closed':
case 'onerror':
if(authData.value) {
reconnect()
} else{
// setTimeout( () => {
// showToast({title: '链接已关闭,请重启小程序', icon: 'none'});
// }, 1500)
}
break;
}
})
watch(currentMsg, msg => {
console.log(msg.msgSubFlag)
if(msg.msgSubFlag === 'OtherLoginIn'){
showToast({
title: '当前账号在其他设备登录,您已自动下线',
icon: 'none'
});
submitLogOut({login_id: authData.value.id}).then(_ => {
close();
navigateTo({url: '/pages/login/index'});
});
}
}) })
......
import { onMounted } from "vue"; import { onMounted } from "vue";
import { navigateTo } from '@tarojs/taro' import { reLaunch } from '@tarojs/taro'
import { useInjector } from "vue-vulcan"; import { useInjector } from "vue-vulcan";
import { useAuthData } from "../../../any-hooks/auth/useAuthData"; import { useAuthData } from "../../../any-hooks/auth/useAuthData";
...@@ -7,7 +7,7 @@ export function useAuthCheck() { ...@@ -7,7 +7,7 @@ export function useAuthCheck() {
const {authData} = useInjector(useAuthData); const {authData} = useInjector(useAuthData);
onMounted( () => { onMounted( () => {
if(!authData.value?.token) { if(!authData.value?.token) {
navigateTo({url: '/pages/login/index'}) reLaunch({url: '/pages/login/index'})
} }
}) })
} }
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import { useInjector } from 'vue-vulcan'; import { useInjector } from 'vue-vulcan';
import { useCallCenter } from 'any-hooks/communication/useCallCenter'; import { useCallCenter } from 'any-hooks/communication/useCallCenter';
import { navigateBack } from '@tarojs/taro'; import { navigateBack } from '@tarojs/taro';
import { watch } from '@vue/runtime-core'; import { onBeforeUnmount, watch } from '@vue/runtime-core';
const { target, caller, myCallState, answerCaller, hangup } = useInjector(useCallCenter); const { target, caller, myCallState, answerCaller, hangup } = useInjector(useCallCenter);
const onTapHangup = () => { const onTapHangup = () => {
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
}; };
}) })
onBeforeUnmount(() => {
hangup();
console.log('leave')
})
</script> </script>
<template> <template>
......
...@@ -14,19 +14,10 @@ ...@@ -14,19 +14,10 @@
<template> <template>
<view class="contact-list"> <view class="contact-list">
<!-- <view class="contact-item" v-for="(item, key) in contacts" :key="key" @tap="gotoDetail(item.id)">
<image class="avatar" :src="item.avatar" />
<view class="info">
<view>{{item.nickname}}</view>
<text>{{item.group_name}}</text>
</view>
<image v-if="item.is_signin === '1'" @tap.stop="callContact(item)" class="call" src="../../assets/call3x.png" mode="widthFix"/>
<image v-else class="call" src="../../assets/call-no3x.png" mode="widthFix"/>
</view> -->
<view class="contact-role-group" v-for="(group, key, index) in roleContacts" :key="index"> <view class="contact-role-group" v-for="(group, key, index) in roleContacts" :key="index">
<view class="role-name pd-2">{{key}}</view> <view class="role-name pd-2">{{key}}</view>
<view class="white-box"> <view class="white-box">
<view class="contact-item pd-2" v-for="(item, i) in group" :key="i"> <view class="contact-item pd-2" v-for="(item, i) in group" :key="i" @tap="gotoDetail(item.id)">
<image class="avatar" :src="item.avatar" /> <image class="avatar" :src="item.avatar" />
<view class="info"> <view class="info">
<view>{{item.nickname}}</view> <view>{{item.nickname}}</view>
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
const [showLogo, setShowLogo] = useState(true); const [showLogo, setShowLogo] = useState(true);
const [viewMode, setViewMode] = useState<'items' | 'groups'>('items'); const [viewMode, setViewMode] = useState<'items' | 'groups'>('items');
const { keyword } = useInjector(useContacts); const { keyword, setKeyWord } = useInjector(useContacts);
const { rect } = useInjector(useAppInitInfo); const { rect } = useInjector(useAppInitInfo);
const capTop = ref(`${rect.top}px`); const capTop = ref(`${rect.top}px`);
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
<scroll-view class="home-contents" :scrollY="true" @scroll="onScroll"> <scroll-view class="home-contents" :scrollY="true" @scroll="onScroll">
<view class="tabs pd-1"> <view class="tabs pd-1">
<text class="tab-item contacts" :class="{active: viewMode==='items'}" @tap="setViewMode('items')">联系人</text> <text class="tab-item contacts" :class="{active: viewMode==='items'}" @tap="setViewMode('items');setKeyWord('')">联系人</text>
<text class="tab-item group" :class="{active: viewMode==='groups'}" @tap="setViewMode('groups')">群组</text> <text class="tab-item group" :class="{active: viewMode==='groups'}" @tap="setViewMode('groups');setKeyWord('')">群组</text>
</view> </view>
<view class="list"> <view class="list">
<contacts-list v-if="viewMode === 'items'"></contacts-list> <contacts-list v-if="viewMode === 'items'"></contacts-list>
......
<script lang="ts" setup> <script lang="ts" setup>
import { navigateTo } from '@tarojs/taro'; import { navigateTo } from '@tarojs/taro';
import { useWorkGroups } from 'any-hooks/contacts/useWorkGroups'; import { useContacts } from 'any-hooks/contacts/useContacts';
import { useInjector } from 'vue-vulcan';
const { groups } = useWorkGroups(); const { filterGroups } = useInjector(useContacts);
const gotoGroupContacts = (id: string) => { const gotoGroupContacts = (id: string) => {
navigateTo({url: `/pages/group-contacts/index?id=${id}`}) navigateTo({url: `/pages/group-contacts/index?id=${id}`})
} }
...@@ -11,11 +12,11 @@ import { useWorkGroups } from 'any-hooks/contacts/useWorkGroups'; ...@@ -11,11 +12,11 @@ import { useWorkGroups } from 'any-hooks/contacts/useWorkGroups';
<template> <template>
<view class="work-group-list white-box"> <view class="work-group-list white-box">
<view class="group-item pd-1" v-for="(item, key) in groups" :key="key" @tap="gotoGroupContacts(item.id)"> <view class="group-item pd-1" v-for="(item, key) in filterGroups" :key="key" @tap="gotoGroupContacts(item.id)">
<image class="group-icon" src="../../assets/group3x.png" mode="widthFix"/> <image class="group-icon" src="../../assets/group3x.png" mode="widthFix"/>
<text class="group-name">{{item.title}}</text> <text class="group-name">{{item.title}}</text>
</view> </view>
<data-empty v-if="!groups?.length"></data-empty> <data-empty v-if="!filterGroups?.length"></data-empty>
</view> </view>
</template> </template>
...@@ -25,7 +26,7 @@ import { useWorkGroups } from 'any-hooks/contacts/useWorkGroups'; ...@@ -25,7 +26,7 @@ import { useWorkGroups } from 'any-hooks/contacts/useWorkGroups';
.group-item{ .group-item{
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 30px; margin: 35px 0;
.group-icon{ .group-icon{
width: 72px; width: 72px;
height: 62px; height: 62px;
......
export default { export default {
navigationBarTitleText: 'anyremote' navigationStyle: 'custom'
} }
<script setup> <script setup>
import { computed, watch } from 'vue'; import { computed, onMounted, watch } from 'vue';
import { navigateTo, navigateBack, showModal } from '@tarojs/taro'; import { navigateTo, navigateBack, showModal, showToast, hideHomeButton, redirectTo, switchTab } from '@tarojs/taro';
import { useLogin } from '../../../any-hooks/auth/useLogin'; import { useLogin } from '../../../any-hooks/auth/useLogin';
import { useInjector } from 'vue-vulcan'; import { useInjector, useRequest } from 'vue-vulcan';
import { useNetSocketStore } from 'any-hooks/communication/useNetSocketStore'; import { useNetSocketStore } from 'any-hooks/communication/useNetSocketStore';
import { useLogOut } from 'any-hooks/auth/useLogOut'; import { useLogOut } from 'any-hooks/auth/useLogOut';
...@@ -10,29 +10,58 @@ ...@@ -10,29 +10,58 @@
const { submitLogOut } = useLogOut(); const { submitLogOut } = useLogOut();
const { initConnect } = useInjector(useNetSocketStore); const { initConnect } = useInjector(useNetSocketStore);
const allowSubmit = computed(() => !!loginData.login_id && loginData.login_password); const allowSubmit = computed(() => !!loginData.login_id && loginData.login_password);
const [,requestAuthState] = useRequest<{is_signin: '1' | '0'}>('/getUserCallStatus', {auto: false});
onMounted(() => {
hideHomeButton();
})
const onSubmit = () => { const onSubmit = () => {
submitLogin().then( _ => { requestAuthState({login_name: loginData.login_id}).then(res => {
navigateBack(); if(res.callState === '1') {
showToast({title: '当前用户处于通话状态, 无法覆盖登录'});
return;
}
if(res.is_signin === '1') {
showModal({
title:'当前账号已在线,是否确认登录?',
success: e => {
if(e.confirm){
submitLogin().then( r => {
initConnect(r);
switchTab({url: '/pages/index/index'})
})
}
}
})
} else {
submitLogin().then( r => {
initConnect(r);
switchTab({url: '/pages/index/index'})
})
}
}) })
} }
</script> </script>
<template> <template>
<view class="page white-box"> <view class="page white-box login-wrapper">
<view class="titles"> <view class="titles">
<view class="header-title">欢迎使用anyremote</view> <view class="header-title">欢迎使用anyremote</view>
<text class="sub-title">请输入您的账号密码</text> <text class="sub-title">请输入您的账号密码</text>
</view> </view>
<view class="login-box"> <view class="login-box">
<input class="login-item" placeholder="请输入您的账号" v-model="loginData.login_id"> <input class="login-item" placeholder="请输入您的账号" v-model="loginData.login_id">
<input class="login-item" type="password" placeholder="请输入密码" v-model="loginData.login_password"> <input class="login-item" type="password" placeholder="请输入您的密码" v-model="loginData.login_password">
<button class="login-btn" @tap="onSubmit()" :disabled="!allowSubmit" :class="{allow: allowSubmit}">登录</button> <button class="login-btn" @tap="onSubmit()" :disabled="!allowSubmit" :class="{allow: allowSubmit}">登录</button>
</view> </view>
</view> </view>
</template> </template>
<style lang="less"> <style lang="less">
.login-wrapper{
padding-top:150px;
}
.titles{ .titles{
margin: 60px 0; margin: 60px 0;
.header-title{ .header-title{
......
...@@ -3,16 +3,14 @@ ...@@ -3,16 +3,14 @@
import { useInjector, useState } from 'vue-vulcan'; import { useInjector, useState } from 'vue-vulcan';
import StreamPlayer from 'src/components/stream-player.vue'; import StreamPlayer from 'src/components/stream-player.vue';
import StreamPusher from 'src/components/stream-pusher.vue'; import StreamPusher from 'src/components/stream-pusher.vue';
import { createLivePusherContext, navigateBack, showModal, showToast } from '@tarojs/taro'; import { createLivePusherContext, navigateBack, showModal, showToast, switchTab } from '@tarojs/taro';
import { watch } from '@vue/runtime-core'; import { watch } from '@vue/runtime-core';
import { useAppInitInfo } from 'src/hooks/common/useAppInitInfo'; import { useAppInitInfo } from 'src/hooks/common/useAppInitInfo';
import Invite from './invite.vue'; import Invite from './invite.vue';
import { useCallCenter } from 'any-hooks/communication/useCallCenter'; import { useCallCenter } from 'any-hooks/communication/useCallCenter';
import { UserData } from 'any-hooks/types/user'; import { UserData } from 'any-hooks/types/user';
import { useChannelStore } from 'any-hooks/communication/useChannelStore';
const { target } = useInjector(useCallCenter); const { target } = useInjector(useCallCenter);
const { currentChannel } = useInjector(useChannelStore);
const { streamList, localPushurl, voiceMute, mode, switchLocalMicState, switchVideoOrAudio, leave } = useInjector(useMeetingCenter); const { streamList, localPushurl, voiceMute, mode, switchLocalMicState, switchVideoOrAudio, leave } = useInjector(useMeetingCenter);
const { topDistance } = useAppInitInfo(); const { topDistance } = useAppInitInfo();
...@@ -38,8 +36,7 @@ import { useChannelStore } from 'any-hooks/communication/useChannelStore'; ...@@ -38,8 +36,7 @@ import { useChannelStore } from 'any-hooks/communication/useChannelStore';
success: res => { success: res => {
if(res.confirm) { if(res.confirm) {
leave(); leave();
navigateBack({delta: 2}); switchTab({url: '/pages/index/index'});
} }
} }
}) })
...@@ -52,10 +49,10 @@ import { useChannelStore } from 'any-hooks/communication/useChannelStore'; ...@@ -52,10 +49,10 @@ import { useChannelStore } from 'any-hooks/communication/useChannelStore';
/** 返回上一页 */ /** 返回上一页 */
const backToIndex = () => { const backToIndex = () => {
navigateBack({delta: 2}) switchTab({url: '/pages/index/index'})
} }
/** 切换通讯画面 0-n表示最大化远程画面 -1表示最大化本地画面 -2表示取消最大化,所有画面均分显示 */ /** 切换通讯画面 0-n表示最大化指定的远程画面; -1表示最大化本地画面; -2表示取消最大化,所有画面均分显示 */
const [activeVideo, setActive] = useState(-2); const [activeVideo, setActive] = useState(-2);
const toggleActive = (index: number) => { const toggleActive = (index: number) => {
if(activeVideo.value === -2) { if(activeVideo.value === -2) {
...@@ -78,9 +75,9 @@ import { useChannelStore } from 'any-hooks/communication/useChannelStore'; ...@@ -78,9 +75,9 @@ import { useChannelStore } from 'any-hooks/communication/useChannelStore';
<template> <template>
<view class ="meeting-container page col-page" :style="{paddingTop: topDistance+'px'}"> <view class ="meeting-container page col-page" :style="{paddingTop: topDistance+'px'}">
<invite v-if="inviting" @choose="onInvite($event)" @cancel="setInviting(false)"></invite> <invite v-if="inviting" @choose="onInvite($event)" @cancel="setInviting(false)"></invite>
<view class="c-info" style="color:#fff"> <!-- <view class="c-info" style="color:#fff">
{{currentChannel?.channel_id}} {{currentChannel?.channel_id}}
</view> </view> -->
<view class="videos"> <view class="videos">
<stream-player <stream-player
class="video-item" class="video-item"
......
<script setup> <script setup>
import MeetingBar from '../../components/mini-meeting-bar.vue'; import MeetingBar from '../../components/mini-meeting-bar.vue';
import { navigateTo, showModal } from '@tarojs/taro'; import { navigateTo, reLaunch, showModal } from '@tarojs/taro';
import { useAuthData } from 'any-hooks/auth/useAuthData'; import { useAuthData } from 'any-hooks/auth/useAuthData';
import { useLogOut } from 'any-hooks/auth/useLogOut'; import { useLogOut } from 'any-hooks/auth/useLogOut';
import { useCallCenter } from 'any-hooks/communication/useCallCenter'; import { useCallCenter } from 'any-hooks/communication/useCallCenter';
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
if(res.confirm) return submitLogOut({login_id: authData.value.id}); if(res.confirm) return submitLogOut({login_id: authData.value.id});
return null return null
}).then(res => { }).then(res => {
res!== null && navigateTo({url: '/pages/login/index'}); res!== null && reLaunch({url: '/pages/login/index'});
}) })
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment