陶杰
2024-12-29 2581f9ae47ed8342b1494bc84f4236dcedb66fbc
1.短信模板、短信批量任务
已添加6个文件
1023 ■■■■■ 文件已修改
components/sms/copy-textarea.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/sms/select-all-user.vue 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/sms/template-download.vue 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/sms/send-batch/_id.vue 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/sms/send-batch/index.vue 349 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/sms/template/index.vue 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/sms/copy-textarea.vue
对比新文件
@@ -0,0 +1,92 @@
<template>
  <div class="copy-textarea">
    <div>
      <span style="color:red;">手动输入最多支持100个号码,大批量号码建议通过文件导入形式提交</span>
      <el-button type="text" @click="clearVal">点击清空</el-button></div>
    <el-input type="textarea" :rows="5" v-model="currentValue"
      placeholder="提示:一行输入一个号码,多个手机号请换行隔开。"
      width="80%"
      @change="handlerInputChange"
    ></el-input>
    <div>
      <span style="color:gray;">提示:一行输入一个号码,多个手机号请换行隔开。</span>
    </div>
  </div>
</template>
<script>
import cloneDeep from 'lodash.clonedeep'
export default {
  props: {
    value: {
      type: String,
      default:'',
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      dialogVisible: false,
      currentValue: '',
    }
  },
  watch: {
    value: {
      immediate: true,
      handler(value) {
        this.currentValue = value
      },
    },
  },
  methods: {
    clearVal(){
      this.$elBusUtil
        .confirm('确定要清空吗?')
        .then(() => {
          this.currentValue = ''
          this.$emit('input', '')
          this.$emit('change', '')
        })
        .catch(() => {})
    },
    handlerInputChange(){
      this.$emit('input', this.currentValue)
      this.$emit('change', this.currentValue)
    }
  },
}
</script>
<style lang="scss" scoped>
.copy-textarea {
}
</style>
<style lang="scss">
.shop-user-dialog {
  .dialog-container {
    display: flex;
    align-items: flex-start;
    &__list {
      flex: 1;
      border-right: 1px solid #eee;
      height: 100%;
    }
    &__selected {
      width: 40%;
      height: 100%;
      padding: 24px;
      .el-bus-title {
        margin-bottom: 15px;
      }
      .el-tag {
        margin-right: 6px;
        margin-bottom: 6px;
      }
    }
  }
}
</style>
components/sms/select-all-user.vue
对比新文件
@@ -0,0 +1,244 @@
<template>
  <div class="select-shop-user">
    <el-button v-if="!disabled" type="primary" @click="chooseUser">选择用户列表</el-button>
    <el-table v-if="value && value.length > 0" :data="value">
      <el-table-column label="id" prop="id"></el-table-column>
      <el-table-column label="名称" prop="loginName"></el-table-column>
      <el-table-column label="注册手机号方式" prop="tel"></el-table-column>
      <el-table-column v-if="!disabled" label="操作">
        <template #default="{ $index }">
          <text-button type="danger" @click="deleteUser($index)">删除</text-button>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog :visible.sync="dialogVisible" title="选择用户列表" append-to-body :close-on-click-modal="false"
      custom-class="shop-user-dialog" width="80%">
      <div class="dialog-container">
        <div class="dialog-container__list">
          <el-bus-crud v-bind="tableConfig" />
        </div>
        <div class="dialog-container__selected">
          <el-bus-title title="已添加用户" size="mini" />
          <el-tag v-for="(tag, i) in currentValue" :key="tag.id" closable @close="deleteCurrentUser(i)">{{ tag.loginName
            }}</el-tag>
        </div>
      </div>
      <div slot="footer">
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="confirm">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import cloneDeep from 'lodash.clonedeep'
export default {
  props: {
    value: {
      type: Array,
      default: () => [],
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      dialogVisible: false,
      currentValue: [],
      tableConfig: {
        url: 'flower/api/user/user/list',
        saveQuery: false,
        hasNew: false,
        hasEdit: false,
        hasDelete: false,
        hasView: false,
        columns: [
          { type: 'selection' },
          { label: 'id', prop: 'id' },
          { label: '名称', prop: 'loginName' },
          { label: '注册手机号', prop: 'tel' },
        ],
        extraButtons: [
          {
            text: '选择',
            show: (row) =>
              !this.currentValue.find((item) => item.id === row.id),
            atClick: (row) => {
              this.currentValue.push({
                id: row.id,
                loginName: row.loginName,
                tel: row.tel,
              })
              return false
            },
          },
          {
            text: '取消选择',
            show: (row) => this.currentValue.find((item) => item.id === row.id),
            atClick: (row) => {
              const index = this.currentValue.findIndex(
                (item) => item.id === row.id
              )
              this.currentValue.splice(index, 1)
              return false
            },
          },
        ],
        headerButtons: [
          {
            text: '批量选择',
            type: 'primary',
            disabled: (selected) => selected.length === 0,
            atClick: (selected) => {
              console.log(selected)
              selected.forEach(item => {
                // 检查 selected 数组的每个元素是否已在 currentValue 中
                if (!this.currentValue.some(currentItem => currentItem.id === item.id)) {
                  this.currentValue.push({
                    id: item.id,
                    loginName: item.loginName,
                    tel: item.tel,
                  })
                }
              });
              return true
            },
          },
          {
            text: '批量取消',
            type: 'primary',
            disabled: (selected) => selected.length === 0,
            atClick: (selected) => {
              selected.forEach(item => {
                // 检查 selected 数组的每个元素是否存在于 currentValue 中
                const index = this.currentValue.findIndex(currentItem => currentItem.id === item.id);
                if (index !== -1) {
                  this.currentValue.splice(index, 1); // 如果存在,则移除
                }
              });
              return true
            },
          },
        ],
        searchFormAttrs: {
          labelWidth: 'auto',
        },
        searchForm: [
          {
            type: 'row',
            span: 12,
            items: [
              {
                label: '列表类型:',
                id: 'userType',
                type: 'bus-select-dict',
                el: {
                  code: 'USER_TYPE',
                  multiple: false,
                  style: 'width:100%',
                },
                default: 'customer',
                searchImmediately: true,
                on: {
                change: (e, updateForm, obj) => {
                  console.log(e[0])
                  // if (e[0] === 'supplier') {
                  //   this.tableConfig.url = 'flower/api/supplier/page'
                  // } else if (e[0] === 'partner') {
                  //   this.tableConfig.url = 'flower/api/partner/page'
                  // }else if(e[0]==='customer'){
                  //   this.tableConfig.url = 'flower/api/customer/page'
                  // }
                },
              },
              },
              { label: 'id:', id: 'id', type: 'input' },
              { label: '名称:', id: 'loginName', type: 'input' },
              { label: '注册手机号:', id: 'tel', type: 'input' },
            ],
          },
        ],
      },
    }
  },
  watch: {
    value: {
      immediate: true,
      handler(value) {
        this.currentValue = cloneDeep(value || [])
      },
    },
  },
  methods: {
    handleSelectionChange(rows) {
      console.log(rows)
      alert("全选")
    },
    chooseUser() {
      this.currentValue = cloneDeep(this.value || [])
      this.dialogVisible = true
    },
    deleteCurrentUser(i) {
      this.currentValue.splice(i, 1)
    },
    deleteUser(i) {
      this.$elBusUtil
        .confirm('确定要删除吗?')
        .then(() => {
          const userList = cloneDeep(this.value || [])
          userList.splice(i, 1)
          this.$emit('input', userList)
          this.$emit('change', userList)
        })
        .catch(() => { })
    },
    confirm() {
      this.$emit('input', this.currentValue)
      this.$emit('change', this.currentValue)
      this.dialogVisible = false
    },
    cancel() {
      this.dialogVisible = false
    },
  },
}
</script>
<style lang="scss" scoped>
.select-shop-user {}
</style>
<style lang="scss">
.shop-user-dialog {
  .dialog-container {
    display: flex;
    align-items: flex-start;
    &__list {
      flex: 1;
      border-right: 1px solid #eee;
      height: 100%;
    }
    &__selected {
      width: 40%;
      height: 100%;
      padding: 24px;
      .el-bus-title {
        margin-bottom: 15px;
      }
      .el-tag {
        margin-right: 6px;
        margin-bottom: 6px;
      }
    }
  }
}
</style>
components/sms/template-download.vue
对比新文件
@@ -0,0 +1,80 @@
<template>
  <div class="copy-textarea">
    <div>
      <el-link href="https://hmy-flower.oss-cn-shanghai.aliyuncs.com/a5/a57ec65b165148e5a669e7766743e489template_phone.xlsx" download="template_phone.xlsx">
        <span style="color:#5FA7EE;">点击下载模板</span>
      </el-link>
      <!-- <el-link @click="downloadTemplate">点击下载模板a</el-link> -->
    </div>
  </div>
</template>
<script>
import cloneDeep from 'lodash.clonedeep'
export default {
  props: {
    value: {
      type: String,
      default:'',
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      dialogVisible: false,
      currentValue: '',
    }
  },
  watch: {
    value: {
      immediate: true,
      handler(value) {
        this.currentValue = value
      },
    },
  },
  methods: {
    downloadTemplate() {
      const link = document.createElement('a');
      link.href = 'https://hmy-flower.oss-cn-shanghai.aliyuncs.com/a5/a57ec65b165148e5a669e7766743e489template_phone.xlsx';
      link.download = 'template_phone.xlsx';
      link.click();
    }
  },
}
</script>
<style lang="scss" scoped>
.copy-textarea {
}
</style>
<style lang="scss">
.shop-user-dialog {
  .dialog-container {
    display: flex;
    align-items: flex-start;
    &__list {
      flex: 1;
      border-right: 1px solid #eee;
      height: 100%;
    }
    &__selected {
      width: 40%;
      height: 100%;
      padding: 24px;
      .el-bus-title {
        margin-bottom: 15px;
      }
      .el-tag {
        margin-right: 6px;
        margin-bottom: 6px;
      }
    }
  }
}
</style>
pages/sms/send-batch/_id.vue
对比新文件
@@ -0,0 +1,135 @@
<template>
  <div class="base-page-wrapper coupon-detail">
    <el-bus-title title="基本信息" size="small" />
    <!-- <el-bus-form ref="form" label-width="auto" :content="formContent" readonly class="readonly-form" /> -->
    <el-form ref="form" label-width="100px">
      <el-form-item label="模板名称:"> {{ statisticsData.smsTaskName || '' }} </el-form-item>
      <el-form-item label="号码数量:"> {{ statisticsData.totalNum || 0 }} </el-form-item>
    </el-form>
    <div class="base-page-wrapper__line"></div>
    <el-bus-title title="发送结果" size="small" />
    <div><el-row :gutter="20">
        <el-col :span="3" class="mb-2">
          <el-card>
            <div class="statistic-title">发送号码数量</div>
            <div class="statistic-num">{{ statisticsData.totalNum || 0 }}</div>
          </el-card>
        </el-col>
        <el-col :span="3" class="mb-2">
          <el-card>
            <div class="statistic-title">成功</div>
            <div class="statistic-num">{{ statisticsData.successNum || 0 }}</div>
          </el-card>
        </el-col>
        <el-col :span="3" class="mb-2">
          <el-card>
            <div class="statistic-title">失败</div>
            <div class="statistic-num">{{ statisticsData.failureNum || 0 }}</div>
          </el-card>
        </el-col>
        <el-col :span="3" class="mb-2">
          <el-card>
            <div class="statistic-title">发送中</div>
            <div class="statistic-num"> {{ statisticsData.sendingNum || 0 }} </div>
          </el-card>
        </el-col>
      </el-row></div>
    <div class="base-page-wrapper__line"></div>
    <el-bus-title title="发放记录" size="small" />
    <el-bus-crud v-bind="recordTableConfig" />
    <div class="text-center mt-20">
      <el-button class="min-w-100" @click="goBack">返回</el-button>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      statisticsData:{},
      recordTableConfig: {
        url: `flower/v2/sms-task-detail/list`,
        hasOperation: false,
        hasNew: false,
        extraQuery: {
          smsTaskId: this.$route.params.id,
        },
        columns: [
          { label: '接收号码', prop: 'phone' },
          { label: '发送时间', prop: 'createTime' },
          { label: '发送结果', prop: 'resultStr' },
          { label: '失败原因', prop: 'failReason' },
        ],
        searchForm: [
          {
            type: 'row',
            items: [
              { label: '接收号码', id: 'phone', type: 'input', searchImmediately: true, },
              {
                label: '发送结果',
                id: 'result',
                type: 'bus-select-dict',
                el: {
                  code: 'SMS_SEND_RESULT',
                  multiple: false,
                  style: 'width:100%',
                  clearable: true,
                },
                searchImmediately: true,
              },
            ],
          },
        ],
      },
    }
  },
  head() {
    return {
      title: '批量发送短信详情',
    }
  },
  mounted() {
    this.getInitData()
  },
  methods: {
    async getInitData() {
      const { code, data } = await this.$elBusHttp.request(
            `flower/v2/sms-task-detail/taskStatistics/${this.$route.params.id}`,
            {
              method: 'get',
              // params: {
              //   id: this.$route.params.id
              // }
            }
          )
          if (code === 0) {
            console.log("data")
            console.log(data)
            this.statisticsData = data
          }
    },
  },
}
</script>
<style lang="scss" scoped>
@import '@/assets/coupon/detail.scss';
@import '@/assets/statistic/index.scss';
.statistic-title {
  text-align: center;
  font-size: 16px;
  color: $main-title-color;
  font-weight: bold;
  margin-bottom: 6px;
}
.statistic-num {
  text-align: center;
  font-size: 16px;
  color: $primary-color;
}
</style>
pages/sms/send-batch/index.vue
对比新文件
@@ -0,0 +1,349 @@
<template>
  <el-bus-crud ref="curd" v-bind="tableConfig" />
</template>
<script>
import dayjs from 'dayjs'
import 'dayjs/locale/zh-cn'
import SelectAllUser from '@/components/sms/select-all-user'
import CopyTextarea from '@/components/sms/copy-textarea'
import TemplateDownload from '@/components/sms/template-download'
export default {
  data() {
    const defaultDate = `${dayjs().format('YYYY-MM-DD')} 00:00:00`
    return {
      tableConfig: {
        url: 'flower/v2/sms-task/list',
        newUrl: 'flower/v2/sms-task/new',
        editUrl: 'flower/v2/sms-task/edit',
        viewUrl: 'flower/v2/sms-task',
        viewOnPath: true,
        deleteUrl: 'flower/v2/sms-task/delete',
        hasNew: true,
        newText: '添加发送任务',
        dialogNeedRequest: true,
        canEdit: (row) => row.status === 'wait_publish',
        canDelete: (row) => row.status === 'wait_publish',
        extraButtons: [
          {
            text: '发布',
            show: (row) => {
              return row.status === 'wait_publish';
            },
            atClick: async (row) => {
              try {
                await this.$elBusUtil.confirm('确定要发布吗?')
                const { code } = await this.$elBusHttp.request(
                  `flower/v2/sms-task/publish`,
                  {
                    method: 'post',
                    data: {
                      id: row.id,
                    }
                  }
                )
                if (code === 0) {
                  this.$message.success('发布成功')
                }
              } catch (e) {
                return false
              }
            },
          },
        ],
        onResetView: (row) => {
          // this.$router.push(`${this.$route.path}/${row.id}`)
          // const searchFormRef = this.$refs.crud.$refs.searchForm
          // const searchFormValue = searchFormRef.getFormValue()
          const url = this.$router.resolve(
            `/sms/send-batch/${row.id}`
          ).href
          window.open(url, '_blank')
        },
        columns: [
          { label: '任务名称', prop: 'name' },
          { label: '模板名称', prop: 'smsTemplateName' },
          { label: '模板描述', prop: 'smsTemplateDesc' },
          { label: '任务状态', prop: 'statusStr' },
          { label: '创建时间', prop: 'createTime' },
        ],
        searchForm: [
          {
            type: 'row',
            items: [
              { label: '任务名称', id: 'name', type: 'input' },
              { label: '模板名称', id: 'smsTemplateName', type: 'input' },
              {
                label: '任务状态',
                id: 'status',
                type: 'bus-select-dict',
                el: {
                  code: 'SMS_TASK_STATUS',
                  multiple: false,
                  style: 'width:100%',
                },
              },
              {
                label: '创建时间',
                id: 'startDate',
                component: 'el-bus-date-range',
                el: {
                  clearable: true,
                },
                // commonFormat: true,
                // commonFormatProps: ['startDate', 'endDate'],
                inputFormat: (row) => {
                  if ('startDate' in row || 'endDate' in row) {
                    return [
                      this.$elBusUtil.toDate(row.startDate),
                      this.$elBusUtil.toDate(row.endDate),
                    ]
                  }
                },
                outputFormat: (val) => {
                  return {
                    startDate: val[0] ? `${this.$elBusUtil.toDate(val[0])} 00:00:00` : undefined,
                    endDate: val[1] ? `${this.$elBusUtil.toDate(val[1])} 23:59:59` : undefined,
                  }
                },
                customClass: 'in-bus-form',
                // commonRules: true,
                // default: [defaultDate, defaultDate],
              },
            ],
          },
        ],
        form: [
          {
            label: '任务名称',
            id: 'name',
            type: 'input',
            rules: {
              required: true,
              message: '请输入任务名称',
              trigger: 'blur',
            },
          },
          {
            label: '短信模板:',
            id: 'smsTemplateId',
            type: 'bus-select',
            el: {
              interfaceUri: 'flower/v2/sms-template/templateName/all',
              extraQuery: {
                current: 1,
                size: 2000,
              },
              props: {
                label: 'name',
                value: 'id',
                // dataPath: 'data',
              },
              filterable: true,
              multiple: false,
              style: 'width:100%',
            },
            rules: {
              required: true,
              message: '请选择短信模板',
              trigger: 'change',
            },
          },
          {
            label: '接收号码:',
            id: 'type',
            type: 'bus-radio',
            el: {
              code: 'SMS_RECEIVE_TYPE',
              // hasAll: false,
              // childType: 'el-radio-button',
            },
            str: true,
            on: {
              change: (e, updateForm, obj) => {
                // updateForm({
                //   // fileUrl: undefined,
                //   // fileUrlDesc: undefined,
                //   // pointCostomIdList: undefined,
                //   // input: undefined,
                // })
              },
            },
            default: this.$route.query.status || '',
            span: 24,
            searchImmediately: true,
            rules: {
              required: true,
              message: '请输入接收号码',
              trigger: 'change',
            },
          },
          {
            label: '导入接收文件',
            id: 'fileUrl',
            component: 'el-bus-upload',
            el: {
              // listType: 'text',
              accept: ".xls,.xlsx",
              limit: 1
            },
            commonFormat: true,
            forceDisabled: true,
            hidden: (row) => {
              return row.type !== 'IMPORT'
            },
            readonly: false,
            rules: [
              { required: true, message: '请上传文件' },
              {
                validator: (rule, value, callback) => {
                  if (!value || value.length > 1) {
                    callback(new Error('只能上传一个文件'));
                  } else {
                    callback();
                  }
                },
                trigger: 'change',
              },
            ],
          },
          {
            label: '',
            id: 'fileUrlDesc',
            component: TemplateDownload,
            hidden: (row) => row.type !== 'IMPORT',
          },
          {
            label: '手动输入:',
            id: 'phones',
            component: CopyTextarea,
            el: {
              type: 'textarea',
            },
            // hidden: (row) => row.discountType !== 'ratio',
            hidden: (row) => row.type !== 'INPUT',
            readonly: false,
            span: 24,
            rules: [
              { required: true, message: '请输入号码', trigger: 'blur,change', },
              // {
              //   validator: (rule, value, callback) => {
              //     // 如果值为空,直接返回错误
              //     if (!value || value.trim() === '') {
              //       callback(new Error('请输入电话号码,每个号码后跟换行符'));
              //       return;
              //     }
              //     // 正则表达式:只匹配中国大陆手机号格式
              //     const phoneRegex = /^1[3-9]\d{9}$/;
              //     const lines = value.split('\n'); // 按换行符分割文本
              //     // 遍历每一行并校验
              //     for (let i = 0; i < lines.length; i++) {
              //       const line = lines[i]; // 每一行去除空格
              //       if (line && !phoneRegex.test(line)) {
              //         // 如果当前行的电话号码格式不正确,提示出错的行号
              //         callback(new Error(`第 ${i + 1} 行电话号码格式不正确,请检查输入, 如 电话号码后面有空格等`));
              //         return; // 一旦发现不符合的号码格式,就终止校验
              //       }
              //     }
              //     if(lines.length>100){
              //       callback(new Error(`手动输入最多支持100个号码`));
              //     }
              //     // 所有行都符合格式,执行 callback()
              //     callback();
              //   },
              //   trigger: 'blur',
              // }
              {
                validator: (rule, value, callback) => {
                  // 如果值为空,直接返回错误
                  if (!value || value.trim() === '') {
                    callback(new Error('请输入电话号码,每个号码后跟换行符'));
                    return;
                  }
                  const phoneRegex = /^1[3-9]\d{9}$/; // 校验手机号格式
                  const lines = value.split('\n'); // 按换行符分割文本
                  const phoneCount = {}; // 用来统计电话号码出现次数
                  if (lines.length > 100) {
                    callback(new Error(`手动输入最多支持100个号码`));
                  }
                  // 校验每一行的电话号码
                  for (let i = 0; i < lines.length; i++) {
                    const line = lines[i].trim();
                    if (line) {
                      // 如果当前行不是空的,校验其格式
                      if (!phoneRegex.test(line)) {
                        callback(new Error(`第 ${i + 1} 行电话号码格式不正确,请检查输入`));
                        return;
                      }
                      // 统计号码出现的次数
                      phoneCount[line] = (phoneCount[line] || 0) + 1;
                    }
                  }
                  // 收集所有重复的电话号码
                  const duplicates = [];
                  for (const phone in phoneCount) {
                    if (phoneCount[phone] > 1) {
                      duplicates.push(`${phone} 重复了 ${phoneCount[phone]} 次`);
                    }
                  }
                  // 如果有重复号码,返回错误并列出所有重复的号码
                  if (duplicates.length > 0) {
                    callback(new Error(`以下电话号码重复:\n${duplicates.join('\n')}`));
                    return;
                  }
                  // 校验通过
                  callback();
                },
                trigger: 'blur',
              }
            ],
          },
          {
            label: '选择用户列表',
            id: 'smsUserDTOS',
            component: SelectAllUser,
            hidden: (row) => row.type !== 'SELECT',
            rules: { required: true, message: '请选择领取用户' },
            inputFormat: (row) => {
              if ('smsUserDTOS' in row) {
                return row.smsUserDTOS.filter((i) => i)
              }
            },
            outputFormat: (val) => {
              return val?.length ? val.map((i) => {return {userId:i.id,userPhone:i.tel} }) : []
            },
            forceDisabled: true,
          },
        ],
      },
    }
  },
  head() {
    return {
      title: '批量发送短信',
    }
  },
}
</script>
pages/sms/template/index.vue
对比新文件
@@ -0,0 +1,123 @@
<template>
  <el-bus-crud v-bind="tableConfig" />
</template>
<script>
import dayjs from 'dayjs'
import 'dayjs/locale/zh-cn'
export default {
  data() {
    const defaultDate = `${dayjs().format('YYYY-MM-DD')} 00:00:00`
    return {
      tableConfig: {
        url: 'flower/v2/sms-template/list',
        newUrl: 'flower/v2/sms-template/new',
        deleteUrl: 'flower/v2/sms-template/delete',
        editUrl: 'flower/v2/sms-template/edit',
        columns: [
          { label: 'ID', prop: 'id' },
          { label: 'CODE', prop: 'code' },
          { label: '模板名称', prop: 'name' },
          { label: '模板描述', prop: 'description' },
          { label: '创建时间', prop: 'createTime' },
        ],
        searchForm: [
          {
            type: 'row',
            items: [
              { label: 'ID', id: 'id', type: 'input' },
              { label: 'CODE', id: 'code', type: 'input' },
              { label: '模板名称', id: 'name', type: 'input' },
              {
                label: '创建时间',
                id: 'startDate',
                component: 'el-bus-date-range',
                el: {
                  clearable: true,
                },
                // commonFormat: true,
                commonFormatProps: ['startDate', 'endDate'],
                inputFormat: (row) => {
                  if ('startDate' in row || 'endDate' in row) {
                    return [
                      this.$elBusUtil.toDate(row.startDate),
                      this.$elBusUtil.toDate(row.endDate),
                    ]
                  }
                },
                outputFormat: (val) => {
                  return {
                    startDate:val[0] ? `${this.$elBusUtil.toDate(val[0])} 00:00:00`: undefined,
                    endDate: val[1] ?`${this.$elBusUtil.toDate(val[1])} 23:59:59`: undefined,
                  }
                },
                customClass: 'in-bus-form',
                // commonRules: true,
                // default: [defaultDate, defaultDate],
              },
            ],
          },
        ],
        form: [
          {
            label: 'CODE:',
            id: 'code',
            type: 'bus-select',
            el: {
              interfaceUri: 'flower/v2/sms-template/aliyun/list',
              extraQuery: {
                current: 1,
                size: 2000,
              },
              props: {
                label: 'templateName',
                value: 'templateCode',
                // dataPath: 'records',
              },
              filterable: true,
              multiple: false,
              style: 'width:100%',
            },
            rules: {
              required: true,
              message: '请选择CODE',
              trigger: 'blur',
            },
          },
          {
            label: '模板名称:',
            id: 'name',
            type: 'input',
            rules: {
              required: true,
              message: '请输入模板名称',
              trigger: 'blur',
            },
          },
          {
            label: '模板描述:',
            id: 'description',
            type: 'input',
            el: {
              type: 'textarea',
              rows: 6,
            },
            rules: {
              required: true,
              message: '请输入模板描述',
              trigger: 'blur',
            },
          },
        ],
      },
    }
  },
  head() {
    return {
      title: '短信模板维护',
    }
  },
}
</script>