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
daa124a4
authored
Apr 09, 2023
by
dhb52
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 微信自动回复
parent
7cf8ea8d
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
433 additions
and
1 deletions
+433
-1
src/views/mp/autoReply/index.vue
+433
-1
No files found.
src/views/mp/autoReply/index.vue
View file @
daa124a4
<
template
>
<
template
>
<span>
开发中
</span>
<div
class=
"app-container"
>
<doc-alert
title=
"自动回复"
url=
"https://doc.iocoder.cn/mp/auto-reply/"
/>
<!-- 搜索工作栏 -->
<el-form
:model=
"queryParams"
ref=
"queryFormRef"
size=
"small"
:inline=
"true"
v-show=
"showSearch"
label-width=
"68px"
>
<el-form-item
label=
"公众号"
prop=
"accountId"
>
<el-select
v-model=
"queryParams.accountId"
placeholder=
"请选择公众号"
>
<el-option
v-for=
"item in accounts"
:key=
"parseInt(item.id)"
:label=
"item.name"
:value=
"parseInt(item.id)"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
@
click=
"handleQuery"
><Icon
icon=
"ep:search"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
><Icon
icon=
"ep:refresh"
/>
重置
</el-button>
</el-form-item>
</el-form>
<ContentWrap>
<!-- tab 切换 -->
<el-tabs
v-model=
"type"
@
tab-change=
"handleTabChange"
>
<!-- 操作工具栏 -->
<el-row
:gutter=
"10"
class=
"mb8"
>
<el-col
:span=
"1.5"
>
<el-button
type=
"primary"
plain
size=
"small"
@
click=
"handleAdd"
v-hasPermi=
"['mp:auto-reply:create']"
v-if=
"type !== '1' || list.length
<
=
0
"
><Icon
icon=
"ep:plus"
/>
新增
</el-button>
</el-col>
<!--
<right-toolbar
v-model:showSearch=
"showSearch"
@
query-table=
"getList"
/>
-->
</el-row>
<!-- tab 项 -->
<el-tab-pane
name=
"1"
>
<template
#
label
>
<span><Icon
icon=
"ep:star-off"
/>
关注时回复
</span>
</
template
>
</el-tab-pane>
<el-tab-pane
name=
"2"
>
<
template
#
label
>
<span><Icon
icon=
"ep:chat-line-round"
/>
消息回复
</span>
</
template
>
</el-tab-pane>
<el-tab-pane
name=
"3"
>
<
template
#
label
>
<span><Icon
icon=
"ep:news"
/>
关键词回复
</span>
</
template
>
</el-tab-pane>
</el-tabs>
<!-- 列表 -->
<el-table
v-loading=
"loading"
:data=
"list"
>
<el-table-column
label=
"请求消息类型"
align=
"center"
prop=
"requestMessageType"
v-if=
"type === '2'"
/>
<el-table-column
label=
"关键词"
align=
"center"
prop=
"requestKeyword"
v-if=
"type === '3'"
/>
<el-table-column
label=
"匹配类型"
align=
"center"
prop=
"requestMatch"
v-if=
"type === '3'"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.MP_AUTO_REPLY_REQUEST_MATCH"
:value=
"scope.row.requestMatch"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"回复消息类型"
align=
"center"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.MP_MESSAGE_TYPE"
:value=
"scope.row.responseMessageType"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"回复内容"
align=
"center"
>
<
template
#
default=
"scope"
>
<div
v-if=
"scope.row.responseMessageType === 'text'"
>
{{
scope
.
row
.
responseContent
}}
</div>
<div
v-else-if=
"scope.row.responseMessageType === 'voice'"
>
<WxVoicePlayer
:url=
"scope.row.responseMediaUrl"
/>
</div>
<div
v-else-if=
"scope.row.responseMessageType === 'image'"
>
<a
target=
"_blank"
:href=
"scope.row.responseMediaUrl"
>
<img
:src=
"scope.row.responseMediaUrl"
style=
"width: 100px"
/>
</a>
</div>
<div
v-else-if=
"
scope.row.responseMessageType === 'video' ||
scope.row.responseMessageType === 'shortvideo'
"
>
<WxVideoPlayer
:url=
"scope.row.responseMediaUrl"
style=
"margin-top: 10px"
/>
</div>
<div
v-else-if=
"scope.row.responseMessageType === 'news'"
>
<WxNews
:articles=
"scope.row.responseArticles"
/>
</div>
<div
v-else-if=
"scope.row.responseMessageType === 'music'"
>
<WxMusic
:title=
"scope.row.responseTitle"
:description=
"scope.row.responseDescription"
:thumb-media-url=
"scope.row.responseThumbMediaUrl"
:music-url=
"scope.row.responseMusicUrl"
:hq-music-url=
"scope.row.responseHqMusicUrl"
/>
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"创建时间"
align=
"center"
prop=
"createTime"
width=
"180"
>
<
template
#
default=
"scope"
>
<span>
{{
formatDate
(
scope
.
row
.
createTime
)
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
class-name=
"small-padding fixed-width"
>
<
template
#
default=
"scope"
>
<el-button
size=
"small"
type=
"primary"
link
@
click=
"handleUpdate(scope.row)"
v-hasPermi=
"['mp:auto-reply:update']"
><Icon
icon=
"ep:edit"
/>
修改
</el-button>
<el-button
size=
"small"
type=
"primary"
link
@
click=
"handleDelete(scope.row)"
v-hasPermi=
"['mp:auto-reply:delete']"
><Icon
icon=
"ep:delete"
/>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 添加或修改自动回复的对话框 -->
<el-dialog
:title=
"title"
v-model=
"open"
width=
"800px"
append-to-body
>
<el-form
ref=
"formRef"
:model=
"form"
:rules=
"rules"
label-width=
"80px"
>
<el-form-item
label=
"消息类型"
prop=
"requestMessageType"
v-if=
"type === '2'"
>
<el-select
v-model=
"form.requestMessageType"
placeholder=
"请选择"
>
<
template
v-for=
"dict in getDictOptions(DICT_TYPE.MP_MESSAGE_TYPE)"
:key=
"dict.value"
>
<el-option
v-if=
"requestMessageTypes.includes(dict.value)"
:label=
"dict.label"
:value=
"dict.value"
/>
</
template
>
</el-select>
</el-form-item>
<el-form-item
label=
"匹配类型"
prop=
"requestMatch"
v-if=
"type === '3'"
>
<el-select
v-model=
"form.requestMatch"
placeholder=
"请选择匹配类型"
clearable
size=
"small"
>
<el-option
v-for=
"dict in getDictOptions(DICT_TYPE.MP_AUTO_REPLY_REQUEST_MATCH)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"parseInt(dict.value)"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"关键词"
prop=
"requestKeyword"
v-if=
"type === '3'"
>
<el-input
v-model=
"form.requestKeyword"
placeholder=
"请输入内容"
clearable
/>
</el-form-item>
<el-form-item
label=
"回复消息"
>
<WxReplySelect
:objData=
"objData"
v-if=
"hackResetWxReplySelect"
/>
</el-form-item>
</el-form>
<
template
#
footer
>
<span
class=
"dialog-footer"
>
<el-button
@
click=
"cancel"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"handleSubmit"
>
确 定
</el-button>
</span>
</
template
>
</el-dialog>
</ContentWrap>
</div>
</template>
</template>
<
script
setup
>
import
{
ref
,
reactive
,
onMounted
,
nextTick
}
from
'vue'
import
WxVideoPlayer
from
'@/views/mp/components/wx-video-play/main.vue'
import
WxVoicePlayer
from
'@/views/mp/components/wx-voice-play/main.vue'
import
WxMusic
from
'@/views/mp/components/wx-music/main.vue'
import
WxNews
from
'@/views/mp/components/wx-news/main.vue'
import
WxReplySelect
from
'@/views/mp/components/wx-reply/main.vue'
import
{
getSimpleAccountList
}
from
'@/api/mp/account'
import
{
createAutoReply
,
deleteAutoReply
,
getAutoReply
,
getAutoReplyPage
,
updateAutoReply
}
from
'@/api/mp/autoReply'
import
{
DICT_TYPE
,
getDictOptions
}
from
'@/utils/dict'
import
{
formatDate
}
from
'@/utils/formatTime'
import
{
ContentWrap
}
from
'@/components/ContentWrap'
const
message
=
useMessage
()
const
queryFormRef
=
ref
()
const
formRef
=
ref
()
// tab 类型(1、关注时回复;2、消息回复;3、关键词回复)
const
type
=
ref
(
'3'
)
// 允许选择的请求消息类型
const
requestMessageTypes
=
[
'text'
,
'image'
,
'voice'
,
'video'
,
'shortvideo'
,
'location'
,
'link'
]
// 遮罩层
const
loading
=
ref
(
true
)
// 显示搜索条件
const
showSearch
=
ref
(
true
)
// 总条数
const
total
=
ref
(
0
)
// 自动回复列表
const
list
=
ref
([])
// 查询参数
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
accountId
:
undefined
})
// 弹出层标题
const
title
=
ref
(
''
)
// 是否显示弹出层
const
open
=
ref
(
false
)
// 表单参数
const
form
=
ref
({})
// 回复消息
const
objData
=
ref
({
type
:
'text'
})
// 表单校验
const
rules
=
{
requestKeyword
:
[{
required
:
true
,
message
:
'请求的关键字不能为空'
,
trigger
:
'blur'
}],
requestMatch
:
[{
required
:
true
,
message
:
'请求的关键字的匹配不能为空'
,
trigger
:
'blur'
}]
}
const
hackResetWxReplySelect
=
ref
(
false
)
// 重置 WxReplySelect 组件,解决无法清除的问题
// 公众号账号列表
const
accounts
=
ref
([])
onMounted
(()
=>
{
getSimpleAccountList
().
then
((
data
)
=>
{
accounts
.
value
=
data
// 默认选中第一个
if
(
accounts
.
value
.
length
>
0
)
{
queryParams
.
accountId
=
accounts
.
value
[
0
].
id
}
// 加载数据
getList
()
})
})
/** 查询列表 */
const
getList
=
async
()
=>
{
// 如果没有选中公众号账号,则进行提示。
if
(
!
queryParams
.
accountId
)
{
message
.
error
(
'未选中公众号,无法查询自动回复'
)
return
false
}
loading
.
value
=
false
// 处理查询参数
let
params
=
{
...
queryParams
,
type
:
type
.
value
}
// 执行查询
getAutoReplyPage
(
params
).
then
((
data
)
=>
{
list
.
value
=
data
.
list
total
.
value
=
data
.
total
loading
.
value
=
false
})
}
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getList
()
}
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
?.
resetFields
()
// 默认选中第一个
if
(
accounts
.
value
.
length
>
0
)
{
queryParams
.
accountId
=
accounts
.
value
[
0
].
id
}
handleQuery
()
}
const
handleTabChange
=
(
tabName
)
=>
{
type
.
value
=
tabName
handleQuery
()
}
/** 新增按钮操作 */
const
handleAdd
=
()
=>
{
reset
()
resetEditor
()
// 打开表单,并设置初始化
open
.
value
=
true
title
.
value
=
'新增自动回复'
objData
.
value
=
{
type
:
'text'
,
accountId
:
queryParams
.
accountId
}
}
/** 修改按钮操作 */
const
handleUpdate
=
(
row
)
=>
{
reset
()
resetEditor
()
console
.
log
(
row
)
getAutoReply
(
row
.
id
).
then
((
data
)
=>
{
// 设置属性
form
.
value
=
{
...
data
}
delete
form
.
value
[
'responseMessageType'
]
delete
form
.
value
[
'responseContent'
]
delete
form
.
value
[
'responseMediaId'
]
delete
form
.
value
[
'responseMediaUrl'
]
delete
form
.
value
[
'responseDescription'
]
delete
form
.
value
[
'responseArticles'
]
objData
.
value
=
{
type
:
data
.
responseMessageType
,
accountId
:
queryParams
.
accountId
,
content
:
data
.
responseContent
,
mediaId
:
data
.
responseMediaId
,
url
:
data
.
responseMediaUrl
,
title
:
data
.
responseTitle
,
description
:
data
.
responseDescription
,
thumbMediaId
:
data
.
responseThumbMediaId
,
thumbMediaUrl
:
data
.
responseThumbMediaUrl
,
articles
:
data
.
responseArticles
,
musicUrl
:
data
.
responseMusicUrl
,
hqMusicUrl
:
data
.
responseHqMusicUrl
}
// 打开表单
open
.
value
=
true
title
.
value
=
'修改自动回复'
})
}
const
handleSubmit
=
()
=>
{
formRef
.
value
?.
validate
((
valid
)
=>
{
if
(
!
valid
)
{
return
}
// 处理回复消息
const
form
=
{
...
form
.
value
}
form
.
responseMessageType
=
objData
.
value
.
type
form
.
responseContent
=
objData
.
value
.
content
form
.
responseMediaId
=
objData
.
value
.
mediaId
form
.
responseMediaUrl
=
objData
.
value
.
url
form
.
responseTitle
=
objData
.
value
.
title
form
.
responseDescription
=
objData
.
value
.
description
form
.
responseThumbMediaId
=
objData
.
value
.
thumbMediaId
form
.
responseThumbMediaUrl
=
objData
.
value
.
thumbMediaUrl
form
.
responseArticles
=
objData
.
value
.
articles
form
.
responseMusicUrl
=
objData
.
value
.
musicUrl
form
.
responseHqMusicUrl
=
objData
.
value
.
hqMusicUrl
if
(
form
.
value
.
id
!==
undefined
)
{
updateAutoReply
(
form
).
then
(()
=>
{
message
.
success
(
'修改成功'
)
open
.
value
=
false
getList
()
})
}
else
{
createAutoReply
(
form
).
then
(()
=>
{
message
.
success
(
'新增成功'
)
open
.
value
=
false
getList
()
})
}
})
}
// 表单重置
const
reset
=
()
=>
{
form
.
value
=
{
id
:
undefined
,
accountId
:
queryParams
.
accountId
,
type
:
type
.
value
,
requestKeyword
:
undefined
,
requestMatch
:
type
.
value
===
'3'
?
1
:
undefined
,
requestMessageType
:
undefined
}
formRef
.
value
?.
resetFields
()
}
// 取消按钮
const
cancel
=
()
=>
{
open
.
value
=
false
reset
()
}
// 表单 Editor 重置
const
resetEditor
=
()
=>
{
hackResetWxReplySelect
.
value
=
false
// 销毁组件
nextTick
(()
=>
{
hackResetWxReplySelect
.
value
=
true
// 重建组件
})
}
const
handleDelete
=
async
(
row
)
=>
{
await
message
.
confirm
(
'是否确认删除此数据?'
)
await
deleteAutoReply
(
row
.
id
)
await
getList
()
message
.
success
(
'删除成功'
)
}
</
script
>
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