123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- <template>
- <div>
- <a-card>
- <div class="table-page-search-wrapper">
- <a-form layout="inline" @submit.prevent="handleSearch">
- <a-row :gutter="48">
- <a-col :md="6" :sm="24">
- <a-form-item label="请求IP">
- <a-input v-model:value="queryParam.requestIp" placeholder="请输入请求IP" />
- </a-form-item>
- </a-col>
- <a-col :md="6" :sm="24">
- <a-form-item label="用户ID">
- <a-input v-model:value="queryParam.uid" placeholder="请输入用户ID" />
- </a-form-item>
- </a-col>
- <a-col :md="6" :sm="24">
- <a-form-item label="规则ID">
- <a-input v-model:value="queryParam.ruleId" placeholder="请输入规则ID" />
- </a-form-item>
- </a-col>
- <a-col :md="6" :sm="24">
- <a-form-item label="实例ID">
- <a-input v-model:value="queryParam.hostId" placeholder="请输入实例ID" />
- </a-form-item>
- </a-col>
- <a-col :md="6" :sm="24">
- <a-form-item label="API">
- <a-input v-model:value="queryParam.api" placeholder="请输入API路径" />
- </a-form-item>
- </a-col>
- <a-col :md="6" :sm="24">
- <a-form-item label="API名称">
- <a-input v-model:value="queryParam.apiName" placeholder="请输入API名称" />
- </a-form-item>
- </a-col>
- <a-col :md="6" :sm="24">
- <a-form-item label="API类型">
- <a-select v-model:value="queryParam.apiType" placeholder="请选择API类型" allow-clear>
- <a-select-option value="get">get</a-select-option>
- <a-select-option value="add">add</a-select-option>
- <a-select-option value="delete">delete</a-select-option>
- <a-select-option value="edit">edit</a-select-option>
- </a-select>
- </a-form-item>
- </a-col>
- <a-col :md="6" :sm="24">
- <a-form-item label="名称">
- <a-input v-model:value="queryParam.name" placeholder="请输入名称" />
- </a-form-item>
- </a-col>
- <a-col :md="24" :sm="24">
- <span class="table-page-search-submitButtons">
- <a-button type="primary" @click="handleSearch">查询</a-button>
- <a-button style="margin-left: 8px" @click="resetSearch">重置</a-button>
- </span>
- </a-col>
- </a-row>
- </a-form>
- </div>
- <a-table
- :columns="columns"
- :row-key="record => record.id"
- :data-source="dataSource"
- :loading="loading"
- :pagination="pagination"
- @change="handleTableChange"
- :scroll="{ x: 'max-content' }"
- bordered
- size="middle"
- >
- <template #bodyCell="{ column, record }">
- <template v-if="column.dataIndex === 'action'">
- <a-button type="link" @click="goToInfo(record.id)">详情</a-button>
- </template>
- </template>
- </a-table>
- </a-card>
-
- <!-- WAF日志详情模态框 -->
- <waf-log-detail-modal ref="detailModalRef" />
- </div>
- </template>
- <script setup>
- import { ref, onMounted } from 'vue';
- import { getWafLogList } from '~/api/waf/waflog.js';
- import WafLogDetailModal from './components/waf-log-detail-modal.vue';
- const loading = ref(false);
- const dataSource = ref([]);
- const pagination = ref({
- current: 1,
- pageSize: 10,
- total: 0,
- showTotal: (total) => `共 ${total} 条`,
- showSizeChanger: true,
- pageSizeOptions: ['10', '20', '50', '100'],
- showQuickJumper: true,
- });
- const queryParam = ref({
- requestIp: '',
- uid: '',
- ruleId: '',
- hostId: '',
- api: '',
- apiName: '',
- apiType: '',
- name: '',
- });
- const columns = [
- { title: 'ID', dataIndex: 'id', fixed: 'left', width: 80 },
- { title: '用户ID', dataIndex: 'uid', width: 100 },
- { title: '名称', dataIndex: 'name', width: 150, ellipsis: true },
- { title: '请求IP', dataIndex: 'requestIp', width: 140 },
- { title: '实例ID', dataIndex: 'hostId', width: 100 },
- { title: '规则ID', dataIndex: 'ruleId', width: 100 },
- { title: 'User Agent', dataIndex: 'userAgent', width: 250, ellipsis: true },
- { title: 'API', dataIndex: 'api', width: 180, ellipsis: true },
- { title: 'API名称', dataIndex: 'apiName', width: 150, ellipsis: true },
- { title: 'API类型', dataIndex: 'apiType', width: 100 },
- { title: '创建时间', dataIndex: 'createdAt', width: 180 },
- { title: '更新时间', dataIndex: 'updatedAt', width: 180 },
- { title: '操作', dataIndex: 'action', fixed: 'right', width: 100 },
- ];
- const fetchData = () => {
- loading.value = true;
-
- // 构造请求参数,并处理特殊类型
- const params = {
- requestIp: queryParam.value.requestIp || '',
- uid: queryParam.value.uid ? parseInt(queryParam.value.uid) : '',
- ruleId: queryParam.value.ruleId ? parseInt(queryParam.value.ruleId) : '',
- hostId: queryParam.value.hostId ? parseInt(queryParam.value.hostId) : '',
- api: queryParam.value.api || '',
- apiName: queryParam.value.apiName || '',
- apiType: queryParam.value.apiType || '',
- name: queryParam.value.name || '',
- current: pagination.value.current,
- pageSize: pagination.value.pageSize,
- column: 'id',
- order: 'desc'
- };
-
- console.log('发送WAF日志查询参数:', params);
-
- getWafLogList(params).then(response => {
- // 根据实际返回格式处理数据
- if (response && response.code === 0 && response.data) {
- const apiData = response.data;
- if (apiData.records && Array.isArray(apiData.records)) {
- dataSource.value = apiData.records;
- pagination.value.total = apiData.total || 0;
- pagination.value.current = apiData.page || 1;
- pagination.value.pageSize = apiData.pageSize || 10;
- } else {
- dataSource.value = [];
- pagination.value.total = 0;
- console.warn('响应中无WAF日志数据记录');
- }
- } else {
- dataSource.value = [];
- pagination.value.total = 0;
- console.error('无效的WAF日志响应格式或响应错误', response);
- }
- loading.value = false;
- }).catch((error) => {
- console.error('WAF日志请求失败:', error);
- dataSource.value = [];
- loading.value = false;
- });
- };
- const handleTableChange = (pager) => {
- pagination.value.current = pager.current;
- pagination.value.pageSize = pager.pageSize;
- fetchData();
- };
- const handleSearch = () => {
- pagination.value.current = 1;
- fetchData();
- };
- const resetSearch = () => {
- queryParam.value.requestIp = '';
- queryParam.value.uid = '';
- queryParam.value.ruleId = '';
- queryParam.value.hostId = '';
- queryParam.value.api = '';
- queryParam.value.apiName = '';
- queryParam.value.apiType = '';
- queryParam.value.name = '';
- handleSearch();
- };
- const detailModalRef = ref(null);
- const goToInfo = (id) => {
- // 打开模态框而不是跳转页面
- detailModalRef.value?.open(id);
- };
- onMounted(() => {
- fetchData();
- });
- </script>
- <style scoped>
- .table-page-search-wrapper .ant-form-inline .ant-form-item {
- margin-bottom: 24px;
- }
- /* 表格样式优化 */
- :deep(.ant-table-body) {
- overflow-x: auto !important;
- }
- :deep(.ant-table-fixed-header .ant-table-scroll .ant-table-header) {
- margin-bottom: 0 !important;
- padding-bottom: 0 !important;
- overflow: hidden !important;
- }
- :deep(.ant-table-body::-webkit-scrollbar) {
- width: 8px;
- height: 8px;
- }
- :deep(.ant-table-body::-webkit-scrollbar-track) {
- background: #f1f1f1;
- border-radius: 4px;
- }
- :deep(.ant-table-body::-webkit-scrollbar-thumb) {
- background: #c1c1c1;
- border-radius: 4px;
- }
- :deep(.ant-table-body::-webkit-scrollbar-thumb:hover) {
- background: #a8a8a8;
- }
- </style>
|