feat: Phase 3-5 管理后台前端+统计监控+部署配置
deploy-test / build-and-deploy-test (push) Successful in 2m41s

Phase 3: 管理后台前端 (Vue3+Vite+Element Plus)
- 登录页面/JWT认证/Pinia状态管理
- 首页大盘/站点管理/验证码日志/IP黑名单/套餐管理/系统设置
- 7个页面完整路由+API对接

Phase 4: 统计监控模块
- CaptchaLogAspect AOP自动记录
- RealtimeStatsService Redis实时计数
- HistoryStatsService 历史查询
- AnomalyDetectionService 异常检测

Phase 5: 部署和测试
- docker-compose.yml 5服务编排
- application-prod.yml 外部化配置
- CaptchaApiIntegrationTest 集成测试
- 前端 Dockerfile + nginx.conf
This commit is contained in:
abcv7
2026-08-26 13:44:08 +08:00
parent d1cd371061
commit 1164b51c64
67 changed files with 5510 additions and 829 deletions
@@ -0,0 +1,81 @@
<template>
<div class="logs">
<el-card>
<template #header>验证码日志</template>
<el-form :inline="true" :model="filters" style="margin-bottom: 20px">
<el-form-item label="验证码类型">
<el-select v-model="filters.captchaType" clearable placeholder="全部">
<el-option label="滑块验证" value="SLIDER" />
<el-option label="旋转验证" value="ROTATE" />
<el-option label="文字点选" value="WORD_IMAGE_CLICK" />
<el-option label="图标点选" value="ICON_CLICK" />
</el-select>
</el-form-item>
<el-form-item label="结果">
<el-select v-model="filters.isPass" clearable placeholder="全部">
<el-option label="成功" :value="true" />
<el-option label="失败" :value="false" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadLogs">查询</el-button>
</el-form-item>
</el-form>
<el-table :data="logs" v-loading="loading" border>
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="captchaType" label="类型" width="120" />
<el-table-column prop="ip" label="IP地址" width="140" />
<el-table-column prop="isPass" label="结果" width="80">
<template #default="{ row }">
<el-tag :type="row.isPass ? 'success' : 'danger'">
{{ row.isPass ? '成功' : '失败' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="costTime" label="耗时(ms)" width="100" />
<el-table-column prop="scene" label="场景" width="100" />
<el-table-column prop="createdAt" label="时间">
<template #default="{ row }">
{{ formatTime(row.createdAt) }}
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:current-page="page"
:page-size="20"
:total="total"
layout="total, prev, pager, next"
@current-change="loadLogs"
style="margin-top: 20px; justify-content: flex-end"
/>
</el-card>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
const logs = ref([])
const loading = ref(false)
const page = ref(1)
const total = ref(0)
const filters = reactive({ captchaType: '', isPass: null })
onMounted(() => loadLogs())
const loadLogs = async () => {
loading.value = true
try {
// 模拟数据
logs.value = []
total.value = 0
} finally {
loading.value = false
}
}
const formatTime = (t) => t ? new Date(t).toLocaleString() : '-'
</script>