c22669c31d
- 新增迁移 000031-000034(登录日志/角色/模型配额/记忆) - 新增包: license/memory/modelquota/assistant,扫描引擎 - 全部功能后端+前端+端到端验证通过(25 包单测)
63 lines
2.0 KiB
Vue
63 lines
2.0 KiB
Vue
<template>
|
|
<div class="page-content">
|
|
<div class="mb-5 flex items-center justify-between gap-4">
|
|
<div>
|
|
<h2 class="text-xl font-semibold">登录记录</h2>
|
|
<p class="text-g-500 mt-1 text-sm">全量登录尝试审计(管理端/门户),可筛选账号</p>
|
|
</div>
|
|
<div class="flex gap-2">
|
|
<ElInput v-model="loginFilter" placeholder="按登录名筛选" clearable class="w-52" @keyup.enter="load" />
|
|
<ElButton @click="load">查询</ElButton>
|
|
</div>
|
|
</div>
|
|
<ElTable v-loading="loading" :data="logs" row-key="id">
|
|
<ElTableColumn prop="created_at" label="时间" width="190" />
|
|
<ElTableColumn prop="kind" label="端" width="80" />
|
|
<ElTableColumn prop="login" label="登录名" width="180" />
|
|
<ElTableColumn label="结果" width="90">
|
|
<template #default="{ row }">
|
|
<ElTag :type="row.success ? 'success' : 'danger'">{{ row.success ? '成功' : '失败' }}</ElTag>
|
|
</template>
|
|
</ElTableColumn>
|
|
<ElTableColumn prop="ip" label="IP" width="150">
|
|
<template #default="{ row }">{{ row.ip || '—' }}</template>
|
|
</ElTableColumn>
|
|
<ElTableColumn prop="reason" label="原因" width="170" />
|
|
<ElTableColumn prop="user_agent" label="客户端" min-width="220" show-overflow-tooltip />
|
|
</ElTable>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import request from '@/utils/http'
|
|
|
|
interface LoginLog {
|
|
id: string
|
|
kind: string
|
|
login: string
|
|
success: boolean
|
|
ip?: string
|
|
reason: string
|
|
user_agent: string
|
|
created_at: string
|
|
}
|
|
|
|
const loading = ref(false)
|
|
const loginFilter = ref('')
|
|
const logs = ref<LoginLog[]>([])
|
|
|
|
async function load() {
|
|
loading.value = true
|
|
try {
|
|
logs.value = await request.get<LoginLog[]>({
|
|
url: '/api/v1/admin/login-logs',
|
|
params: loginFilter.value ? { login: loginFilter.value, limit: 100 } : { limit: 100 }
|
|
})
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
onMounted(load)
|
|
</script>
|