Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
34fe09e2
authored
Nov 04, 2024
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【功能完善】商城客服: 客服布局样式调整
parent
1d01955b
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
155 additions
and
79 deletions
+155
-79
src/views/mall/promotion/kefu/components/KeFuConversationList.vue
+12
-8
src/views/mall/promotion/kefu/components/KeFuMessageList.vue
+72
-30
src/views/mall/promotion/kefu/components/index.ts
+2
-2
src/views/mall/promotion/kefu/components/member/MemberInfo.vue
+54
-16
src/views/mall/promotion/kefu/components/member/OrderBrowsingHistory.vue
+0
-0
src/views/mall/promotion/kefu/components/member/ProductBrowsingHistory.vue
+0
-0
src/views/mall/promotion/kefu/index.vue
+15
-23
No files found.
src/views/mall/promotion/kefu/components/KeFuConversationList.vue
View file @
34fe09e2
<
template
>
<div
class=
"kefu"
>
<el-aside
class=
"kefu-conversation-aside p-10px h-100%"
width=
"260px"
>
<div
class=
"color-[#999] font-bold my-10px"
>
会话记录(
{{
conversationList
.
length
}}
)
</div>
<div
v-for=
"item in conversationList"
:key=
"item.id"
...
...
@@ -22,7 +23,7 @@
<div
class=
"ml-10px w-100%"
>
<div
class=
"flex justify-between items-center w-100%"
>
<span
class=
"username"
>
{{
item
.
userNickname
}}
</span>
<span
class=
"color-[
var(--left-menu-text-color)
]"
style=
"font-size: 13px"
>
<span
class=
"color-[
#999
]"
style=
"font-size: 13px"
>
{{
formatPast
(
item
.
lastMessageTime
,
'YYYY-MM-DD'
)
}}
</span>
</div>
...
...
@@ -31,7 +32,7 @@
v-dompurify-html=
"
getConversationDisplayText(item.lastMessageContentType, item.lastMessageContent)
"
class=
"last-message flex items-center color-[
var(--left-menu-text-color)
]"
class=
"last-message flex items-center color-[
#999
]"
>
</div>
</div>
...
...
@@ -65,7 +66,7 @@
取消
</li>
</ul>
</
div
>
</
el-aside
>
</
template
>
<
script
lang=
"ts"
setup
>
...
...
@@ -179,7 +180,9 @@ watch(showRightMenu, (val) => {
</
script
>
<
style
lang=
"scss"
scoped
>
.kefu
{
.kefu-conversation-aside
{
background-color
:
#fff
;
&-conversation
{
height
:
60px
;
padding
:
10px
;
...
...
@@ -206,12 +209,13 @@ watch(showRightMenu, (val) => {
}
.active
{
border-left
:
5px
#3271ff
solid
;
background-color
:
var
(
--login-bg-color
);
//
border-left
:
5px
#96afea
solid
;
background-color
:
rgba
(
128
,
128
,
128
,
0.5
);
//
透明色,暗黑模式下也能体现
border-radius
:
8px
;
}
.pinned
{
background-color
:
var
(
--left-menu-bg-active-color
);
background-color
:
rgba
(
128
,
128
,
128
,
0.5
);
//
透明色,暗黑模式下也能体现
}
.right-menu-ul
{
...
...
src/views/mall/promotion/kefu/components/KeFuMessageList.vue
View file @
34fe09e2
<
template
>
<el-container
v-if=
"showKeFuMessageList"
class=
"kefu"
>
<el-header>
<el-header
class=
"kefu-header"
>
<div
class=
"kefu-title"
>
{{
conversation
.
userNickname
}}
</div>
</el-header>
<el-main
class=
"kefu-content overflow-visible"
>
<el-scrollbar
ref=
"scrollbarRef"
always
height=
"calc(100vh - 495px)"
@
scroll=
"handleScroll"
>
<div
v-if=
"refreshContent"
ref=
"innerRef"
class=
"w-[100%] p
b-3
px"
>
<el-scrollbar
ref=
"scrollbarRef"
always
@
scroll=
"handleScroll"
>
<div
v-if=
"refreshContent"
ref=
"innerRef"
class=
"w-[100%] p
x-10
px"
>
<!-- 消息列表 -->
<div
v-for=
"(item, index) in getMessageList0"
:key=
"item.id"
class=
"w-[100%]"
>
<div
class=
"flex justify-center items-center mb-20px"
>
...
...
@@ -43,7 +43,9 @@
class=
"w-60px h-60px"
/>
<div
:class=
"
{ 'kefu-message': KeFuMessageContentTypeEnum.TEXT === item.contentType }"
:class=
"
{
'kefu-message': KeFuMessageContentTypeEnum.TEXT === item.contentType
}"
class="p-10px"
>
<!-- 文本消息 -->
...
...
@@ -71,10 +73,10 @@
<MessageItem
:message=
"item"
>
<ProductItem
v-if=
"KeFuMessageContentTypeEnum.PRODUCT === item.contentType"
:spuId=
"getMessageContent(item).spuId"
:picUrl=
"getMessageContent(item).picUrl"
:price=
"getMessageContent(item).price"
:skuText=
"getMessageContent(item).introduction"
:spuId=
"getMessageContent(item).spuId"
:title=
"getMessageContent(item).spuName"
:titleWidth=
"400"
class=
"max-w-70%"
...
...
@@ -108,23 +110,29 @@
<Icon
class=
"ml-5px"
icon=
"ep:bottom"
/>
</div>
</el-main>
<el-footer
height=
"230px"
>
<div
class=
"h-[100%]"
>
<div
class=
"chat-tools flex items-center"
>
<EmojiSelectPopover
@
select-emoji=
"handleEmojiSelect"
/>
<PictureSelectUpload
class=
"ml-15px mt-3px cursor-pointer"
@
send-picture=
"handleSendPicture"
/>
</div>
<el-input
v-model=
"message"
:rows=
"6"
style=
"border-style: none"
type=
"textarea"
/>
<div
class=
"h-45px flex justify-end"
>
<el-button
class=
"mt-10px"
type=
"primary"
@
click=
"handleSendMessage"
>
发送
</el-button>
</div>
<el-footer
class=
"kefu-footer"
>
<div
class=
"chat-tools flex items-center"
>
<EmojiSelectPopover
@
select-emoji=
"handleEmojiSelect"
/>
<PictureSelectUpload
class=
"ml-15px mt-3px cursor-pointer"
@
send-picture=
"handleSendPicture"
/>
</div>
<el-input
v-model=
"message"
:rows=
"6"
placeholder=
"输入消息,Enter发送,Shift+Enter换行"
style=
"border-style: none"
type=
"textarea"
@
keyup
.
enter
.
prevent=
"handleSendMessage"
/>
</el-footer>
</el-container>
<el-empty
v-else
description=
"请选择左侧的一个会话后开始"
/>
<el-container
v-else
class=
"kefu"
>
<el-main>
<el-empty
description=
"请选择左侧的一个会话后开始"
/>
</el-main>
</el-container>
</template>
<
script
lang=
"ts"
setup
>
...
...
@@ -262,7 +270,11 @@ const handleSendPicture = async (picUrl: string) => {
}
/** 发送文本消息 */
const
handleSendMessage
=
async
()
=>
{
const
handleSendMessage
=
async
(
event
:
any
)
=>
{
// shift 不发送
if
(
event
.
shiftKey
)
{
return
}
// 1. 校验消息是否为空
if
(
isEmpty
(
unref
(
message
.
value
)))
{
messageTool
.
notifyWarning
(
'请输入消息后再发送哦!'
)
...
...
@@ -357,14 +369,29 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
<
style
lang=
"scss"
scoped
>
.kefu
{
&-title
{
border-bottom
:
#e4e0e0
solid
1px
;
height
:
60px
;
line-height
:
60px
;
background-color
:
#fff
;
width
:
calc
(
100%
-
300px
-
260px
);
border-left
:
var
(
--el-border-color
)
solid
1px
;
.kefu-header
{
background
:
#fbfbfb
;
box-shadow
:
0
0
0
0
#dcdfe6
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
&-title
{
font-size
:
18px
;
font-weight
:
bold
;
}
}
&
-content
{
margin
:
0
;
padding
:
0
;
position
:
relative
;
height
:
100%
;
width
:
100%
;
.newMessageTip
{
position
:
absolute
;
...
...
@@ -447,21 +474,36 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
border-radius
:
12
rpx
;
padding
:
8
rpx
16
rpx
;
margin-bottom
:
16
rpx
;
//
background-color
:
#e8e8e8
;
color
:
#999
;
font-size
:
24
rpx
;
}
}
.chat-tools
{
width
:
100%
;
border
:
var
(
--el-border-color
)
solid
1px
;
border-radius
:
10px
;
height
:
44px
;
.kefu-footer
{
display
:
flex
;
flex-direction
:
column
;
height
:
auto
;
margin
:
0
;
padding
:
0
;
border-top
:
var
(
--el-border-color
)
solid
1px
;
.chat-tools
{
width
:
100%
;
height
:
44px
;
}
}
::v-deep
(
textarea
)
{
resize
:
none
;
}
:deep
(
.el-input__wrapper
)
{
box-shadow
:
none
!important
;
border-radius
:
0
;
}
::v-deep
(
.el-textarea__inner
)
{
box-shadow
:
none
!important
;
}
}
</
style
>
src/views/mall/promotion/kefu/components/index.ts
View file @
34fe09e2
import
KeFuConversationList
from
'./KeFuConversationList.vue'
import
KeFuMessageList
from
'./KeFuMessageList.vue'
import
Member
BrowsingHistory
from
'./history/MemberBrowsingHistory
.vue'
import
Member
Info
from
'./member/MemberInfo
.vue'
export
{
KeFuConversationList
,
KeFuMessageList
,
Member
BrowsingHistory
}
export
{
KeFuConversationList
,
KeFuMessageList
,
Member
Info
}
src/views/mall/promotion/kefu/components/
history/MemberBrowsingHistory
.vue
→
src/views/mall/promotion/kefu/components/
member/MemberInfo
.vue
View file @
34fe09e2
<!-- 目录是不是叫 member 好点。然后这个组件是 MemberInfo,里面有浏览足迹 -->
<
template
>
<div
v-show=
"!isEmpty(conversation)"
class=
"kefu"
>
<div
class=
"header-title h-60px flex justify-center items-center"
>
他的足迹
</div>
<el-tabs
v-model=
"activeName"
class=
"demo-tabs"
@
tab-click=
"handleClick"
>
<el-tab-pane
label=
"最近浏览"
name=
"a"
/>
<el-tab-pane
label=
"订单列表"
name=
"b"
/>
</el-tabs>
<div>
<el-scrollbar
ref=
"scrollbarRef"
always
height=
"calc(115vh - 400px)"
@
scroll=
"handleScroll"
>
<!-- 最近浏览 -->
<ProductBrowsingHistory
v-if=
"activeName === 'a'"
ref=
"productBrowsingHistoryRef"
/>
<!-- 订单列表 -->
<OrderBrowsingHistory
v-if=
"activeName === 'b'"
ref=
"orderBrowsingHistoryRef"
/>
</el-scrollbar>
</div>
</div>
<el-empty
v-show=
"isEmpty(conversation)"
description=
"请选择左侧的一个会话后开始"
/>
<el-container
class=
"kefu"
>
<el-header
class=
"kefu-header"
>
<el-tabs
v-model=
"activeName"
class=
"kefu-tabs"
@
tab-click=
"handleClick"
>
<el-tab-pane
label=
"最近浏览"
name=
"a"
/>
<el-tab-pane
label=
"订单列表"
name=
"b"
/>
</el-tabs>
</el-header>
<el-main
class=
"kefu-content"
>
<div
v-show=
"!isEmpty(conversation)"
>
<el-scrollbar
ref=
"scrollbarRef"
always
@
scroll=
"handleScroll"
>
<!-- 最近浏览 -->
<ProductBrowsingHistory
v-if=
"activeName === 'a'"
ref=
"productBrowsingHistoryRef"
/>
<!-- 订单列表 -->
<OrderBrowsingHistory
v-if=
"activeName === 'b'"
ref=
"orderBrowsingHistoryRef"
/>
</el-scrollbar>
</div>
<el-empty
v-show=
"isEmpty(conversation)"
description=
"请选择左侧的一个会话后开始"
/>
</el-main>
</el-container>
</
template
>
<
script
lang=
"ts"
setup
>
...
...
@@ -91,6 +94,41 @@ const handleScroll = debounce(() => {
</
script
>
<
style
lang=
"scss"
scoped
>
.kefu
{
margin
:
0
;
padding
:
0
;
height
:
100%
;
width
:
300px
!important
;
background-color
:
#fff
;
border-left
:
var
(
--el-border-color
)
solid
1px
;
&-header
{
background
:
#fbfbfb
;
box-shadow
:
0
0
0
0
#dcdfe6
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
&-title
{
font-size
:
18px
;
font-weight
:
bold
;
}
}
&
-content
{
margin
:
0
;
padding
:
0
;
position
:
relative
;
height
:
100%
;
width
:
100%
;
}
&
-tabs
{
height
:
100%
;
width
:
100%
;
}
}
.header-title
{
border-bottom
:
#e4e0e0
solid
1px
;
}
...
...
src/views/mall/promotion/kefu/components/
history
/OrderBrowsingHistory.vue
→
src/views/mall/promotion/kefu/components/
member
/OrderBrowsingHistory.vue
View file @
34fe09e2
File moved
src/views/mall/promotion/kefu/components/
history
/ProductBrowsingHistory.vue
→
src/views/mall/promotion/kefu/components/
member
/ProductBrowsingHistory.vue
View file @
34fe09e2
File moved
src/views/mall/promotion/kefu/index.vue
View file @
34fe09e2
<
template
>
<el-
row
:gutter=
"10
"
>
<el-
container
class=
"kefu-layout
"
>
<!-- 会话列表 -->
<el-col
:span=
"6"
>
<ContentWrap>
<KeFuConversationList
ref=
"keFuConversationRef"
@
change=
"handleChange"
/>
</ContentWrap>
</el-col>
<KeFuConversationList
ref=
"keFuConversationRef"
@
change=
"handleChange"
/>
<!-- 会话详情(选中会话的消息列表) -->
<el-col
:span=
"12"
>
<ContentWrap>
<KeFuMessageList
ref=
"keFuChatBoxRef"
@
change=
"getConversationList"
/>
</ContentWrap>
</el-col>
<KeFuMessageList
ref=
"keFuChatBoxRef"
@
change=
"getConversationList"
/>
<!-- 会员足迹(选中会话的会员足迹) -->
<el-col
:span=
"6"
>
<ContentWrap>
<MemberBrowsingHistory
ref=
"memberBrowsingHistoryRef"
/>
</ContentWrap>
</el-col>
</el-row>
<MemberInfo
ref=
"memberInfoRef"
/>
</el-container>
</
template
>
<
script
lang=
"ts"
setup
>
import
{
KeFuConversationList
,
KeFuMessageList
,
Member
BrowsingHistory
}
from
'./components'
import
{
KeFuConversationList
,
KeFuMessageList
,
Member
Info
}
from
'./components'
import
{
WebSocketMessageTypeConstants
}
from
'./components/tools/constants'
import
{
KeFuConversationRespVO
}
from
'@/api/mall/promotion/kefu/conversation'
import
{
getRefreshToken
}
from
'@/utils/auth'
...
...
@@ -91,10 +79,10 @@ const getConversationList = () => {
/** 加载指定会话的消息列表 */
const
keFuChatBoxRef
=
ref
<
InstanceType
<
typeof
KeFuMessageList
>>
()
const
member
BrowsingHistoryRef
=
ref
<
InstanceType
<
typeof
MemberBrowsingHistory
>>
()
const
member
InfoRef
=
ref
<
InstanceType
<
typeof
MemberInfo
>>
()
const
handleChange
=
(
conversation
:
KeFuConversationRespVO
)
=>
{
keFuChatBoxRef
.
value
?.
getNewMessageList
(
conversation
)
member
BrowsingHistory
Ref
.
value
?.
initHistory
(
conversation
)
member
Info
Ref
.
value
?.
initHistory
(
conversation
)
}
/** 初始化 */
...
...
@@ -112,9 +100,13 @@ onBeforeUnmount(() => {
</
script
>
<
style
lang=
"scss"
>
.kefu
{
height
:
calc
(
100vh
-
165px
);
overflow
:
auto
;
/* 确保内容可滚动 */
.kefu-layout
{
position
:
absolute
;
flex
:
1
;
top
:
0
;
left
:
0
;
height
:
100%
;
width
:
100%
;
}
/* 定义滚动条样式 */
...
...
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