Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
foreign
/
customer-service
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
03c9c8d6
authored
Jul 13, 2021
by
panjiangyi
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
格式化代码
parent
342401e1
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
388 additions
and
351 deletions
chat-list.vue
chat-room.vue
chat.vue
components/file-icon.vue
components/image-preview.vue
components/message.vue
components/video-player-icon.vue
components/video-preview.vue
components/voice.vue
components/who-read-list.vue
hybrid-input/index.vue
message-input.vue
message-list.vue
store/index.ts
third-party/image/index.ts
utils/jwt/index.ts
xim/index.ts
xim/logger.ts
xim/models/user.ts
xim/token.ts
xim/xim.ts
chat-list.vue
View file @
03c9c8d6
...
...
@@ -71,25 +71,26 @@
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Vue
,
Prop
,
Watch
}
from
"vue-property-decorator"
import
{
chatStore
,
ChatStore
}
from
"@/customer-service/store/model"
import
buttonThrottle
from
"@/utils/button-throttle"
;
import
{
Component
,
Prop
,
Vue
}
from
"vue-property-decorator"
;
import
{
chatStore
,
ChatStore
}
from
"@/customer-service/store/model"
;
// import { popupService } from "@/views/common-module/component/element-upgrades/fast-service-popup";
import
buttonThrottle
from
"@/utils/button-throttle"
import
Chat
from
"@/customer-service/xim"
import
{
formatTime
,
TimeFormatRule
}
from
"@/customer-service/utils/time"
import
{
formatTime
,
TimeFormatRule
}
from
"@/customer-service/utils/time"
;
import
Chat
from
"@/customer-service/xim"
;
export
function
parserMessage
(
type
:
string
,
rawMsg
:
string
)
{
if
(
!
type
)
return
""
if
(
!
rawMsg
)
return
""
const
msg
=
JSON
.
parse
(
rawMsg
)
if
(
!
type
)
return
""
;
if
(
!
rawMsg
)
return
""
;
const
msg
=
JSON
.
parse
(
rawMsg
)
;
if
(
type
===
"text"
)
{
return
msg
.
text
return
msg
.
text
;
}
else
if
(
type
===
"image"
)
{
return
`[图片]`
return
`[图片]`
;
}
else
if
(
type
===
"file"
)
{
return
`[文件]`
return
`[文件]`
;
}
else
{
;
`[不支持的消息格式]`
return
`[不支持的消息格式]`
;
}
}
type
Chat
=
ChatStore
.
STATE_MY_CHAT_ROOM_LIST
[
"list"
][
number
]
...
...
@@ -101,8 +102,10 @@ export default class ChatList extends Vue {
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
)
private
readonly
chatId
!
:
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_CURRENT_CHAT_UNIPLAT_ID
)
private
readonly
currentChatUniplatId
!
:
ChatStore
.
STATE_CHAT_CURRENT_CHAT_UNIPLAT_ID
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_CURRENT_CHAT_VERSION
)
private
readonly
uniplatVersion
!
:
ChatStore
.
STATE_CHAT_CURRENT_CHAT_VERSION
...
...
@@ -127,58 +130,58 @@ export default class ChatList extends Vue {
private
searchKeyword
=
""
private
get
chatRooms
()
{
return
this
.
chatList
?.
list
||
[]
return
this
.
chatList
?.
list
||
[]
;
}
private
isSelected
(
item
:
Chat
)
{
if
(
this
.
currentChatUniplatId
)
{
return
item
.
uniplatId
===
this
.
currentChatUniplatId
return
item
.
uniplatId
===
this
.
currentChatUniplatId
;
}
return
this
.
selected
===
item
.
uniplatId
return
this
.
selected
===
item
.
uniplatId
;
}
async
created
()
{
await
this
.
getMyChatList
()
this
.
setSource
(
ChatStore
.
StateChatSourceDirection
.
Server
)
this
.
selectFirstChat
()
await
this
.
getMyChatList
()
;
this
.
setSource
(
ChatStore
.
StateChatSourceDirection
.
Server
)
;
this
.
selectFirstChat
()
;
}
mounted
()
{
this
.
saveMyId
()
this
.
goToOnlyRoom
()
this
.
saveMyId
()
;
this
.
goToOnlyRoom
()
;
}
private
goToOnlyRoom
()
{
if
(
this
.
chatRooms
.
length
===
1
)
{
const
wantedChat
=
this
.
chatRooms
[
0
]
this
.
goToChatRoom
(
wantedChat
)
const
wantedChat
=
this
.
chatRooms
[
0
]
;
this
.
goToChatRoom
(
wantedChat
)
;
}
}
private
selectFirstChat
()
{
if
(
this
.
chatId
!=
null
)
return
if
(
!
this
.
chatRooms
.
length
)
return
const
{
chat_id
,
uniplat_version
,
uniplatId
}
=
this
.
chatRooms
[
0
]
if
(
this
.
chatId
!=
null
)
return
;
if
(
!
this
.
chatRooms
.
length
)
return
;
const
{
chat_id
,
uniplat_version
,
uniplatId
}
=
this
.
chatRooms
[
0
]
;
this
.
saveChatId
({
chatId
:
chat_id
,
v
:
uniplat_version
,
uniplatId
,
})
})
;
}
@
buttonThrottle
()
private
async
search
()
{
this
.
searchKeyword
=
this
.
searchKeyword
.
trim
()
this
.
searchKeyword
=
this
.
searchKeyword
.
trim
()
;
if
(
!
this
.
searchKeyword
)
{
await
this
.
getMyChatList
()
await
this
.
getMyChatList
()
;
}
else
{
await
this
.
getMyChatList
(
this
.
searchKeyword
)
await
this
.
getMyChatList
(
this
.
searchKeyword
)
;
}
}
private
goToChatRoom
(
data
:
Chat
)
{
if
(
this
.
currentChatUniplatId
===
data
.
uniplatId
)
{
return
return
;
}
this
.
saveChatId
({
...
...
@@ -186,21 +189,21 @@ export default class ChatList extends Vue {
.
chat_id
,
v
:
data
.
uniplat_version
,
uniplatId
:
data
.
uniplatId
,
}).
finally
(
this
.
raiseChatIdChanged
)
}).
finally
(
this
.
raiseChatIdChanged
)
;
this
.
saveChatTitle
(
data
.
uniplatId
)
this
.
saveChatTitle
(
data
.
uniplatId
)
;
}
private
raiseChatIdChanged
()
{
this
.
$emit
(
"change"
)
this
.
$emit
(
"change"
)
;
}
private
parseMesage
(
data
:
Chat
)
{
return
parserMessage
(
data
.
msg_type
,
data
.
msg
)
return
parserMessage
(
data
.
msg_type
,
data
.
msg
)
;
}
private
formatTimestamp
(
v
:
number
)
{
return
formatTime
(
v
,
{
short
:
true
,
rule
:
TimeFormatRule
.
Hour12
})
return
formatTime
(
v
,
{
short
:
true
,
rule
:
TimeFormatRule
.
Hour12
})
;
}
}
</
script
>
...
...
chat-room.vue
View file @
03c9c8d6
...
...
@@ -86,17 +86,18 @@
<
script
lang=
"ts"
>
import
{
Component
,
Watch
,
Vue
,
Ref
,
Provide
,
Prop
,
}
from
"vue-property-decorator"
import
MessageInput
from
"@/customer-service/message-input.vue"
import
messages
from
"@/customer-service/message-list.vue"
Provide
,
Ref
,
Vue
,
Watch
,
}
from
"vue-property-decorator"
;
import
MessageInput
from
"@/customer-service/message-input.vue"
;
import
messages
from
"@/customer-service/message-list.vue"
;
// import CusomterInfo from "./customer-info.vue"
// import OrderInfo from "./order-info.vue"
import
{
ChatStore
,
chatStore
}
from
"@/customer-service/store/model"
import
{
ChatStore
,
chatStore
}
from
"@/customer-service/store/model"
;
type
RoomInfoTab
=
"customer"
|
"order"
...
...
@@ -114,25 +115,31 @@ export default class ChatRoom extends Vue {
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_CLEAR_CURRENT_CHAT_MEMBERS
)
private
readonly
clearChatMembers
!
:
ChatStore
.
MUTATION_CLEAR_CURRENT_CHAT_MEMBERS
@
chatStore
.
State
(
ChatStore
.
STATE_CURRENT_CHAT_TITLE
)
private
readonly
chatTitle
!
:
ChatStore
.
STATE_CURRENT_CHAT_TITLE
@
chatStore
.
State
(
ChatStore
.
STATE_CURRENT_CHAT_INPUTING
)
private
readonly
currentInputPeople
!
:
ChatStore
.
STATE_CURRENT_CHAT_INPUTING
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_CURRENT_CHAT_UNIPLAT_ID
)
private
readonly
currentChatUniplatId
!
:
ChatStore
.
STATE_CHAT_CURRENT_CHAT_UNIPLAT_ID
@
chatStore
.
State
(
ChatStore
.
STATE_MY_CHAT_ROOM_LIST
)
private
readonly
myChatList
!
:
ChatStore
.
STATE_MY_CHAT_ROOM_LIST
private
allChatList
=
{
list
:
[]
}
@
Prop
({
type
:
Function
})
private
close
?:
()
=>
void
@
Provide
()
showReadSummary
=
true
@
Watch
(
"currentChatUniplatId"
)
private
whenCurrentChatIdChanged
(
newValue
:
string
,
oldValue
:
string
)
{
if
(
Number
(
oldValue
)
===
Number
(
newValue
))
return
this
.
hideMembers
()
this
.
clearChatMembers
()
if
(
Number
(
oldValue
)
===
Number
(
newValue
))
return
;
this
.
hideMembers
()
;
this
.
clearChatMembers
()
;
}
private
activeTab
:
RoomInfoTab
=
"customer"
...
...
@@ -141,38 +148,41 @@ export default class ChatRoom extends Vue {
private
get
getCurrentInputingPeople
()
{
return
this
.
currentInputPeople
.
map
((
k
)
=>
""
/* this.userInfo[k].name */
)
.
join
(
"、"
)
.
join
(
"、"
)
;
}
private
get
currentChat
()
{
const
chatId
=
this
.
currentChatUniplatId
let
result
=
this
.
myChatList
.
list
.
find
((
k
)
=>
k
.
uniplatId
===
chatId
)
if
(
result
)
return
result
result
=
this
.
allChatList
.
list
.
find
((
k
)
=>
k
.
uniplatId
===
chatId
)
return
result
??
{}
const
chatId
=
this
.
currentChatUniplatId
;
let
result
=
this
.
myChatList
.
list
.
find
((
k
)
=>
k
.
uniplatId
===
chatId
)
;
if
(
result
)
return
result
;
result
=
this
.
allChatList
.
list
.
find
((
k
)
=>
k
.
uniplatId
===
chatId
)
;
return
result
??
{}
;
}
private
get
notOnlyCheck
():
boolean
{
return
true
return
true
;
}
private
get
customerInfoTabShow
()
{
return
this
.
activeTab
===
"customer"
return
this
.
activeTab
===
"customer"
;
}
private
get
orderInfoTabShow
()
{
return
this
.
activeTab
===
"order"
return
this
.
activeTab
===
"order"
;
}
private
showMembers
()
{
this
.
membersPanelVisibility
=
!
this
.
membersPanelVisibility
this
.
membersPanelVisibility
=
!
this
.
membersPanelVisibility
;
}
private
hideMembers
()
{
this
.
membersPanelVisibility
=
false
this
.
membersPanelVisibility
=
false
;
}
private
onError
(
msg
:
string
)
{
console
.
error
(
msg
)
this
.
$message
.
error
(
msg
)
// eslint-disable-next-line no-console
console
.
error
(
msg
);
this
.
$message
.
error
(
msg
);
}
}
</
script
>
...
...
chat.vue
View file @
03c9c8d6
...
...
@@ -19,11 +19,13 @@
</el-dialog>
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Vue
}
from
"vue-property-decorator"
import
MessageList
from
"./message-list.vue"
import
ChatRoom
from
"./chat-room.vue"
import
ChatList
from
"./chat-list.vue"
import
{
ChatStore
,
chatStore
}
from
"@/customer-service/store/model"
import
{
Component
,
Vue
}
from
"vue-property-decorator"
;
import
ChatList
from
"./chat-list.vue"
;
import
ChatRoom
from
"./chat-room.vue"
;
import
MessageList
from
"./message-list.vue"
;
import
{
ChatStore
,
chatStore
}
from
"@/customer-service/store/model"
;
@
Component
({
components
:
{
MessageList
,
ChatRoom
,
ChatList
}
})
export
default
class
Chat
extends
Vue
{
...
...
@@ -32,13 +34,15 @@ export default class Chat extends Vue {
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_DIALOG_VISIBLE
)
private
readonly
visible
:
ChatStore
.
STATE_CHAT_DIALOG_VISIBLE
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_HIDE_CHAT
)
private
readonly
hide
:
ChatStore
.
MUTATION_HIDE_CHAT
@
chatStore
.
Action
(
ChatStore
.
ACTION_TERINATE_CHAT
)
private
readonly
_terminate
:
ChatStore
.
ACTION_TERINATE_CHAT
private
terminate
()
{
this
.
_terminate
()
this
.
_terminate
()
;
}
}
</
script
>
...
...
components/file-icon.vue
View file @
03c9c8d6
...
...
@@ -3,9 +3,10 @@
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Vue
}
from
"vue-property-decorator"
import
{
Model
}
from
"vue-property-decorator"
import
{
FileType
,
getSvg
}
from
"./file-controller"
import
{
Component
,
Model
,
Vue
}
from
"vue-property-decorator"
;
import
{
FileType
,
getSvg
}
from
"./file-controller"
;
@
Component
({
components
:
{}
})
export
default
class
FileIcon
extends
Vue
{
...
...
@@ -13,55 +14,55 @@ export default class FileIcon extends Vue {
private
value
!
:
FileType
private
get
audio
()
{
return
this
.
value
===
FileType
.
Audio
return
this
.
value
===
FileType
.
Audio
;
}
private
get
excel
()
{
return
this
.
value
===
FileType
.
Excel
return
this
.
value
===
FileType
.
Excel
;
}
private
get
image
()
{
return
this
.
value
===
FileType
.
Image
return
this
.
value
===
FileType
.
Image
;
}
private
get
others
()
{
return
this
.
value
===
FileType
.
Others
return
this
.
value
===
FileType
.
Others
;
}
private
get
pdf
()
{
return
this
.
value
===
FileType
.
Pdf
return
this
.
value
===
FileType
.
Pdf
;
}
private
get
ppt
()
{
return
this
.
value
===
FileType
.
Ppt
return
this
.
value
===
FileType
.
Ppt
;
}
private
get
rp
()
{
return
this
.
value
===
FileType
.
Rp
return
this
.
value
===
FileType
.
Rp
;
}
private
get
txt
()
{
return
this
.
value
===
FileType
.
Txt
return
this
.
value
===
FileType
.
Txt
;
}
private
get
video
()
{
return
this
.
value
===
FileType
.
Video
return
this
.
value
===
FileType
.
Video
;
}
private
get
word
()
{
return
this
.
value
===
FileType
.
Word
return
this
.
value
===
FileType
.
Word
;
}
private
get
xmid
()
{
return
this
.
value
===
FileType
.
Xmind
return
this
.
value
===
FileType
.
Xmind
;
}
private
get
zip
()
{
return
this
.
value
===
FileType
.
Zip
return
this
.
value
===
FileType
.
Zip
;
}
private
get
html
()
{
return
getSvg
(
this
.
value
)
return
getSvg
(
this
.
value
)
;
}
}
</
script
>
...
...
components/image-preview.vue
View file @
03c9c8d6
...
...
@@ -31,7 +31,7 @@
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Vue
,
Model
,
Prop
}
from
"vue-property-decorator"
import
{
Component
,
Model
,
Prop
,
Vue
}
from
"vue-property-decorator"
;
@
Component
({
components
:
{}
})
export
default
class
ImagePreview
extends
Vue
{
...
...
@@ -42,8 +42,8 @@ export default class ImagePreview extends Vue {
private
file
!
:
{
name
:
string
;
url
:
string
}
private
style
:
{
"max-height"
:
number
|
string
"max-width"
:
number
|
string
"max-height"
:
number
|
string
;
"max-width"
:
number
|
string
;
}
=
{
"max-height"
:
"300px"
,
"max-width"
:
"600px"
,
...
...
@@ -54,19 +54,19 @@ export default class ImagePreview extends Vue {
()
=>
(
this
.
style
=
{
"max-height"
:
"300px"
,
"max-width"
:
"600px"
}),
300
)
this
.
$emit
(
"update"
,
false
)
)
;
this
.
$emit
(
"update"
,
false
)
;
}
private
set2Default
()
{
this
.
style
=
{
"max-height"
:
"1600px"
,
"max-width"
:
"1600px"
}
this
.
style
=
{
"max-height"
:
"1600px"
,
"max-width"
:
"1600px"
}
;
}
private
get
getAttachment
()
{
if
(
this
.
file
)
{
return
this
.
file
.
name
return
this
.
file
.
name
;
}
return
"文件下载"
return
"文件下载"
;
}
}
</
script
>
...
...
components/message.vue
View file @
03c9c8d6
This diff is collapsed.
Click to expand it.
components/video-player-icon.vue
View file @
03c9c8d6
...
...
@@ -30,7 +30,7 @@
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Vue
}
from
"vue-property-decorator"
import
{
Component
,
Vue
}
from
"vue-property-decorator"
;
@
Component
({
components
:
{}
})
export
default
class
VideoPlayerIcon
extends
Vue
{}
...
...
components/video-preview.vue
View file @
03c9c8d6
...
...
@@ -37,7 +37,7 @@
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Vue
,
Model
,
Prop
,
Ref
,
Watch
}
from
"vue-property-decorator"
import
{
Component
,
Model
,
Prop
,
Ref
,
Vue
,
Watch
}
from
"vue-property-decorator"
;
@
Component
({
components
:
{}
})
export
default
class
VideoPreview
extends
Vue
{
...
...
@@ -51,8 +51,8 @@ export default class VideoPreview extends Vue {
private
video
!
:
HTMLVideoElement
private
style
:
{
"max-height"
:
number
|
string
"max-width"
:
number
|
string
"max-height"
:
number
|
string
;
"max-width"
:
number
|
string
;
}
=
{
"max-height"
:
"800px"
,
"max-width"
:
"800px"
,
...
...
@@ -63,28 +63,28 @@ export default class VideoPreview extends Vue {
()
=>
(
this
.
style
=
{
"max-height"
:
"300px"
,
"max-width"
:
"600px"
}),
300
)
this
.
$emit
(
"update"
,
false
)
)
;
this
.
$emit
(
"update"
,
false
)
;
}
private
set2Default
()
{
this
.
style
=
{
"max-height"
:
"1600px"
,
"max-width"
:
"1600px"
}
this
.
style
=
{
"max-height"
:
"1600px"
,
"max-width"
:
"1600px"
}
;
}
private
get
getAttachment
()
{
if
(
this
.
file
)
{
return
this
.
file
.
name
return
this
.
file
.
name
;
}
return
"视频下载"
return
"视频下载"
;
}
@
Watch
(
"value"
)
private
onOpen
()
{
if
(
this
.
value
)
{
this
.
video
?.
load
()
setTimeout
(()
=>
this
.
video
?.
play
(),
100
)
this
.
video
?.
load
()
;
setTimeout
(()
=>
this
.
video
?.
play
(),
100
)
;
}
else
{
this
.
video
?.
pause
()
this
.
video
?.
pause
()
;
}
}
}
...
...
components/voice.vue
View file @
03c9c8d6
...
...
@@ -32,9 +32,9 @@
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Vue
}
from
"vue-property-decorator"
import
{
Prop
}
from
"vue-property-decorator"
import
{
Watch
}
from
"vue-property-decorator"
import
{
Component
,
Prop
,
Vue
,
Watch
}
from
"vue-property-decorator"
;
@
Component
({
components
:
{}
})
export
default
class
VoiceIcon
extends
Vue
{
...
...
@@ -51,21 +51,21 @@ export default class VoiceIcon extends Vue {
private
onLoadingChanged
()
{
if
(
this
.
loading
)
{
this
.
interval
=
window
.
setInterval
(()
=>
{
const
v
=
this
.
status
+
1
const
v
=
this
.
status
+
1
;
if
(
v
>
3
)
{
this
.
status
=
0
this
.
status
=
0
;
}
else
{
this
.
status
=
v
this
.
status
=
v
;
}
},
500
)
},
500
)
;
}
else
{
clearInterval
(
this
.
interval
)
this
.
status
=
0
clearInterval
(
this
.
interval
)
;
this
.
status
=
0
;
}
}
beforeDestroy
()
{
clearInterval
(
this
.
interval
)
clearInterval
(
this
.
interval
)
;
}
}
</
script
>
components/who-read-list.vue
View file @
03c9c8d6
...
...
@@ -41,19 +41,21 @@
</div>
</template>
<
script
lang=
"ts"
>
import
{
Component
,
Vue
,
Prop
,
Ref
}
from
"vue-property-decorator"
import
{
namespace
}
from
"vuex-class"
import
{
ChatStore
}
from
"@/customer-service/store/model"
import
xim
from
"@/customer-service/xim/xim"
import
{
unique
}
from
"../utils"
import
chat
from
"../xim"
import
*
as
dto
from
"../model"
import
{
Component
,
Prop
,
Ref
,
Vue
}
from
"vue-property-decorator"
;
import
{
namespace
}
from
"vuex-class"
;
const
chatStoreNamespace
=
namespace
(
"chatStore"
)
import
*
as
dto
from
"../model"
;
import
{
unique
}
from
"../utils"
;
import
{
ChatStore
}
from
"@/customer-service/store/model"
;
import
xim
from
"@/customer-service/xim/xim"
;
const
chatStoreNamespace
=
namespace
(
"chatStore"
);
@
Component
({
components
:
{}
})
export
default
class
WhoReadList
extends
Vue
{
@
chatStoreNamespace
.
State
(
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
)
private
readonly
chatId
!
:
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
@
chatStoreNamespace
.
State
(
ChatStore
.
STATE_CHAT_MY_ID
)
private
readonly
chatMyId
!
:
ChatStore
.
STATE_CHAT_MY_ID
...
...
@@ -61,6 +63,7 @@ export default class WhoReadList extends Vue {
type
:
Number
,
})
private
msgId
!
:
number
@
Ref
(
"list-con"
)
private
listCon
!
:
HTMLElement
...
...
@@ -70,74 +73,79 @@ export default class WhoReadList extends Vue {
private
unreadlist
:
{
name
:
string
;
avatar
:
string
}[]
=
[]
private
loading
=
false
private
startLoading
()
{
this
.
loading
=
true
this
.
loading
=
true
;
}
private
endLoading
()
{
this
.
loading
=
false
this
.
loading
=
false
;
}
public
async
created
()
{
this
.
startLoading
()
await
this
.
getReader
()
this
.
endLoading
()
this
.
startLoading
()
;
await
this
.
getReader
()
;
this
.
endLoading
()
;
}
public
mounted
()
{
this
.
enableBlur
()
this
.
enableBlur
()
;
const
{
top
,
left
}
=
(
this
.
listCon
.
parentNode
as
HTMLElement
).
getBoundingClientRect
()
this
.
top
=
top
this
.
left
=
left
).
getBoundingClientRect
()
;
this
.
top
=
top
;
this
.
left
=
left
;
}
private
enableBlur
()
{
this
.
listCon
.
setAttribute
(
"tabindex"
,
"-1"
)
this
.
listCon
.
focus
()
this
.
listCon
.
setAttribute
(
"tabindex"
,
"-1"
)
;
this
.
listCon
.
focus
()
;
}
private
async
getUserNameByid
(
eid
:
string
)
{
const
data
=
await
this
.
sdk
.
model
(
"user"
).
detail
(
eid
).
query
()
return
data
.
row
.
first_name
.
value
as
string
const
data
=
await
this
.
sdk
.
model
(
"user"
).
detail
(
eid
).
query
()
;
return
data
.
row
.
first_name
.
value
as
string
;
}
private
async
getReader
()
{
if
(
this
.
chatId
==
null
)
return
if
(
this
.
msgId
==
null
)
return
const
userInfo
=
chat
.
getUserMapping
()
const
data
=
await
xim
.
fetchMsgInBox
(
this
.
chatId
,
this
.
msgId
)
if
(
this
.
chatId
==
null
)
return
;
if
(
this
.
msgId
==
null
)
return
;
const
data
=
await
xim
.
fetchMsgInBox
(
this
.
chatId
,
this
.
msgId
);
const
readerlist
=
this
.
uniqueReaderList
(
data
.
args
[
0
]
as
dto
.
OneWhoReadMessage
[]
)
)
;
this
.
readlist
=
await
Promise
.
all
(
readerlist
.
filter
((
k
)
=>
k
.
is_read
)
.
filter
((
k
)
=>
k
.
eid
!==
this
.
chatMyId
)
.
map
(
async
(
k
)
=>
{
const
eid
=
k
.
eid
const
name
=
await
this
.
getUserNameByid
(
eid
)
const
eid
=
k
.
eid
;
const
name
=
await
this
.
getUserNameByid
(
eid
)
;
return
{
eid
,
name
,
avatar
:
""
,
}
}
;
})
)
)
;
this
.
unreadlist
=
await
Promise
.
all
(
readerlist
.
filter
((
k
)
=>
!
k
.
is_read
)
.
filter
((
k
)
=>
k
.
eid
!==
this
.
chatMyId
)
.
map
(
async
(
k
)
=>
{
const
eid
=
k
.
eid
const
name
=
await
this
.
getUserNameByid
(
eid
)
const
eid
=
k
.
eid
;
const
name
=
await
this
.
getUserNameByid
(
eid
)
;
return
{
eid
,
name
,
avatar
:
""
,
}
}
;
})
)
)
;
}
private
uniqueReaderList
(
data
:
dto
.
OneWhoReadMessage
[])
{
return
unique
(
data
,
function
(
item
,
all
)
{
return
all
.
findIndex
((
k
)
=>
k
.
eid
===
item
.
eid
)
})
return
all
.
findIndex
((
k
)
=>
k
.
eid
===
item
.
eid
)
;
})
;
}
}
</
script
>
...
...
hybrid-input/index.vue
View file @
03c9c8d6
...
...
@@ -237,7 +237,7 @@ export default class Input extends Vue {
}
}
else
{
promiseArr
.
push
(
new
Promise
<
void
>
((
res
lo
ve
)
=>
{
new
Promise
<
void
>
((
res
ol
ve
)
=>
{
const
contentType
=
items
[
i
].
type
;
items
[
i
].
getAsString
((
k
)
=>
{
/*
...
...
@@ -267,7 +267,7 @@ export default class Input extends Vue {
}
}
while
(
result
);
}
res
lo
ve
();
res
ol
ve
();
});
})
);
...
...
@@ -514,10 +514,6 @@ export default class Input extends Vue {
this
.
emojiPanelVisibility
=
false
;
}
private
noop
()
{
}
private
setupEmoji
()
{
EmojiService
.
onReady
(()
=>
{
const
service
=
new
EmojiService
();
...
...
message-input.vue
View file @
03c9c8d6
...
...
@@ -9,23 +9,26 @@
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Ref
,
Vue
,
Watch
}
from
"vue-property-decorator"
import
{
Component
,
Ref
,
Vue
,
Watch
}
from
"vue-property-decorator"
;
import
ChatInput
,
{
FILE_INFO_CLASS
,
isImageOrFile
,
}
from
"./hybrid-input/index.vue"
import
{
ChatStore
,
chatStore
}
from
"@/customer-service/store/model"
import
{
ChatLoggerService
}
from
"./xim/logger"
import
xim
from
"./xim/xim"
import
{
Message
}
from
"./model"
import
{
uploadFile
}
from
"./service/upload"
}
from
"./hybrid-input/index.vue"
;
import
{
Message
}
from
"./model"
;
import
{
uploadFile
}
from
"./service/upload"
;
import
{
ChatLoggerService
}
from
"./xim/logger"
;
import
xim
from
"./xim/xim"
;
import
{
ChatStore
,
chatStore
}
from
"@/customer-service/store/model"
;
let
sendingMessageIndex
=
1
let
sendingMessageIndex
=
1
;
@
Component
({
components
:
{
ChatInput
}
})
export
default
class
MessageInput
extends
Vue
{
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_DIALOG_VISIBLE
)
private
readonly
chatRoomVisible
:
ChatStore
.
STATE_CHAT_DIALOG_VISIBLE
@
chatStore
.
Action
(
ChatStore
.
ACTION_SEND_MESSAGE
)
private
readonly
sendMsg
!
:
ChatStore
.
ACTION_SEND_MESSAGE
...
...
@@ -55,44 +58,45 @@ export default class MessageInput extends Vue {
@
Watch
(
"chatRoomVisible"
)
private
whenChatRoomShow
()
{
if
(
!
this
.
chatRoomVisible
)
return
this
.
chatInput
.
focus
()
if
(
!
this
.
chatRoomVisible
)
return
;
this
.
chatInput
.
focus
()
;
}
private
async
sendMessage
(
msg
:
ChildNode
[],
done
:
()
=>
void
)
{
if
(
this
.
chatIniting
)
{
return
return
;
}
for
(
const
item
of
msg
)
{
if
(
isImageOrFile
(
item
))
{
if
((
item
as
Element
).
classList
.
contains
(
FILE_INFO_CLASS
))
{
this
.
sendFile
(
item
,
"file"
)
this
.
sendFile
(
item
,
"file"
)
;
}
else
{
this
.
sendFile
(
item
,
"image"
)
this
.
sendFile
(
item
,
"image"
)
;
}
continue
continue
;
}
if
(
item
.
textContent
)
{
this
.
sendText
(
item
.
textContent
)
this
.
sendText
(
item
.
textContent
)
;
}
}
ChatLoggerService
.
logger
?.
debug
(
"all messages sent"
)
done
()
this
.
$emit
(
"sent"
)
ChatLoggerService
.
logger
?.
debug
(
"all messages sent"
)
;
done
()
;
this
.
$emit
(
"sent"
)
;
}
private
async
onInput
()
{
if
(
this
.
chatId
==
null
)
return
await
xim
.
inputing
(
this
.
chatId
)
if
(
this
.
chatId
==
null
)
return
;
await
xim
.
inputing
(
this
.
chatId
)
;
}
private
sendText
(
text
:
string
)
{
if
(
text
&&
text
.
trim
())
{
const
msg
=
{
text
:
text
.
trim
()
}
const
msg
=
{
text
:
text
.
trim
()
}
;
if
(
this
.
source
)
{
Object
.
assign
(
msg
,
{
source
:
this
.
source
})
Object
.
assign
(
msg
,
{
source
:
this
.
source
})
;
}
this
.
sendMsg
({
msgType
:
"text"
,
msg
:
JSON
.
stringify
(
msg
)
})
this
.
sendMsg
({
msgType
:
"text"
,
msg
:
JSON
.
stringify
(
msg
)
})
;
}
}
...
...
@@ -100,24 +104,24 @@ export default class MessageInput extends Vue {
const
src
=
JSON
.
parse
(
file
.
attributes
[
`data-
${
type
}
`
]?.
value
||
""
)
as
{
url
:
string
name
:
string
size
:
number
}
url
:
string
;
name
:
string
;
size
:
number
;
}
;
if
(
src
)
{
const
index
=
this
.
sendSendingMessage
(
type
,
src
)
const
file
=
await
this
.
readBlobUrl2Base64
(
src
.
url
,
src
.
name
)
const
index
=
this
.
sendSendingMessage
(
type
,
src
)
;
const
file
=
await
this
.
readBlobUrl2Base64
(
src
.
url
,
src
.
name
)
;
if
(
file
)
{
let
w
=
0
let
h
=
0
let
w
=
0
;
let
h
=
0
;
if
(
type
===
"image"
)
{
const
img
=
new
Image
()
img
.
src
=
src
.
url
const
img
=
new
Image
()
;
img
.
src
=
src
.
url
;
img
.
onload
=
function
()
{
w
=
img
.
naturalWidth
h
=
img
.
naturalHeight
}
img
.
remove
()
w
=
img
.
naturalWidth
;
h
=
img
.
naturalHeight
;
}
;
img
.
remove
()
;
}
uploadFile
(
file
,
this
.
chatId
||
0
,
w
,
h
)
.
then
((
r
)
=>
{
...
...
@@ -126,42 +130,43 @@ export default class MessageInput extends Vue {
url
:
r
,
name
:
file
.
name
,
size
:
file
.
size
,
}
}
;
if
(
this
.
source
)
{
Object
.
assign
(
msg
,
{
source
:
this
.
source
})
Object
.
assign
(
msg
,
{
source
:
this
.
source
})
;
}
if
(
w
&&
h
)
{
Object
.
assign
(
msg
,
{
w
,
h
})
Object
.
assign
(
msg
,
{
w
,
h
})
;
}
this
.
sendMsg
({
msgType
:
type
,
msg
:
JSON
.
stringify
(
msg
),
})
this
.
removeSendingMessages
(
index
)
URL
.
revokeObjectURL
(
src
.
url
)
})
;
this
.
removeSendingMessages
(
index
)
;
URL
.
revokeObjectURL
(
src
.
url
)
;
}
else
{
this
.
setMsg2Failed
(
index
)
this
.
setMsg2Failed
(
index
)
;
}
})
.
catch
((
e
)
=>
{
console
.
error
(
e
)
// eslint-disable-next-line no-console
console
.
error
(
e
);
this
.
setMsg2Failed
(
index
)
})
this
.
setMsg2Failed
(
index
)
;
})
;
}
}
}
private
setMsg2Failed
(
index
:
number
)
{
this
.
failedSendingMessage
(
index
)
this
.
failedSendingMessage
(
index
)
;
}
private
sendSendingMessage
(
type
:
string
,
msg
:
any
)
{
const
index
=
sendingMessageIndex
++
const
index
=
sendingMessageIndex
++
;
if
(
this
.
source
)
{
Object
.
assign
(
msg
,
{
source
:
this
.
source
,
eid
:
this
.
chatMyId
})
Object
.
assign
(
msg
,
{
source
:
this
.
source
,
eid
:
this
.
chatMyId
})
;
}
if
(
this
.
chatId
)
{
this
.
appendSendingMessages
({
...
...
@@ -170,20 +175,20 @@ export default class MessageInput extends Vue {
ts
:
Date
.
now
(),
type
,
msg
:
JSON
.
stringify
(
msg
),
}
as
Message
)
return
-
index
}
as
Message
)
;
return
-
index
;
}
return
0
return
0
;
}
private
readBlobUrl2Base64
(
url
:
string
,
name
:
string
)
{
return
fetch
(
url
)
.
then
((
r
)
=>
r
.
blob
())
.
then
((
blob
)
=>
new
File
([
blob
],
name
))
.
then
((
blob
)
=>
new
File
([
blob
],
name
))
;
}
private
onError
(
e
:
any
)
{
this
.
$emit
(
"error"
,
e
.
message
||
e
)
this
.
$emit
(
"error"
,
e
.
message
||
e
)
;
}
}
</
script
>
message-list.vue
View file @
03c9c8d6
This diff is collapsed.
Click to expand it.
store/index.ts
View file @
03c9c8d6
import
{
RootStoreState
}
from
"@/store/model"
;
import
{
Module
}
from
"vuex"
;
import
{
ChatMember
}
from
"../model"
;
...
...
@@ -5,28 +6,25 @@ import { isAccessibleUrl } from "../service/tools";
import
{
unique
}
from
"../utils"
;
import
{
decode
}
from
"../utils/jwt"
;
import
Chat
from
"../xim"
;
import
chat
from
"../xim/"
;
import
chatType
from
"../xim/chat-type"
;
import
xim
,
{
ChatNotifyListener
}
from
"../xim/xim"
;
import
{
ChatMemberType
,
ChatStatus
,
ChatStore
,
ChatStoreState
}
from
"./model"
;
import
{
RootStoreState
}
from
"@/store/model"
;
export
const
ns
=
ChatStore
.
ns
;
const
sdk
=
c
hat
.
getSdk
;
const
sdk
=
C
hat
.
getSdk
;
const
UniplatChatModelName
=
"UniplatChat"
;
const
model
=
()
=>
sdk
().
model
(
UniplatChatModelName
);
const
orgId
=
c
hat
.
getOrgId
;
const
getMyinfo
=
(
function
()
{
let
data
;
return
async
()
=>
{
if
(
data
!=
null
)
return
data
;
data
=
sdk
().
getUserInfo
();
return
data
;
};
})();
const
orgId
=
C
hat
.
getOrgId
;
//
const getMyinfo = (function () {
//
let data;
//
return async () => {
//
if (data != null) return data;
//
data = sdk().getUserInfo();
//
return data;
//
};
//
})();
function
uniqueMessages
(
messages
:
NonNullable
<
ChatStore
.
STATE_CHAT_MSG_HISTORY
>
)
{
...
...
@@ -49,23 +47,23 @@ const removeRegisterChatEvents: (() => void)[] = [];
async
function
preCacheImgs
(
msgs
:
any
[])
{
await
Promise
.
all
(
msgs
.
map
((
k
)
=>
{
return
new
Promise
((
don
e
:
(
p
:
void
)
=>
void
)
=>
{
return
new
Promise
((
resolv
e
:
(
p
:
void
)
=>
void
)
=>
{
if
(
k
.
type
===
"image"
)
{
const
msg
=
JSON
.
parse
(
k
.
msg
);
const
url
=
msg
.
url
;
if
(
!
isAccessibleUrl
(
url
))
{
don
e
();
resolv
e
();
}
if
(
url
&&
isAccessibleUrl
(
url
))
{
const
preCache
=
new
Image
();
preCache
.
src
=
url
;
preCache
.
onload
=
()
=>
don
e
();
setTimeout
(
don
e
,
2000
);
preCache
.
onload
=
()
=>
resolv
e
();
setTimeout
(
resolv
e
,
2000
);
}
else
{
don
e
();
resolv
e
();
}
}
else
{
don
e
();
resolv
e
();
}
});
})
...
...
@@ -291,7 +289,7 @@ export default {
actions
:
{
async
[
ChatStore
.
ACTION_GET_MY_CHAT_LIST
](
{
commit
},
...
params
:
Parameters
<
ChatStore
.
ACTION_GET_MY_CHAT_LIST
>
//
...params: Parameters<ChatStore.ACTION_GET_MY_CHAT_LIST>
)
{
const
{
pageData
}
=
await
model
().
list
().
query
({
pageIndex
:
1
,
...
...
@@ -316,12 +314,12 @@ export default {
total
:
pageData
.
record_count
,
});
},
async
[
ChatStore
.
ACTION_JOIN_CHAT
](
{
commit
},
chatId
:
Parameters
<
ChatStore
.
ACTION_JOIN_CHAT
>
[
0
]
)
{
// return await XimService.getInstance().joinChat(chatId)
},
//
async [ChatStore.ACTION_JOIN_CHAT](
//
{ commit },
//
chatId: Parameters<ChatStore.ACTION_JOIN_CHAT>[0]
//
) {
//
// return await XimService.getInstance().joinChat(chatId)
//
},
async
[
ChatStore
.
ACTION_GET_CHAT_MESSAGES
]({
state
,
commit
})
{
const
chatId
=
state
[
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
];
if
(
chatId
==
null
)
return
;
...
...
@@ -332,6 +330,7 @@ export default {
commit
(
ChatStore
.
MUTATION_SCROLL_TO_BOTTOM
);
return
data
;
}
catch
(
error
)
{
// eslint-disable-next-line no-console
console
.
error
(
error
);
}
},
...
...
@@ -379,6 +378,7 @@ export default {
await
dispatch
(
ChatStore
.
ACTION_GET_FRESH_MESSAGE
);
return
data
;
}
catch
(
error
)
{
// eslint-disable-next-line no-console
console
.
error
(
"testing 信息发送失败"
,
error
);
}
},
...
...
@@ -397,7 +397,7 @@ export default {
msgs
[
msgs
.
length
-
1
].
id
);
}
const
lastMsg
=
newMsgsArr
[
newMsgsArr
.
length
-
1
];
//
const lastMsg = newMsgsArr[newMsgsArr.length - 1];
await
preCacheImgs
(
newMsgsArr
);
commit
(
ChatStore
.
MUTATION_SCROLL_TO_BOTTOM
);
},
...
...
@@ -432,7 +432,7 @@ export default {
detailManager
.
done
();
const
{
id
}
=
await
action
.
dryExecute
();
// 无法得到chat id
const
data
=
await
sdk
()
await
sdk
()
.
model
(
UniplatChatModelName
)
.
action
(
"createXimChat"
)
.
updateInitialParams
({
...
...
@@ -451,13 +451,13 @@ export default {
uniplatId
:
newChat
.
uniplatId
,
});
},
async
[
ChatStore
.
ACTION_CREATE_NEW_CHAT_BY_CLIENT_SIDE
](
{
commit
,
dispatch
},
option
:
{
customerServiceId
?:
number
|
string
;
customerServiceGroupId
?:
number
;
}
)
{},
//
async [ChatStore.ACTION_CREATE_NEW_CHAT_BY_CLIENT_SIDE](
//
{ commit, dispatch },
//
option: {
//
customerServiceId?: number | string;
//
customerServiceGroupId?: number;
//
}
//
) {},
async
[
ChatStore
.
ACTION_REGISTER_EVENT
]({
dispatch
,
commit
,
state
})
{
const
chatId
=
state
[
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
];
if
(
chatId
==
null
)
return
;
...
...
@@ -471,7 +471,6 @@ export default {
)
{
return
;
}
console
.
log
(
"事件消息已读"
,
e
);
if
(
chatId
!==
e
.
chat_id
)
return
;
const
msgs
=
state
[
ChatStore
.
STATE_CHAT_MSG_HISTORY
];
if
(
msgs
==
null
)
return
;
...
...
@@ -554,6 +553,7 @@ export default {
phone
:
info
.
row
.
last_name
.
value
as
string
,
};
}
catch
(
error
)
{
// eslint-disable-next-line no-console
console
.
error
(
error
);
result
=
member
;
}
...
...
third-party/image/index.ts
View file @
03c9c8d6
...
...
@@ -25,14 +25,14 @@ export class ImageCompresser {
maxWidth
:
number
,
maxHeight
:
number
):
Promise
<
File
|
null
>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
return
new
Promise
<
File
>
((
resolve
,
reject
)
=>
{
const
img
=
new
Image
();
const
reader
=
new
FileReader
();
reader
.
onload
=
(
e
)
=>
{
if
(
e
&&
e
.
target
&&
e
.
target
.
result
)
{
img
.
src
=
e
.
target
.
result
as
string
;
}
else
{
reject
();
reject
(
new
Error
(
"file load failed"
)
);
}
};
reader
.
readAsDataURL
(
file
);
...
...
@@ -49,7 +49,7 @@ export class ImageCompresser {
newFile
.
size
<=
file
.
size
?
newFile
:
file
);
}
else
{
reject
();
reject
(
new
Error
(
"file load failed"
)
);
}
})
.
catch
(
reject
);
...
...
@@ -77,7 +77,7 @@ export class ImageCompresser {
const
canvas
=
document
.
createElement
(
"canvas"
);
const
context
=
canvas
.
getContext
(
"2d"
);
if
(
!
context
)
{
reject
();
reject
(
new
Error
(
" compress image failed"
)
);
return
;
}
const
{
width
:
originWidth
,
height
:
originHeight
}
=
img
;
// 最大尺寸限制
...
...
utils/jwt/index.ts
View file @
03c9c8d6
...
...
@@ -22,7 +22,7 @@ function base64_url_decode(str: string) {
output
+=
"="
;
break
;
default
:
throw
"Illegal base64url string!"
;
throw
new
Error
(
"Illegal base64url string!"
)
;
}
try
{
...
...
xim/index.ts
View file @
03c9c8d6
...
...
@@ -8,14 +8,14 @@ import tokenManager from "./token";
import
xim
from
"./xim"
;
class
Chat
{
private
_sdk
?:
()
=>
UniplatSdk
private
_orgId
:
()
=>
string
|
number
=
()
=>
"0"
private
token
!
:
TokenStringGetter
private
_sdk
?:
()
=>
UniplatSdk
;
private
_orgId
:
()
=>
string
|
number
=
()
=>
"0"
;
private
token
!
:
TokenStringGetter
;
private
userMapping
:
{
[
key
:
string
]:
{
name
:
string
;
avatar
:
string
}
}
=
{}
{}
;
private
webHost
=
false
private
webHost
=
false
;
public
async
setup
(
option
:
ChatOption
)
{
if
(
!
option
)
{
...
...
@@ -46,11 +46,11 @@ class Chat {
public
getSdk
=
()
=>
{
if
(
this
.
_sdk
==
null
)
return
;
return
this
.
_sdk
();
}
}
;
public
getOrgId
=
()
=>
{
return
this
.
_orgId
();
}
}
;
public
isWebHost
()
{
return
this
.
webHost
;
...
...
xim/logger.ts
View file @
03c9c8d6
import
{
ChatServiceLogger
}
from
"../model"
;
export
class
ChatLoggerService
{
public
static
logger
=
console
...
...
xim/models/user.ts
View file @
03c9c8d6
...
...
@@ -4,10 +4,11 @@ export enum UserType {
Customer
,
// 客户
}
export
default
interface
User
{
type
User
=
{
uid
:
string
;
oid
:
string
;
eid
:
string
;
jwt
:
string
;
userType
:
UserType
;
};;;;;;;;;;
};
export
default
User
;
xim/token.ts
View file @
03c9c8d6
import
{
ChatOption
,
TokenStringGetter
}
from
"./../model"
;
import
{
TokenStringGetter
}
from
"./../model"
;
function
Token
()
{
let
_token
:
TokenStringGetter
;
return
{
...
...
xim/xim.ts
View file @
03c9c8d6
...
...
@@ -12,7 +12,7 @@ wampDebug(true);
const
DefaultMsgPageSize
=
20
;
function
emptyFunc
()
{
return
null
;
}
export
type
MsgListener
=
(
msg
:
Message
)
=>
void
...
...
@@ -58,7 +58,7 @@ export class Xim {
public
async
open
(
url
:
string
,
token
:
TokenStringGetter
)
{
this
.
connectionPending
=
true
;
await
new
Promise
((
success
:
(
p
?:
unknown
)
=>
void
,
failed
)
=>
{
await
new
Promise
((
resolve
:
(
p
?:
unknown
)
=>
void
,
reject
)
=>
{
this
.
paramsForReconnection
=
{
url
,
token
};
this
.
close
();
...
...
@@ -67,15 +67,15 @@ export class Xim {
this
.
client
=
client
;
client
.
onstatuschange
=
(
status
:
any
,
details
:
any
)
=>
{
this
.
onStatusChange
.
call
(
this
,
status
,
details
);
this
.
onStatusChange
(
status
,
details
);
if
(
status
===
"DISCONNECTED"
||
status
===
"CLOSED"
)
{
failed
(
);
reject
(
status
);
}
};
client
.
onconnected
=
()
=>
{
this
.
onConnected
.
apply
(
this
);
success
();
resolve
();
};
client
.
onmsg
=
this
.
handleMsg
.
bind
(
this
);
...
...
@@ -92,15 +92,16 @@ export class Xim {
* token过期或者切换用户登录时,需要设置新的token
*/
public
async
setToken
(
token
:
TokenStringGetter
)
{
const
client
=
this
.
client
!
;
const
client
=
this
.
client
;
if
(
client
==
null
)
return
;
client
.
close
();
client
.
setToken
(
this
.
trimToken
(
await
token
()));
client
.
open
();
}
public
fetchMsgInBox
(
chatId
:
number
,
msgId
:
number
)
{
return
this
.
client
!
.
fetchMsgInBox
(
chatType
,
chatId
,
msgId
);
if
(
this
.
client
==
null
)
return
;
return
this
.
client
.
fetchMsgInBox
(
chatType
,
chatId
,
msgId
);
}
/**
...
...
@@ -113,13 +114,14 @@ export class Xim {
msg
:
string
)
{
this
.
checkConnected
();
return
this
.
client
!
.
sendMsg
(
chatType
,
chatId
,
msgType
,
msg
,
""
,
{});
if
(
this
.
client
==
null
)
return
;
return
this
.
client
.
sendMsg
(
chatType
,
chatId
,
msgType
,
msg
,
""
,
{});
}
public
inputing
(
chatId
:
number
)
{
this
.
checkConnected
();
return
this
.
client
!
.
userInput
(
chatType
,
chatId
);
if
(
this
.
client
==
null
)
return
;
return
this
.
client
.
userInput
(
chatType
,
chatId
);
}
/*
...
...
@@ -127,8 +129,8 @@ export class Xim {
*/
public
fetchChatMembers
(
chat_id
:
number
)
{
this
.
checkConnected
();
return
this
.
client
!
.
fetchChatMembers
(
chat_id
);
if
(
this
.
client
==
null
)
return
;
return
this
.
client
.
fetchChatMembers
(
chat_id
);
}
/**
...
...
@@ -143,7 +145,8 @@ export class Xim {
desc
=
true
):
Promise
<
Message
[]
>
{
this
.
checkConnected
();
const
res
=
await
this
.
client
!
.
fetchChatMsgs
(
chatType
,
chatId
,
{
if
(
this
.
client
==
null
)
return
;
const
res
=
await
this
.
client
.
fetchChatMsgs
(
chatType
,
chatId
,
{
lid
,
rid
,
limit
,
...
...
@@ -283,8 +286,9 @@ export class Xim {
}
private
onConnected
()
{
if
(
this
.
client
==
null
)
return
;
// 连接成功后,需要调用pubUserInfo, 否则服务端会认为此连接无效
this
.
client
!
.
pubUserInfo
(
""
);
this
.
client
.
pubUserInfo
(
""
);
this
.
debug
(
"xim connected"
);
}
...
...
@@ -334,10 +338,12 @@ export class Xim {
}
private
checkConnected
()
{
if
(
!
this
.
client
!
.
connected
)
{
if
(
this
.
client
==
null
)
return
;
if
(
!
this
.
client
.
connected
)
{
try
{
this
.
client
?.
open
();
}
catch
(
e
)
{
// eslint-disable-next-line no-console
console
.
error
(
"checkConnected"
,
e
);
this
.
reOpen
();
}
...
...
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