Skip to content

Commit 34fe09e

Browse files
author
puhui999
committed
【功能完善】商城客服: 客服布局样式调整
1 parent 1d01955 commit 34fe09e

File tree

7 files changed

+155
-79
lines changed

7 files changed

+155
-79
lines changed

src/views/mall/promotion/kefu/components/KeFuConversationList.vue

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<template>
2-
<div class="kefu">
2+
<el-aside class="kefu-conversation-aside p-10px h-100%" width="260px">
3+
<div class="color-[#999] font-bold my-10px">会话记录({{ conversationList.length }})</div>
34
<div
45
v-for="item in conversationList"
56
:key="item.id"
@@ -22,7 +23,7 @@
2223
<div class="ml-10px w-100%">
2324
<div class="flex justify-between items-center w-100%">
2425
<span class="username">{{ item.userNickname }}</span>
25-
<span class="color-[var(--left-menu-text-color)]" style="font-size: 13px">
26+
<span class="color-[#999]" style="font-size: 13px">
2627
{{ formatPast(item.lastMessageTime, 'YYYY-MM-DD') }}
2728
</span>
2829
</div>
@@ -31,7 +32,7 @@
3132
v-dompurify-html="
3233
getConversationDisplayText(item.lastMessageContentType, item.lastMessageContent)
3334
"
34-
class="last-message flex items-center color-[var(--left-menu-text-color)]"
35+
class="last-message flex items-center color-[#999]"
3536
>
3637
</div>
3738
</div>
@@ -65,7 +66,7 @@
6566
取消
6667
</li>
6768
</ul>
68-
</div>
69+
</el-aside>
6970
</template>
7071

7172
<script lang="ts" setup>
@@ -179,7 +180,9 @@ watch(showRightMenu, (val) => {
179180
</script>
180181

181182
<style lang="scss" scoped>
182-
.kefu {
183+
.kefu-conversation-aside {
184+
background-color: #fff;
185+
183186
&-conversation {
184187
height: 60px;
185188
padding: 10px;
@@ -206,12 +209,13 @@ watch(showRightMenu, (val) => {
206209
}
207210
208211
.active {
209-
border-left: 5px #3271ff solid;
210-
background-color: var(--login-bg-color);
212+
//border-left: 5px #96afea solid;
213+
background-color: rgba(128, 128, 128, 0.5); // 透明色,暗黑模式下也能体现
214+
border-radius: 8px;
211215
}
212216
213217
.pinned {
214-
background-color: var(--left-menu-bg-active-color);
218+
background-color: rgba(128, 128, 128, 0.5); // 透明色,暗黑模式下也能体现
215219
}
216220
217221
.right-menu-ul {

src/views/mall/promotion/kefu/components/KeFuMessageList.vue

Lines changed: 72 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<template>
22
<el-container v-if="showKeFuMessageList" class="kefu">
3-
<el-header>
3+
<el-header class="kefu-header">
44
<div class="kefu-title">{{ conversation.userNickname }}</div>
55
</el-header>
66
<el-main class="kefu-content overflow-visible">
7-
<el-scrollbar ref="scrollbarRef" always height="calc(100vh - 495px)" @scroll="handleScroll">
8-
<div v-if="refreshContent" ref="innerRef" class="w-[100%] pb-3px">
7+
<el-scrollbar ref="scrollbarRef" always @scroll="handleScroll">
8+
<div v-if="refreshContent" ref="innerRef" class="w-[100%] px-10px">
99
<!-- 消息列表 -->
1010
<div v-for="(item, index) in getMessageList0" :key="item.id" class="w-[100%]">
1111
<div class="flex justify-center items-center mb-20px">
@@ -43,7 +43,9 @@
4343
class="w-60px h-60px"
4444
/>
4545
<div
46-
:class="{ 'kefu-message': KeFuMessageContentTypeEnum.TEXT === item.contentType }"
46+
:class="{
47+
'kefu-message': KeFuMessageContentTypeEnum.TEXT === item.contentType
48+
}"
4749
class="p-10px"
4850
>
4951
<!-- 文本消息 -->
@@ -71,10 +73,10 @@
7173
<MessageItem :message="item">
7274
<ProductItem
7375
v-if="KeFuMessageContentTypeEnum.PRODUCT === item.contentType"
74-
:spuId="getMessageContent(item).spuId"
7576
:picUrl="getMessageContent(item).picUrl"
7677
:price="getMessageContent(item).price"
7778
:skuText="getMessageContent(item).introduction"
79+
:spuId="getMessageContent(item).spuId"
7880
:title="getMessageContent(item).spuName"
7981
:titleWidth="400"
8082
class="max-w-70%"
@@ -108,23 +110,29 @@
108110
<Icon class="ml-5px" icon="ep:bottom" />
109111
</div>
110112
</el-main>
111-
<el-footer height="230px">
112-
<div class="h-[100%]">
113-
<div class="chat-tools flex items-center">
114-
<EmojiSelectPopover @select-emoji="handleEmojiSelect" />
115-
<PictureSelectUpload
116-
class="ml-15px mt-3px cursor-pointer"
117-
@send-picture="handleSendPicture"
118-
/>
119-
</div>
120-
<el-input v-model="message" :rows="6" style="border-style: none" type="textarea" />
121-
<div class="h-45px flex justify-end">
122-
<el-button class="mt-10px" type="primary" @click="handleSendMessage">发送</el-button>
123-
</div>
113+
<el-footer class="kefu-footer">
114+
<div class="chat-tools flex items-center">
115+
<EmojiSelectPopover @select-emoji="handleEmojiSelect" />
116+
<PictureSelectUpload
117+
class="ml-15px mt-3px cursor-pointer"
118+
@send-picture="handleSendPicture"
119+
/>
124120
</div>
121+
<el-input
122+
v-model="message"
123+
:rows="6"
124+
placeholder="输入消息,Enter发送,Shift+Enter换行"
125+
style="border-style: none"
126+
type="textarea"
127+
@keyup.enter.prevent="handleSendMessage"
128+
/>
125129
</el-footer>
126130
</el-container>
127-
<el-empty v-else description="请选择左侧的一个会话后开始" />
131+
<el-container v-else class="kefu">
132+
<el-main>
133+
<el-empty description="请选择左侧的一个会话后开始" />
134+
</el-main>
135+
</el-container>
128136
</template>
129137

130138
<script lang="ts" setup>
@@ -262,7 +270,11 @@ const handleSendPicture = async (picUrl: string) => {
262270
}
263271
264272
/** 发送文本消息 */
265-
const handleSendMessage = async () => {
273+
const handleSendMessage = async (event: any) => {
274+
// shift 不发送
275+
if (event.shiftKey) {
276+
return
277+
}
266278
// 1. 校验消息是否为空
267279
if (isEmpty(unref(message.value))) {
268280
messageTool.notifyWarning('请输入消息后再发送哦!')
@@ -357,14 +369,29 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
357369

358370
<style lang="scss" scoped>
359371
.kefu {
360-
&-title {
361-
border-bottom: #e4e0e0 solid 1px;
362-
height: 60px;
363-
line-height: 60px;
372+
background-color: #fff;
373+
width: calc(100% - 300px - 260px);
374+
border-left: var(--el-border-color) solid 1px;
375+
376+
.kefu-header {
377+
background: #fbfbfb;
378+
box-shadow: 0 0 0 0 #dcdfe6;
379+
display: flex;
380+
align-items: center;
381+
justify-content: space-between;
382+
383+
&-title {
384+
font-size: 18px;
385+
font-weight: bold;
386+
}
364387
}
365388
366389
&-content {
390+
margin: 0;
391+
padding: 0;
367392
position: relative;
393+
height: 100%;
394+
width: 100%;
368395
369396
.newMessageTip {
370397
position: absolute;
@@ -447,21 +474,36 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
447474
border-radius: 12rpx;
448475
padding: 8rpx 16rpx;
449476
margin-bottom: 16rpx;
450-
//background-color: #e8e8e8;
451477
color: #999;
452478
font-size: 24rpx;
453479
}
454480
}
455481
456-
.chat-tools {
457-
width: 100%;
458-
border: var(--el-border-color) solid 1px;
459-
border-radius: 10px;
460-
height: 44px;
482+
.kefu-footer {
483+
display: flex;
484+
flex-direction: column;
485+
height: auto;
486+
margin: 0;
487+
padding: 0;
488+
border-top: var(--el-border-color) solid 1px;
489+
490+
.chat-tools {
491+
width: 100%;
492+
height: 44px;
493+
}
461494
}
462495
463496
::v-deep(textarea) {
464497
resize: none;
465498
}
499+
500+
:deep(.el-input__wrapper) {
501+
box-shadow: none !important;
502+
border-radius: 0;
503+
}
504+
505+
::v-deep(.el-textarea__inner) {
506+
box-shadow: none !important;
507+
}
466508
}
467509
</style>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import KeFuConversationList from './KeFuConversationList.vue'
22
import KeFuMessageList from './KeFuMessageList.vue'
3-
import MemberBrowsingHistory from './history/MemberBrowsingHistory.vue'
3+
import MemberInfo from './member/MemberInfo.vue'
44

5-
export { KeFuConversationList, KeFuMessageList, MemberBrowsingHistory }
5+
export { KeFuConversationList, KeFuMessageList, MemberInfo }

src/views/mall/promotion/kefu/components/history/MemberBrowsingHistory.vue renamed to src/views/mall/promotion/kefu/components/member/MemberInfo.vue

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
<!-- 目录是不是叫 member 好点。然后这个组件是 MemberInfo,里面有浏览足迹 -->
22
<template>
3-
<div v-show="!isEmpty(conversation)" class="kefu">
4-
<div class="header-title h-60px flex justify-center items-center">他的足迹</div>
5-
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
6-
<el-tab-pane label="最近浏览" name="a" />
7-
<el-tab-pane label="订单列表" name="b" />
8-
</el-tabs>
9-
<div>
10-
<el-scrollbar ref="scrollbarRef" always height="calc(115vh - 400px)" @scroll="handleScroll">
11-
<!-- 最近浏览 -->
12-
<ProductBrowsingHistory v-if="activeName === 'a'" ref="productBrowsingHistoryRef" />
13-
<!-- 订单列表 -->
14-
<OrderBrowsingHistory v-if="activeName === 'b'" ref="orderBrowsingHistoryRef" />
15-
</el-scrollbar>
16-
</div>
17-
</div>
18-
<el-empty v-show="isEmpty(conversation)" description="请选择左侧的一个会话后开始" />
3+
<el-container class="kefu">
4+
<el-header class="kefu-header">
5+
<el-tabs v-model="activeName" class="kefu-tabs" @tab-click="handleClick">
6+
<el-tab-pane label="最近浏览" name="a" />
7+
<el-tab-pane label="订单列表" name="b" />
8+
</el-tabs>
9+
</el-header>
10+
<el-main class="kefu-content">
11+
<div v-show="!isEmpty(conversation)">
12+
<el-scrollbar ref="scrollbarRef" always @scroll="handleScroll">
13+
<!-- 最近浏览 -->
14+
<ProductBrowsingHistory v-if="activeName === 'a'" ref="productBrowsingHistoryRef" />
15+
<!-- 订单列表 -->
16+
<OrderBrowsingHistory v-if="activeName === 'b'" ref="orderBrowsingHistoryRef" />
17+
</el-scrollbar>
18+
</div>
19+
<el-empty v-show="isEmpty(conversation)" description="请选择左侧的一个会话后开始" />
20+
</el-main>
21+
</el-container>
1922
</template>
2023

2124
<script lang="ts" setup>
@@ -91,6 +94,41 @@ const handleScroll = debounce(() => {
9194
</script>
9295

9396
<style lang="scss" scoped>
97+
.kefu {
98+
margin: 0;
99+
padding: 0;
100+
height: 100%;
101+
width: 300px !important;
102+
background-color: #fff;
103+
border-left: var(--el-border-color) solid 1px;
104+
105+
&-header {
106+
background: #fbfbfb;
107+
box-shadow: 0 0 0 0 #dcdfe6;
108+
display: flex;
109+
align-items: center;
110+
justify-content: center;
111+
112+
&-title {
113+
font-size: 18px;
114+
font-weight: bold;
115+
}
116+
}
117+
118+
&-content {
119+
margin: 0;
120+
padding: 0;
121+
position: relative;
122+
height: 100%;
123+
width: 100%;
124+
}
125+
126+
&-tabs {
127+
height: 100%;
128+
width: 100%;
129+
}
130+
}
131+
94132
.header-title {
95133
border-bottom: #e4e0e0 solid 1px;
96134
}

src/views/mall/promotion/kefu/index.vue

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,16 @@
11
<template>
2-
<el-row :gutter="10">
2+
<el-container class="kefu-layout">
33
<!-- 会话列表 -->
4-
<el-col :span="6">
5-
<ContentWrap>
6-
<KeFuConversationList ref="keFuConversationRef" @change="handleChange" />
7-
</ContentWrap>
8-
</el-col>
4+
<KeFuConversationList ref="keFuConversationRef" @change="handleChange" />
95
<!-- 会话详情(选中会话的消息列表) -->
10-
<el-col :span="12">
11-
<ContentWrap>
12-
<KeFuMessageList ref="keFuChatBoxRef" @change="getConversationList" />
13-
</ContentWrap>
14-
</el-col>
6+
<KeFuMessageList ref="keFuChatBoxRef" @change="getConversationList" />
157
<!-- 会员足迹(选中会话的会员足迹) -->
16-
<el-col :span="6">
17-
<ContentWrap>
18-
<MemberBrowsingHistory ref="memberBrowsingHistoryRef" />
19-
</ContentWrap>
20-
</el-col>
21-
</el-row>
8+
<MemberInfo ref="memberInfoRef" />
9+
</el-container>
2210
</template>
2311

2412
<script lang="ts" setup>
25-
import { KeFuConversationList, KeFuMessageList, MemberBrowsingHistory } from './components'
13+
import { KeFuConversationList, KeFuMessageList, MemberInfo } from './components'
2614
import { WebSocketMessageTypeConstants } from './components/tools/constants'
2715
import { KeFuConversationRespVO } from '@/api/mall/promotion/kefu/conversation'
2816
import { getRefreshToken } from '@/utils/auth'
@@ -91,10 +79,10 @@ const getConversationList = () => {
9179
9280
/** 加载指定会话的消息列表 */
9381
const keFuChatBoxRef = ref<InstanceType<typeof KeFuMessageList>>()
94-
const memberBrowsingHistoryRef = ref<InstanceType<typeof MemberBrowsingHistory>>()
82+
const memberInfoRef = ref<InstanceType<typeof MemberInfo>>()
9583
const handleChange = (conversation: KeFuConversationRespVO) => {
9684
keFuChatBoxRef.value?.getNewMessageList(conversation)
97-
memberBrowsingHistoryRef.value?.initHistory(conversation)
85+
memberInfoRef.value?.initHistory(conversation)
9886
}
9987
10088
/** 初始化 */
@@ -112,9 +100,13 @@ onBeforeUnmount(() => {
112100
</script>
113101

114102
<style lang="scss">
115-
.kefu {
116-
height: calc(100vh - 165px);
117-
overflow: auto; /* 确保内容可滚动 */
103+
.kefu-layout {
104+
position: absolute;
105+
flex: 1;
106+
top: 0;
107+
left: 0;
108+
height: 100%;
109+
width: 100%;
118110
}
119111
120112
/* 定义滚动条样式 */

0 commit comments

Comments
 (0)