sms-send-log-drawer.vue 8.62 KB
<template>
  <el-drawer
    title="发送日志"
    :visible.sync="visible"
    size="75%"
    append-to-body
    :wrapper-closable="false"
    custom-class="sms-send-log-drawer"
    @open="onOpen"
  >
    <div class="sms-send-log-body">
      <div class="sms-send-log-toolbar">
        <el-select
          v-model="query.sceneCode"
          size="small"
          clearable
          placeholder="场景"
          class="toolbar-item toolbar-item--scene"
        >
          <el-option label="Birthday" value="Birthday" />
          <el-option label="Login" value="Login" />
          <el-option label="Register" value="Register" />
          <el-option label="VerifyCode" value="VerifyCode" />
        </el-select>
        <el-select
          v-model="query.status"
          size="small"
          clearable
          placeholder="状态"
          class="toolbar-item toolbar-item--status"
        >
          <el-option label="成功" :value="1" />
          <el-option label="失败" :value="0" />
          <el-option label="跳过" :value="2" />
        </el-select>
        <el-date-picker
          v-model="dateRange"
          type="daterange"
          size="small"
          value-format="yyyy-MM-dd"
          range-separator="至"
          start-placeholder="业务日起"
          end-placeholder="业务日止"
          class="toolbar-item toolbar-item--date"
        />
        <el-button size="small" icon="el-icon-search" @click="search">查询</el-button>
        <el-button size="small" icon="el-icon-refresh" @click="reset">重置</el-button>
      </div>

      <NCC-table v-loading="loading" :data="list" class="sms-send-log-table">
        <el-table-column label="时间" width="165">
          <template slot-scope="{ row }">
            {{ row.creatorTime ? ncc.dateFormat(row.creatorTime, 'YYYY-MM-DD HH:mm:ss') : '无' }}
          </template>
        </el-table-column>
        <el-table-column prop="sceneCode" label="场景" width="100" show-overflow-tooltip>
          <template slot-scope="{ row }">{{ row.sceneCode || '无' }}</template>
        </el-table-column>
        <el-table-column prop="mobileMasked" label="手机号" width="120" show-overflow-tooltip>
          <template slot-scope="{ row }">{{ $maskMobile(row.mobileMasked) || '无' }}</template>
        </el-table-column>
        <el-table-column prop="memberName" label="会员" width="90" show-overflow-tooltip>
          <template slot-scope="{ row }">{{ row.memberName || '无' }}</template>
        </el-table-column>
        <el-table-column prop="sendContent" label="内容" min-width="280" show-overflow-tooltip>
          <template slot-scope="{ row }">
            {{ row.sendContent || formatSendContent(row) || '无' }}
          </template>
        </el-table-column>
        <el-table-column prop="creatorUserName" label="发送人" width="100" show-overflow-tooltip>
          <template slot-scope="{ row }">
            <div class="table-cell-with-icon">
              <i class="el-icon-user cell-icon cell-icon--primary" />
              <span>{{ row.creatorUserName || '无' }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="状态" width="100" align="center">
          <template slot-scope="{ row }">
            <el-tag
              size="mini"
              :type="row.status === 1 ? 'success' : (row.status === 2 ? 'warning' : 'danger')"
              disable-transitions
            >
              {{ row.statusName || statusName(row.status) }}
            </el-tag>
            <el-tag v-if="row.isTest === 1" size="mini" type="warning" disable-transitions>测试</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="providerResult" label="结果" min-width="140" show-overflow-tooltip>
          <template slot-scope="{ row }">{{ row.providerResult || '无' }}</template>
        </el-table-column>
      </NCC-table>

      <pagination
        :total="total"
        :page.sync="query.currentPage"
        :limit.sync="query.pageSize"
        @pagination="loadList"
      />
    </div>
  </el-drawer>
</template>

<script>
import { getSmsSendLogList } from '@/api/extend/lqSms'

export default {
  name: 'SmsSendLogDrawer',
  data() {
    return {
      visible: false,
      loading: false,
      dateRange: [],
      query: {
        currentPage: 1,
        pageSize: 10,
        sceneCode: '',
        status: undefined,
        startDate: '',
        endDate: ''
      },
      list: [],
      total: 0
    }
  },
  methods: {
    open() {
      this.visible = true
    },
    onOpen() {
      this.search()
    },
    syncDateRange() {
      const range = this.dateRange || []
      this.query.startDate = range[0] || ''
      this.query.endDate = range[1] || ''
    },
    search() {
      this.query.currentPage = 1
      this.loadList()
    },
    reset() {
      this.dateRange = []
      this.query = {
        currentPage: 1,
        pageSize: this.query.pageSize || 10,
        sceneCode: '',
        status: undefined,
        startDate: '',
        endDate: ''
      }
      this.loadList()
    },
    loadList() {
      this.syncDateRange()
      this.loading = true
      const payload = {
        currentPage: this.query.currentPage,
        pageSize: this.query.pageSize,
        sceneCode: this.query.sceneCode || undefined,
        status: this.query.status === '' || this.query.status === null
          ? undefined
          : this.query.status,
        startDate: this.query.startDate || undefined,
        endDate: this.query.endDate || undefined
      }
      return getSmsSendLogList(payload).then(res => {
        const page = (res && res.data) || {}
        this.list = page.list || []
        this.total = page.pagination && page.pagination.total != null
          ? page.pagination.total
          : (page.total || 0)
      }).catch(() => {
        this.list = []
        this.total = 0
      }).finally(() => {
        this.loading = false
      })
    },
    statusName(status) {
      const map = { 0: '失败', 1: '成功', 2: '跳过' }
      return map[status] || '无'
    },
    formatSendContent(row) {
      if (!row) return ''
      const parts = []
      if (row.signName) parts.push(`【${row.signName}】`)
      if (row.templateCode) parts.push(`(${row.templateCode})`)
      if (row.templateParam) parts.push(row.templateParam)
      return parts.join(' ')
    }
  }
}
</script>

<style lang="scss" scoped>
.sms-send-log-body {
  display: flex;
  flex-direction: column;
  padding: 0 16px 16px;
  height: 100%;
  box-sizing: border-box;
  overflow: hidden;
}

.sms-send-log-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  flex-shrink: 0;
}

.toolbar-item {
  &--scene {
    width: 120px;
  }

  &--status {
    width: 100px;
  }

  &--date {
    width: 260px;
    max-width: 100%;
  }
}

</style>

<style lang="scss">
/*
 * 发送日志抽屉 append-to-body,表格不在 #app 内,全局 #app .el-table 41px 不生效。
 * 与 common.scss / NCC-table 行高规范对齐。
 */
.sms-send-log-drawer {
  .el-drawer__body {
    padding: 0;
    overflow: hidden;
  }

  .sms-send-log-table {
    flex: 1;
    min-height: 0;

    .el-table {
      width: 100% !important;
    }

    .el-table__body-wrapper,
    .el-table__header-wrapper {
      overflow-x: hidden !important;
    }
  }

  .el-table:not(.columnTable) {
    th.el-table__cell,
    td.el-table__cell,
    .el-table__header-wrapper th,
    .el-table__body-wrapper td,
    .el-table__fixed-header-wrapper th,
    .el-table__fixed-body-wrapper td {
      padding: 0 !important;
      height: 41px !important;
      line-height: normal !important;
      box-sizing: border-box;
      vertical-align: middle !important;
    }

    .cell {
      box-sizing: border-box;
      display: flex;
      align-items: center;
      height: 41px !important;
      line-height: normal !important;
      white-space: nowrap !important;
      overflow: hidden;
      text-overflow: ellipsis;
      min-width: 0;
    }

    .el-table__header .cell {
      display: flex;
      align-items: center;
      height: 41px !important;
      line-height: normal !important;
    }

    td.is-center > .cell,
    th.is-center > .cell {
      justify-content: center;
    }

    td.is-right > .cell,
    th.is-right > .cell {
      justify-content: flex-end;
    }

    td.is-left > .cell,
    th.is-left > .cell {
      justify-content: flex-start;
    }

    .cell .el-tag {
      height: 20px;
      line-height: 18px;
      padding: 0 5px;
      font-size: 12px;
      margin: 0;
      flex-shrink: 0;
    }

    .cell .el-tag + .el-tag {
      margin-left: 4px;
    }

    .cell .table-cell-with-icon {
      height: 41px;
    }
  }
}
</style>