|
- {% extends "../layout.html" %}
-
- {% block title %}短信记录{% endblock %}
-
- {% block content %}
- <div id="smsApp" v-cloak>
- <el-card shadow="never">
- <template #header>
- <div class="flex items-center justify-between">
- <span class="font-medium">短信发送记录</span>
- </div>
- </template>
-
- <!-- 筛选栏 -->
- <div class="flex items-center gap-4 mb-4 flex-wrap">
- <el-input v-model="query.keyword" placeholder="搜索手机号..." style="width:180px;" clearable @keyup.enter="loadList"></el-input>
- <el-select v-model="query.bizType" placeholder="业务类型" style="width:140px;" clearable>
- <el-option label="实名认证" value="real_name_auth"></el-option>
- <el-option label="修改手机号" value="change_phone"></el-option>
- </el-select>
- <el-select v-model="query.status" placeholder="发送状态" style="width:120px;" clearable>
- <el-option label="待发送" :value="0"></el-option>
- <el-option label="已发送" :value="1"></el-option>
- <el-option label="发送失败" :value="2"></el-option>
- </el-select>
- <el-date-picker v-model="dateRange" type="daterange" range-separator="至"
- start-placeholder="开始日期" end-placeholder="结束日期"
- value-format="YYYY-MM-DD" style="width:240px;" :teleported="false"></el-date-picker>
- <el-button type="primary" @click="loadList">搜索</el-button>
- <el-button @click="resetQuery">重置</el-button>
- </div>
-
- <!-- 信息栏 -->
- <div class="flex items-center gap-3 mb-3 text-sm text-gray-500">
- <span>共 <b class="text-orange-500">${ total }</b> 条记录</span>
- </div>
-
- <!-- 表格 -->
- <el-table :data="list" v-loading="loading" border>
- <el-table-column prop="id" label="ID" width="70"></el-table-column>
- <el-table-column prop="mobile" label="手机号" width="130"></el-table-column>
- <el-table-column prop="code" label="验证码" width="90"></el-table-column>
- <el-table-column prop="biz_type" label="业务类型" width="120">
- <template #default="{ row }">
- <el-tag size="small" :type="bizTypeMap[row.biz_type]?.type || 'info'">${ bizTypeMap[row.biz_type]?.text || row.biz_type }</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="status" label="状态" width="100">
- <template #default="{ row }">
- <el-tag size="small" :type="statusMap[row.status]?.type || 'info'">${ statusMap[row.status]?.text || '未知' }</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="fail_reason" label="失败原因" min-width="180">
- <template #default="{ row }">
- <span class="text-gray-500">${ row.fail_reason || '-' }</span>
- </template>
- </el-table-column>
- <el-table-column prop="ip" label="IP地址" width="130"></el-table-column>
- <el-table-column prop="create_time" label="发送时间" width="170">
- <template #default="{ row }">${ row.create_time?.slice(0,19) }</template>
- </el-table-column>
- </el-table>
-
- <!-- 分页 -->
- <div class="flex justify-end mt-4">
- <el-pagination background layout="total, sizes, prev, pager, next" :total="total" v-model:page-size="pageSize" :page-sizes="[20, 50, 100]" v-model:current-page="page" @current-change="loadList" @size-change="onSizeChange"></el-pagination>
- </div>
- </el-card>
- </div>
- {% endblock %}
-
- {% block js %}
- <script>
- const { createApp, ref, reactive, onMounted } = Vue;
-
- const app = createApp({
- delimiters: ['${', '}'],
- setup() {
- const loading = ref(false);
- const list = ref([]);
- const total = ref(0);
- const page = ref(1);
- const pageSize = ref(20);
- const query = reactive({ keyword: '', bizType: '', status: '' });
- const dateRange = ref(null);
-
- const bizTypeMap = {
- real_name_auth: { type: 'primary', text: '实名认证' },
- change_phone: { type: 'warning', text: '修改手机号' }
- };
-
- const statusMap = {
- 0: { type: 'info', text: '待发送' },
- 1: { type: 'success', text: '已发送' },
- 2: { type: 'danger', text: '发送失败' }
- };
-
- async function loadList() {
- loading.value = true;
- try {
- const params = new URLSearchParams({
- page: page.value, pageSize: pageSize.value,
- keyword: query.keyword, bizType: query.bizType,
- status: query.status !== '' && query.status !== null ? query.status : '',
- startDate: dateRange.value ? dateRange.value[0] : '',
- endDate: dateRange.value ? dateRange.value[1] : ''
- });
- const res = await fetch('/admin/system/sms/list?' + params).then(r => r.json());
- if (res.code === 0) {
- list.value = res.data.data || [];
- total.value = res.data.count || 0;
- }
- } finally { loading.value = false; }
- }
-
- function resetQuery() {
- query.keyword = '';
- query.bizType = '';
- query.status = '';
- dateRange.value = null;
- page.value = 1;
- loadList();
- }
-
- function onSizeChange() {
- page.value = 1;
- loadList();
- }
-
- onMounted(() => loadList());
-
- return { loading, list, total, page, pageSize, query, dateRange, bizTypeMap, statusMap, loadList, resetQuery, onSizeChange };
- }
- });
-
- app.use(ElementPlus, { locale: ElementPlusLocaleZhCn });
- app.mount('#smsApp');
- </script>
- {% endblock %}
|