<template> <div class="focus-reply"> <div class="clear-both top"> <span class="title">自动回复</span> <el-button type="success" plain style="float: right" @click="add" v-if="!$store.state.readonly">添加回复</el-button> </div> <el-tabs v-model="activeName" type="card" @tab-click="handleClick"> <el-tab-pane label="新用户关注" name="focus_reply_new"></el-tab-pane> <el-tab-pane label="无课用户关注" name="focus_reply_no_course"></el-tab-pane> <el-tab-pane label="有课用户关注" name="focus_reply_course"></el-tab-pane> <el-tab-pane label="有订单无课用户关注" name="order_no_course_reply"></el-tab-pane> <!-- <el-tab-pane label="团购未成功关注" name="focus_reply_group_not_success"></el-tab-pane> --> <el-tab-pane label="自动回复" name="auto_reply"></el-tab-pane> <el-tab-pane label="30-60分钟无课用户自动回复" name="half_hour_no_course_reply"></el-tab-pane> <!--<el-tab-pane label="24小时内无课用户自动回复" name="twenty_four_hour_no_course_reply"></el-tab-pane>--> <!--<el-tab-pane label="48小时内无课用户自动回复" name="forty_eight_no_course_reply"></el-tab-pane>--> <el-tab-pane label="小程序自动回复" name="mini_auto_reply"></el-tab-pane> </el-tabs> <el-table :data="list" style="width: 100%;" max-height="800"> <el-table-column fixed label="类型" width="150"> <template slot-scope="scope"> {{scope.row.type | typeFilter}} </template> </el-table-column> <el-table-column label="内容"> <template slot-scope="scope"> <!--<div v-if="scope.row.type === 'text'">--> <!--{{scope.row.content}}--> <!--</div>--> <div v-if="scope.row.type === 'text'" v-html="scope.row.content.replace(/\/[\u4E00-\u9FA5]{1,3}/gi, emotion)"></div> <a v-else-if="scope.row.type === 'image' && scope.row.content" :href="scope.row.content" target="_blank"> <img class="shotcut" :src="scope.row.content"> </a> <div v-else-if="scope.row.type === 'image' && scope.row.variable"> 老师二维码 </div> <div v-else-if="scope.row.type === 'video'"> <a :href="scope.row.content.down_url" target="_blank">{{scope.row.content.title}}</a> </div> <div v-else-if="scope.row.type === 'voice'"> {{scope.row.content.name}} </div> <div v-else-if="scope.row.type === 'news'"> <div class="news-media"> <div v-for="(child, childIndex) in scope.row.content.news_item" style="position: relative"> <div v-if="scope.row.content.news_item.length === 1" class="single-cover"> <div class="title">{{child.title}}</div> <img :src="child.thumb_url" style="width: 100%;margin-top: 20px;"/> <div class="digest">{{child.digest}}</div> <a class="preview" :href="child.url" target="_blank"> 预览文章 </a> </div> <div v-else-if="scope.row.content.news_item.length > 1" class="clear-both bottomCover" style="position: relative"> <div v-if="childIndex === 0" class="muti-cover"> <img style="width: 100%;margin-top: 20px;" :src="child.thumb_url"/> <div class="bottom-title">{{child.title}}</div> </div> <div class="next-cover clear-both" v-else> <span class="next-title">{{child.title}}</span> <img class="next-img" :src="child.thumb_url"/> </div> <a class="preview" :href="child.url" target="_blank"> 预览文章 </a> </div> </div> </div> </div> <div v-else-if="scope.row.type === 'news-item'"> <div class="news-media"> <div style="position: relative"> <a :href="scope.row.url" target="_blank" style="text-decoration: none;"> <div class="single-cover"> <img :src="scope.row.thumb_url" style="width: 100%;"/> <div class="title">{{scope.row.title}}</div> <div class="digest">{{scope.row.description}}</div> </div> </a> </div> </div> </div> <div v-else-if="scope.row.type === 'link'" class="news-media" style="display: inline-block;width: 150px;"> <el-card :body-style="{ padding: '0px' }"> <a :href="scope.row.url" target="_blank" style="position: relative; color: #333; text-decoration: none;"> <div style="margin: 3px;line-height: 2" class="ellip">{{scope.row.title}}</div> <div class="f-bt" style="position: relative;margin-left: 3px;"> <div style="color: #666;width: 63%;word-break: break-all;word-wrap: break-word;line-height: 1;">{{scope.row.description}}</div> <img :src="scope.row.thumb_url" style="width: 35%; height: auto"/> </div> </a> </el-card> </div> </template> </el-table-column> <el-table-column fixed="right" label="操作" v-if="!$store.state.readonly" width="240"> <template slot-scope="scope"> <el-button @click.native.prevent="editRow(scope.$index, list)" type="button" size="small"> 编辑 </el-button> <el-button @click.native.prevent="deleteRow(scope.$index, list)" v-if="$store.state.deletePermission" type="button" size="small"> 移除 </el-button> <el-button v-if="scope.$index!==0" @click.native.prevent="moveRow(scope.$index-1,scope.$index)" type="button" size="small"> 上移 </el-button> <el-button v-if="scope.$index!==list.length-1" @click.native.prevent="moveRow(scope.$index,scope.$index + 1)" type="button" size="small"> 下移 </el-button> </template> </el-table-column> </el-table> <dialog-com v-if="dialogObj.show" :dialogObj="dialogObj" @changeShow="changeShow" @reflash="getList"/> </div> </template> <script> import dialogCom from './focusReplyDialog' import {updateConfigApi,saveConfigApi,getConfigListApi} from "../../service/api"; import page from '../framework/page' export default { name: "focusReply", data(){ return{ loading:false, total:0, nowPage:1, limit: 10, activeName: 'focus_reply_new', id: null, list: [], form:{ key:'focus_reply_new', value:'focus_reply_new', desc:'' }, content: '', imageContent: '', type: 'text', mediaList: [], showMedia: false, rules:{ value:[ { required: true, message: '请输入规则名称', trigger: 'change' } ], desc:[ { required: true, message: '请输入回复内容', trigger: 'change' } ], qr:[ { required: true, message: '请输入二维码', trigger: 'change' } ] }, dialogObj:{ show:false, id:'', index: -1, list: [] } } }, components:{ page, dialogCom }, mounted(){ this.getList() }, filters: { typeFilter(value){ if(!value) return ''; if(value === 'text') { return '文字' } else if(value === 'image') { return '图片' } else if(value === 'news'){ return '图文' } else if(value === 'video'){ return '视频' } else if(value === 'voice'){ return '语音' } else if(value === 'news-item'){ return '图文链接' } else if(value === 'link'){ return '链接' } else { return val } }, contentFilter(row){ if (row.type === 'text') { return row.content } else if (row.type === 'image'){ let content = `<img src='${row.content}'>` return content; } } }, methods:{ emotion (res) { let word = res.replace(/\//gi,'') const list = ['微笑', '撇嘴', '色', '发呆', '得意', '流泪', '害羞', '闭嘴', '睡', '大哭', '尴尬', '发怒', '调皮', '呲牙', '惊讶', '难过', '酷', '冷汗', '抓狂', '吐', '偷笑', '可爱', '白眼', '傲慢', '饥饿', '困', '惊恐', '流汗', '憨笑', '大兵', '奋斗', '咒骂', '疑问', '嘘', '晕', '折磨', '衰', '骷髅', '敲打', '再见', '擦汗', '抠鼻', '鼓掌', '糗大了', '坏笑', '左哼哼', '右哼哼', '哈欠', '鄙视', '委屈', '快哭了', '阴险', '亲亲', '吓', '可怜', '菜刀', '西瓜', '啤酒', '篮球', '乒乓', '咖啡', '饭', '猪头', '玫瑰', '凋谢', '示爱', '爱心', '心碎', '蛋糕', '闪电', '炸弹', '刀', '足球', '瓢虫', '便便', '月亮', '太阳', '礼物', '拥抱', '强', '弱', '握手', '胜利', '抱拳', '勾引', '拳头', '差劲', '爱你', 'NO', 'OK', '爱情', '飞吻', '跳跳', '发抖', '怄火', '转圈', '磕头', '回头', '跳绳', '挥手', '激动', '街舞', '献吻', '左太极', '右太极'] let index = list.indexOf(word) return `<img src="https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/${index}.gif" align="middle">` }, handleClick(tab) { this.form = { key:tab.name, value:tab.name, desc:'' } this.nowPage = 1; this.getList(); this.id=''; }, save(){ let json = this.form let _desc = []; if (this.type === 'text') { if (!this.content) { this.$message({ showClose: true, message: '请输入文本内容' }); return; } _desc[0] = { type : this.type, content: this.content } } else if (this.type === 'image') { if (!this.imageContent) { this.$message({ showClose: true, message: '请选择图片' }); return } _desc[0] = this.imageContent } json.desc = JSON.stringify(_desc) if (this.id) { updateConfigApi(this.id,json).then(res=>{ this.$message({ type: 'success', message: '修改成功!' }); }) } else { saveConfigApi(json).then(res=>{ this.$message({ type: 'success', message: '保存成功!' }); }) } }, onChooseMedia(val){ this.addContent(this.type, val.url, val.media_id); this.showMedia = false; }, addContent(type, content, mediaId) { let obj = {}; if (content) { obj = { type: type, content: content }; } if (mediaId) { obj.media_id = mediaId; } this.imageContent = obj }, getList(){ getConfigListApi({key: this.form.key}).then(res => { if (res.list.length > 0) { this.id = res.list[0].id; let _desc = JSON.parse(res.list[0].desc); this.list = _desc || []; } else { this.list = [] } }) }, add(){ this.dialogObj = { show: true, id: this.id ? this.id : null, index: -1, list: this.list, key: this.form.key, value: this.form.value } }, editRow(index, row){ this.dialogObj = { show: true, id: this.id, index: index, list: this.list, key: this.form.key, value: this.form.value } }, deleteRow(index , list){ this.$confirm('此操作将删除该文件, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { let desc = list; desc.splice(index,1); let json = { key: this.form.key, value: this.form.value } json.desc = JSON.stringify(desc) updateConfigApi(this.id,json).then(res=>{ this.$message({ type: 'success', message: '删除成功!' }); this.getList(); }) }).catch(()=>{ this.$message({ type: 'success', message: '已取消删除!' }); }) }, moveRow(first,second){ let _first = this.list[first]; let _second = this.list[second]; this.list[first] = _second; this.list[second] = _first; let desc = this.list; let json = { key: this.form.key, value: this.form.value } json.desc = JSON.stringify(desc) updateConfigApi(this.id,json).then(res=>{ this.$message({ type: 'success', message: '保存成功!' }); this.getList(); }) }, changeShow(val){ this.dialogObj.show = val; } } } </script> <style scoped lang="less"> .focus-reply { padding: 20px 0; } ul, ol { padding-left: 0; list-style-type: none; } .title { color: #353535; font-size: 20px; font-weight: 400; line-height: 1; } .top { margin-bottom: 30px; } .content { padding-top: 40px; margin-top: 24px; border-top: 1px solid #E4E8EB; } .inner { border: 1px solid #E4E8EB; background-color: #FFFFFF; } .inner-bottom { border-top: 1px solid #E4E8EB; } .img-action { padding: 17px 20px; min-height: 215px; } .img-create-access { position: relative; border: 2px dotted #E4E8EB; width: 48.6%; height: 211px; text-align: center; } .img-create-access:first-child { float: left; } .img-create-access__link { display: inline-block; vertical-align: middle; color: #9A9A9A; margin: 0 10px; margin-top: 68px; text-decoration: none; } .img-create-access__link:before { content: " "; display: block; width: 36px; height: 36px; margin: 0 auto 5px; background: transparent url(https://res.wx.qq.com/mpres/en_US/htmledition/pages/modules/msg_sender/images/icon36_add_gray.png) no-repeat 0 0; } .weui-desktop-msg-sender__tabs { line-height: 38px; background-color: #FFFFFF; } .sender__tab_selected { color: #44B549; } .weui-desktop-msg-sender__tab:hover, .weui-desktop-msg-sender__tab_selected { color: #44B549; } .weui-desktop-msg-sender__tab { display: inline-block; padding: 0 20px; cursor: pointer; } .weui-desktop-msg-sender__tab:hover.weui-desktop-msg-sender__tab_text:before, .weui-desktop-msg-sender__tab_selected.weui-desktop-msg-sender__tab_text:before { background-image: url(https://res.wx.qq.com/mpres/en_US/htmledition/pages/modules/msg_sender/svg/default/sender_text_current.svg); } .weui-desktop-msg-sender__tab_img:before { background: transparent url(https://res.wx.qq.com/mpres/en_US/htmledition/pages/modules/msg_sender/svg/default/sender_img.svg) no-repeat 0 0; } .weui-desktop-msg-sender__tab:hover.weui-desktop-msg-sender__tab_img:before, .weui-desktop-msg-sender__tab_selected.weui-desktop-msg-sender__tab_img:before { background-image: url(https://res.wx.qq.com/mpres/en_US/htmledition/pages/modules/msg_sender/svg/default/sender_img_current.svg); } .weui-desktop-msg-sender__tab:before { content: " "; display: inline-block; width: 22px; height: 20px; vertical-align: middle; margin: -0.2em 5px 0 0; } .tool_bar { padding-top: 0; padding-bottom: 50px; margin-top: 40px; margin-left: 20px; } .tool_bar > .weui-desktop-btn { margin-right: 1em; } .weui-desktop-btn_primary { background-color: #1AAD19; border-color: #1AAD19; color: #FFFFFF; } .weui-desktop-btn { display: inline-block; padding: 0 22px; min-width: 54px; line-height: 2.42857143; vertical-align: middle; text-align: center; text-decoration: none; border-radius: 3px; font-size: 14px; cursor: pointer; border-width: 1px; border-style: solid; box-sizing: content-box; } .weui-desktop-popover__wrp { display: inline; position: relative; font-size: 14px; } .weui-desktop-btn_default { background-color: #FBFBFB; border-color: #E4E8EB; color: #353535; } .inner-emotion_editor { margin: 2%; } .shotcut { width: 50px; } .clear-both{ &:after{ content: ''; display: block; clear: both; } } .news-media { padding: 10px; width: 200px; background-color: #fff; } .news-media img{ width: 100%; } .s-news img { width: 50px; float: right; } .title { font-size: 16px; font-weight: 400; display: block; line-height: 1.2; color: #353535; } .digest { padding-top: 12px; color: #9A9A9A; font-size: 14px; } .single-cover { /*padding: 20px 15px 15px;*/ } .muti-cover { position: relative; padding: 20px 15px 0 15px; } .bottom-title { color: #FFFFFF; background-color: rgba(0, 0, 0, 0.55); position: absolute; left: 15px; right: 15px; bottom: 0; padding: 8px 12px; } .next-cover { padding: 12px 15px; position: relative; } .next-img { float: right; margin-left: 12px; width: 60px !important; height: 60px !important; } .next-title { overflow: hidden; font-weight: 400; word-wrap: break-word; -webkit-hyphens: auto; -ms-hyphens: auto; hyphens: auto; color: #353535; } .single-cover:hover .preview,.bottomCover:hover .preview{ display: flex; justify-content: center; align-items: center; color: #fff; } .preview { display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); text-decoration: none; } .ellip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .f-bt { display: flex; position: relative; justify-content: space-between; align-items: flex-start; } </style>