autoReply.vue 12.2 KB
<template>
  <div>
    <el-row type="flex" class="add-btn" justify="end">
      <el-col :span="6" style="text-align: right;">
        <el-button type="success" plain @click="add" v-if="!$store.state.readonly">添加回复</el-button>
      </el-col>
    </el-row>
    <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
      <el-tab-pane label="公众号关键词回复" name="keywords_reply"></el-tab-pane>
      <el-tab-pane label="小程序关键词回复" name="mini_keywords_reply"></el-tab-pane>
    </el-tabs>
    <el-table
      :data="list"
      style="width: 100%">
      <el-table-column type="expand">
        <template slot-scope="props">
          <el-form label-position="top"  class="demo-table-expand">
            <el-form-item label="回复内容">
              <div v-for="(item, index) in props.row.desc">
              <span style="width:120px;display: inline-block;text-align:right;margin:10px 0;">
                回复{{index+1}}({{item.type | type}}):
                </span>   
                <span v-if="item.content && item.type==='text'">
                  <span v-html="item.content.replace(/\/[\u4E00-\u9FA5]{1,3}/gi, emotion)"></span>
                </span>
                <span v-if="item.content && item.type==='image'">
                  <!-- 回复{{index+1}} -->
                    <img class="img" :src="item.content" style="vertical-align:text-top;" /></span>
                <span v-if="item.type==='image' && item.variable">
                  <!-- 回复{{index+1}}: -->
                  老师二维码</span>
                <a v-if="item.type === 'video'" :href="item.content.down_url" target="_blank">{{item.content.title}}</a>
                <div v-if="item.type==='news' && item.content && item.content.news_item" class="news-media" style="display: inline-block;width: 200px;vertical-align:text-top;">
                  <el-card :body-style="{ padding: '0px' }">
                    <div v-for="(child, childIndex) in item.content.news_item" style="position: relative;">
                      <div v-if="item.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="item.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>
                  </el-card>
                </div>
                <div v-if="item.type === 'link'" class="news-media" style="display: inline-block;width: 200px;vertical-align:text-top;">
                  <el-card :body-style="{ padding: '0px' }">
                    <a :href="item.url" target="_blank" style="position: relative; color: #333; text-decoration: none;">
                      <div style="margin: 3px;line-height: 2" class="ellip">{{item.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;">{{item.description}}</div>
                        <img :src="item.thumb_url" style="width: 35%; height: auto"/>
                      </div>
                    </a>
                  </el-card>
                </div>
                <div v-else-if="item.type === 'news-item'" style="width: 200px;display: inline-block;vertical-align:text-top;" class="news-media">
                  <el-card :body-style="{ padding: '0px' }">
                    <a :href="item.url" target="_blank" style="position: relative; color: #333; text-decoration: none;">
                      <img :src="item.thumb_url" style="width: 100%; height: auto"/>
                      <div style="margin: 3px;line-height: 2" class="ellip">{{item.title}}</div>
                      <div style="color: #666;width: 63%;word-break: break-all;word-wrap: break-word;line-height: 1;">{{item.description}}</div>
                    </a>
                  </el-card>
                </div>
              </div>
            </el-form-item>
          </el-form>
        </template>
      </el-table-column>
      <el-table-column
        label="ID"
        prop="id">
      </el-table-column>
      <el-table-column
        label="关键词"
        prop="value">
      </el-table-column>
      <el-table-column
        label="回复内容">
        <template slot-scope="scope">
          {{scope.row.desc.length }} 条回复
        </template>
      </el-table-column>
      <el-table-column
        prop="created_at"
        label="创建时间">
      </el-table-column>
      <el-table-column
        width="250"
        v-if="!$store.state.readonly"
        label="操作">
        <template slot-scope="scope">
          <el-button size="mini" plain type="warning" @click="edit(scope.row)">
            编辑
          </el-button>
          <el-button size="mini" plain type="danger" @click="del(scope.row)" v-if="$store.state.deletePermission">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <dialog-com :dialogObj="dialogObj" @changeShow="changeShow" @reflash="getList"/>
         <page :total="total" :limit="limit" @pageChange="onPageChange" @sizeChange="onSizeChange"/>

  </div>
</template>

<script>
    import dialogCom from './autoReplyDialog'
    import {getConfigListApi,deleteConfigApi,getConfigDetailApi} from "../../service/api";
    import page from '../framework/page'
    export default {
      name: "autoReply",
      data() {
        return {
          total:0,
          nowPage:1,
          limit: 10,
          dialogObj:{
            value:'',
            desc:'',
            show:false,
            id:''
          },
          activeName: 'keywords_reply',
          list: []
        }
      },
      components:{
        dialogCom,
        page
      },
      mounted(){
        this.getList()
      },
      filters: {
        type(value){
          if (value === 'text') {
            return '文本'
          } else if (value === 'voice') {
            return '语音'
          } else if (value === 'video') {
            return '视频'
          } else if (value === 'image') {
            return '图片'
          } else if (value === 'news') {
            return '图文'
          } else if (value === 'link') {
            return '链接'
          } else if (value === 'news-item') {
            return '图文链接'
          } else {
            return value
          }
        }
      },
      methods: {
         onPageChange(val){
        this.nowPage = val;
        this.getList();
        },
        onSizeChange(val){
          this.nowPage = 1;
          this.limit = val;
          this.getList();
        },
        // 将匹配结果替换表情图片
        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">`
        },
        changeShow(data){
          this.dialogObj.show=data
        },
        getList(){
          let json={
            key:this.activeName,
             limit: this.limit,
             page: this.nowPage
          };

          getConfigListApi(json).then(res => {
           for(var i=0;i<res.list.length;i++){
             if(res.list[i].desc){
                res.list[i].desc= JSON.parse(res.list[i].desc)
             }
           }
            this.list = res.list;
            this.total = res.total;

          })
        },
        add(){
          this.dialogObj.id = '';
          this.dialogObj.value = '';
          this.dialogObj.desc = '';
          this.dialogObj.key = this.activeName;
          this.dialogObj.show = true
        },
        edit(data){
          getConfigDetailApi(data.id).then((res) => {
            this.dialogObj.id = res.id;
            this.dialogObj.value = res.value;
            this.dialogObj.desc = res.desc;
            this.dialogObj.key = this.activeName;
            this.dialogObj.show = true;
          });
        },
        del(data){
          this.$confirm('此操作将删除该记录?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            deleteConfigApi(data.id).then(res=>{
              this.getList()
              this.$message({
                type: 'success',
                message: '删除成功!'
              });
            });
          });
        },
        handleClick(tab) {
          this.activeName = tab.name;
          this.getList();
        },
      }
    }
</script>

<style scoped lang="less">
  @import "../../util/public";
  .add-btn {
    margin: 10px 0;
  }
  .img {
    width: 200px;
  }
  .news-media {
    width: 25%;
  }
  .news-media img{
    width: 100%;
  }
  .news-media .el-card{
      padding: 10px;
  }
  .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: 15px 10px 10px;
    line-height: 1.2;
  }
  .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;
  }
  .f-bt {
    display: flex;
    position: relative;
    justify-content: space-between;
    align-items: flex-start;
  }
  .ellip {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
</style>