You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
WeChat/src/views/modules/wx/msg-reply-rule-add-or-updat...

261 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<!-- el-dialog组件用于弹出对话框根据dataForm中是否有id来设置标题为新增修改点击模态框背景不关闭对话框通过visible属性双向绑定控制显示隐藏 -->
<el-dialog :title="!dataForm.id? '新增' : '修改'" :close-on-click-modal="false" :visible.sync="visible" >
<!-- el-form组件定义表单绑定dataForm数据模型应用dataRule验证规则设置标签宽度为80px -->
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" label-width="80px">
<!-- 规则名称的表单项对应dataForm中的ruleName属性设置了必填验证 -->
<el-form-item label="规则名称" prop="ruleName">
<!-- el-input组件实现输入框双向绑定dataForm.ruleName有占位提示文字 -->
<el-input v-model="dataForm.ruleName" placeholder="规则名称"></el-input>
</el-form-item>
<!-- 匹配词的表单项使用自定义的tags-editor组件双向绑定dataForm.matchValue用于输入或编辑匹配词可能是多个类似标签形式 -->
<el-form-item label="匹配词" prop="matchValue">
<tags-editor v-model="dataForm.matchValue"></tags-editor>
</el-form-item>
<!-- 第一行布局使用el-row包裹 -->
<el-row>
<!-- 占12列用于放置作用范围相关的表单元素 -->
<el-col :span="12">
<!-- 作用范围的表单项对应dataForm中的appid属性通过下拉选择框选择有全部公众号和当前公众号两个选项 -->
<el-form-item label="作用范围" prop="appid">
<el-select v-model="dataForm.appid" placeholder="作用范围">
<el-option label="全部公众号" value=""></el-option>
<el-option label="当前公众号" :value="selectedAppid"></el-option>
</el-select>
</el-form-item>
</el-col>
<!-- 同样占12列用于放置精确匹配相关的表单元素使用el-switch组件实现开关切换功能双向绑定dataForm.exactMatch -->
<el-col :span="12">
<el-form-item label="精确匹配" prop="exactMatch">
<el-switch v-model="dataForm.exactMatch" :active-value="true" :inactive-value="false"></el-switch>
</el-form-item>
</el-col>
</el-row>
<!-- 第二行布局 -->
<el-row>
<!-- 占12列用于放置回复类型相关的表单元素 -->
<el-col :span="12">
<!-- 回复类型的表单项对应dataForm中的replyType属性通过下拉选择框选择选项通过循环KefuMsgType生成选择改变时触发onReplyTypeChange方法 -->
<el-form-item label="回复类型" prop="replyType">
<el-select v-model="dataForm.replyType" @change="onReplyTypeChange">
<el-option v-for="(name,key) in KefuMsgType" :key="key" :value="key" :label="name"></el-option>
</el-select>
</el-form-item>
</el-col>
<!-- 占12列用于放置是否启用相关的表单元素使用el-switch组件实现开关切换功能双向绑定dataForm.status -->
<el-col :span="12">
<el-form-item label="是否启用" prop="status">
<el-switch v-model="dataForm.status" :active-value="true" :inactive-value="false"></el-switch>
</el-form-item>
</el-col>
</el-row>
<!-- 第三行布局 -->
<el-row>
<!-- 占12列用于放置生效时间相关的表单元素使用el-time-picker组件实现时间选择功能绑定dataForm.effectTimeStart设置时间格式 -->
<el-col :span="12">
<el-form-item label="生效时间" prop="effectTimeStart">
<el-time-picker v-model="dataForm.effectTimeStart" value-format="HH:mm:ss"></el-time-picker>
</el-form-item>
</el-col>
<!-- 占12列用于放置失效时间相关的表单元素使用el-time-picker组件实现时间选择功能绑定dataForm.effectTimeEnd设置时间格式 -->
<el-col :span="12">
<el-form-item label="失效时间" prop="effectTimeEnd">
<el-time-picker v-model="dataForm.effectTimeEnd" value-format="HH:mm:ss"></el-time-picker>
</el-form-item>
</el-col>
</el-row>
<!-- 回复内容的表单项对应dataForm中的replyContent属性使用el-input组件实现文本域输入框双向绑定dataForm.replyContent有行数设置和占位提示文字 -->
<el-form-item label="回复内容" prop="replyContent">
<el-input v-model="dataForm.replyContent" type="textarea" :rows="5" placeholder="文本、图文ID、media_id、json配置"></el-input>
<!-- 当回复类型为文本时显示插入链接按钮点击调用addLink方法在回复内容中添加链接 -->
<el-button type="text" v-show="'text'==dataForm.replyType" @click="addLink">插入链接</el-button>
<!-- 根据assetsType的值决定是否显示按钮点击打开素材选择器通过控制assetsSelectorVisible属性按钮文字根据回复类型有所不同 -->
<el-button type="text" v-show="assetsType" @click="assetsSelectorVisible=true">
从素材库中选择<span v-if="'miniprogrampage'==dataForm.replyType || 'music'==dataForm.replyType">缩略图</span>
</el-button>
</el-form-item>
<!-- 备注说明的表单项对应dataForm中的desc属性使用el-input组件实现输入框双向绑定dataForm.desc有占位提示文字 -->
<el-form-item label="备注说明" prop="desc">
<el-input v-model="dataForm.desc" placeholder="备注说明"></el-input>
</el-form-item>
</el-form>
<!-- 对话框底部的按钮区域,通过插槽定义 -->
<span slot="footer" class="dialog-footer">
<!-- 取消按钮点击时设置visible为false关闭对话框 -->
<el-button @click="visible = false">取消</el-button>
<!-- 确定按钮类型为主要按钮点击时调用dataFormSubmit方法进行表单提交 -->
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</span>
<!-- 素材选择器组件,根据条件控制显示,通过属性和事件与当前组件进行交互,用于选择素材相关操作 -->
<assets-selector v-if="assetsSelectorVisible && assetsType" :visible="assetsSelectorVisible" :selectType="assetsType" @selected="onAssetsSelect" @onClose="assetsSelectorVisible=false"></assets-selector>
</el-dialog>
</template>
<script>
// 引入Vuex的mapState辅助函数用于将Vuex中的状态映射到组件的计算属性中
import { mapState } from 'vuex'
export default {
components: {
// 异步加载tags-editor组件用于编辑匹配词相关功能
tagsEditor: () => import('@/components/tags-editor'),
// 异步加载AssetsSelector组件用于选择素材相关功能
AssetsSelector: () => import('./assets/assets-selector')
},
data() {
return {
visible: false,
assetsSelectorVisible: false,
dataForm: {
// 规则ID初始化为0
ruleId: 0,
appid: '',
ruleName: "",
exactMatch: false,
matchValue: "",
replyType: 'text',
replyContent: "",
status: true,
desc: "",
effectTimeStart: "00:00:00",
effectTimeEnd: "23:59:59"
},
dataRule: {
// 规则名称的验证规则必填触发验证的时机是失去焦点blur
ruleName: [
{ required: true, message: "规则名称不能为空", trigger: "blur" }
],
// 匹配词的验证规则,必填,触发验证的时机是失去焦点
matchValue: [
{ required: true, message: "匹配的关键词、事件等不能为空", trigger: "blur" }
],
// 回复类型的验证规则,必填,触发验证的时机是失去焦点
replyType: [
{ required: true, message: "回复类型1:文本2:图文3媒体不能为空", trigger: "blur" }
],
// 回复内容的验证规则,必填,触发验证的时机是失去焦点
replyContent: [
{ required: true, message: "回复内容不能为空", trigger: "blur" }
],
// 是否启用的验证规则,必填,触发验证的时机是失去焦点
status: [
{ required: true, message: "是否有效不能为空", trigger: "blur" }
],
// 生效起始时间的验证规则,必填,触发验证的时机是失去焦点
effectTimeStart: [
{ required: true, message: "生效起始时间不能为空", trigger: "blur" }
],
// 生效结束时间的验证规则,必填,触发验证的时机是失去焦点
effectTimeEnd: [
{ required: true, message: "生效结束时间不能为空", trigger: "blur" }
]
}
};
},
computed: mapState({
// 从Vuex的state中获取message模块下的KefuMsgType状态映射到组件的计算属性中用于回复类型下拉框的选项数据
KefuMsgType: state => state.message.KefuMsgType,
// 从Vuex的state中获取wxAccount模块下的selectedAppid状态映射到组件的计算属性中用于作用范围下拉框中当前公众号选项的值
selectedAppid: state => state.wxAccount.selectedAppid,
assetsType() {
const config = {
// 定义消息类型与选择素材类型的对应关系,用于根据回复类型确定在素材库中选择的素材类型
'image': 'image',
'voice': 'voice',
'video': 'video',
'mpnews': 'news',
'miniprogrampage': 'image', // 小程序需选择卡片图
'music': 'image'
};
return config[this.dataForm.replyType] || '';
}
}),
methods: {
init(id) {
// 初始化时设置dataForm的ruleId属性传入的id为空则设置为0
this.dataForm.ruleId = id || 0;
// 设置对话框显示状态为true即打开对话框
this.visible = true;
this.$nextTick(() => {
// 表单DOM更新后重置表单所有字段的值
this.$refs["dataForm"].resetFields();
if (this.dataForm.ruleId) {
// 如果ruleId有值表示是修改操作发起HTTP请求获取规则详情信息
this.$http({
url: this.$http.adornUrl(`/manage/msgReplyRule/info/${this.dataForm.ruleId}`),
method: "get",
params: this.$http.adornParams()
}).then(({ data }) => {
if (data && data.code === 200) {
// 如果请求成功将返回的规则数据赋值给dataForm
this.dataForm = data.msgReplyRule;
}
});
}
});
},
// 表单提交方法
dataFormSubmit() {
// 对表单进行验证验证结果通过回调函数的参数valid返回
this.$refs["dataForm"].validate(valid => {
if (valid) {
// 如果表单验证通过发起HTTP请求保存或更新规则数据根据ruleId是否有值判断是新增还是更新操作
this.$http({
url: this.$http.adornUrl(`/manage/msgReplyRule/${!this.dataForm.ruleId? "save" : "update"}`),
method: "post",
data: this.$http.adornData(this.dataForm)
}).then(({ data }) => {
if (data && data.code === 200) {
// 如果操作成功,弹出成功提示信息,提示框关闭后设置对话框隐藏,并通过$emit触发父组件的refreshDataList事件
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.visible = false;
this.$emit("refreshDataList");
}
});
} else {
// 如果操作失败,弹出错误提示信息
this.$message.error(data.msg);
}
});
}
});
},
addLink() {
// 插入链接的方法,在回复内容中添加一个简单的链接示例文本(实际应用中可能需要更灵活的处理方式来确定链接地址和文字等)
this.dataForm.replyContent += '<a href="链接地址"></a>'
},
onReplyTypeChange(value) {
// JSON便使
if ("miniprogrampage" == value) {
let demo = { title: "标题", appid: "小程序APPID", pagepath: "页面地址", thumb_media_id: "缩略图media_id" };
this.dataForm.replyContent = JSON.stringify(demo, null, 4)
} else if ("music" == value) {
let demo = { musicurl: "音乐链接", hqmusicurl: "高品质链接", title: "标题", description: "描述", thumb_media_id: "缩略图media_id" }
this.dataForm.replyContent = JSON.stringify(demo, null, 4)
} else if ("msgmenu" == value) {
let demo = { head_content: "开头文字", list: [{ id: "菜单1ID", content: "菜单2内容" }, { id: "菜单2ID", content: "菜单2内容" }, { id: "菜单nID", content: "菜单n内容" }], tail_content: "结尾文字" }
this.dataForm.replyContent = JSON.stringify(demo, null, 4)
} else if ("news" == value) {
let demo = { title: "文章标题", description: "文章简介", url: "链接URL", picUrl: "缩略图URL" }
this.dataForm.replyContent = JSON.stringify(demo, null, 4)
} else {
this.dataForm.replyContent = 'media_id'
}
},
onAssetsSelect(assetsInfo) {
// media_idmediaId
if (this.dataForm.replyType =='miniprogrampage' || this.dataForm.replyType =='music') {
let data = JSON.parse(this.dataForm.replyContent);
if (data && data.thumb_media_id) data.thumb_media_id = assetsInfo.mediaId;
this.dataForm.replyContent = JSON.stringify(data, null, 4);
} else {
this.dataForm.replyContent = assetsInfo.mediaId;
}
this.assetsSelectorVisible = false;
}
}
};
</script>