feat: 添加短信验证码发送记录功能
This commit is contained in:
@@ -33,6 +33,11 @@ const navItems = ref([
|
||||
icon: 'pi pi-shopping-cart',
|
||||
command: () => router.push('/orders')
|
||||
},
|
||||
{
|
||||
label: '短信认证',
|
||||
icon: 'pi pi-comment',
|
||||
command: () => router.push('/sms-code-sends')
|
||||
},
|
||||
{
|
||||
label: '设置',
|
||||
icon: 'pi pi-cog',
|
||||
|
||||
14
frontend/admin/src/api/smsCodeSendService.js
Normal file
14
frontend/admin/src/api/smsCodeSendService.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import httpClient from './httpClient';
|
||||
|
||||
export const smsCodeSendService = {
|
||||
get({ page = 1, limit = 10, phone = '' } = {}) {
|
||||
return httpClient.get('/sms-code-sends', {
|
||||
params: {
|
||||
page,
|
||||
limit,
|
||||
phone: phone.trim()
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
115
frontend/admin/src/pages/SmsCodeSendPage.vue
Normal file
115
frontend/admin/src/pages/SmsCodeSendPage.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<script setup>
|
||||
import { smsCodeSendService } from '@/api/smsCodeSendService';
|
||||
import { formatDate } from '@/utils/date';
|
||||
import Column from 'primevue/column';
|
||||
import DataTable from 'primevue/datatable';
|
||||
import InputText from 'primevue/inputtext';
|
||||
import ProgressSpinner from 'primevue/progressspinner';
|
||||
import Toast from 'primevue/toast';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
const phone = ref('');
|
||||
const loading = ref(false);
|
||||
const searchTimeout = ref(null);
|
||||
|
||||
const records = ref({
|
||||
items: [],
|
||||
total: 0,
|
||||
page: 1,
|
||||
limit: 10
|
||||
});
|
||||
|
||||
const first = ref(0);
|
||||
const rows = ref(10);
|
||||
|
||||
const fetchRecords = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const currentPage = (first.value / rows.value) + 1;
|
||||
const resp = await smsCodeSendService.get({
|
||||
page: currentPage,
|
||||
limit: rows.value,
|
||||
phone: phone.value
|
||||
});
|
||||
records.value = resp.data;
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch sms code sends:', error);
|
||||
toast.add({ severity: 'error', summary: '错误', detail: '加载短信验证码记录失败', life: 3000 });
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onPage = (event) => {
|
||||
first.value = event.first;
|
||||
rows.value = event.rows;
|
||||
fetchRecords();
|
||||
};
|
||||
|
||||
const onSearch = () => {
|
||||
if (searchTimeout.value) {
|
||||
clearTimeout(searchTimeout.value);
|
||||
}
|
||||
searchTimeout.value = setTimeout(() => {
|
||||
first.value = 0;
|
||||
fetchRecords();
|
||||
}, 300);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchRecords();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Toast />
|
||||
|
||||
<div class="w-full">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-2xl font-semibold text-gray-800">短信认证</h1>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="pb-10 flex gap-3 items-center">
|
||||
<InputText v-model="phone" placeholder="按手机号筛选..." class="flex-1" @input="onSearch" />
|
||||
</div>
|
||||
|
||||
<DataTable :value="records.items" :paginator="true" :rows="rows" :totalRecords="records.total"
|
||||
:loading="loading" :lazy="true" :first="first" @page="onPage"
|
||||
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
|
||||
:rowsPerPageOptions="[10, 25, 50]"
|
||||
currentPageReportTemplate="显示第 {first} 到 {last} 条,共 {totalRecords} 条结果" dataKey="id" stripedRows
|
||||
removableSort class="p-datatable-sm" responsiveLayout="scroll">
|
||||
|
||||
<template #empty>
|
||||
<div class="text-center p-4">暂无短信验证码记录。</div>
|
||||
</template>
|
||||
|
||||
<template #loading>
|
||||
<div class="flex flex-col items-center justify-center p-4">
|
||||
<ProgressSpinner style="width:50px;height:50px" />
|
||||
<span class="mt-2">加载短信验证码记录...</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<Column field="id" header="ID" sortable></Column>
|
||||
<Column field="phone" header="手机号" sortable></Column>
|
||||
<Column field="code" header="验证码" sortable></Column>
|
||||
<Column field="sent_at" header="发送时间" sortable>
|
||||
<template #body="{ data }">
|
||||
{{ formatDate(data.sent_at) }}
|
||||
</template>
|
||||
</Column>
|
||||
<Column field="expires_at" header="过期时间" sortable>
|
||||
<template #body="{ data }">
|
||||
{{ formatDate(data.expires_at) }}
|
||||
</template>
|
||||
</Column>
|
||||
</DataTable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -52,6 +52,11 @@ const routes = [
|
||||
name: 'Orders',
|
||||
component: () => import('./pages/OrderPage.vue'),
|
||||
},
|
||||
{
|
||||
path: '/sms-code-sends',
|
||||
name: 'SmsCodeSends',
|
||||
component: () => import('./pages/SmsCodeSendPage.vue'),
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
|
||||
Reference in New Issue
Block a user