<div class="layui-fluid layui-anim febs-anim" id="firewall-country-list" lay-title="防火墙国家白名单">
|
<div class="layui-row febs-container">
|
<div class="layui-col-md12">
|
<div class="layui-card">
|
<div class="layui-card-header">站点国家白名单管理</div>
|
<div class="layui-card-body">
|
<!-- 站点选择 -->
|
<div class="layui-form-item">
|
<label class="layui-form-label">选择站点:</label>
|
<div class="layui-input-inline" style="width: 250px;">
|
<select id="site-select" lay-filter="site-select" lay-search="">
|
<option value="">请选择站点</option>
|
</select>
|
</div>
|
<button class="layui-btn layui-btn-normal" type="button" id="reload-btn" style="margin-left: 10px;">
|
<i class="layui-icon"></i> 手动reload
|
</button>
|
</div>
|
|
<hr class="layui-bg-gray">
|
|
<!-- 国家选择区域 -->
|
<div id="country-area" style="display:none;">
|
<div class="layui-form-item">
|
<label class="layui-form-label">当前允许国家:</label>
|
<div class="layui-input-block" id="current-countries" style="padding-top: 9px;">
|
<span style="color:#999;">暂无数据</span>
|
</div>
|
</div>
|
|
<div class="layui-form-item">
|
<label class="layui-form-label">选择国家:</label>
|
<div class="layui-input-block" id="country-checkboxes" style="padding-top: 5px;">
|
</div>
|
</div>
|
|
<div class="layui-form-item">
|
<div class="layui-input-block">
|
<button class="layui-btn" lay-submit="" lay-filter="save-country-rule" id="save-btn">
|
<i class="layui-icon"></i> 保存规则
|
</button>
|
<span class="layui-word-aux" style="margin-left: 15px;">保存后自动生成Nginx配置并reload</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<style>
|
.layui-form-label { width: 130px; }
|
.layui-form-item .layui-input-block { margin-left: 160px; }
|
.country-tag {
|
display: inline-block;
|
padding: 2px 12px;
|
margin: 2px 4px;
|
background: #5FB878;
|
color: #fff;
|
border-radius: 2px;
|
font-size: 13px;
|
}
|
.country-checkbox-item {
|
display: inline-block;
|
width: 140px;
|
margin: 4px 0;
|
}
|
</style>
|
|
<script data-th-inline="none" type="text/javascript">
|
layui.use(['jquery', 'form', 'febs', 'layer'], function () {
|
var $ = layui.jquery,
|
febs = layui.febs,
|
form = layui.form,
|
layer = layui.layer,
|
$view = $('#firewall-country-list'),
|
currentSiteId = null;
|
|
// 常用国家列表
|
var allCountries = [
|
{code: 'BR', name: '巴西'},
|
{code: 'US', name: '美国'},
|
{code: 'JP', name: '日本'},
|
{code: 'KR', name: '韩国'},
|
{code: 'SG', name: '新加坡'},
|
{code: 'GB', name: '英国'},
|
{code: 'DE', name: '德国'},
|
{code: 'FR', name: '法国'},
|
{code: 'AU', name: '澳大利亚'},
|
{code: 'CA', name: '加拿大'},
|
{code: 'IT', name: '意大利'},
|
{code: 'ES', name: '西班牙'},
|
{code: 'NL', name: '荷兰'},
|
{code: 'SE', name: '瑞典'},
|
{code: 'CH', name: '瑞士'},
|
{code: 'MX', name: '墨西哥'},
|
{code: 'AR', name: '阿根廷'},
|
{code: 'CL', name: '智利'},
|
{code: 'CO', name: '哥伦比亚'},
|
{code: 'PE', name: '秘鲁'},
|
{code: 'TH', name: '泰国'},
|
{code: 'VN', name: '越南'},
|
{code: 'MY', name: '马来西亚'},
|
{code: 'ID', name: '印度尼西亚'},
|
{code: 'PH', name: '菲律宾'},
|
{code: 'IN', name: '印度'},
|
{code: 'AE', name: '阿联酋'},
|
{code: 'SA', name: '沙特阿拉伯'},
|
{code: 'ZA', name: '南非'},
|
{code: 'RU', name: '俄罗斯'},
|
{code: 'CN', name: '中国'},
|
{code: 'HK', name: '中国香港'},
|
{code: 'TW', name: '中国台湾'},
|
{code: 'MO', name: '中国澳门'}
|
];
|
|
// 加载站点列表
|
function loadSites() {
|
febs.get(ctx + 'admin/firewall/sites', null, function (res) {
|
var sites = res.data || [];
|
var $select = $('#site-select');
|
$select.empty();
|
$select.append('<option value="">请选择站点</option>');
|
sites.forEach(function (s) {
|
$select.append('<option value="' + s.id + '">' + s.siteName + ' (' + s.domain + ')</option>');
|
});
|
form.render('select');
|
});
|
}
|
|
// 加载当前站点的国家白名单
|
function loadCountries(siteId) {
|
currentSiteId = siteId;
|
febs.get(ctx + 'admin/firewall/site/' + siteId + '/countries', null, function (res) {
|
var countries = res.data || [];
|
var enabledCodes = {};
|
countries.forEach(function (c) {
|
enabledCodes[c.code] = true;
|
});
|
|
// 先显示区域,再渲染表单元素(layui 在隐藏 DOM 上渲染可能失败)
|
$('#country-area').show();
|
|
// 渲染当前允许国家标签
|
var $current = $('#current-countries');
|
if (countries.length === 0) {
|
$current.html('<span style="color:#999;">暂无允许的国家</span>');
|
} else {
|
var html = '';
|
countries.forEach(function (c) {
|
html += '<span class="country-tag">' + c.name + ' (' + c.code + ')</span>';
|
});
|
$current.html(html);
|
}
|
|
// 渲染复选框(在可见区域中渲染)
|
var $checkboxes = $('#country-checkboxes');
|
var checkboxHtml = '';
|
allCountries.forEach(function (c) {
|
var checked = enabledCodes[c.code] ? ' checked' : '';
|
checkboxHtml += '<span class="country-checkbox-item">'
|
+ '<input type="checkbox" name="country" value="' + c.code + '" title="' + c.name + ' (' + c.code + ')" lay-skin="primary"' + checked + '>'
|
+ '</span>';
|
});
|
$checkboxes.html(checkboxHtml);
|
form.render('checkbox');
|
|
// 完整渲染一次表单,确保所有 layui 组件(select/checkbox/button)正确初始化
|
form.render(null, 'firewall-country-list');
|
});
|
}
|
|
// 站点切换
|
form.on('select(site-select)', function (data) {
|
if (data.value) {
|
loadCountries(data.value);
|
} else {
|
$('#country-area').hide();
|
}
|
});
|
|
// 保存规则
|
form.on('submit(save-country-rule)', function () {
|
if (!currentSiteId) {
|
layer.msg('请先选择站点', {icon: 2});
|
return false;
|
}
|
|
var countries = [];
|
$view.find('input[name="country"]:checked').each(function () {
|
countries.push($(this).val());
|
});
|
|
febs.post(ctx + 'admin/firewall/site/country/save', {
|
siteId: currentSiteId,
|
countries: countries
|
}, function (res) {
|
layer.msg('保存成功,Nginx 配置已更新', {icon: 1});
|
loadCountries(currentSiteId);
|
});
|
return false;
|
});
|
|
// 手动reload
|
$('#reload-btn').on('click', function () {
|
if (!currentSiteId) {
|
layer.msg('请先选择站点', {icon: 2});
|
return;
|
}
|
layer.confirm('确定要手动触发 Nginx reload 吗?', function (index) {
|
febs.post(ctx + 'admin/firewall/site/' + currentSiteId + '/reload', {}, function (res) {
|
layer.close(index);
|
layer.msg('Nginx reload 信号已发送', {icon: 1});
|
});
|
});
|
});
|
|
// 初始化
|
loadSites();
|
});
|
</script>
|