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
23a41a63
authored
Jan 06, 2022
by
杨铁龙
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge branch 'master' of
http://gitlab.corp.qinqinxiaobao.com:9880/uniplat/customer-service
parents
1f7c7ff4
d1f6c56f
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
126 additions
and
86 deletions
components/image-preview.vue
components/message.vue
service/monitor.ts
store/index.ts
store/model.ts
utils/chat-info.ts
utils/user-info.ts
components/image-preview.vue
View file @
23a41a63
...
...
@@ -3,21 +3,17 @@
:modal=
"false"
:before-close=
"close"
:visible=
"value"
custom-class=
"hide-header show-close padding-0 width-auto"
:show-close=
"false"
custom-class=
"transparent"
width=
"90%"
>
<div
class=
"d-flex flex-column"
>
<div
class=
"preview-title text-center"
>
图片预览
</div>
<div
class=
"d-flex justify-content-center"
style=
"min-width: 300px"
>
<img
v-if=
"file"
:src=
"file.url"
:style=
"style"
/>
<div
class=
"d-flex justify-content-center"
>
<img
v-if=
"file"
:src=
"file.url"
/>
<i
class=
"el-icon-close"
@
click=
"close"
></i>
</div>
<div
class=
"d-flex justify-content-center actions"
>
<span
class=
"d-flex align-items-center justify-content-center"
@
click=
"set2Default"
>
1:1
</span
>
<a
class=
"d-flex align-items-center justify-content-center"
:href=
"file.url"
...
...
@@ -31,60 +27,55 @@
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Model
,
Prop
,
Vue
}
from
"vue-property-decorator"
;
import
{
Component
,
Model
,
Prop
,
Vue
}
from
"vue-property-decorator"
;
@
Component
({
components
:
{}
})
export
default
class
ImagePreview
extends
Vue
{
@
Component
({
components
:
{}
})
export
default
class
ImagePreview
extends
Vue
{
@
Model
(
"update"
)
private
value
!
:
boolean
;
@
Prop
()
private
file
!
:
{
name
:
string
;
url
:
string
};
private
style
:
{
"max-height"
:
number
|
string
;
"max-width"
:
number
|
string
;
}
=
{
"max-height"
:
"300px"
,
"max-width"
:
"600px"
,
};
private
close
()
{
setTimeout
(
()
=>
(
this
.
style
=
{
"max-height"
:
"300px"
,
"max-width"
:
"600px"
}),
300
);
this
.
$emit
(
"update"
,
false
);
}
private
set2Default
()
{
this
.
style
=
{
"max-height"
:
"1600px"
,
"max-width"
:
"1600px"
};
}
private
get
getAttachment
()
{
if
(
this
.
file
)
{
return
this
.
file
.
name
;
}
return
"文件下载"
;
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.preview-title
{
font-size
:
18px
;
color
:
#333
;
margin-bottom
:
15px
;
}
img
{
max-width
:
100%
;
max-height
:
100%
;
.actions
{
&
+
i
{
top
:
-25px
;
right
:
20px
;
background-color
:
rgba
(
0
,
0
,
0
,
0.5
);
border-radius
:
50%
;
padding
:
5px
;
font-size
:
40px
;
color
:
#fff
;
display
:
table
;
position
:
relative
;
z-index
:
1
;
cursor
:
pointer
;
}
}
.actions
{
margin
:
15px
0
;
>
span,
a
{
width
:
3
0px
;
height
:
3
0px
;
width
:
5
0px
;
height
:
5
0px
;
background-color
:
#7a7b7d
;
color
:
#fff
;
border-radius
:
50%
;
...
...
@@ -92,16 +83,12 @@ export default class ImagePreview extends Vue {
i
{
color
:
#fff
;
font-size
:
2
0px
;
font-size
:
3
0px
;
}
&
+
span
{
margin-left
:
15px
;
}
}
>
a
{
margin-left
:
15px
;
}
}
</
style
>
components/message.vue
View file @
23a41a63
...
...
@@ -78,12 +78,7 @@
/>
<avatar
v-if=
"!isQuestionAnswerMessage && !isWithdrawMessage"
:src=
"
chatRole === 'admin' ||
chatRole === 'customer-service'
? defaultAvatar
: avatar
"
:src=
"avatar || defaultAvatar"
shape=
"circle"
/>
</div>
...
...
@@ -224,8 +219,8 @@
@
chatStore
.
State
(
ChatStore
.
STATE_CHAT_CURRENT_USER_UID
)
private
readonly
chatMyId
!
:
ChatStore
.
STATE_CHAT_CURRENT_USER_UID
;
@
chatStore
.
Getter
(
ChatStore
.
STATE_CURRENT
_CHAT_MEMBERS
)
private
readonly
allChatMembers
!
:
ChatStore
.
STATE_
CURRENT
_CHAT_MEMBERS
;
@
chatStore
.
State
(
ChatStore
.
STATE_ALL_HISTORY
_CHAT_MEMBERS
)
private
readonly
allChatMembers
!
:
ChatStore
.
STATE_
ALL_HISTORY
_CHAT_MEMBERS
;
@
chatStore
.
Getter
(
ChatStore
.
GETTER_CURRENT_CHAT_PRESENT_MEMBERS
)
private
readonly
chatMembers
!
:
ChatStore
.
GETTER_CURRENT_CHAT_PRESENT_MEMBERS
;
...
...
@@ -403,7 +398,10 @@
if
(
this
.
chatMembers
)
{
const
t
=
this
.
chatMembers
.
find
((
i
)
=>
i
.
eid
===
this
.
data
.
eid
);
if
(
t
)
{
const
name
=
this
.
getFilterUsername
(
t
.
alias_name
||
t
.
name
);
const
name
=
this
.
getFilterUsername
(
t
.
alias_name
as
string
,
t
.
name
);
if
(
name
)
{
return
name
;
}
...
...
@@ -413,15 +411,18 @@
return
this
.
refetchUsername
;
}
private
getFilterUsername
(
name
:
string
)
{
private
getFilterUsername
(
name1
:
string
,
name2
:
string
)
{
const
backend
=
Xim
.
isBackend
();
if
(
this
.
currentChat
&&
this
.
currentChat
.
catalog
===
"福利宝"
&&
this
.
chatRole
===
"customer-service"
)
{
return
`采购顾问
${
name
}
`
;
return
backend
&&
name1
?
`采购顾问
${
name1
}
(
${
name2
}
)`
:
`采购顾问
${
name1
||
name2
}
`
;
}
return
name
;
return
backend
&&
name1
?
`
${
name1
}
(
${
name2
}
)`
:
name1
||
name2
;
}
private
get
avatar
()
{
...
...
@@ -615,7 +616,14 @@
if
(
this
.
data
&&
this
.
data
.
eid
)
{
ChatUserInfoService
.
getUserInfo
(
this
.
data
.
eid
).
then
((
r
)
=>
{
if
(
r
)
{
this
.
refetchUsername
=
r
.
alias_name
||
r
.
name
||
r
.
phone
;
if
(
Xim
.
isBackend
()
&&
r
.
alias_name
)
{
this
.
refetchUsername
=
`
${
r
.
alias_name
}
(
${
r
.
name
||
r
.
phone
}
)`
;
}
else
{
this
.
refetchUsername
=
r
.
alias_name
||
r
.
name
||
r
.
phone
;
}
r
.
icon
&&
(
this
.
refetchUserIcon
=
r
.
icon
);
}
});
...
...
service/monitor.ts
View file @
23a41a63
...
...
@@ -3,17 +3,17 @@ import { UniplatSdk } from "uniplat-sdk";
import
{
ImEnvironment
}
from
"../model"
;
export
const
enum
Product
{
Default
=
'default'
,
QqxbWeixin
=
'qqxb-weixin'
,
QqxbApp
=
'qqxb-app'
,
Fulibao
=
'fulibao'
,
HrManager
=
'hr-manager'
,
Hrs100
=
'hrs100'
,
HrsApp
=
'hrs-app'
,
BiJie
=
'bi-jie'
,
Cashier
=
'cashier'
,
Default
=
"default"
,
QqxbWeixin
=
"qqxb-weixin"
,
QqxbApp
=
"qqxb-app"
,
Fulibao
=
"fulibao"
,
HrManager
=
"hr-manager"
,
Hrs100
=
"hrs100"
,
HrsApp
=
"hrs-app"
,
BiJie
=
"bi-jie"
,
Cashier
=
"cashier"
,
Uniplat
=
"uniplat"
,
DeShengJiuYeBao
=
'de-sheng-jiu-ye-bao'
DeShengJiuYeBao
=
"de-sheng-jiu-ye-bao"
,
}
const
enum
ProductTable
{
...
...
@@ -88,10 +88,13 @@ class WebMonitor {
public
useSdk
(
sdk
:
UniplatSdk
,
options
:
SdkMonitorOption
)
{
this
.
envir
=
options
.
envir
;
this
.
product
=
options
.
product
;
sdk
.
events
.
addUniversalErrorResponseCallback
((
r
:
AxiosResponse
<
any
>
)
=>
{
sdk
.
events
.
addUniversalErrorResponseCallback
(
(
r
:
AxiosResponse
<
any
>
)
=>
{
if
(
this
.
enable
())
{
const
msg
:
string
[]
=
[];
msg
.
push
(
`URL:
${
decodeURIComponent
(
r
.
config
.
url
as
string
)}
`
);
msg
.
push
(
`URL:
${
decodeURIComponent
(
r
.
config
.
url
as
string
)}
`
);
msg
.
push
(
`Token:
${
sdk
.
global
.
jwtToken
}
`
);
const
header
=
r
.
config
.
headers
;
if
(
header
)
{
...
...
@@ -102,19 +105,23 @@ class WebMonitor {
options
&&
options
.
userAgent
&&
msg
.
push
(
`UserAgent:
${
window
.
navigator
.
userAgent
}
`
);
r
.
config
&&
r
.
config
.
params
&&
msg
.
push
(
`Params:
${
r
.
config
.
params
}
`
);
r
.
config
&&
r
.
config
.
data
&&
msg
.
push
(
`Payload:
${
JSON
.
stringify
(
r
.
config
.
data
)}
`
);
r
.
config
&&
r
.
config
.
params
&&
msg
.
push
(
`Params:
${
JSON
.
stringify
(
r
.
config
.
params
)}
`
);
r
.
config
&&
r
.
config
.
data
&&
msg
.
push
(
`Payload:
${
JSON
.
stringify
(
r
.
config
.
data
)}
`
);
msg
.
push
(
`Exception:
${((
r
.
data
.
error
as
string
)
||
""
).
substring
(
0
,
500
)}
`
`Exception:
${(
(
r
.
data
.
error
as
string
)
||
""
).
substring
(
0
,
500
)}
`
);
r
&&
r
.
config
&&
this
.
error
(
msg
.
join
(
"\n"
));
}
});
}
);
}
}
...
...
store/index.ts
View file @
23a41a63
...
...
@@ -159,6 +159,7 @@ export default {
[
ChatStore
.
STATE_CHAT_MY_UID
]:
null
,
[
ChatStore
.
STATE_CHAT_SOURCE
]:
ServiceType
.
Frontend
,
[
ChatStore
.
STATE_CURRENT_CHAT_MEMBERS
]:
null
,
[
ChatStore
.
STATE_ALL_HISTORY_CHAT_MEMBERS
]:
null
,
[
ChatStore
.
STATE_CURRENT_CHAT_TITLE
]:
""
,
[
ChatStore
.
STATE_FUNC_SCROLL_TO_BOTTOM
]:
()
=>
true
,
[
ChatStore
.
STATE_FUNC_ON_NEW_MSG
]:
()
=>
true
,
...
...
@@ -881,7 +882,7 @@ export default {
commit
(
ChatStore
.
MUTATION_CLEAR_CHAT_MSG_HISTORY
);
commit
(
ChatStore
.
MUTATION_SAVE_CURRENT_CHAT_ID
,
chatId
);
await
getChatModelInfo
(
getChatModelInfo
(
wantedChatRoom
.
model_name
,
wantedChatRoom
.
obj_id
,
wantedChatRoom
.
detail_name
...
...
@@ -895,13 +896,13 @@ export default {
ChatStore
.
MUTATION_SAVE_CURRENT_CHAT_UNIPLAT_ID
,
info
.
uniplatId
);
dispatch
(
ChatStore
.
ACTION_GET_CHAT_MEMBERS
);
})
.
catch
(
console
.
error
);
commit
(
ChatStore
.
MUTATION_INITING_CHAT
);
removeRegisterChatEvents
.
forEach
((
k
)
=>
k
());
removeRegisterChatEvents
=
[];
try
{
await
dispatch
(
ChatStore
.
ACTION_GET_CHAT_MEMBERS
);
await
Promise
.
all
([
dispatch
(
ChatStore
.
ACTION_REGISTER_EVENT
),
dispatch
(
ChatStore
.
ACTION_GET_CHAT_MESSAGES
),
...
...
@@ -937,7 +938,7 @@ export default {
const
getChatMembersResult
=
await
xim
.
fetchChatMembers
(
chatId
);
if
(
!
getChatMembersResult
)
return
;
const
chatMembers
=
getChatMembersResult
.
args
[
0
]
as
ChatMember
[];
let
newChatMembers
=
await
Promise
.
all
(
const
all
=
await
Promise
.
all
(
chatMembers
.
map
(
async
(
member
)
=>
{
let
result
:
NonNullable
<
ChatStore
.
STATE_CURRENT_CHAT_MEMBERS
>
[
number
];
try
{
...
...
@@ -956,7 +957,8 @@ export default {
return
result
;
})
);
newChatMembers
=
newChatMembers
.
filter
((
it
)
=>
!
it
.
is_exited
);
(
<
any
>
state
)[
ChatStore
.
STATE_ALL_HISTORY_CHAT_MEMBERS
]
=
all
;
const
newChatMembers
=
all
.
filter
((
it
)
=>
!
it
.
is_exited
);
const
member
=
newChatMembers
.
find
(
(
it
)
=>
it
.
eid
===
...
...
@@ -969,6 +971,7 @@ export default {
commit
(
ChatStore
.
MUTATION_CHAT_UPDATE_IS_MEMBER
,
false
);
commit
(
ChatStore
.
MUTATION_CHAT_UPDATE_USER_TYPE
,
"0"
);
}
commit
(
ChatStore
.
MUTATION_SAVE_CURRENT_CHAT_MEMBERS
,
unique
(
newChatMembers
,
function
(
item
,
all
)
{
...
...
store/model.ts
View file @
23a41a63
...
...
@@ -73,6 +73,11 @@ export namespace ChatStore {
|
readonly
(
dto
.
ChatMember
&
dto
.
ChatMemberExtraInfo
)[]
|
null
;
export
const
STATE_ALL_HISTORY_CHAT_MEMBERS
=
"当前会话历史所有参与者"
;
export
type
STATE_ALL_HISTORY_CHAT_MEMBERS
=
|
readonly
(
dto
.
ChatMember
&
dto
.
ChatMemberExtraInfo
)[]
|
null
;
export
const
STATE_CURRENT_CHAT_TITLE
=
"会话标题"
;
export
type
STATE_CURRENT_CHAT_TITLE
=
string
;
...
...
utils/chat-info.ts
View file @
23a41a63
...
...
@@ -88,7 +88,7 @@ export async function getChatModelInfo(
}
)
as
ChatModelInfoData
;
le
t
removing
=
[];
cons
t
removing
=
[];
for
(
const
item
of
waitingAction
)
{
if
(
item
.
key
===
key
)
{
item
.
resolve
(
o
);
...
...
utils/user-info.ts
View file @
23a41a63
import
{
UniplatSdk
}
from
"uniplat-sdk"
;
import
Chat
from
"../xim"
;
export
type
UserMapping
=
{
[
eid
:
string
]:
{
export
interface
ChatUserSummaryInfo
{
name
:
string
;
phone
:
string
;
icon
:
string
;
alias_name
:
string
;
};
};
}
export
type
UserMapping
=
{
[
eid
:
string
]:
ChatUserSummaryInfo
};
const
userMapping
:
UserMapping
=
{};
...
...
@@ -25,6 +25,12 @@ interface UserInfo {
export
const
getUserMapping
=
()
=>
userMapping
;
const
loadingKeys
=
new
Set
<
string
>
();
let
waitingAction
:
{
key
:
string
;
resolve
:
(
d
:
ChatUserSummaryInfo
)
=>
void
;
}[]
=
[];
export
class
ChatUserInfoService
{
public
static
async
getUserInfo
(
eid
:
string
,
sdk
?:
UniplatSdk
)
{
if
(
userMapping
[
eid
])
{
...
...
@@ -33,6 +39,15 @@ export class ChatUserInfoService {
if
(
!+
eid
||
+
eid
<
0
)
{
return
{
name
:
""
,
phone
:
""
,
icon
:
""
,
alias_name
:
""
};
}
if
(
loadingKeys
.
has
(
eid
))
{
return
new
Promise
<
ChatUserSummaryInfo
>
((
resolve
)
=>
waitingAction
.
push
({
key
:
eid
,
resolve
})
);
}
loadingKeys
.
add
(
eid
);
const
info
=
await
(
sdk
||
Chat
.
getSdk
())
.
domainService
(
"passport"
,
...
...
@@ -47,6 +62,21 @@ export class ChatUserInfoService {
alias_name
:
info
.
alias_name
,
};
userMapping
[
eid
]
=
data
;
const
removing
=
[];
for
(
const
item
of
waitingAction
)
{
if
(
item
.
key
===
eid
)
{
item
.
resolve
(
data
);
removing
.
push
(
item
.
key
);
}
}
for
(
const
item
of
removing
)
{
waitingAction
=
waitingAction
.
filter
((
i
)
=>
i
.
key
!==
item
);
}
loadingKeys
.
delete
(
eid
);
return
data
;
}
...
...
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