<template>
  <div class="dm-wrap" v-loading="loading">
    <el-row :gutter="20">
      <el-form label-width="80px" ref="form" :model="form" :rules="rules">
        <el-col :span="12">
          <el-form-item label="短信签名">
            <div class="sign">
              <el-input v-model="form.sign" disabled class="ipt"></el-input>
              <span class="tip" style="margin-left: 20px;">修改签名请联系商家运营</span>
            </div>
          </el-form-item>
          <el-form-item label="模板名称" prop="title">
            <el-input v-model="form.title" :maxlength="10" show-word-limit placeholder="用于商户自己区分，对短信收件人不可见"></el-input>
          </el-form-item>
          <el-form-item label="短信类型" prop="type">
            <el-radio-group v-model="form.type" @change="showMoreFlag = false">
              <el-radio v-for="(v, i) in typeOptions" :key="i" :label="v.value">{{ v.label }}</el-radio>
            </el-radio-group>
            <div class="rule">
              <div class="top">短信发送规则</div>
              <div class="content" v-if="form.type == 0">
                <p>1、字数规范：单条短信按70字算（含签名、变量的实际取值）；</p>
                <p class="pd90">超过70字后，总长度按67字/条计算条数（比如140字按3条计费）；</p>
                <p class="pd90">汉字、字母、数字、标点符号（不区分全角/半角）以及空格等都按1个字计算；</p>
                <p class="pd90">换行/Enter会导致短信分多条计算；</p>
                <p>2、格式规范：不能包含【】、￥、★、^_^&等特殊符号，防止乱码；</p>
                <p>2、变量规范：不支持全变量模板，不支持中文变量参数，不支持变量嵌套（如{1{3}}）；</p>
                <p>
                  4、政策规范：不能发送房产、移民、贷款、政治、色情、暴力等违法类短信；
                  <el-button v-show="!showMoreFlag" type="text" @click="showMoreFlag = true" style="margin-left: 5px">查看更多<i class="iconfont icon-zhankai- arrow_icon"/></el-button>
                </p>
                <p v-show="showMoreFlag">
                  禁止发送股票、移民、面试招聘、彩票、返利、抽奖、贷款、催款、征信、投资理财、赌博、中奖、毒品、党政、法律维权、众筹、慈善捐款、宗教、迷信、殡葬、刷单、空包网、一元夺宝、一元秒杀、A 货、医疗、整形、美容、会所、酒吧、足浴、暴力、恐吓、色情、皮草、助考、装修（含建材和家私）、商标注册、加群、加 QQ 或者加微信、相亲交友、贩卖个人信息、宣传短信通道、游戏推广、会展推广、网站推广、优惠券类推广、卡类推广、保险推广、信用卡提额、返现返利、代开发票、邀请好评、酒类、用户拉新以及用户召回等类型的短信。
                  <el-button v-show="showMoreFlag" type="text" @click="showMoreFlag = false" style="margin-left: 5px">收起</el-button>
                </p>
              </div>
              <div class="content" v-else>
                <p>1、字数规范：单条短信按70字算（含签名、后缀和变量的实际取值）；</p>
                <p class="pd90">超过70字后，总长度按67字/条计算条数（比如140字按3条计费）；</p>
                <p class="pd90">汉字、字母、数字、标点符号（不区分全角/半角）以及空格等都按1个字计算；</p>
                <p class="pd90">换行/Enter会导致短信分多条计算；</p>
                <p>2、格式规范：不能包含【】、￥、★、^_^&等特殊符号，防止乱码；</p>
                <p>3、变量规范：不支持全变量模板，不支持中文变量参数，不支持变量嵌套（如{1{3}}）；</p>
                <p>
                  4、政策规范：不能发送房产、移民、贷款、政治、色情、暴力等违法类短信；
                  <el-button v-show="!showMoreFlag" type="text" @click="showMoreFlag = true" style="margin-left: 5px">查看更多<i class="iconfont icon-zhankai- arrow_icon"/></el-button>
                </p>
                <p v-show="showMoreFlag">
                  禁止发送股票、移民、面试招聘、彩票、返利、抽奖、贷款、催款、征信、投资理财、赌博、中奖、毒品、党政、法律维权、众筹、慈善捐款、宗教、迷信、殡葬、刷单、空包网、一元夺宝、一元秒杀、A 货、医疗、整形、美容、会所、酒吧、足浴、暴力、恐吓、色情、皮草、助考、装修（含建材和家私）、商标注册、加群、加 QQ 或者加微信、相亲交友、贩卖个人信息、宣传短信通道、游戏推广、会展推广、网站推广、优惠券类推广、卡类推广、保险推广、信用卡提额、返现返利、代开发票、邀请好评、酒类、用户拉新以及用户召回等类型的短信。
                  <el-button v-show="showMoreFlag" type="text" @click="showMoreFlag = false" style="margin-left: 5px">收起</el-button>
                </p>
              </div>
            </div>
          </el-form-item>
          <el-form-item label="短信内容" prop="content" class="pb10">
            <el-input ref="textarea" type="textarea" placeholder="请输入短信内容" :rows="8" v-model="form.content" resize="none" :maxlength="450" show-word-limit @input="resetValidateStatus"></el-input>
            <div class="other_fn">
              <div class="left">
                <el-popover v-model="templateVisbile" placement="bottom-start" width="650" trigger="click">
                  <el-button slot="reference" type="text">添加变量参数</el-button>
                  <div class="popver_content">
                    <p>可添加参数表如下，参数变量的字数长度会动态变化，请勿添加过多变量；注意：{19]{20}变量，只有当积分体系是GIC计算时才生效，否则添加后无效。</p>
                    <ul>
                      <li v-for="(val, key) in templateVar" :key="key">
                        <span class="item" @click="addVar(key, val)">{{ '{' + key + '}' }}={{ val }}</span>
                      </li>
                    </ul>
                  </div>
                </el-popover>
                <template v-if="userData.wxaLinkFlag == 1">
                  <span class="line"></span>
                  <el-button type="text" @click="transferLink.show = true">插入小程序链接</el-button>
                  <!-- <el-button type="text" @click="reduceLink.show = true">压缩H5链接</el-button> -->
                </template>
              </div>
              <el-button type="primary" style="border-radius: 0" :disabled="!contentLength" @click="validateContent">校验屏蔽词</el-button>
            </div>
            <div class="tip" style="margin-top: 8px;line-height: 17px">
              已输入 <span style="color: #303133">{{ contentLength }}</span> 字（不包含变量参数）<br />
              <!--内容 + 签名 + 回T退订后缀-->
              短信长度 <span style="color: #303133">{{ contentLength + form.sign.length + (isEcmMsg ? 4 : 0) }}</span> 个字（{{ isEcmMsg ? '包含签名和后缀，不包含变量参数' : '包含签名，不包含变量参数' }}）计费条数以实际为准。
            </div>
            <div class="validate_res success" v-if="validateStatus == 1"><i class="iconfont icon-chenggong mr6 icon_size" />校验通过</div>
            <div class="validate_res error" v-else-if="validateStatus == 0">
              <p><i class="iconfont icon-shibai mr6 icon_size" />校验失败</p>
              <div class="reason">{{ validaErrorMsg }}</div>
            </div>
          </el-form-item>
          <el-form-item label="申请说明" prop="remark">
            <el-input type="textarea" :rows="8" v-model="form.remark" :maxlength="120" show-word-limit resize="none" placeholder="填写模板应用场景，用于辅助运营商审核"></el-input>
          </el-form-item>
        </el-col>
      </el-form>
      <div class="preview">
        <div class="preview_content">
          <div class="inner">{{ previewContent }}</div>
        </div>
      </div>
    </el-row>
    <div class="btn_bottom">
      <el-button type="primary" @click="submit('form')">提交审核</el-button>
      <el-button @click="$router.go(-1)">返 回</el-button>
    </div>
    <!-- 压缩链接 -->
    <el-dialog :visible.sync="reduceLink.show" title="压缩链接" width="798px" @closed="reduceLink.link = ''">
      <el-form label-width="100px">
        <el-form-item label="请输入网址：">
          <dm-input class="reduce-link-input" type="textarea" :rows="4" v-model="reduceLink.link"></dm-input>
          <p class="reduce-link-tip">如果链接只能在微信环境下打开，则浏览器会提示需要在微信下打开此链接，但是无法直接跳转到微信</p>
        </el-form-item>
      </el-form>
      <template slot="footer">
        <el-button @click="reduceLink.show = false">取消</el-button>
        <el-button type="primary" @click="onReduceLink">生成链接</el-button>
      </template>
    </el-dialog>
    <!-- 插入小程序链接 -->
    <el-dialog :visible.sync="transferLink.show" title="插入小程序链接" width="878px" @closed="onTransferLinkClose">
      <div class="layout--tips" style="margin:0 0 20px 20px;width:750px;display:inline-block;">
        <i class="el-icon-info"></i> 因微信小程序规则调整（2022年4月11日已调整），影响如下。为了准确使用该功能，请仔细阅读该提示:<br />
        1、链接有效期为永久；<br />
        2、单个小程序每天生成链接数上限为 50 万条，建议使用该方式 触达的用户数小于50万/天。
      </div>
      <el-form label-width="110px">
        <el-form-item label="链接类型：">
          <el-button @click="selectLink.show = true">{{ selectLink.linkData.name || '设置小程序链接' }}</el-button>
        </el-form-item>
      </el-form>
      <template slot="footer">
        <el-button @click="transferLink.show = false">取消</el-button>
        <el-button type="primary" @click="onTransferLink">生成链接</el-button>
      </template>
    </el-dialog>
    <el-dialog :visible.sync="insertLink.show" title="链接生成">
      <div class="insert-link">
        <p class="link-text">{{ insertLink.link }}</p>
        <el-button type="text" v-clipboard:text="insertLink.link">复制</el-button>
      </div>
      <template slot="footer">
        <el-button @click="insertLink.show = false">上一步</el-button>
        <el-button type="primary" @click="onInsert">插入链接</el-button>
      </template>
    </el-dialog>
    <linktools :linkVisible.sync="selectLink.show" :linkData="selectLink.linkData" :remove="[5, 35]" :can-save="true" @linkSelect="onSaveLink" /><!-- 链接小工具 - 转赠 -->
  </div>
</template>
<script>
import linktools from '@/components/linktools-fulls/index';
import { _debounce } from '@/utils/index';
import { saveTempService, LoadTempInfo, checkSmsContext } from '@/service/api/messageApi.js';
import { compressLink, getTransferLink, getUserLogin, getSign } from '@/service/api/commonApi.js';
export default {
  name: 'add-temp',
  components: { linktools },
  data() {
    const valiContent = (rules, value, callback) => {
      // 如果是通过链接小工具生成的链接，并且链接前或者后无空格时，自动补齐空格
      if (Array.isArray(this.insertLink.inserted)) {
        this.insertLink.inserted.forEach(el => {
          // 校验content中所有链接的前面或者后面都有一个空格
          const reg = new RegExp(`${el}`, 'g');
          value = value.replace(reg, (str, index) => {
            if (value[index - 1] != ' ') {
              str = ' ' + str;
            }
            if (value[index + str.length] != ' ') {
              str = str + ' ';
            }
            return str;
          });
        });
      }
      this.form.content = value;
      // 如果是复制的链接，提示链接后面需要保留一个空格，如果用户不添加空格则无法保存
      const urlReg = /(https?|ftp|file):\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]/g;
      let validate = false;
      value.replace(urlReg, (str, $1, index) => {
        if (!validate) {
          validate = value[index - 1] != ' ' || value[index + str.length] != ' ';
        }
      });
      if (validate) {
        return callback(new Error('链接前面和后面需要保留一个空格！'));
      }
      callback();
    };
    return {
      loading: false,
      form: {
        sign: '',
        smsRecordlateId: '',
        title: '',
        type: 1,
        content: '',
        remark: '',
        gicSmsTemplateId: ''
      },
      typeOptions: [{ value: 1, label: '营销短信' }, { value: 0, label: '普通短信' }], // eslint-disable-line
      rules: {
        title: { required: true, message: '请输入模板名称', trigger: 'blur' },
        type: { required: true, message: '请选择短信类型', trigger: 'blur' },
        content: [
          { required: true, message: '请输入短信内容', trigger: 'blur' },
          { validator: valiContent, trigger: 'blur' }
        ],
        remark: { required: true, message: '请输入申请说明', trigger: 'blur' }
      },
      editFlag: this.$route.meta.type === 'edit',
      userData: {},
      // 压缩链接
      reduceLink: {
        show: false,
        link: ''
      },
      // 插入小程序链接相关
      insertLink: {
        show: false,
        link: '',
        inserted: [] // 已经插入到短信内容的链接，用来校验在短信文本中链接前后是否有空格
      },
      // 转换链接
      transferLink: {
        show: false,
        type: '0', // 0-短期有效，1-长期有效，2-永久有效
        dayNum: 1, // 天数
        pageId: '' // pageId
      },
      // 链接小工具选择链接
      selectLink: {
        show: false,
        linkData: {}
      },
      // 模板变量
      templateVisbile: false,
      templateVar: {
        1: '姓名',
        2: '姓名+先生/女士',
        3: '生日日期',
        4: '生日天数',
        5: '关注日期',
        6: '关注天数',
        7: '主门店品牌名称',
        8: '主门店名称',
        9: '主门店电话',
        10: '专属导购姓名',
        11: '专属导购手机号',
        12: '开卡日期',
        13: '开卡天数',
        14: '开卡门店名称',
        15: '会员卡号',
        16: '会员等级名称',
        17: '主门店地址',
        18: '会员等级剩余有效天数',
        19: '积分余额',
        20: '30天内将过期积分额度',
        21: '储值余额',
        22: '消费总额',
        23: '消费次数',
        24: '最近消费日期',
        25: '最近消费间隔',
        26: '最高单笔消费',
        27: '最近消费门店名称',
        28: '最近消费品牌名称',
        29: '入会后的生日次数'
      },
      validateStatus: null, // 校验状态 null未校验 0失败 1成功
      showMoreFlag: false, // 展示更多文案flag
      validaErrorMsg: '' // 校验失败内容
    };
  },
  computed: {
    contentLength() {
      const reg = /\{(\d+)\}/g;
      let content = this.form.content.replace(reg, (match, para) => {
        if (this.templateVar[para]) return '';
        else return match;
      });
      return content.length;
    },
    previewContent() {
      const reg = /\{(\d+)\}/g;
      let content = this.form.content.replace(reg, (match, para) => {
        if (this.templateVar[para]) return `{${this.templateVar[para]}}`;
        else return match;
      });
      return this.form.sign + (content || '{短信内容}') + (this.isEcmMsg ? '回T退订' : '');
    },
    isEcmMsg() {
      return this.form.type == 1;
    }
  },
  async created() {
    if (this.editFlag) {
      this.LoadTempInfo();
    } else {
      const sign = await getSign();
      this.form.sign = sign.result.signText ? `【${sign.result.signText}】` : '';
    }
    this.getUserData();
  },
  methods: {
    submit: _debounce(function(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          if (this.validateStatus == null) return this.$message.error('请校验短信内容屏蔽词');
          else if (this.validateStatus == 0) return this.$message.error('短信内容校验失败，请检查');
          this.saveTempService();
        } else {
          return false;
        }
      });
    }),
    async saveTempService() {
      if (this.loading) {
        return;
      }
      try {
        this.loading = true;
        const para = Object.assign({}, this.form);
        delete para.sign;
        await saveTempService(para);
        this.$tips({ type: 'success', message: '操作成功' });
        this.$router.push('/message/temp');
        this.loading = false;
      } catch (err) {
        this.$tips({ type: 'error', message: '操作失败' });
        this.loading = false;
      }
    },
    async LoadTempInfo() {
      this.loading = true;
      let sign = await getSign();
      let res = await LoadTempInfo({ gicSmsTemplateId: this.$route.params.id });
      let content = res.result.smsContent.trim() || '';
      if (res.result.smsType == 1 && content.slice(-4) == '回T退订') {
        content = content.slice(0, -4);
      }
      this.form = {
        type: res.result.smsType,
        content: content,
        remark: res.result.remark,
        title: res.result.smsTitle,
        gicSmsTemplateId: res.result.gicSmsTemplateId,
        sign: sign.result.signText ? `【${sign.result.signText}】` : ''
      };
      this.loading = false;
    },
    getUserData() {
      getUserLogin().then(res => {
        this.userData = res.result || {};
      });
    },
    // 生成短连接
    onReduceLink() {
      if (!this.reduceLink.link) {
        return this.$tips({ type: 'error', message: '请输入网址' });
      }
      this.loading = true;
      compressLink({ link: this.reduceLink.link }, false, false, 'post')
        .then(res => {
          this.insertLink.show = true;
          this.insertLink.link = res.result;
        })
        .finally(() => (this.loading = false));
    },
    // 保存链接小工具返回的链接数据
    onSaveLink(linkData) {
      this.selectLink.linkData = linkData;
    },
    onTransferLinkClose() {
      this.selectLink.linkData = {};
      this.transferLink.type = '0';
      this.transferLink.dayNum = 1;
    },
    // 将小程序链接转换成中转页链接
    onTransferLink() {
      if (!this.selectLink.linkData.id) {
        return this.$tips({ type: 'error', message: '请选择小程序链接' });
      }
      this.loading = true;
      const { type, dayNum } = this.transferLink;
      const requestData = { type, dayNum, pageLink: JSON.stringify(this.selectLink.linkData) };
      getTransferLink(requestData, false, false, 'post')
        .then(res => {
          this.insertLink.link = res.result;
          this.insertLink.show = true;
        })
        .finally(() => (this.loading = false));
    },
    onInsert() {
      // 链接插入短信中需要前后有一个空格
      this.form.content = `${this.form.content} ${this.insertLink.link} `;
      this.insertLink.show = false;
      this.reduceLink.show = false;
      this.transferLink.show = false;
      this.insertLink.inserted.push(this.insertLink.link);
    },
    // 向短信内容中插入模板变量
    addVar(key, val) {
      const curPos = this.$refs['textarea'].$el.children[0].selectionStart;
      let curContent = this.form.content;
      this.form.content = curContent.slice(0, curPos) + `{${key}}` + curContent.slice(curPos, curContent.length);
      this.templateVisbile = false;
    },
    // 校验屏蔽词
    validateContent() {
      checkSmsContext({ context: this.form.content, type: this.form.type })
        .then(res => {
          this.validateStatus = 1;
        })
        .catch(err => {
          this.validateStatus = 0;
          this.validaErrorMsg = err.data.message;
        });
    },
    // 重置校验屏蔽词的状态
    resetValidateStatus() {
      if (this.validateStatus) this.validateStatus = null;
    }
  }
};
</script>
<style lang="scss" scoped>
.reduce-link-input {
  /deep/ .dm-input__counter {
    display: none;
  }
}
.reduce-link-tip {
  margin-top: 5px;
  text-align: right;
  font-size: 12px;
  color: #606266;
  line-height: 17px;
}
.transfer-link-uint {
  margin: 0 15px 0 8px;
  font-size: 14px;
  color: #303133;
  line-height: 20px;
}
.transfer-link-tip {
  font-size: 12px;
  color: #909399;
  line-height: 17px;
}
.insert-link {
  padding: 18px 12px;
  background: #f3f6f9;
  .link-text {
    display: inline-block;
    vertical-align: middle;
    margin-right: 10px;
    max-width: 80%;
    font-size: 14px;
    font-weight: 400;
    color: #606266;
    line-height: 20px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
.preview {
  display: inline-block;
  margin-left: 134px;
  width: 320px;
  min-height: 567px;
  background: url('~@/assets/img/template_bg.png') no-repeat center top / contain;
  .preview_content {
    margin: 107px 0 0 27px;
    height: 435px;
    overflow-y: auto;
    .inner {
      margin: 50px 0 0 0;
      box-sizing: border-box;
      word-break: break-all;
      border-radius: 14px;
      padding: 10px;
      width: 200px;
      background: #eaeaec;
    }
  }
}
.sign {
  display: flex;
  justify-content: space-between;
  .ipt {
    flex: 1;
  }
}
.rule {
  margin-top: 16px;
  background: #f5f7fa;
  .top {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 98px;
    height: 20px;
    background: #ebecf0;
    border-radius: 0px 0px 96px 0px;
    color: #303133;
    font-weight: 600;
    font-size: 12px;
  }
  .content {
    padding: 11px 10px;
    p {
      color: #606266;
      font-size: 12px;
      line-height: 17px;
      &.pd90 {
        padding-left: 90px;
      }
    }
    .arrow_icon {
      margin-left: 4px;
      font-size: 12px;
    }
  }
}
.other_fn {
  padding-left: 11px;
  border: 1px solid #dcdfe6;
  border-top: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  .line {
    display: inline-block;
    width: 1px;
    height: 10px;
    background-color: #dcdfe6;
    margin: 0 6px;
  }
}
.tip {
  color: #909399;
  font-size: 12px;
}
.popver_content {
  p {
    color: #909399;
    font-size: 12px;
    line-height: 20px;
  }
  ul {
    li {
      width: 33%;
      display: inline-block;
      margin-top: 10px;
      .item {
        height: 22px;
        background: #f7f8fa;
        border-radius: 2px;
        border: 1px solid #dcdfe6;
        padding: 1px 6px;
        color: #303133;
        box-sizing: border-box;
        display: inline-block;
        &:hover {
          color: #2f54eb;
          border-color: #2f54eb;
          background: #f0f5ff;
        }
      }
    }
  }
}
.validate_res {
  padding: 0 17px;
  margin-top: 7px;
  .mr6 {
    margin-right: 6px;
  }
  &.success {
    background: #e4fdda;
    color: #52c41a;
  }
  &.error {
    background: #ffece4;
    .reason {
      color: #606266;
      font-size: 12px;
      line-height: 17px;
      padding: 7px 0 11px 0;
    }
    p {
      color: #f5222d;
    }
  }
}
.icon_size {
  font-size: 20px;
  vertical-align: middle;
}
.btn_bottom {
  margin-top: 50px;
  padding-left: 80px;
}
</style>
