mp:增加【自动回复】的前端实现

This commit is contained in:
YunaiV 2023-01-17 00:01:07 +08:00
parent ab41c96641
commit 1e402d8063
9 changed files with 239 additions and 112 deletions

View File

@ -8,11 +8,13 @@ import cn.iocoder.yudao.module.mp.convert.message.MpAutoReplyConvert;
import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpAutoReplyDO;
import cn.iocoder.yudao.module.mp.service.message.MpAutoReplyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@ -37,4 +39,13 @@ public class MpAutoReplyController {
return success(MpAutoReplyConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/get")
@ApiOperation("获得公众号自动回复")
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('mp:auto-reply:query')")
public CommonResult<MpAutoReplyRespVO> getAutoReply(@RequestParam("id") Long id) {
MpAutoReplyDO autoReply = mpAutoReplyService.getAutoReply(id);
return success(MpAutoReplyConvert.INSTANCE.convert(autoReply));
}
}

View File

@ -30,7 +30,7 @@ public class MpAutoReplyBaseVO {
@ApiModelProperty(value = "请求的关键字", example = "关键字", notes = "当 type 为 MpAutoReplyTypeEnum#KEYWORD 时,必填")
private String requestKeyword;
@ApiModelProperty(value = "请求的关键字", example = "关键字", notes = "当 type 为 MpAutoReplyTypeEnum#KEYWORD 时,必填")
@ApiModelProperty(value = "请求的匹配方式", example = "1", notes = "当 type 为 MpAutoReplyTypeEnum#KEYWORD 时,必填")
private Integer requestMatch;
@ApiModelProperty(value = "请求的消息类型", example = "text", notes = "当 type 为 MpAutoReplyTypeEnum#MESSAGE 时,必填")

View File

@ -6,6 +6,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;
@ApiModel("管理后台 - 公众号自动回复 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ -20,4 +22,7 @@ public class MpAutoReplyRespVO extends MpAutoReplyBaseVO {
@ApiModelProperty(value = "微信公众号 appid", required = true, example = "wx1234567890")
private String appId;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
}

View File

@ -27,4 +27,6 @@ public interface MpAutoReplyConvert {
PageResult<MpAutoReplyRespVO> convertPage(PageResult<MpAutoReplyDO> page);
MpAutoReplyRespVO convert(MpAutoReplyDO bean);
}

View File

@ -21,6 +21,14 @@ public interface MpAutoReplyService {
*/
PageResult<MpAutoReplyDO> getAutoReplyPage(MpMessagePageReqVO pageVO);
/**
* 获得公众号自动回复
*
* @param id 编号
* @return 自动回复
*/
MpAutoReplyDO getAutoReply(Long id);
/**
* 当收到消息时自动回复
*

View File

@ -44,6 +44,11 @@ public class MpAutoReplyServiceImpl implements MpAutoReplyService {
return mpAutoReplyMapper.selectPage(pageVO);
}
@Override
public MpAutoReplyDO getAutoReply(Long id) {
return mpAutoReplyMapper.selectById(id);
}
@Override
public WxMpXmlOutMessage replyForMessage(String appId, WxMpXmlMessage wxMessage) {
// 第一步匹配自动回复

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 创建公众号的自动回复
export function createAutoReply(data) {
return request({
url: '/mp/auto-reply/create',
method: 'post',
data: data
})
}
// 更新公众号的自动回复
export function updateAutoReply(data) {
return request({
url: '/mp/auto-reply/update',
method: 'put',
data: data
})
}
// 删除公众号的自动回复
export function deleteAutoReply(id) {
return request({
url: '/mp/auto-reply/delete?id=' + id,
method: 'delete'
})
}
// 获得公众号的自动回复
export function getAutoReply(id) {
return request({
url: '/mp/auto-reply/get?id=' + id,
method: 'get'
})
}
// 获得公众号的自动回复分页
export function getAutoReplyPage(query) {
return request({
url: '/mp/auto-reply/page',
method: 'get',
params: query
})
}

View File

@ -58,6 +58,9 @@ export const DICT_TYPE = {
PAY_REFUND_ORDER_STATUS: 'pay_refund_order_status', // 退款订单状态
PAY_REFUND_ORDER_TYPE: 'pay_refund_order_type', // 退款订单类别
// ========== MP 模块 ==========
MP_AUTO_REPLY_REQUEST_MATCH: 'mp_auto_reply_request_match', // 自动回复请求匹配类型
// ========== MALL - PRODUCT 模块 ==========
PRODUCT_SPU_STATUS: 'product_spu_status', // 商品 SPU 状态

View File

@ -22,6 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
芋道源码
移除 avue 框架使用 element-ui 重写
重写代码保持和现有项目保持一致
-->
<template>
<div class="app-container">
@ -44,10 +45,10 @@ SOFTWARE.
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['mp:auto-reply:create']" v-if="list.length <= 0">新增
v-hasPermi="['mp:auto-reply:create']" v-if="type !== '1' || list.length <= 0">新增
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
</el-row>
<!-- 列表 -->
<el-tab-pane name="1">
@ -97,7 +98,11 @@ SOFTWARE.
<span slot="label"><i class="el-icon-news"></i> 关键词回复</span>
<el-table v-loading="loading" :data="list">
<el-table-column label="关键词" align="center" prop="requestKeyword"/>
<el-table-column label="匹配类型" align="center" prop="requestMatch"/>
<el-table-column label="匹配类型" align="center" prop="requestMatch">
<template v-slot="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" prop="responseMessageType"/>
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
@ -118,39 +123,31 @@ SOFTWARE.
</el-tab-pane>
</el-tabs>
<el-dialog :title="handleType === 'add' ? '新增回复消息' : '修改回复消息'" :visible.sync="dialog1Visible" width="50%">
<el-form label-width="100px">
<el-form-item label="请求消息类型" v-if="type == '2'">
<el-select v-model="objData.reqType" placeholder="请选择">
<el-option
v-for="item in dictData.get('wx_req_type')"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
v-if="item.value !== 'event'">
<!-- 添加或修改自动回复的对话框 -->
<el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="消息类型" prop="requestMessageType" v-if="type === '2'">
<el-select v-model="form.requestMessageType" placeholder="请选择">
<el-option v-for="item in dictData.get('wx_req_type')" :key="item.value" :label="item.label"
:value="item.value" :disabled="item.disabled" v-if="item.value !== 'event'">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="匹配类型" v-if="type === '3'">
<el-select v-model="objData.repMate" placeholder="请选择" style="width: 100px">
<el-option
v-for="item in dictData.get('wx_rep_mate')"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<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 this.getDictDatas(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="关键词" v-if="type === '3'">
<el-input placeholder="请输入内容" v-model="objData.reqKey" clearable> </el-input>
<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"></WxReplySelect>
<wx-reply-select :objData="objData" v-if="hackResetWxReplySelect" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialog1Visible = false"> </el-button>
<el-button @click="cancel"> </el-button>
<el-button type="primary" @click="handleSubmit"> </el-button>
</span>
</el-dialog>
@ -158,11 +155,9 @@ SOFTWARE.
</template>
<script>
// import { getPage, getObj, addObj, putObj, delObj } from '@/api/wxmp/wxautoreply'
// import { tableOption1, tableOption2, tableOption3 } from '@/const/crud/wxmp/wxautoreply'
import WxReplySelect from '@/views/mp/components/wx-reply/main.vue'
import { getSimpleAccounts } from "@/api/mp/account";
import { getTagPage } from "@/api/mp/tag";
import { createAutoReply, deleteAutoReply, getAutoReply, getAutoReplyPage, updateAutoReply } from "@/api/mp/autoReply";
export default {
name: 'mpAutoReply',
@ -188,13 +183,24 @@ export default {
accountId: undefined,
},
dialog1Visible:false,
objData:{
repType : 'text'
//
title: "",
//
open: false,
//
form: {},
//
objData: {
type : 'text'
},
handleType: null,
//
rules: {
requestKeyword: [{ required: true, message: "请求的关键字不能为空", trigger: "blur" }],
requestMatch: [{ required: true, message: "请求的关键字的匹配不能为空", trigger: "blur" }],
},
hackResetWxReplySelect: false, // WxReplySelect
dictData: new Map(),
hackResetWxReplySelect: false,
//
accounts: []
@ -211,14 +217,7 @@ export default {
this.getList();
})
// this.getPage(this.page)
this.dictData.set('wx_rep_mate',[{
value: '1',
label: '全匹配'
},{
value: '2',
label: '半匹配'
}])
// TODO
this.dictData.set('wx_req_type',[{
value: 'text',
label: '文本'
@ -250,15 +249,18 @@ export default {
getList() {
//
if (!this.queryParams.accountId) {
this.$message.error('未选中公众号,无法查询标签')
this.$message.error('未选中公众号,无法查询自动回复')
return false
}
this.loading = false
//
let params = {...this.queryParams}
let params = {
...this.queryParams,
type: this.type
}
//
getTagPage(params).then(response => {
getAutoReplyPage(params).then(response => {
this.list = response.data.list
this.total = response.data.total
this.loading = false
@ -278,75 +280,122 @@ export default {
}
this.handleQuery()
},
handleAdd(){
this.hackResetWxReplySelect = false//
this.$nextTick(() => {
this.hackResetWxReplySelect = true//
})
this.handleType = 'add'
this.dialog1Visible = true
this.objData = {
repType : 'text'
}
},
handleEdit(row){
this.hackResetWxReplySelect = false//
this.$nextTick(() => {
this.hackResetWxReplySelect = true//
})
this.handleType = 'edit'
this.dialog1Visible = true
this.objData = Object.assign({}, row)
},
handleClick(tab, event){
this.tableData = []
this.page.currentPage = 1
handleClick(tab, event) {
this.type = tab.name
this.getPage(this.page)
this.handleQuery()
},
handleDel: function(row, index) {
var _this = this
this.$confirm('是否确认删除此数据', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delObj(row.id)
}).then(data => {
_this.$message({
showClose: true,
message: '删除成功',
type: 'success'
})
this.getPage(this.page)
}).catch(function(err) { })
/** 新增按钮操作 */
handleAdd(){
this.reset();
this.resetEditor();
//
this.open = true
this.title = '新增自动回复';
this.objData = {
type : 'text'
}
},
handleSubmit(row){
if(this.handleType === 'add'){
addObj(Object.assign({
type:this.type
}, this.objData)).then(data => {
this.$message({
showClose: true,
message: '添加成功',
type: 'success'
})
this.getPage(this.page)
this.dialog1Visible = false
})
}
if(this.handleType === 'edit'){
putObj(this.objData).then(data => {
this.$message({
showClose: true,
message: '修改成功',
type: 'success'
})
this.getPage(this.page)
this.dialog1Visible = false
})
}
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.resetEditor();
const id = row.id;
getAutoReply(id).then(response => {
//
this.form = {...response.data}
this.$delete(this.form, 'responseMessageType');
this.$delete(this.form, 'responseContent');
this.$delete(this.form, 'responseMediaId');
this.$delete(this.form, 'responseMediaUrl');
this.$delete(this.form, 'responseDescription');
this.$delete(this.form, 'responseArticles');
this.objData = {
type: response.data.responseMessageType,
accountId: this.queryParams.accountId,
content: response.data.responseContent,
mediaId: response.data.responseMediaId,
url: response.data.responseMediaUrl,
title: response.data.responseTitle,
description: response.data.responseDescription,
thumbMediaId: response.data.responseThumbMediaId,
thumbMediaUrl: response.data.responseThumbMediaUrl,
articles: response.data.responseArticles,
musicUrl: response.data.responseMusicUrl,
hqMusicUrl: response.data.responseHqMusicUrl,
}
//
this.open = true
this.title = '修改自动回复';
})
},
handleSubmit() {
this.$refs["form"].validate(valid => {
if (!valid) {
return;
}
//
const form = {...this.form};
form.responseMessageType = this.objData.type;
form.responseContent = this.objData.content;
form.responseMediaId = this.objData.mediaId;
form.responseMediaUrl = this.objData.url;
form.responseTitle = this.objData.title;
form.responseDescription = this.objData.description;
form.responseThumbMediaId = this.objData.thumbMediaId;
form.responseThumbMediaUrl = this.objData.thumbMediaUrl;
form.responseArticles = this.objData.articles;
form.responseMusicUrl = this.objData.musicUrl;
form.responseHqMusicUrl = this.objData.hqMusicUrl;
if (this.form.id !== undefined) {
updateAutoReply(form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
createAutoReply(form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
});
},
//
reset() {
this.form = {
id: undefined,
accountId: this.queryParams.accountId,
type: this.type,
requestKeyword: undefined,
requestMatch: this.type === '3' ? 1 : undefined,
requestMessageType: undefined,
};
this.resetForm("form");
},
//
cancel() {
this.open = false;
this.reset();
},
// Editor
resetEditor() {
this.hackResetWxReplySelect = false //
this.$nextTick(() => {
this.hackResetWxReplySelect = true //
})
},
handleDelete: function(row) {
const ids = row.id;
this.$modal.confirm('是否确认删除此数据?').then(function() {
return deleteAutoReply(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
}
}