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
39bbc202
authored
Oct 21, 2021
by
Sixong.Zhu
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
cs
parent
474ad190
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
472 additions
and
470 deletions
components/chat-list.vue
components/controller/chat-list.ts
components/message-list.vue
service/upload.ts
components/chat-list.vue
View file @
39bbc202
...
...
@@ -53,198 +53,198 @@
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Prop
,
Ref
,
Vue
}
from
"vue-property-decorator"
;
import
Controller
from
"./controller/chat-list"
;
import
{
EVENTS
}
from
"@/EventConsts"
;
import
avatar
from
"@/customer-service/components/avatar.vue"
;
import
{
Chat
as
ChatType
}
from
"@/customer-service/xim/models/chat"
;
import
{
ServiceType
}
from
"../model"
;
import
xim
from
"@/customer-service/xim"
;
@
Component
({
components
:
{
avatar
}
})
export
default
class
ChatList
extends
Controller
{
private
searchKeyword
=
""
;
@
Prop
({
type
:
Number
,
default
:
-
1
})
private
selected
!
:
number
;
@
Ref
(
"scrollbar"
)
private
scrollbar
:
Vue
&
{
update
:
()
=>
void
};
private
unReadMsgCount
=
0
;
private
get
chatRooms
()
{
if
(
this
.
chatList
)
{
const
list
=
this
.
chatList
.
list
.
filter
((
chat
)
=>
chat
.
title
.
indexOf
(
this
.
searchKeyword
)
>
-
1
)
.
sort
((
x
,
y
)
=>
y
.
last_msg_ts
-
x
.
last_msg_ts
);
let
unReadMsgCount
=
0
;
list
.
filter
((
chat
)
=>
chat
.
unread_msg_count
>
0
).
forEach
((
chat
)
=>
{
unReadMsgCount
+=
chat
.
unread_msg_count
;
});
this
.
unReadMsgCount
=
unReadMsgCount
;
this
.
$emit
(
"list-count-update"
,
this
.
unReadMsgCount
);
xim
.
$emit
(
EVENTS
.
NewMsg
,
this
.
unReadMsgCount
);
return
list
;
import
{
Component
,
Prop
,
Ref
,
Vue
}
from
"vue-property-decorator"
;
import
Controller
from
"./controller/chat-list"
;
import
{
EVENTS
}
from
"@/EventConsts"
;
import
avatar
from
"@/customer-service/components/avatar.vue"
;
import
{
Chat
as
ChatType
}
from
"@/customer-service/xim/models/chat"
;
import
{
ServiceType
}
from
"../model"
;
import
xim
from
"@/customer-service/xim"
;
@
Component
({
components
:
{
avatar
}
})
export
default
class
ChatList
extends
Controller
{
private
searchKeyword
=
""
;
@
Prop
({
type
:
Number
,
default
:
-
1
})
private
selected
!
:
number
;
@
Ref
(
"scrollbar"
)
private
readonly
scrollbar
!
:
Vue
&
{
update
:
()
=>
void
};
private
unReadMsgCount
=
0
;
private
get
chatRooms
()
{
if
(
this
.
chatList
)
{
const
list
=
this
.
chatList
.
list
.
filter
((
chat
)
=>
chat
.
title
.
indexOf
(
this
.
searchKeyword
)
>
-
1
)
.
sort
((
x
,
y
)
=>
y
.
last_msg_ts
-
x
.
last_msg_ts
);
let
unReadMsgCount
=
0
;
list
.
filter
((
chat
)
=>
chat
.
unread_msg_count
>
0
).
forEach
((
chat
)
=>
{
unReadMsgCount
+=
chat
.
unread_msg_count
;
});
this
.
unReadMsgCount
=
unReadMsgCount
;
this
.
$emit
(
"list-count-update"
,
this
.
unReadMsgCount
);
xim
.
$emit
(
EVENTS
.
NewMsg
,
this
.
unReadMsgCount
);
return
list
;
}
return
[];
}
return
[];
}
private
isSelected
(
item
:
ChatType
)
{
if
(
this
.
chatId
)
{
return
item
.
chat_id
===
this
.
chatId
;
private
isSelected
(
item
:
ChatType
)
{
if
(
this
.
chatId
)
{
return
item
.
chat_id
===
this
.
chatId
;
}
return
this
.
selected
===
item
.
chat_id
;
}
return
this
.
selected
===
item
.
chat_id
;
}
async
created
()
{
await
this
.
getMyChatList
();
this
.
setSource
(
ServiceType
.
Backend
);
this
.
scrollbar
.
update
();
}
mounted
()
{
this
.
saveMyId
();
}
async
created
()
{
await
this
.
getMyChatList
();
this
.
setSource
(
ServiceType
.
Backend
);
this
.
scrollbar
.
update
();
}
public
async
search
(
searchKeyword
:
string
)
{
this
.
searchKeyword
=
searchKeyword
.
trim
();
}
mounted
(
)
{
this
.
saveMyId
();
}
private
async
goToChatRoom
(
data
:
ChatType
)
{
if
(
this
.
chatId
===
data
.
chat_id
)
{
this
.
showChat
();
return
;
public
async
search
(
searchKeyword
:
string
)
{
this
.
searchKeyword
=
searchKeyword
.
trim
();
}
await
this
.
saveChatId
(
data
.
chat_id
).
finally
(
this
.
raiseChatIdChanged
);
this
.
showChat
();
this
.
close
();
private
async
goToChatRoom
(
data
:
ChatType
)
{
if
(
this
.
chatId
===
data
.
chat_id
)
{
this
.
showChat
();
return
;
}
await
this
.
saveChatId
(
data
.
chat_id
).
finally
(
this
.
raiseChatIdChanged
);
if
(
data
.
unread_msg_count
>
0
)
{
data
.
unread_msg_count
=
0
;
this
.
showChat
();
this
.
close
();
if
(
data
.
unread_msg_count
>
0
)
{
data
.
unread_msg_count
=
0
;
}
}
}
private
raiseChatIdChanged
()
{
this
.
$emit
(
"change"
);
}
private
raiseChatIdChanged
()
{
this
.
$emit
(
"change"
);
}
private
close
()
{
this
.
$emit
(
"close"
);
}
private
close
()
{
this
.
$emit
(
"close"
);
}
private
goToDetail
(
model_name
:
string
,
keyvalue
:
string
)
{
this
.
$router
.
push
(
`/
${
this
.
$route
.
params
.
project
}
/
${
this
.
$route
.
params
.
entrance
}
/detail/
${
model_name
}
/key/
${
keyvalue
}
`
);
this
.
close
();
private
goToDetail
(
model_name
:
string
,
keyvalue
:
string
)
{
this
.
$router
.
push
(
`/
${
this
.
$route
.
params
.
project
}
/
${
this
.
$route
.
params
.
entrance
}
/detail/
${
model_name
}
/key/
${
keyvalue
}
`
);
this
.
close
();
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.chat-list-con
{
display
:
inline-block
;
width
:
25%
;
box-sizing
:
border-box
;
height
:
100%
;
border-right
:
1px
solid
#ddd
;
.title
{
padding-left
:
20px
;
line-height
:
59px
;
font-size
:
18px
;
border-bottom
:
1px
solid
#e1e1e1
;
}
}
.chat-list
{
text-align
:
center
;
}
.chat-list-scroll
{
height
:
100%
;
.empty
{
margin-top
:
100%
;
}
}
.keyword-input
{
width
:
90%
;
margin
:
15px
;
/deep/
.el-input__inner
{
font-size
:
13px
;
height
:
30px
;
line-height
:
30px
;
border-radius
:
15px
;
padding-right
:
15px
;
.chat-list-con
{
display
:
inline-block
;
width
:
25%
;
box-sizing
:
border-box
;
height
:
100%
;
border-right
:
1px
solid
#ddd
;
.title
{
padding-left
:
20px
;
line-height
:
59px
;
font-size
:
18px
;
border-bottom
:
1px
solid
#e1e1e1
;
}
}
/
deep
/
.el-icon-time
{
background
:
transparent
;
.chat-list
{
text-align
:
center
;
}
/
deep
/
.el-input__icon
{
line-height
:
32px
;
.chat-list-scroll
{
height
:
100%
;
.empty
{
margin-top
:
100%
;
}
}
}
.chat-list
{
.chat-item
{
position
:
relative
;
cursor
:
pointer
;
padding
:
4px
15px
1
0px
;
border-bottom
:
1px
solid
#eee
;
&:hover
{
background
:
#e4f0ff
;
.keyword-input
{
width
:
90%
;
margin
:
15px
;
/deep/
.el-input__inner
{
font-size
:
13px
;
height
:
3
0px
;
line-height
:
30px
;
border-radius
:
15px
;
padding-right
:
15px
;
}
&
.selected
{
background
:
#f0f0f0
;
/
deep
/
.el-icon-time
{
background
:
transparent
;
}
.red-dot
{
position
:
absolute
;
min-width
:
14px
;
height
:
14px
;
line-height
:
14px
;
padding
:
0
2px
;
background
:
#e87005
;
border-radius
:
7px
;
z-index
:
1
;
right
:
10px
;
bottom
:
10px
;
font-size
:
12px
;
color
:
#fff
;
/
deep
/
.el-input__icon
{
line-height
:
32px
;
}
.chat-info
{
display
:
inline-block
;
vertical-align
:
middle
;
width
:
calc
(
100%
-
10px
);
.chat-name
{
line-height
:
35px
;
font-size
:
16px
;
}
.chat-list
{
.chat-item
{
position
:
relative
;
cursor
:
pointer
;
padding
:
4px
15px
10px
;
border-bottom
:
1px
solid
#eee
;
&:hover
{
background
:
#e4f0ff
;
}
}
.chat-info-left
{
text-align
:
start
;
font-size
:
14px
;
line-height
:
20px
;
color
:
#333333
;
margin-bottom
:
10px
;
.chat-time
{
text-align
:
end
;
flex
:
none
;
color
:
#999999
;
margin-left
:
10px
;
&
.selected
{
background
:
#f0f0f0
;
}
.red-dot
{
position
:
absolute
;
min-width
:
14px
;
height
:
14px
;
line-height
:
14px
;
padding
:
0
2px
;
background
:
#e87005
;
border-radius
:
7px
;
z-index
:
1
;
right
:
10px
;
bottom
:
10px
;
font-size
:
12px
;
line-height
:
1
;
color
:
#fff
;
}
.chat-info
{
display
:
inline-block
;
vertical-align
:
middle
;
width
:
calc
(
100%
-
10px
);
.chat-name
{
line-height
:
35px
;
font-size
:
16px
;
}
}
.chat-info-left
{
text-align
:
start
;
font-size
:
14px
;
line-height
:
20px
;
color
:
#333333
;
margin-bottom
:
10px
;
.chat-time
{
text-align
:
end
;
flex
:
none
;
color
:
#999999
;
margin-left
:
10px
;
font-size
:
12px
;
line-height
:
1
;
}
}
.chat-msg
{
color
:
#888
;
text-align
:
start
;
font-size
:
12px
;
margin-top
:
-15px
;
}
}
.chat-msg
{
color
:
#888
;
text-align
:
start
;
font-size
:
12px
;
margin-top
:
-15px
;
}
}
}
.chat-check-detail
{
margin-left
:
10px
;
}
.chat-check-detail
{
margin-left
:
10px
;
}
</
style
>
components/controller/chat-list.ts
View file @
39bbc202
...
...
@@ -3,6 +3,7 @@ import { parserMessage } from ".";
import
{
chatStore
,
ChatStore
}
from
"@/customer-service/store/model"
;
import
{
formatTime
,
TimeFormatRule
}
from
"@/customer-service/utils/time"
;
import
{
Chat
as
ChatItem
}
from
"@/customer-service/xim/models/chat"
;
import
Xim
from
"@/customer-service/xim"
;
@
Component
({
components
:
{}
})
export
default
class
ChatList
extends
Vue
{
...
...
@@ -48,11 +49,13 @@ export default class ChatList extends Vue {
@
chatStore
.
Action
(
ChatStore
.
ACTION_CLEAR_CURRENT_CHAT_DATA
)
protected
readonly
reset
!
:
ChatStore
.
ACTION_CLEAR_CURRENT_CHAT_DATA
;
private
readonly
invoker
=
Xim
.
getSdk
();
protected
parseMesage
(
data
:
ChatItem
)
{
if
(
data
.
last_msg_sender
&&
data
.
last_msg_sender
!==
"0"
)
{
if
(
!
this
.
userNames
[
data
.
last_msg_sender
])
{
this
.
updateUserName
({
id
:
data
.
last_msg_sender
,
name
:
""
});
this
.
sdk
this
.
invoker
.
model
(
"user"
)
.
detail
(
data
.
last_msg_sender
)
.
query
()
...
...
@@ -62,7 +65,7 @@ export default class ChatList extends Vue {
name
:
userInfo
.
row
.
first_name
.
display
as
string
,
});
})
.
catch
(()
=>
{});
.
catch
(()
=>
{
});
}
}
if
(
data
.
last_msg_content
===
""
)
{
...
...
components/message-list.vue
View file @
39bbc202
...
...
@@ -38,372 +38,374 @@
</template>
<
script
lang=
"ts"
>
import
{
Component
,
Prop
,
Ref
,
Vue
,
Watch
}
from
"vue-property-decorator"
;
import
{
Message
,
MessageType
}
from
"../model"
;
import
{
throttle
}
from
"../utils"
;
import
{
formatTime
}
from
"../utils/time"
;
import
ImagePreview
from
"./image-preview.vue"
;
import
message
from
"./message.vue"
;
import
VideoPreview
from
"./video-preview.vue"
;
import
{
ChatStore
,
chatStore
}
from
"@/customer-service/store/model"
;
import
{
dbController
}
from
"../database"
;
import
{
Component
,
Prop
,
Ref
,
Vue
,
Watch
}
from
"vue-property-decorator"
;
import
{
Message
,
MessageType
}
from
"../model"
;
import
{
throttle
}
from
"../utils"
;
import
{
formatTime
}
from
"../utils/time"
;
import
ImagePreview
from
"./image-preview.vue"
;
import
message
from
"./message.vue"
;
import
VideoPreview
from
"./video-preview.vue"
;
import
{
ChatStore
,
chatStore
}
from
"@/customer-service/store/model"
;
import
{
dbController
}
from
"../database"
;
@
Component
({
components
:
{
message
,
ImagePreview
,
VideoPreview
}
})
export
default
class
MessageList
extends
Vue
{
@
chatStore
.
Getter
(
ChatStore
.
STATE_CHAT_MSG_HISTORY
)
private
readonly
historyMessage
!
:
ChatStore
.
STATE_CHAT_MSG_HISTORY
;
@
Component
({
components
:
{
message
,
ImagePreview
,
VideoPreview
}
})
export
default
class
MessageList
extends
Vue
{
@
chatStore
.
Getter
(
ChatStore
.
STATE_CHAT_MSG_HISTORY
)
private
readonly
historyMessage
!
:
ChatStore
.
STATE_CHAT_MSG_HISTORY
;
@
chatStore
.
Getter
(
ChatStore
.
STATE_CHAT_SENDING_MESSAGES
)
private
readonly
sendingMessages
!
:
ChatStore
.
STATE_CHAT_SENDING_MESSAGES
;
@
chatStore
.
Getter
(
ChatStore
.
STATE_CHAT_SENDING_MESSAGES
)
private
readonly
sendingMessages
!
:
ChatStore
.
STATE_CHAT_SENDING_MESSAGES
;
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
)
private
readonly
chatId
!
:
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
;
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
)
private
readonly
chatId
!
:
ChatStore
.
STATE_CHAT_CURRENT_CHAT_ID
;
@
chatStore
.
State
(
ChatStore
.
STATE_CURRENT_CHAT_INITING
)
private
readonly
chatIniting
!
:
ChatStore
.
STATE_CURRENT_CHAT_INITING
;
@
chatStore
.
State
(
ChatStore
.
STATE_CURRENT_CHAT_INITING
)
private
readonly
chatIniting
!
:
ChatStore
.
STATE_CURRENT_CHAT_INITING
;
@
chatStore
.
Action
(
ChatStore
.
ACTION_GET_CHAT_MESSAGES_BEFORE_SPECIFIC_ID
)
private
readonly
getLastPageMsg
!
:
ChatStore
.
ACTION_GET_CHAT_MESSAGES_BEFORE_SPECIFIC_ID
;
@
chatStore
.
Action
(
ChatStore
.
ACTION_GET_CHAT_MESSAGES_BEFORE_SPECIFIC_ID
)
private
readonly
getLastPageMsg
!
:
ChatStore
.
ACTION_GET_CHAT_MESSAGES_BEFORE_SPECIFIC_ID
;
@
chatStore
.
Action
(
ChatStore
.
ACTION_GET_CHAT_MESSAGES_AFTER_SPECIFIC_ID
)
private
readonly
getNextPageMsg
!
:
ChatStore
.
ACTION_GET_CHAT_MESSAGES_AFTER_SPECIFIC_ID
;
@
chatStore
.
Action
(
ChatStore
.
ACTION_GET_CHAT_MESSAGES_AFTER_SPECIFIC_ID
)
private
readonly
getNextPageMsg
!
:
ChatStore
.
ACTION_GET_CHAT_MESSAGES_AFTER_SPECIFIC_ID
;
@
chatStore
.
Action
(
ChatStore
.
ACTION_CLEAR_CURRENT_CHAT_DATA
)
private
readonly
clearChatId
!
:
ChatStore
.
ACTION_CLEAR_CURRENT_CHAT_DATA
;
@
chatStore
.
Action
(
ChatStore
.
ACTION_CLEAR_CURRENT_CHAT_DATA
)
private
readonly
clearChatId
!
:
ChatStore
.
ACTION_CLEAR_CURRENT_CHAT_DATA
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_SAVE_FUNC_SCROLL_TO_BOTTOM
)
private
readonly
saveScrollToBottomFunc
!
:
ChatStore
.
MUTATION_SAVE_FUNC_SCROLL_TO_BOTTOM
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_SAVE_FUNC_SCROLL_TO_BOTTOM
)
private
readonly
saveScrollToBottomFunc
!
:
ChatStore
.
MUTATION_SAVE_FUNC_SCROLL_TO_BOTTOM
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_CLEAR_FUNC_SCROLL_TO_BOTTOM
)
private
readonly
clearScrollToBottomFunc
!
:
ChatStore
.
MUTATION_CLEAR_FUNC_SCROLL_TO_BOTTOM
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_CLEAR_FUNC_SCROLL_TO_BOTTOM
)
private
readonly
clearScrollToBottomFunc
!
:
ChatStore
.
MUTATION_CLEAR_FUNC_SCROLL_TO_BOTTOM
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_SAVE_FUNC_ON_NEW_MSG
)
private
readonly
onNewMessage
!
:
ChatStore
.
MUTATION_SAVE_FUNC_ON_NEW_MSG
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_SAVE_FUNC_ON_NEW_MSG
)
private
readonly
onNewMessage
!
:
ChatStore
.
MUTATION_SAVE_FUNC_ON_NEW_MSG
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_CLEAR_FUNC_ON_NEW_MSG
)
private
readonly
clearNewMessage
!
:
ChatStore
.
MUTATION_CLEAR_FUNC_ON_NEW_MSG
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_CLEAR_FUNC_ON_NEW_MSG
)
private
readonly
clearNewMessage
!
:
ChatStore
.
MUTATION_CLEAR_FUNC_ON_NEW_MSG
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_WITHDRAW
)
private
readonly
executeWithDraw
!
:
ChatStore
.
MUTATION_WITHDRAW
;
@
chatStore
.
Mutation
(
ChatStore
.
MUTATION_WITHDRAW
)
private
readonly
executeWithDraw
!
:
ChatStore
.
MUTATION_WITHDRAW
;
@
Prop
({
default
:
"circle"
})
private
shape
!
:
string
;
@
Prop
({
default
:
"circle"
})
private
shape
!
:
string
;
private
get
messages
()
{
if
(
this
.
historyMessage
)
{
if
(
this
.
sendingMessages
)
{
return
[...
this
.
historyMessage
,
...
this
.
sendingMessages
].
filter
(
(
i
)
=>
i
.
chat_id
===
this
.
chatId
&&
i
.
id
>
0
);
}
return
this
.
historyMessage
;
}
private
get
messages
()
{
if
(
this
.
historyMessage
)
{
if
(
this
.
sendingMessages
)
{
return
[...
this
.
historyMessage
,
...
this
.
sendingMessages
]
.
filter
(
(
i
)
=>
i
.
chat_id
===
this
.
chatId
return
this
.
sendingMessages
.
filter
(
(
i
)
=>
i
.
chat_id
===
this
.
chatId
&&
i
.
id
>
0
);
}
return
this
.
historyMessage
;
}
if
(
this
.
sendingMessages
)
{
return
this
.
sendingMessages
.
filter
(
(
i
)
=>
i
.
chat_id
===
this
.
chatId
);
return
[];
}
return
[];
}
// 添加时间戳的最大间隔消息数
private
readonly
timeLimit
=
48
;
// 添加时间戳的最大间隔消息数
private
readonly
timeLimit
=
48
;
private
scroll2EndWhenMessageLoaded
=
false
;
private
scroll2EndWhenMessageLoaded
=
false
;
private
preview
=
false
;
private
imagePreview
=
{};
private
preview
=
false
;
private
image
Preview
=
{};
private
previewVideo
=
false
;
private
video
Preview
=
{};
private
previewVideo
=
false
;
private
videoPreview
=
{};
@
Ref
(
"message-scrollbar"
)
private
scollbarElement
!
:
Vue
&
{
update
:
()
=>
void
;
};
@
Ref
(
"message-scrollbar"
)
private
scollbarElement
!
:
Vue
&
{
update
:
()
=>
void
;
};
private
get
scollWrapper
():
HTMLElement
|
null
{
return
this
.
scollbarElement
?.
$el
?.
firstChild
as
HTMLElement
;
}
private
get
scollWrapper
():
HTMLElement
|
null
{
return
this
.
scollbarElement
?.
$el
?.
firstChild
as
HTMLElement
;
}
@
Watch
(
"messages"
)
private
whenHasMessages
()
{
this
.
$nextTick
(()
=>
this
.
scollbarElement
.
update
());
}
@
Watch
(
"messages"
)
private
whenHasMessages
()
{
this
.
$nextTick
(()
=>
this
.
scollbarElement
.
update
());
}
@
Watch
(
"preview"
)
private
onPreviewChanged
()
{
if
(
!
this
.
preview
)
{
this
.
raiseFileOpen
(
false
);
}
}
@
Watch
(
"preview"
)
private
onPreviewChanged
()
{
if
(
!
this
.
preview
)
{
this
.
raiseFileOpen
(
false
);
@
Watch
(
"previewVideo"
)
private
onVideoPreviewChanged
()
{
if
(
!
this
.
previewVideo
)
{
this
.
raiseFileOpen
(
false
);
}
}
}
@
Watch
(
"previewVideo"
)
private
onVideoPreviewChanged
()
{
if
(
!
this
.
previewVideo
)
{
this
.
raiseFileOpen
(
false
);
private
raiseFileOpen
(
value
:
boolean
)
{
this
.
$emit
(
"file-open"
,
value
);
}
}
private
raiseFileOpen
(
value
:
boolean
)
{
this
.
$emit
(
"file-open"
,
value
);
}
private
get
messageTimestampDictionary
()
{
const
dic
=
{}
as
{
[
prop
:
number
]:
boolean
};
let
count
=
0
;
if
(
this
.
historyMessage
)
{
this
.
historyMessage
.
forEach
((
message
,
index
,
array
)
=>
{
if
(
index
===
0
||
this
.
whetherShowTime
(
array
[
index
-
1
],
message
)
||
count
===
this
.
timeLimit
-
1
)
{
dic
[
message
.
id
]
=
true
;
count
=
0
;
}
else
{
count
++
;
}
});
}
private
get
messageTimestampDictionary
()
{
const
dic
=
{}
as
{
[
prop
:
number
]:
boolean
};
let
count
=
0
;
if
(
this
.
historyMessage
)
{
this
.
historyMessage
.
forEach
((
message
,
index
,
array
)
=>
{
if
(
index
===
0
||
this
.
whetherShowTime
(
array
[
index
-
1
],
message
)
||
count
===
this
.
timeLimit
-
1
)
{
dic
[
message
.
id
]
=
true
;
count
=
0
;
}
else
{
count
++
;
return
dic
;
}
private
loading
=
false
;
private
loadingOld
=
false
;
private
loadingNew
=
false
;
public
created
()
{
this
.
handleScrollWrapper
();
this
.
onNewMessage
((
e
)
=>
{
if
(
e
.
type
===
MessageType
.
Withdraw
)
{
this
.
executeWithDraw
(
e
.
ref_id
)
;
dbController
.
removeMessage
(
e
.
chat_id
,
e
.
ref_id
)
.
finally
(()
=>
this
.
refresh
())
;
}
});
}
return
dic
;
}
private
loading
=
false
;
private
loadingOld
=
false
;
private
loadingNew
=
false
;
public
created
()
{
this
.
handleScrollWrapper
();
this
.
onNewMessage
((
e
)
=>
{
if
(
e
.
type
===
MessageType
.
Withdraw
)
{
this
.
executeWithDraw
(
e
.
ref_id
);
dbController
.
removeMessage
(
e
.
chat_id
,
e
.
ref_id
)
.
finally
(()
=>
this
.
refresh
());
}
});
}
public
mounted
()
{
this
.
scollWrapper
&&
this
.
scollWrapper
.
addEventListener
(
"scroll"
,
this
.
handleScroll
);
this
.
saveScrollToBottomFunc
(
this
.
scrollToNewMsg
);
this
.
scrollToNewMsg
();
setTimeout
(()
=>
this
.
scroll2End
(
200
));
setTimeout
(()
=>
this
.
scroll2End
(
1000
),
200
);
}
public
mounted
()
{
this
.
scollWrapper
&&
this
.
scollWrapper
.
addEventListener
(
"scroll"
,
this
.
handleScroll
);
this
.
saveScrollToBottomFunc
(
this
.
scrollToNewMsg
);
this
.
scrollToNewMsg
();
setTimeout
(()
=>
this
.
scroll2End
(
200
));
setTimeout
(()
=>
this
.
scroll2End
(
1000
),
200
);
}
public
beforeDestroy
()
{
this
.
scollWrapper
&&
this
.
scollWrapper
.
removeEventListener
(
"scroll"
,
this
.
handleScroll
);
this
.
clearScrollToBottomFunc
();
this
.
clearNewMessage
();
// this.clearChatId();
}
public
beforeDestroy
()
{
this
.
scollWrapper
&&
this
.
scollWrapper
.
removeEventListener
(
"scroll"
,
this
.
handleScroll
);
this
.
clearScrollToBottomFunc
();
this
.
clearNewMessage
();
// this.clearChatId();
}
public
scroll2End
(
delay
?:
number
)
{
this
.
$nextTick
(()
=>
{
const
wrap
=
this
.
scollbarElement
?.
$el
.
querySelector
(
".el-scrollbar__wrap"
)
as
HTMLElement
;
if
(
wrap
)
{
if
(
delay
)
{
return
setTimeout
(
()
=>
(
wrap
.
scrollTop
=
Math
.
max
(
wrap
.
scrollHeight
+
100
,
10000
)),
delay
);
public
scroll2End
(
delay
?:
number
)
{
this
.
$nextTick
(()
=>
{
const
wrap
=
this
.
scollbarElement
?.
$el
.
querySelector
(
".el-scrollbar__wrap"
)
as
HTMLElement
;
if
(
wrap
)
{
if
(
delay
)
{
return
setTimeout
(
()
=>
(
wrap
.
scrollTop
=
Math
.
max
(
wrap
.
scrollHeight
+
100
,
10000
)),
delay
);
}
wrap
.
scrollTop
=
Math
.
max
(
wrap
.
scrollHeight
+
100
,
10000
);
}
wrap
.
scrollTop
=
Math
.
max
(
wrap
.
scrollHeight
+
100
,
10000
);
}
});
}
});
}
private
startLoading
()
{
this
.
loading
=
true
;
}
private
startLoading
()
{
this
.
loading
=
true
;
}
private
endLoading
()
{
this
.
loading
=
false
;
}
private
endLoading
()
{
this
.
loading
=
false
;
}
private
startLoadingOld
()
{
this
.
startLoading
();
this
.
loadingOld
=
true
;
}
private
startLoadingOld
()
{
this
.
startLoading
();
this
.
loadingOld
=
true
;
}
private
endLoadingOld
()
{
this
.
endLoading
();
this
.
loadingOld
=
false
;
}
private
endLoadingOld
()
{
this
.
endLoading
();
this
.
loadingOld
=
false
;
}
private
startLoadingNew
()
{
this
.
startLoading
();
this
.
loadingNew
=
true
;
}
private
startLoadingNew
()
{
this
.
startLoading
();
this
.
loadingNew
=
true
;
}
private
endLoadingNew
()
{
this
.
endLoading
();
this
.
loadingNew
=
false
;
}
private
endLoadingNew
()
{
this
.
endLoading
();
this
.
loadingNew
=
false
;
}
private
handleScroll
!
:
()
=>
void
;
private
handleScrollWrapper
()
{
let
oldScrollTop
=
0
;
this
.
handleScroll
=
()
=>
{
const
wrapper
=
this
.
scollWrapper
;
const
gap
=
150
;
if
(
wrapper
==
null
)
return
;
const
view
=
wrapper
.
firstChild
as
HTMLElement
;
const
wrapperH
=
wrapper
.
getBoundingClientRect
().
height
;
const
viewH
=
view
.
getBoundingClientRect
().
height
;
let
scrollUp
=
false
;
let
scrollDown
=
false
;
if
(
oldScrollTop
>
wrapper
.
scrollTop
)
{
scrollUp
=
true
;
scrollDown
=
false
;
}
else
if
(
oldScrollTop
<
wrapper
.
scrollTop
)
{
scrollUp
=
false
;
scrollDown
=
true
;
}
this
.
forbidScrollTopToZero
(
wrapper
);
if
(
wrapper
.
scrollTop
<=
gap
)
{
scrollUp
&&
this
.
fetchOldMsg
();
}
if
(
wrapper
.
scrollTop
-
40
-
(
viewH
-
wrapperH
)
>=
-
gap
)
{
scrollDown
&&
this
.
fetchNewMsg
();
private
handleScroll
!
:
()
=>
void
;
private
handleScrollWrapper
()
{
let
oldScrollTop
=
0
;
this
.
handleScroll
=
()
=>
{
const
wrapper
=
this
.
scollWrapper
;
const
gap
=
150
;
if
(
wrapper
==
null
)
return
;
const
view
=
wrapper
.
firstChild
as
HTMLElement
;
const
wrapperH
=
wrapper
.
getBoundingClientRect
().
height
;
const
viewH
=
view
.
getBoundingClientRect
().
height
;
let
scrollUp
=
false
;
let
scrollDown
=
false
;
if
(
oldScrollTop
>
wrapper
.
scrollTop
)
{
scrollUp
=
true
;
scrollDown
=
false
;
}
else
if
(
oldScrollTop
<
wrapper
.
scrollTop
)
{
scrollUp
=
false
;
scrollDown
=
true
;
}
this
.
forbidScrollTopToZero
(
wrapper
);
if
(
wrapper
.
scrollTop
<=
gap
)
{
scrollUp
&&
this
.
fetchOldMsg
();
}
if
(
wrapper
.
scrollTop
-
40
-
(
viewH
-
wrapperH
)
>=
-
gap
)
{
scrollDown
&&
this
.
fetchNewMsg
();
}
oldScrollTop
=
wrapper
.
scrollTop
;
};
}
/* scrollTop为0时,新加载的消息后,滚动条也会保持在0的位置 */
private
forbidScrollTopToZero
(
ele
:
HTMLElement
)
{
if
(
ele
.
scrollTop
<=
10
)
{
ele
.
scrollTop
=
10
;
}
oldScrollTop
=
wrapper
.
scrollTop
;
};
}
}
/* scrollTop为0时,新加载的消息后,滚动条也会保持在0的位置 */
private
forbidScrollTopToZero
(
ele
:
HTMLElement
)
{
if
(
ele
.
scrollTop
<=
10
)
{
ele
.
scrollTop
=
10
;
private
scrollToNewMsg
()
{
this
.
$nextTick
(()
=>
{
if
(
this
.
loading
)
return
;
this
.
scroll2End
();
});
}
}
private
scrollToNewMsg
()
{
this
.
$nextTick
(()
=>
{
@
throttle
()
private
async
fetchOldMsg
()
{
if
(
this
.
loading
)
return
;
this
.
scroll2End
();
});
}
const
msg
=
this
.
historyMessage
;
if
(
msg
==
null
)
return
;
if
(
msg
.
length
===
0
)
return
;
this
.
startLoadingOld
();
const
msgId
=
msg
[
0
].
id
;
const
data
=
await
this
.
getLastPageMsg
(
msgId
);
if
(
data
.
length
===
0
)
{
// eslint-disable-next-line no-console
console
.
log
(
"没有更多老消息了"
);
}
this
.
$emit
(
"last-page"
,
msgId
);
this
.
endLoadingOld
();
}
@
throttle
()
private
async
fetchOldMsg
()
{
if
(
this
.
loading
)
return
;
const
msg
=
this
.
historyMessage
;
if
(
msg
==
null
)
return
;
if
(
msg
.
length
===
0
)
return
;
this
.
startLoadingOld
();
const
msgId
=
msg
[
0
].
id
;
const
data
=
await
this
.
getLastPageMsg
(
msgId
);
if
(
data
.
length
===
0
)
{
// eslint-disable-next-line no-console
console
.
log
(
"没有更多老消息了"
);
@
throttle
()
private
async
fetchNewMsg
()
{
if
(
this
.
loading
)
return
;
const
msg
=
this
.
historyMessage
;
if
(
msg
==
null
)
return
;
if
(
msg
.
length
===
0
)
return
;
this
.
startLoadingNew
();
const
msgId
=
msg
[
msg
.
length
-
1
].
id
;
const
data
=
await
this
.
getNextPageMsg
(
msgId
);
if
(
data
.
length
===
0
)
{
// eslint-disable-next-line no-console
console
.
log
(
"没有更多新消息了"
);
}
this
.
$emit
(
"next-page"
,
msgId
);
this
.
endLoadingNew
();
}
this
.
$emit
(
"last-page"
,
msgId
);
this
.
endLoadingOld
();
}
@
throttle
()
private
async
fetchNewMsg
()
{
if
(
this
.
loading
)
return
;
const
msg
=
this
.
historyMessage
;
if
(
msg
==
null
)
return
;
if
(
msg
.
length
===
0
)
return
;
this
.
startLoadingNew
();
const
msgId
=
msg
[
msg
.
length
-
1
].
id
;
const
data
=
await
this
.
getNextPageMsg
(
msgId
);
if
(
data
.
length
===
0
)
{
// eslint-disable-next-line no-console
console
.
log
(
"没有更多新消息了"
);
private
format2Time
(
time
:
number
)
{
return
formatTime
(
time
);
}
this
.
$emit
(
"next-page"
,
msgId
);
this
.
endLoadingNew
();
}
private
format2Time
(
time
:
number
)
{
return
formatTime
(
time
)
;
}
private
whetherShowTime
(
previous
:
Message
,
current
:
Message
)
{
return
current
.
ts
-
previous
.
ts
>
180
;
}
private
whetherShowTime
(
previous
:
Message
,
current
:
Message
)
{
return
current
.
ts
-
previous
.
ts
>
180
;
}
private
open
(
file
:
{
type
:
string
;
msg
:
{
url
:
string
;
name
:
string
;
size
:
number
};
})
{
if
(
file
.
type
===
"image"
)
{
this
.
imagePreview
=
file
.
msg
;
this
.
preview
=
true
;
return
this
.
raiseFileOpen
(
true
);
}
private
open
(
file
:
{
type
:
string
;
msg
:
{
url
:
string
;
name
:
string
;
size
:
number
};
})
{
if
(
file
.
type
===
"image"
)
{
this
.
imagePreview
=
file
.
msg
;
this
.
preview
=
true
;
return
this
.
raiseFileOpen
(
true
);
if
(
file
.
type
===
"video"
)
{
this
.
videoPreview
=
file
.
msg
;
this
.
previewVideo
=
true
;
return
this
.
raiseFileOpen
(
true
);
}
}
if
(
file
.
type
===
"video"
)
{
this
.
videoPreview
=
file
.
msg
;
this
.
previewVideo
=
true
;
return
this
.
raiseFileOpen
(
true
);
/**
* 获取当期消息列表头尾消息的id
*/
public
getStart2EndMessageIds
()
{
const
v
:
{
start
:
number
;
end
:
number
}
=
{
start
:
0
,
end
:
0
};
if
(
this
.
historyMessage
&&
this
.
historyMessage
.
length
)
{
const
start
=
this
.
historyMessage
[
0
];
v
.
start
=
start
.
id
;
const
end
=
this
.
historyMessage
[
this
.
historyMessage
.
length
-
1
];
v
.
end
=
end
.
id
;
}
return
v
;
}
}
/**
* 获取当期消息列表头尾消息的id
*/
public
getStart2EndMessageIds
()
{
const
v
:
{
start
:
number
;
end
:
number
}
=
{
start
:
0
,
end
:
0
};
if
(
this
.
historyMessage
&&
this
.
historyMessage
.
length
)
{
const
start
=
this
.
historyMessage
[
0
];
v
.
start
=
start
.
id
;
const
end
=
this
.
historyMessage
[
this
.
historyMessage
.
length
-
1
];
v
.
end
=
end
.
id
;
private
refresh
()
{
this
.
fetchNewMsg
();
}
return
v
;
}
private
refresh
()
{
this
.
fetchNewMsg
();
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.message-list
{
padding
:
0
20px
;
padding-right
:
0
;
}
.loading-mask
{
height
:
50px
;
line-height
:
50px
;
text-align
:
center
;
}
.message-template
{
&:first-child
{
.timestamp
{
margin-top
:
20px
;
}
.message-list
{
padding
:
0
20px
;
padding-right
:
0
;
}
&
:last-child
{
padding-bottom
:
10px
;
.loading-mask
{
height
:
50px
;
line-height
:
50px
;
text-align
:
center
;
}
.timestamp
{
font-size
:
12px
;
user-select
:
none
;
.message-template
{
&:first-child
{
padding-top
:
10px
;
.timestamp
{
margin-top
:
20px
;
}
}
&
:last-child
{
padding-bottom
:
10px
;
}
.timestamp
{
font-size
:
12px
;
user-select
:
none
;
}
}
}
</
style
>
service/upload.ts
View file @
39bbc202
import
Vue
from
"vue"
;
import
{
UniplatSdk
}
from
"uniplat-sdk"
const
orgId
=
()
=>
Vue
.
prototype
.
global
.
org
?.
id
??
"0"
;
import
Chat
from
"@/customer-service/xim"
;
export
async
function
uploadFile
(
file
:
File
)
{
let
{
url
}
=
await
(
Vue
.
prototype
.
sdk
as
UniplatSdk
).
uploadFileV2
(
file
)
const
realUrl
=
`
${
Vue
.
prototype
.
sdk
.
global
.
baseUrl
}${
url
}
`
;
return
realUrl
;
const
sdk
=
Chat
.
getSdk
();
let
{
url
}
=
await
sdk
.
uploadFileV2
(
file
)
return
`
${
sdk
.
global
.
baseUrl
}${
url
}
`
;
}
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