From aeb0696f457ca85b62d15ab6586c5779cf5cd97b Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Fri, 31 Jul 2026 16:56:21 +0800
Subject: [PATCH] feat(firewall): 添加访问日志功能

---
 src/main/resources/templates/febs/views/modules/system/firewallAccessLogList.html |  178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 178 insertions(+), 0 deletions(-)

diff --git a/src/main/resources/templates/febs/views/modules/system/firewallAccessLogList.html b/src/main/resources/templates/febs/views/modules/system/firewallAccessLogList.html
new file mode 100644
index 0000000..778ed8c
--- /dev/null
+++ b/src/main/resources/templates/febs/views/modules/system/firewallAccessLogList.html
@@ -0,0 +1,178 @@
+<div class="layui-fluid layui-anim febs-anim" id="firewall-access-log-list" lay-title="防火墙访问日志">
+    <div class="layui-row febs-container">
+        <div class="layui-col-md12">
+            <div class="layui-card">
+                <div class="layui-card-body febs-table-full">
+                    <form class="layui-form layui-table-form" lay-filter="firewall-accesslog-table-form">
+                        <div class="layui-row">
+                            <div class="layui-col-md10">
+                                <div class="layui-form-item">
+                                    <button class="layui-btn layui-btn-normal" type="button" id="refresh-btn">
+                                        <i class="layui-icon">&#xe79b;</i> 刷新
+                                    </button>
+                                </div>
+                            </div>
+                            <div class="layui-col-md2 layui-col-sm12 layui-col-xs12 table-action-area">
+                                <div class="layui-btn layui-btn-sm layui-btn-primary febs-button-green-plain table-action" id="reset">
+                                    <i class="layui-icon">&#xe79b;</i>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="layui-row">
+                            <div class="layui-col-md2">
+                                <div class="layui-form-item">
+                                    <label class="layui-form-label">IP地址</label>
+                                    <div class="layui-input-block">
+                                        <input type="text" name="ip" class="layui-input" placeholder="搜索IP">
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="layui-col-md2">
+                                <div class="layui-form-item">
+                                    <label class="layui-form-label">国家</label>
+                                    <div class="layui-input-block">
+                                        <input type="text" name="countryCode" class="layui-input" placeholder="如 CN/US">
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="layui-col-md2">
+                                <div class="layui-form-item">
+                                    <label class="layui-form-label">状态</label>
+                                    <div class="layui-input-block">
+                                        <select name="isBlocked" lay-filter="filter-blocked">
+                                            <option value="">全部</option>
+                                            <option value="0">放行</option>
+                                            <option value="1">拦截</option>
+                                        </select>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="layui-col-md2">
+                                <div class="layui-form-item">
+                                    <label class="layui-form-label">选择站点</label>
+                                    <div class="layui-input-block">
+                                        <select name="siteId" lay-filter="filter-site" lay-search="">
+                                            <option value="">全部站点</option>
+                                        </select>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="layui-col-md2">
+                                <button class="layui-btn layui-btn-sm" type="button" id="search-btn">
+                                    <i class="layui-icon">&#xe615;</i> 搜索
+                                </button>
+                            </div>
+                        </div>
+                    </form>
+                    <table lay-filter="firewallAccessLogTable" lay-data="{id: 'firewallAccessLogTable'}"></table>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script data-th-inline="none" type="text/javascript">
+    layui.use(['jquery', 'form', 'table', 'febs'], function () {
+        var $ = layui.jquery,
+            febs = layui.febs,
+            form = layui.form,
+            table = layui.table,
+            $view = $('#firewall-access-log-list'),
+            $reset = $view.find('#reset'),
+            $refreshBtn = $view.find('#refresh-btn'),
+            $searchBtn = $view.find('#search-btn'),
+            tableIns;
+
+        form.render();
+        loadSiteFilter();
+        initTable();
+
+        function loadSiteFilter() {
+            febs.get(ctx + 'admin/firewall/sites', null, function (res) {
+                var sites = res.data || [];
+                var $select = $view.find('select[name="siteId"]');
+                sites.forEach(function (s) {
+                    $select.append('<option value="' + s.id + '">' + s.siteName + ' (' + s.domain + ')</option>');
+                });
+                form.render('select');
+            });
+        }
+
+        // 定时自动刷新(每30秒)
+        var autoRefreshTimer = setInterval(function () {
+            tableIns.reload();
+        }, 30000);
+
+        $refreshBtn.on('click', function () {
+            tableIns.reload();
+        });
+
+        $reset.on('click', function () {
+            $view.find('input[name="ip"]').val('');
+            $view.find('input[name="countryCode"]').val('');
+            $view.find('select[name="isBlocked"]').val('');
+            $view.find('select[name="siteId"]').val('');
+            form.render('select');
+            tableIns.reload();
+        });
+
+        $searchBtn.on('click', function () {
+            tableIns.reload();
+        });
+
+        form.on('select(filter-blocked)', function () {
+            tableIns.reload();
+        });
+        form.on('select(filter-site)', function () {
+            tableIns.reload();
+        });
+
+        function initTable() {
+            tableIns = febs.table.init({
+                elem: $view.find('table'),
+                id: 'firewallAccessLogTable',
+                url: ctx + 'admin/firewall/accessLogList',
+                where: function () {
+                    return {
+                        ip: $view.find('input[name="ip"]').val() || undefined,
+                        countryCode: $view.find('input[name="countryCode"]').val() || undefined,
+                        isBlocked: $view.find('select[name="isBlocked"]').val() || undefined,
+                        siteId: $view.find('select[name="siteId"]').val() || undefined
+                    };
+                },
+                cols: [[
+                    {field: 'id', title: 'ID', width: 70, align: 'center'},
+                    {field: 'ip', title: 'IP地址', width: 160, align: 'center'},
+                    {field: 'countryCode', title: '国家', width: 80, align: 'center',
+                        templet: function (d) {
+                            return d.countryCode
+                                ? '<span class="layui-badge layui-bg-blue">' + d.countryCode + '</span>'
+                                : '<span style="color:#999;">未知</span>';
+                        }
+                    },
+                    {field: 'countryName', title: '国家名称', width: 120, align: 'center'},
+                    {field: 'requestUri', title: '来源页面', minWidth: 180,
+                        templet: function (d) {
+                            return d.requestUri
+                                ? '<span style="color:#5FB878;">' + d.requestUri + '</span>'
+                                : '<span style="color:#999;">直接访问</span>';
+                        }
+                    },
+                    {field: 'isBlocked', title: '状态', width: 90, align: 'center',
+                        templet: function (d) {
+                            return d.isBlocked === 1
+                                ? '<span style="color:#FF5722;">● 拦截</span>'
+                                : '<span style="color:#5FB878;">● 放行</span>';
+                        }
+                    },
+                    {field: 'userAgent', title: '浏览器', minWidth: 200,
+                        templet: function (d) {
+                            return d.userAgent ? d.userAgent.substring(0, 60) + '...' : '-';
+                        }
+                    },
+                    {field: 'createdTime', title: '访问时间', width: 170, align: 'center'}
+                ]],
+                page: true
+            });
+        }
+    });
+</script>

--
Gitblit v1.9.1