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
e45cade8
authored
Jul 04, 2024
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【新增】:mall 客服选择并发送图片信息
parent
b0b62eb2
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
132 additions
and
11 deletions
+132
-11
src/views/mall/promotion/kefu/components/KeFuChatBox.vue
+26
-7
src/views/mall/promotion/kefu/components/KeFuConversationBox.vue
+2
-2
src/views/mall/promotion/kefu/components/images/picture.svg
+10
-0
src/views/mall/promotion/kefu/components/index.ts
+1
-1
src/views/mall/promotion/kefu/components/tools/EmojiSelectPopover.vue
+1
-1
src/views/mall/promotion/kefu/components/tools/PictureSelectUpload.vue
+92
-0
src/views/mall/promotion/kefu/components/tools/constants.ts
+0
-0
src/views/mall/promotion/kefu/components/tools/emoji.ts
+0
-0
No files found.
src/views/mall/promotion/kefu/components/KeFuChatBox.vue
View file @
e45cade8
...
...
@@ -71,10 +71,14 @@
</el-main>
<el-footer
height=
"230px"
>
<div
class=
"h-[100%]"
>
<div
class=
"chat-tools"
>
<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"
type=
"textarea"
/>
<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>
...
...
@@ -88,9 +92,10 @@
import
{
ElScrollbar
as
ElScrollbarType
}
from
'element-plus'
import
{
KeFuMessageApi
,
KeFuMessageRespVO
}
from
'@/api/mall/promotion/kefu/message'
import
{
KeFuConversationRespVO
}
from
'@/api/mall/promotion/kefu/conversation'
import
EmojiSelectPopover
from
'./EmojiSelectPopover.vue'
import
{
Emoji
,
useEmoji
}
from
'./emoji'
import
{
KeFuMessageContentTypeEnum
}
from
'./constants'
import
EmojiSelectPopover
from
'./tools/EmojiSelectPopover.vue'
import
PictureSelectUpload
from
'./tools/PictureSelectUpload.vue'
import
{
Emoji
,
useEmoji
}
from
'./tools/emoji'
import
{
KeFuMessageContentTypeEnum
}
from
'./tools/constants'
import
{
isEmpty
}
from
'@/utils/is'
import
{
UserTypeEnum
}
from
'@/utils/constants'
import
{
createImageViewer
}
from
'@/components/ImageViewer'
...
...
@@ -126,6 +131,16 @@ const showChatBox = computed(() => !isEmpty(keFuConversation.value))
const
handleEmojiSelect
=
(
item
:
Emoji
)
=>
{
message
.
value
+=
item
.
name
}
// 处理图片发送
const
handleSendPicture
=
async
(
picUrl
:
string
)
=>
{
// 组织发送消息
const
msg
=
{
conversationId
:
keFuConversation
.
value
.
id
,
contentType
:
KeFuMessageContentTypeEnum
.
IMAGE
,
content
:
picUrl
}
await
sendMessage
(
msg
)
}
// 发送消息
const
handleSendMessage
=
async
()
=>
{
// 1. 校验消息是否为空
...
...
@@ -139,6 +154,11 @@ const handleSendMessage = async () => {
contentType
:
KeFuMessageContentTypeEnum
.
TEXT
,
content
:
message
.
value
}
await
sendMessage
(
msg
)
}
// 发送消息 【共用】
const
sendMessage
=
async
(
msg
:
any
)
=>
{
await
KeFuMessageApi
.
sendKeFuMessage
(
msg
)
message
.
value
=
''
// 3. 加载消息列表
...
...
@@ -248,9 +268,8 @@ onBeforeUnmount(() => {
.chat-tools
{
width
:
100%
;
border
:
#e4e0e0
solid
1px
;
border-radius
:
10px
;
height
:
44px
;
display
:
flex
;
align-items
:
center
;
}
::v-deep
(
textarea
)
{
...
...
src/views/mall/promotion/kefu/components/KeFuConversationBox.vue
View file @
e45cade8
...
...
@@ -35,9 +35,9 @@
<
script
lang=
"ts"
setup
>
import
{
KeFuConversationApi
,
KeFuConversationRespVO
}
from
'@/api/mall/promotion/kefu/conversation'
import
{
useEmoji
}
from
'./emoji'
import
{
useEmoji
}
from
'./
tools/
emoji'
import
{
formatDate
,
getNowDateTime
}
from
'@/utils/formatTime'
import
{
KeFuMessageContentTypeEnum
}
from
'
@/views/mall/promotion/kefu/component
s/constants'
import
{
KeFuMessageContentTypeEnum
}
from
'
./tool
s/constants'
defineOptions
({
name
:
'KeFuConversationBox'
})
const
{
replaceEmoji
}
=
useEmoji
()
...
...
src/views/mall/promotion/kefu/components/images/picture.svg
0 → 100644
View file @
e45cade8
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
t=
"1720063872285"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"6895"
width=
"200"
height=
"200"
>
<path
d=
"M782.16 880.98c-179.31 23.91-361 23.91-540.32 0C138.89 867.25 62 779.43 62 675.57V348.43c0-103.86 76.89-191.69 179.84-205.41 179.31-23.91 361-23.91 540.31 0C885.11 156.75 962 244.57 962 348.43v327.13c0 103.87-76.89 191.69-179.84 205.42z"
fill=
"#FF554D"
p-id=
"6896"
></path>
<path
d=
"M226.11 596.86c-9.74 47.83 17.26 95.6 63.48 111.3C333.49 723.08 394.55 737 469.53 737c59.25 0 105.46-8.69 140.23-19.7 51.59-16.34 79.94-71.16 63.37-122.68-24.47-76.11-65.57-180.7-106.68-180.7-64.62 0-64.62 96.92-64.62 96.92S437.22 317 372.61 317c-82.11 0-117.85 139.12-146.5 279.86z"
fill=
"#FFFFFF"
p-id=
"6897"
></path>
<path
d=
"M782 347m-60 0a60 60 0 1 0 120 0 60 60 0 1 0-120 0Z"
fill=
"#FFBC55"
p-id=
"6898"
></path>
</svg>
src/views/mall/promotion/kefu/components/index.ts
View file @
e45cade8
import
KeFuConversationBox
from
'./KeFuConversationBox.vue'
import
KeFuChatBox
from
'./KeFuChatBox.vue'
import
*
as
Constants
from
'./constants'
import
*
as
Constants
from
'./
tools/
constants'
export
{
KeFuConversationBox
,
KeFuChatBox
,
Constants
}
src/views/mall/promotion/kefu/components/EmojiSelectPopover.vue
→
src/views/mall/promotion/kefu/components/
tools/
EmojiSelectPopover.vue
View file @
e45cade8
...
...
@@ -2,7 +2,7 @@
<
template
>
<el-popover
:width=
"500"
placement=
"top"
trigger=
"click"
>
<template
#
reference
>
<Icon
:size=
"30"
class=
"ml-10px"
icon=
"twemoji:grinning-face"
/>
<Icon
:size=
"30"
class=
"ml-10px
cursor-pointer
"
icon=
"twemoji:grinning-face"
/>
</
template
>
<ElScrollbar
height=
"300px"
>
<ul
class=
"ml-2 flex flex-wrap px-2"
>
...
...
src/views/mall/promotion/kefu/components/tools/PictureSelectUpload.vue
0 → 100644
View file @
e45cade8
<
template
>
<div>
<img
:src=
"Picture"
style=
"width: 35px; height: 35px"
@
click=
"selectAndUpload"
/>
</div>
</
template
>
<
script
lang=
"ts"
setup
>
import
Picture
from
'@/views/mall/promotion/kefu/components/images/picture.svg'
import
*
as
FileApi
from
'@/api/infra/file'
defineOptions
({
name
:
'PictureSelectUpload'
})
const
message
=
useMessage
()
const
emits
=
defineEmits
<
{
(
e
:
'send-picture'
,
v
:
string
):
void
}
>
()
// 选择并上传文件
const
selectAndUpload
=
async
()
=>
{
const
files
:
any
=
await
getFiles
()
message
.
success
(
'图片发送请稍等。。。'
)
const
res
=
await
FileApi
.
updateFile
({
file
:
files
[
0
].
file
})
message
.
success
(
'图片发送成功!'
)
emits
(
'send-picture'
,
res
.
data
)
}
/**
* 唤起文件选择窗口,并获取选择的文件
* @param {Object} options - 配置选项
* @param {boolean} [options.multiple=true] - 是否支持多选
* @param {string} [options.accept=''] - 文件上传格式限制
* @param {number} [options.limit=1] - 单次上传最大文件数
* @param {number} [options.fileSize=500] - 单个文件大小限制(单位:MB)
* @returns {Promise<Array>} 选择的文件列表,每个文件带有一个uid
*/
async
function
getFiles
(
options
=
{})
{
const
{
multiple
,
accept
,
limit
,
fileSize
}
=
{
multiple
:
true
,
accept
:
'image/jpeg, image/png, image/gif'
,
limit
:
1
,
fileSize
:
500
,
...
options
}
// 创建文件选择元素
const
input
=
document
.
createElement
(
'input'
)
input
.
type
=
'file'
input
.
style
.
display
=
'none'
if
(
multiple
)
input
.
multiple
=
true
if
(
accept
)
input
.
accept
=
accept
// 将文件选择元素添加到文档中
document
.
body
.
appendChild
(
input
)
// 触发文件选择元素的点击事件
input
.
click
()
// 等待文件选择元素的 change 事件
try
{
const
files
=
await
new
Promise
((
resolve
,
reject
)
=>
{
input
.
addEventListener
(
'change'
,
(
event
:
any
)
=>
{
const
filesArray
=
Array
.
from
(
event
?.
target
?.
files
||
[])
// 从文档中移除文件选择元素
document
.
body
.
removeChild
(
input
)
// 判断是否超出上传数量限制
if
(
filesArray
.
length
>
limit
)
{
reject
({
errorType
:
'limit'
,
files
:
filesArray
})
return
}
// 判断是否超出上传文件大小限制
const
oversizedFiles
=
filesArray
.
filter
((
file
:
File
)
=>
file
.
size
/
1024
**
2
>
fileSize
)
if
(
oversizedFiles
.
length
>
0
)
{
reject
({
errorType
:
'fileSize'
,
files
:
oversizedFiles
})
return
}
// 生成文件列表,并添加 uid
const
fileList
=
filesArray
.
map
((
file
,
index
)
=>
({
file
,
uid
:
Date
.
now
()
+
index
}))
resolve
(
fileList
)
})
})
return
files
}
catch
(
error
)
{
console
.
error
(
'选择文件出错:'
,
error
)
throw
error
}
}
</
script
>
<
style
lang=
"scss"
scoped
></
style
>
src/views/mall/promotion/kefu/components/constants.ts
→
src/views/mall/promotion/kefu/components/
tools/
constants.ts
View file @
e45cade8
File moved
src/views/mall/promotion/kefu/components/emoji.ts
→
src/views/mall/promotion/kefu/components/
tools/
emoji.ts
View file @
e45cade8
File moved
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