Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
anyremote-miniapp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wxl
anyremote-miniapp
Commits
e7d97607
Commit
e7d97607
authored
Apr 01, 2021
by
wxl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix bugs
parent
954c43df
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
259 additions
and
128 deletions
+259
-128
any-hooks/auth/useLogOut.ts
+7
-4
any-hooks/auth/useLogin.ts
+10
-3
any-hooks/common/useAgoraClient.ts
+1
-1
any-hooks/common/useSocket.ts
+13
-7
any-hooks/communication/useCallCenter.ts
+30
-15
any-hooks/communication/useMeetingCenter.ts
+3
-3
any-hooks/communication/useNetSocketStore.ts
+13
-3
any-hooks/communication/useVideoConference.ts
+5
-5
any-hooks/contacts/useContacts.ts
+23
-5
any-hooks/types/socket.ts
+2
-2
any-hooks/types/user.ts
+1
-1
src/app.config.ts
+1
-1
src/app.ts
+6
-9
src/components/stream-player.vue
+1
-1
src/hooks/http/useHttpIntercept.ts
+9
-1
src/hooks/socket/useCustomeSocket.ts
+2
-1
src/hooks/socket/useSocketHandle.ts
+64
-22
src/hooks/user/useAuthCheck.ts
+3
-2
src/pages/calling/index.vue
+6
-1
src/pages/index/contacts-list.vue
+2
-11
src/pages/index/index.vue
+3
-3
src/pages/index/work-groups-list.vue
+6
-5
src/pages/login/index.config.ts
+2
-2
src/pages/login/index.vue
+37
-8
src/pages/meeting/index.vue
+7
-10
src/pages/mine/index.vue
+2
-2
No files found.
any-hooks/auth/useLogOut.ts
View file @
e7d97607
import
{
useNetSocketStore
}
from
"any-hooks/communication/useNetSocketStore"
;
import
{
useInjector
,
useRequest
}
from
"vue-vulcan"
;
import
{
useAuthData
}
from
"./useAuthData"
;
export
function
useLogOut
()
{
const
[,
request
]
=
useRequest
<
any
>
(
'/loginOut'
,
{
auto
:
false
});
const
{
setAuth
}
=
useInjector
(
useAuthData
);
const
{
close
}
=
useInjector
(
useNetSocketStore
)
const
submitLogOut
=
(
data
:
{
login_id
:
string
})
=>
{
return
request
(
data
).
then
(
_
=>
setAuth
(
null
));
return
request
(
data
).
then
(
_
=>
{
setAuth
(
null
);
close
();
});
}
return
{
submitLogOut
}
}
\ No newline at end of file
}
any-hooks/auth/useLogin.ts
View file @
e7d97607
...
...
@@ -3,6 +3,8 @@ import { reactive } from "vue";
import
{
useInjector
,
useRequest
}
from
"vue-vulcan"
;
import
{
useAuthData
}
from
"./useAuthData"
;
let
LOGIN_STATE
=
false
export
function
useLogin
()
{
const
loginData
=
reactive
({
login_id
:
''
,
...
...
@@ -16,11 +18,17 @@ export function useLogin() {
const
submitLogin
=
()
=>
{
return
request
({...
loginData
,
peer_id
})
.
then
(
data
=>
{
setAuth
(
data
);
return
data
}
)
.
then
(
data
=>
{
LOGIN_STATE
=
true
;
setAuth
(
data
);
return
data
}
)
}
return
{
loginData
,
LOGIN_STATE
,
submitLogin
}
}
\ No newline at end of file
}
any-hooks/common/useAgoraClient.ts
View file @
e7d97607
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
{
AGORA_APP_SDK
}
from
"../communication/token"
;
...
...
any-hooks/common/useSocket.ts
View file @
e7d97607
...
...
@@ -13,7 +13,9 @@ export function useSocket<S = any>() {
const
brokenTime
=
ref
(
0
);
if
(
customeSocket
)
ws
=
customeSocket
;
let
initUrl
:
string
;
const
connect
=
(
url
?:
string
)
=>
{
initUrl
=
url
;
if
(
customeSocket
)
{
ws
.
connect
(
url
)
}
else
{
...
...
@@ -26,10 +28,9 @@ export function useSocket<S = any>() {
brokenTime
.
value
=
0
;
socketSettings
.
heartData
&&
startHeartConnect
();
}
);
ws
.
addEventListener
(
'close'
,
()
=>
{
setStatus
(
'closed'
);
reconnect
(
url
);
});
ws
.
addEventListener
(
'close'
,
()
=>
{
setStatus
(
'closed'
);});
ws
.
addEventListener
(
'error'
,
()
=>
{
setStatus
(
'onerror'
);
reconnect
(
url
);
setStatus
(
'onerror'
);
});
}
...
...
@@ -40,15 +41,16 @@ export function useSocket<S = any>() {
}
// 重连功能
const
limit
=
socketSettings
.
retryLimit
||
5
;
const
reconnect
=
(
url
:
string
)
=>
{
const
limit
=
socketSettings
.
retryLimit
||
100
;
const
reconnect
=
()
=>
{
if
(
!
initUrl
)
return
;
console
.
log
(
'开始重连'
)
brokenTime
.
value
++
;
if
(
brokenTime
.
value
>
limit
)
{
ws
.
close
();
}
else
{
setStatus
(
'reconnect'
);
setTimeout
(
()
=>
connect
(
u
rl
),
brokenTime
.
value
*
1000
);
setTimeout
(
()
=>
connect
(
initU
rl
),
brokenTime
.
value
*
1000
);
}
}
...
...
@@ -56,8 +58,12 @@ export function useSocket<S = any>() {
currentMsg
,
status
,
connect
,
reconnect
,
startHeartConnect
,
send
:
ws
.
send
,
close
:
ws
.
close
close
:
()
=>
{
setStatus
(
'closed'
);
ws
.
close
();
}
}
}
any-hooks/communication/useCallCenter.ts
View file @
e7d97607
...
...
@@ -39,22 +39,24 @@ export function useCallCenter() {
}
})
})
//
12
S后若本地用户仍处于主动呼叫状态,则自动挂断
//
8
S后若本地用户仍处于主动呼叫状态,则自动挂断
setTimeout
(()
=>
{
if
(
myCallState
.
value
===
'calling'
)
hangup
();
},
1
2
000
)
},
1
8
000
)
}
/** 回应呼叫功能 */
const
answerCaller
=
(
subFlag
:
AnyRemoteSubFlag
)
=>
{
const
answerCaller
=
(
subFlag
:
AnyRemoteSubFlag
,
user
?:
UserData
)
=>
{
if
(
subFlag
===
'Connect'
)
{
setCallState
(
'call_accepted'
);
getTokenByChannel
(
caller
.
value
.
channel
);
updateMembers
(
caller
.
value
.
members
,
'join'
)
updateMembers
(
caller
.
value
.
members
,
'join'
)
;
};
const
target
=
user
||
caller
.
value
sendMsg
({
toID
:
caller
.
value
.
id
,
toName
:
caller
.
value
.
nickname
,
toID
:
target
.
id
,
toName
:
target
.
nickname
,
msgMainFlag
:
'CallAnswer'
,
msgSubFlag
:
subFlag
})
...
...
@@ -68,11 +70,23 @@ export function useCallCenter() {
switch
(
msg
.
msgSubFlag
)
{
case
'Request'
:
// 本地呼叫状态为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
setTimeout
(
()
=>
{
if
(
myCallState
.
value
===
'being_called'
){
answerCaller
(
'Busying'
);
answerCaller
(
'Busying'
,
{
id
:
currentMsg
.
value
.
fromID
,
nickname
:
currentMsg
.
value
.
fromName
}
);
setCallState
(
'free'
);
}
},
10000
)
...
...
@@ -80,16 +94,17 @@ export function useCallCenter() {
case
'Hangup'
:
//对方中断呼叫,则将呼叫状态改为free
setCallState
(
'free'
);
setCaller
({
id
:
msg
.
fromID
,
nickname
:
msg
.
fromName
,
action
:
msg
.
msgSubFlag
,
channel
:
msg
.
channelID
,
members
:
msg
.
msgData
?.
members
||
[]
})
break
;
}
setCaller
({
id
:
currentMsg
.
value
.
fromID
,
nickname
:
currentMsg
.
value
.
fromName
,
action
:
msg
.
msgSubFlag
,
channel
:
msg
.
channelID
,
members
:
msg
.
msgData
?.
members
||
[]
})
})
// 监听呼叫目标的回应
watch
(
currentMsg
,
msg
=>
{
...
...
any-hooks/communication/useMeetingCenter.ts
View file @
e7d97607
...
...
@@ -20,14 +20,14 @@ interface MeetingMember {
}
}
/** 会议中心功能, 该功能在呼叫功能生效后使用,此模块会将其他即时交互模块集中到一起,如:音视频通讯模块、文本聊天模块
、白板标注模块等
*/
/** 会议中心功能, 该功能在呼叫功能生效后使用,此模块会将其他即时交互模块集中到一起,如:音视频通讯模块、文本聊天模块
等(目前只有音视频通讯)
*/
export
function
useMeetingCenter
()
{
const
{
hangup
,
myCallState
}
=
useInjector
(
useCallCenter
);
const
{
hangup
,
myCallState
}
=
useInjector
(
useCallCenter
);
const
{
streamList
,
localPushurl
,
voiceMute
,
mode
,
stopVideoConference
,
switchLocalMicState
,
switchVideoOrAudio
}
=
useInjector
(
useVideoConference
);
/** 离开会议(分两步:1.挂断当前呼叫, 2.停止音视频功能) */
const
leave
=
()
=>
{
hangup
(
'leave'
);
hangup
(
'leave'
);
stopVideoConference
();
}
...
...
any-hooks/communication/useNetSocketStore.ts
View file @
e7d97607
import
{
onMounted
}
from
"@vue/runtime-core"
;
import
{
useAuthData
}
from
"any-hooks/auth/useAuthData"
;
import
{
useSocket
}
from
"any-hooks/common/useSocket"
;
import
{
AnyRemoteSocketMessage
,
SocketSettings
}
from
"any-hooks/types/socket"
;
...
...
@@ -19,11 +20,18 @@ export function useNetSocketStore() {
const
{
authData
}
=
useInjector
(
useAuthData
);
const
[
netState
,
setNetState
]
=
useState
<
NetStates
>
(
0
);
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'
})
const
initConnect
=
(
data
:
UserData
)
=>
{
onMounted
(()
=>
{
if
(
!
deviceCode
.
value
)
{
setDevice
(
new
Date
().
getTime
())
}
})
const
initConnect
=
(
data
:
UserData
)
=>
{
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
({
fromID
:
authData
.
value
.
id
,
...
...
@@ -46,6 +54,8 @@ export function useNetSocketStore() {
sendMsg
,
setNetState
,
initConnect
,
reconnect
,
close
,
currentMsg
,
netState
,
status
...
...
any-hooks/communication/useVideoConference.ts
View file @
e7d97607
...
...
@@ -7,7 +7,7 @@ import { useChannelStore } from "./useChannelStore";
/** 视频通讯中心,用于音视频聊天功能,可集成到会议中心模块(不推荐在页面组件中直接使用该hook模块) */
export
function
useVideoConference
()
{
const
{
currentChannel
,
clearChannel
}
=
useInjector
(
useChannelStore
);
const
{
authData
}
=
useInjector
(
useAuthData
);
const
{
authData
}
=
useInjector
(
useAuthData
);
const
{
joinChannelWithAgora
,
leaveChannelWithAgora
,
...
...
@@ -19,10 +19,9 @@ export function useVideoConference() {
localPushurl
,
}
=
useAgoraClient
();
/** 监听频道模块,频道被创建后自动将agora的音视频通讯功能载入频道 */
/** 监听频道模块,频道被创建
、更新
后自动将agora的音视频通讯功能载入频道 */
watch
(
currentChannel
,
channel
=>
{
if
(
!
channel
)
return
;
console
.
log
(
'频道变化'
,
channel
,
authData
.
value
.
peer_id
)
if
(
!
channel
)
return
;
joinChannelWithAgora
(
channel
.
agora_token
,
channel
.
channel_id
,
...
...
@@ -57,8 +56,9 @@ export function useVideoConference() {
setMode
(
mode
.
value
===
'video'
?
'audio'
:
'video'
);
}
/** 停止音视频通讯功能 */
const
stopVideoConference
=
()
=>
{
setVoiceMute
(
false
);
setVoiceMute
(
false
);
//将麦克风、音视频状态重置
setMode
(
'video'
);
clearChannel
();
leaveChannelWithAgora
();
...
...
any-hooks/contacts/useContacts.ts
View file @
e7d97607
import
{
UserData
}
from
"../types/user"
;
import
{
UserData
,
WorkGroupData
}
from
"../types/user"
;
import
{
useInjector
,
useRequest
,
useState
}
from
"vue-vulcan"
;
import
{
computed
,
watch
}
from
"vue"
;
import
{
useAuthData
}
from
"../auth/useAuthData"
;
import
{
useNetSocketStore
}
from
"any-hooks/communication/useNetSocketStore"
;
import
{
Subject
}
from
"rxjs"
;
import
{
debounceTime
}
from
"rxjs/operators"
;
export
function
useContacts
()
{
const
{
authData
}
=
useInjector
(
useAuthData
);
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
contacts
=
computed
(
()
=>
{
...
...
@@ -15,6 +18,10 @@ export function useContacts() {
.
filter
(
item
=>
item
.
nickname
.
includes
(
keyword
.
value
))
});
const
filterGroups
=
computed
(
()
=>
{
return
groups
.
value
?.
filter
(
item
=>
item
.
title
.
includes
(
keyword
.
value
))
})
const
roleContacts
=
computed
(
()
=>
{
const
contactHome
=
{}
as
{[
props
:
string
]:
UserData
[]}
contacts
.
value
?.
forEach
(
item
=>
{
...
...
@@ -42,17 +49,28 @@ export function useContacts() {
}
// 监听socket的home类型消息 实时更新contacts联系人数据
const
req$
=
new
Subject
();
req$
.
pipe
(
debounceTime
(
500
))
.
subscribe
(
_
=>
getUserList
())
watch
(
currentMsg
,
msg
=>
{
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
{
contacts
,
freeContacts
,
roleContacts
,
setKeyWord
,
roleContacts
,
keyword
,
groups
,
filterGroups
,
requestGroups
,
setKeyWord
,
getUserList
,
getContactById
,
getContactsByGroup
,
...
...
any-hooks/types/socket.ts
View file @
e7d97607
...
...
@@ -16,8 +16,8 @@ export interface SocketSettings {
export
type
ConnectStatus
=
'ready'
|
'opening'
|
'onerror'
|
'closed'
|
'reconnect'
;
export
type
AnyRemoteMainFlag
=
'Heart'
|
'Login'
|
'Broadcast'
|
'Home'
|
'CallOffer'
|
'CallAnswer'
|
'ChannelChat'
|
'NotifyUpdateUserList'
|
'SetAtts'
;
export
type
AnyRemoteSubFlag
=
'Request'
|
'Busying'
|
'Connect'
|
'Hangup'
|
'UpdateUserList'
;
export
type
AnyRemoteMainFlag
=
'Heart'
|
'Login'
|
'Broadcast'
|
'Home'
|
'CallOffer'
|
'CallAnswer'
|
'ChannelChat'
|
'NotifyUpdateUserList'
|
'SetAtts'
|
'Login'
;
export
type
AnyRemoteSubFlag
=
'Request'
|
'Busying'
|
'Connect'
|
'Hangup'
|
'UpdateUserList'
|
'OtherLoginIn'
;
export
interface
AnyRemoteSocketMessage
{
fromID
?:
string
;
...
...
any-hooks/types/user.ts
View file @
e7d97607
...
...
@@ -6,7 +6,7 @@ export interface UserData {
avatar
?:
string
;
permission
?:
string
;
token
?:
string
;
is_signin
?:
'1'
|
'
2
'
;
is_signin
?:
'1'
|
'
0
'
;
is_calling
?:
'1'
|
'0'
;
group_name
?:
string
;
diy_group
?:
string
;
...
...
src/app.config.ts
View file @
e7d97607
...
...
@@ -27,7 +27,7 @@ export default {
},
{
"pagePath"
:
"pages/mine/index"
,
"text"
:
"
我的
"
,
"text"
:
"
个人中心
"
,
"iconPath"
:
"assets/user_center.png"
,
"selectedIconPath"
:
"assets/user_center_a.png"
}
...
...
src/app.ts
View file @
e7d97607
import
'./app.less'
;
import
{
authorize
,
getCurrentInstance
}
from
'@tarojs/taro'
;
import
{
authorize
}
from
'@tarojs/taro'
;
import
{
createApp
}
from
'vue'
;
import
{
useCustomeRequest
}
from
'./hooks/http/useCustomeRequest'
;
import
{
useProviders
}
from
'vue-vulcan'
;
...
...
@@ -23,11 +23,8 @@ import dataEmpty from './components/data-empty.vue';
import
MeetingBar
from
'./components/mini-meeting-bar.vue'
;
import
{
useVideoConference
}
from
'any-hooks/communication/useVideoConference'
;
const
App
=
createApp
({
onShow
()
{
console
.
log
(
'show a '
)
},
setup
()
{
const
App
=
createApp
({
setup
()
{
/* 提供全局配置类hook */
useProviders
(
useRequestOption
,
//提供http请求配置项
...
...
@@ -52,13 +49,13 @@ const App = createApp({
useChannelStore
,
//频道信息中心
useCallCenter
,
//多人呼叫中心
useVideoConference
,
//多人视频通讯中心
useMeetingCenter
,
//多人会议中心
useMeetingCenter
,
//多人会议中心
);
authorize
({
scope
:
'scope.camera'
});
useAuthCheck
();
useCallerListener
();
useSocketHandle
();
useCallerListener
();
//全局监听呼叫消息,并执行相应的处理逻辑:提示、页面跳转等
useSocketHandle
();
//全局监听socket的主要状态
}
})
...
...
src/components/stream-player.vue
View file @
e7d97607
...
...
@@ -28,7 +28,7 @@
:autoPauseIfOpenNative=
"false"
:backgroundMute=
"true"
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"
>
<text
class=
"name"
>
{{
contact
.
nickname
}}
</text>
...
...
src/hooks/http/useHttpIntercept.ts
View file @
e7d97607
...
...
@@ -13,7 +13,7 @@ export function useHttpIntercept(): HttpIntercept {
reqs
.
data
.
token
=
token
;
reqs
.
data
.
company_id
=
company_id
;
return
new
Promise
(
(
resolve
,
reject
)
=>
{
if
(
token
||
reqs
.
path
.
includes
(
'login'
))
{
if
(
token
||
reqs
.
path
.
includes
(
'login'
)
||
reqs
.
path
.
includes
(
'CallStatus'
)
)
{
resolve
(
reqs
)
}
else
{
reject
(
`the http request
${
reqs
.
path
}
need token`
)
...
...
@@ -28,6 +28,14 @@ export function useHttpIntercept(): HttpIntercept {
}
const
responseIntercept
=
(
res
:
HttpResponse
)
=>
{
switch
(
res
.
status
)
{
case
404
:
showToast
({
title
:
'网络错误,请稍后再试'
});
break
;
case
504
:
showToast
({
title
:
'服务器响应超时,请稍后重试'
});
break
;
}
return
new
Promise
(
resolve
=>
{
if
(
checkResData
(
res
.
data
))
{
resolve
(
res
.
data
.
data
)
...
...
src/hooks/socket/useCustomeSocket.ts
View file @
e7d97607
...
...
@@ -30,7 +30,8 @@ export function useCustomeSocket(): CustomeSocket<AnyRemoteSocketMessage> {
},
close
()
{
closeSocket
()
}
},
removeEventListener
()
{}
}
}
...
...
src/hooks/socket/useSocketHandle.ts
View file @
e7d97607
import
{
navigateTo
,
showModal
}
from
"@tarojs/taro"
;
import
{
watch
}
from
"@vue/runtime-core"
;
import
{
hideLoading
,
navigateTo
,
showLoading
,
showModal
,
showToast
}
from
"@tarojs/taro"
;
import
{
onMounted
,
watch
}
from
"@vue/runtime-core"
;
import
{
useAuthData
}
from
"any-hooks/auth/useAuthData"
;
import
{
useLogOut
}
from
"any-hooks/auth/useLogOut"
;
import
{
useNetSocketStore
}
from
"any-hooks/communication/useNetSocketStore"
;
import
{
useInjector
,
useRequest
}
from
"vue-vulcan"
;
export
function
useSocketHandle
()
{
const
{
status
,
initConnect
}
=
useInjector
(
useNetSocketStore
);
const
{
authData
}
=
useInjector
(
useAuthData
);
const
[,
requestAuthState
]
=
useRequest
<
{
is_signin
:
'1'
|
'0'
}
>
(
'/getUserCallStatus'
,
{
auto
:
false
});
const
{
status
,
initConnect
,
reconnect
,
close
,
currentMsg
}
=
useInjector
(
useNetSocketStore
);
const
{
authData
}
=
useInjector
(
useAuthData
);
const
[,
requestAuthState
]
=
useRequest
<
any
>
(
'/getUserCallStatus'
,
{
auto
:
false
});
const
{
submitLogOut
}
=
useLogOut
();
watch
(
authData
,
data
=>
{
if
(
!
data
)
return
;
requestAuthState
({
user_id
:
data
.
id
})
.
then
(
res
=>
{
if
(
res
.
is_signin
===
'0'
)
{
initConnect
(
data
)
}
else
{
showModal
({
title
:
'当前账号已在线,是否确认登陆?'
,
success
:
e
=>
{
if
(
e
.
confirm
){
initConnect
(
data
);
}
else
if
(
e
.
cancel
){
submitLogOut
({
login_id
:
data
.
id
}).
then
(
_
=>
navigateTo
({
url
:
'/pages/login/index'
}));
onMounted
(()
=>
{
console
.
log
(
'handle'
,
authData
)
if
(
authData
.
value
)
{
requestAuthState
({
user_id
:
authData
.
value
.
id
})
.
then
(
res
=>
{
if
(
res
.
callState
===
'1'
)
{
showToast
({
title
:
'当前用户处于通话状态, 无法覆盖登录'
});
return
;
}
if
(
res
.
is_signin
===
'0'
)
{
initConnect
(
authData
.
value
)
}
else
{
showModal
({
title
:
'当前账号已在线,是否确认登录?'
,
success
:
e
=>
{
if
(
e
.
confirm
){
initConnect
(
authData
.
value
);
}
else
if
(
e
.
cancel
){
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'
});
});
}
})
...
...
src/hooks/user/useAuthCheck.ts
View file @
e7d97607
import
{
onMounted
}
from
"vue"
;
import
{
navigateTo
}
from
'@tarojs/taro'
import
{
reLaunch
}
from
'@tarojs/taro'
import
{
useInjector
}
from
"vue-vulcan"
;
import
{
useAuthData
}
from
"../../../any-hooks/auth/useAuthData"
;
...
...
@@ -7,7 +7,7 @@ export function useAuthCheck() {
const
{
authData
}
=
useInjector
(
useAuthData
);
onMounted
(
()
=>
{
if
(
!
authData
.
value
?.
token
)
{
navigateTo
({
url
:
'/pages/login/index'
})
reLaunch
({
url
:
'/pages/login/index'
})
}
})
}
\ No newline at end of file
src/pages/calling/index.vue
View file @
e7d97607
...
...
@@ -2,7 +2,7 @@
import
{
useInjector
}
from
'vue-vulcan'
;
import
{
useCallCenter
}
from
'any-hooks/communication/useCallCenter'
;
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
onTapHangup
=
()
=>
{
...
...
@@ -15,6 +15,11 @@
setTimeout
(
navigateBack
,
1000
)
};
})
onBeforeUnmount
(()
=>
{
hangup
();
console
.
log
(
'leave'
)
})
</
script
>
...
...
src/pages/index/contacts-list.vue
View file @
e7d97607
...
...
@@ -13,20 +13,11 @@
</
script
>
<
template
>
<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-list"
>
<view
class=
"contact-role-group"
v-for=
"(group, key, index) in roleContacts"
:key=
"index"
>
<view
class=
"role-name pd-2"
>
{{
key
}}
</view>
<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"
/>
<view
class=
"info"
>
<view>
{{
item
.
nickname
}}
</view>
...
...
src/pages/index/index.vue
View file @
e7d97607
...
...
@@ -10,7 +10,7 @@
const
[
showLogo
,
setShowLogo
]
=
useState
(
true
);
const
[
viewMode
,
setViewMode
]
=
useState
<
'items'
|
'groups'
>
(
'items'
);
const
{
keyword
}
=
useInjector
(
useContacts
);
const
{
keyword
,
setKeyWord
}
=
useInjector
(
useContacts
);
const
{
rect
}
=
useInjector
(
useAppInitInfo
);
const
capTop
=
ref
(
`
${
rect
.
top
}
px`
);
...
...
@@ -34,8 +34,8 @@
<scroll-view
class=
"home-contents"
:scrollY=
"true"
@
scroll=
"onScroll"
>
<view
class=
"tabs pd-1"
>
<text
class=
"tab-item contacts"
:class=
"
{active: viewMode==='items'}" @tap="setViewMode('items')">联系人
</text>
<text
class=
"tab-item group"
:class=
"
{active: viewMode==='groups'}" @tap="setViewMode('groups')">群组
</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')
;setKeyWord('')
">群组
</text>
</view>
<view
class=
"list"
>
<contacts-list
v-if=
"viewMode === 'items'"
></contacts-list>
...
...
src/pages/index/work-groups-list.vue
View file @
e7d97607
<
script
lang=
"ts"
setup
>
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
)
=>
{
navigateTo
({
url
:
`/pages/group-contacts/index?id=
${
id
}
`
})
}
...
...
@@ -11,11 +12,11 @@ import { useWorkGroups } from 'any-hooks/contacts/useWorkGroups';
<
template
>
<view
class=
"work-group-list white-box"
>
<view
class=
"group-item pd-1"
v-for=
"(item, key) in
g
roups"
:key=
"key"
@
tap=
"gotoGroupContacts(item.id)"
>
<view
class=
"group-item pd-1"
v-for=
"(item, key) in
filterG
roups"
:key=
"key"
@
tap=
"gotoGroupContacts(item.id)"
>
<image
class=
"group-icon"
src=
"../../assets/group3x.png"
mode=
"widthFix"
/>
<text
class=
"group-name"
>
{{
item
.
title
}}
</text>
</view>
<data-empty
v-if=
"!
g
roups?.length"
></data-empty>
<data-empty
v-if=
"!
filterG
roups?.length"
></data-empty>
</view>
</
template
>
...
...
@@ -25,7 +26,7 @@ import { useWorkGroups } from 'any-hooks/contacts/useWorkGroups';
.group-item{
display
:
flex
;
align-items
:
center
;
margin
-bottom
:
30px
;
margin
:
35px
0
;
.group-icon{
width
:
72px
;
height
:
62px
;
...
...
src/pages/login/index.config.ts
View file @
e7d97607
export
default
{
navigation
BarTitleText
:
'anyremote'
export
default
{
navigation
Style
:
'custom'
}
src/pages/login/index.vue
View file @
e7d97607
<
script
setup
>
import
{
computed
,
watch
}
from
'vue'
;
import
{
navigateTo
,
navigateBack
,
showModal
}
from
'@tarojs/taro'
;
import
{
computed
,
onMounted
,
watch
}
from
'vue'
;
import
{
navigateTo
,
navigateBack
,
showModal
,
showToast
,
hideHomeButton
,
redirectTo
,
switchTab
}
from
'@tarojs/taro'
;
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
{
useLogOut
}
from
'any-hooks/auth/useLogOut'
;
...
...
@@ -10,29 +10,58 @@
const
{
submitLogOut
}
=
useLogOut
();
const
{
initConnect
}
=
useInjector
(
useNetSocketStore
);
const
allowSubmit
=
computed
(()
=>
!!
loginData
.
login_id
&&
loginData
.
login_password
);
const
[,
requestAuthState
]
=
useRequest
<
{
is_signin
:
'1'
|
'0'
}
>
(
'/getUserCallStatus'
,
{
auto
:
false
});
onMounted
(()
=>
{
hideHomeButton
();
})
const
onSubmit
=
()
=>
{
submitLogin
().
then
(
_
=>
{
navigateBack
();
})
requestAuthState
({
login_name
:
loginData
.
login_id
}).
then
(
res
=>
{
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
>
<
template
>
<view
class=
"page white-box"
>
<view
class=
"page white-box
login-wrapper
"
>
<view
class=
"titles"
>
<view
class=
"header-title"
>
欢迎使用anyremote
</view>
<text
class=
"sub-title"
>
请输入您的账号密码
</text>
</view>
<view
class=
"login-box"
>
<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>
</view>
</view>
</
template
>
<
style
lang=
"less"
>
.login-wrapper
{
padding-top
:
150px
;
}
.titles
{
margin
:
60px
0
;
.header-title{
...
...
src/pages/meeting/index.vue
View file @
e7d97607
...
...
@@ -3,16 +3,14 @@
import
{
useInjector
,
useState
}
from
'vue-vulcan'
;
import
StreamPlayer
from
'src/components/stream-player.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
{
useAppInitInfo
}
from
'src/hooks/common/useAppInitInfo'
;
import
Invite
from
'./invite.vue'
;
import
{
useCallCenter
}
from
'any-hooks/communication/useCallCenter'
;
import
{
UserData
}
from
'any-hooks/types/user'
;
import
{
useChannelStore
}
from
'any-hooks/communication/useChannelStore'
;
const
{
target
}
=
useInjector
(
useCallCenter
);
const
{
currentChannel
}
=
useInjector
(
useChannelStore
);
const
{
target
}
=
useInjector
(
useCallCenter
);
const
{
streamList
,
localPushurl
,
voiceMute
,
mode
,
switchLocalMicState
,
switchVideoOrAudio
,
leave
}
=
useInjector
(
useMeetingCenter
);
const
{
topDistance
}
=
useAppInitInfo
();
...
...
@@ -38,8 +36,7 @@ import { useChannelStore } from 'any-hooks/communication/useChannelStore';
success
:
res
=>
{
if
(
res
.
confirm
)
{
leave
();
navigateBack
({
delta
:
2
});
switchTab
({
url
:
'/pages/index/index'
});
}
}
})
...
...
@@ -52,10 +49,10 @@ import { useChannelStore } from 'any-hooks/communication/useChannelStore';
/** 返回上一页 */
const
backToIndex
=
()
=>
{
navigateBack
({
delta
:
2
})
switchTab
({
url
:
'/pages/index/index'
})
}
/** 切换通讯画面 0-n表示最大化
远程画面 -1表示最大化本地画面
-2表示取消最大化,所有画面均分显示 */
/** 切换通讯画面 0-n表示最大化
指定的远程画面; -1表示最大化本地画面;
-2表示取消最大化,所有画面均分显示 */
const
[
activeVideo
,
setActive
]
=
useState
(
-
2
);
const
toggleActive
=
(
index
:
number
)
=>
{
if
(
activeVideo
.
value
===
-
2
)
{
...
...
@@ -78,9 +75,9 @@ import { useChannelStore } from 'any-hooks/communication/useChannelStore';
<
template
>
<view
class =
"meeting-container page col-page"
:style=
"
{paddingTop: topDistance+'px'}">
<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
}}
</view>
</view>
-->
<view
class=
"videos"
>
<stream-player
class=
"video-item"
...
...
src/pages/mine/index.vue
View file @
e7d97607
<
script
setup
>
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
{
useLogOut
}
from
'any-hooks/auth/useLogOut'
;
import
{
useCallCenter
}
from
'any-hooks/communication/useCallCenter'
;
...
...
@@ -15,7 +15,7 @@
if
(
res
.
confirm
)
return
submitLogOut
({
login_id
:
authData
.
value
.
id
});
return
null
}).
then
(
res
=>
{
res
!==
null
&&
navigateTo
({
url
:
'/pages/login/index'
});
res
!==
null
&&
reLaunch
({
url
:
'/pages/login/index'
});
})
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment