OpenWrt_Luci_Lua/Mi_Lua/luci/view/web/setting/nat.htm

593 lines
22 KiB
HTML
Raw Normal View History

2015-05-09 10:48:46 +00:00
<%
--[[
Info nat
]]--
local ver = require("xiaoqiang.XQVersion").webVersion
local request_uri = luci.http.getenv("REQUEST_URI")
%>
<%include('web/inc/head')%>
<title>小米路由器</title>
<link rel="stylesheet" href="<%=resource%>/web/css/page.set.default.css?v=<%=ver%>"/>
</head>
<body>
<!-- upgread -->
<div class="mod-setting-panel">
<div class="hd">
<h3>端口转发</h3>
<!-- <a href="#" data&#45;order="1" class="btn&#45;offon btn&#45;off" id="btnupnp"></a> -->
</div>
<div class="bd">
<div class="mod-set-nat">
<h4>端口转发</h4>
<form id="portForm" name="portForm" class="form form-horizontal">
<div class="item">
<label for="name" class="k">名称:</label>
<span class="v"><input type="text" name="name" value="" class="text input-large" /></span>
<em class="t"></em>
</div>
<div class="item">
<label for="proto" class="k">协议:</label>
<span class="v">
<select name="proto" class="beautify" style="width:185px;">
<option value='1'>TCP</option>
<option value='2'>UDP</option>
<option value='3'>TCP和UDP</option>
</select>
</span>
<em class="t"></em>
</div>
<div class="item">
<label for="sport" class="k">外部端口:</label>
<span class="v"><input type="text" name="sport" value="" class="text input-large" /></span>
<em class="t"></em>
</div>
<div class="item">
<label for="ip" class="k">内部IP地址</label>
<span class="v"><input type="text" name="ip" value="" class="text input-large" /></span>
<em class="t"></em>
</div>
<div class="item">
<label for="dport" class="k">内部端口:</label>
<span class="v"><input type="text" name="dport" value="" class="text input-large" /></span>
<em class="t"></em>
</div>
<div class="item item-control">
<button type="submit" id="addPort" class="btn btn-primary btn-large"><span>添加</span></button>
</div>
</form>
</div>
<div class="mod-set-nat">
<h4>规则列表</h4>
<form name="portFormEdit">
<table class="table">
<thead>
<tr>
<th>名称</th>
<th>协议</th>
<th>外部端口</th>
<th>内部IP地址</th>
<th>内部端口</th>
<th class="center" width="80">操作</th>
</tr>
</thead>
<tbody id="natlist_port">
</tbody>
</table>
</form>
</div>
<div class="mod-set-nat">
<h4>范围转发</h4>
<form id="rangeForm" name="rangeForm" class="form form-horizontal">
<div class="item">
<label for="name" class="k">名称:</label>
<span class="v"><input type="text" name="name" value="" class="text input-large" /></span>
<em class="t"></em>
</div>
<div class="item">
<label for="proto" class="k">协议:</label>
<span class="v">
<select name="proto" class="beautify" style="width:185px;">
<option value='1'>TCP</option>
<option value='2'>UDP</option>
<option value='3'>TCP和UDP</option>
</select>
</span>
<em class="t"></em>
</div>
<div class="item">
<label for="fport" class="k">起始端口:</label>
<span class="v"><input type="text" name="fport" value="" class="text input-large" /></span>
<em class="t"></em>
</div>
<div class="item">
<label for="tport" class="k">结束端口:</label>
<span class="v"><input type="text" name="tport" value="" class="text input-large" /></span>
<em class="t"></em>
</div>
<div class="item">
<label for="ip" class="k">目标IP</label>
<span class="v"><input type="text" name="ip" value="" class="text input-large" /></span>
<em class="t"></em>
</div>
<div class="item item-control">
<button type="submit" id="addRange" class="btn btn-primary btn-large"><span>添加</span></button>
</div>
</form>
</div>
<div class="mod-set-nat">
<h4>规则列表</h4>
<form name="rangeFormEdit">
<table class="table">
<thead>
<tr>
<th>名称</th>
<th>协议</th>
<th>起始端口</th>
<th>结束端口</th>
<th>目标IP</th>
<th class="center" width="80">操作</th>
</tr>
</thead>
<tbody id="natlist_range">
</tbody>
</table>
</form>
</div>
<div class='mod-set-nat'>
<div class="item item-control">
<button type="submit" id="apply" class="btn btn-primary btn-large"><span>生效</span></button>
</div>
</div>
</div>
</div>
<script type="text/template" id="tpl_tr_port">
{for(var i=0;i<$arr.length;i++)}
<tr>
<td>{js print( StringH.encode4Html( $arr[i].name ) )}</td>
<td>
{if($arr[i].proto == 1)}TCP{/if}
{if($arr[i].proto == 2)}UDP{/if}
{if($arr[i].proto == 3)}TCP和UDP{/if}
</td>
<td>{$arr[i].srcport}</td>
<td>{$arr[i].destip}</td>
<td>{$arr[i].destport}</td>
<td class="center">
<a class="btn btn-danger btn-small delPort" href="javascript:;" data-port="{$arr[i].srcport}"><span>删除</span></a>
</td>
</tr>
{/for}
</script>
<script type="text/template" id="tpl_tr_port_edit">
<tr>
<td class='item'>
<span><input type="text" name="name" value="{{- item.name}}" class="text input-mini" /></span>
<em class="t"></em>
</td>
<td>
<select name="proto" class="">
<option value='1' {{= item.proto=== 1?"selected" : ""}} >TCP</option>
<option value='2' {{= item.proto=== 2?"selected" : ""}} >UDP</option>
<option value='3' {{= item.proto=== 3?"selected" : ""}} >TCP和UDP</option>
</select>
</td>
<td class='item'>
<span><input type="text" name="sport" value="{{- item.srcport }}" class="text input-mini" /></span>
<em class="t"></em>
</td>
<td class='item'>
<span><input type="text" name="ip" value="{{- item.destip }}" class="text input-mini" /></span>
<em class="t"></em>
</td>
<td class='item'>
<span><input type="text" name="dport" value="{{- item.destport }}" class="text input-mini" /></span>
<em class="t"></em>
</td>
<td class='item'>
<a class="btn btn-primary confirmEdit" href="javascript:;"><span>确定</span></a>
<a class="btn cancelEdit" href="javascript:;"><span>取消</span></a>
</td>
</tr>
</script>
<script type="text/template" id="tpl_tr_range">
{for(var i=0;i<$arr.length;i++)}
<tr>
<td>{js print( StringH.encode4Html( $arr[i].name ) )}</td>
<td>
{if($arr[i].proto == 1)}TCP{/if}
{if($arr[i].proto == 2)}UDP{/if}
{if($arr[i].proto == 3)}TCP和UDP{/if}
</td>
<td>{$arr[i].srcport.f}</td>
<td>{$arr[i].srcport.t}</td>
<td>{$arr[i].destip}</td>
<td class="center">
<a class="btn btn-danger btn-small delRange" href="javascript:;" data-port="{$arr[i].srcport.f}"><span>删除</span></a>
</td>
</tr>
{/for}
</script>
<script type="text/template" id="tpl_tr_range_edit">
<tr>
<td class='item'>
<span><input type="text" name="name" value="{{- item.name}}" class="text input-mini" /></span>
<em class="t"></em>
</td>
<td>
<select name="proto" class="">
<option value='1' {{= item.proto=== 1?"selected" : ""}} >TCP</option>
<option value='2' {{= item.proto=== 2?"selected" : ""}} >UDP</option>
<option value='3' {{= item.proto=== 3?"selected" : ""}} >TCP和UDP</option>
</select>
</td>
<td class='item'>
<span><input type="text" name="fport" value="{{- item.srcport.f }}" class="text input-mini" /></span>
<em class="t"></em>
</td>
<td class='item'>
<span><input type="text" name="tport" value="{{- item.srcport.t }}" class="text input-mini" /></span>
<em class="t"></em>
</td>
<td class='item'>
<span><input type="text" name="ip" value="{{- item.destip }}" class="text input-mini" /></span>
<em class="t"></em>
</td>
<td class='item'>
<a class="btn btn-primary confirmEditRange" href="javascript:;"><span>确定</span></a>
<a class="btn cancelEditRange" href="javascript:;"><span>取消</span></a>
</td>
</tr>
</script>
<%include('web/inc/g.js.base')%>
<script>
var modelNat = (function(){
return {
init : function(){
// addPort
$('#addPort').on('click', function(e) {
e.preventDefault();
var data = $('#portForm').serialize();
var validator = FormValidator.checkAll('portForm', [
{
name: 'ip',
display :'内部IP地址',
rules: 'required|valid_ip|callback_no_change'
},
{
name: 'name',
display: '名称',
rules: 'required'
},
{
name: 'sport',
display: '外部端口',
rules: 'required|is_natural|less_than[65536]'
},
{
name: 'dport',
display: '内部端口',
rules: 'required|is_natural|less_than[65536]'
}
]);
if (validator) {
modelNat.addPort(data, 'new');
}
});
// delPort
$('#natlist_port').on('click', '.delPort', function(e) {
e.preventDefault();
var port = $(this).data('port');
modelNat.delPort(port);
});
// editPort
$('#natlist_port').on('click', '.editPort', function(e) {
e.preventDefault();
var item = $(e.currentTarget).data('item');
modelNat.editPort(item, e);
});
// confirmEdit port
$('#natlist_port').on('click', '.confirmEdit', function(e) {
var data = $(e.target).parents('form').serialize();
var validator = FormValidator.checkAll('portFormEdit', [
{
name: 'ip',
display :'内部IP地址',
rules: 'required|valid_ip|callback_no_change'
},
{
name: 'name',
display: '名称',
rules: 'required'
},
{
name: 'sport',
display: '外部端口',
rules: 'required|is_natural|less_than[65536]'
},
{
name: 'dport',
display: '内部端口',
rules: 'required|is_natural|less_than[65536]'
}
]);
if (validator) {
modelNat.addPort(data, 'edit');
}
e.preventDefault();
});
// cancelEdit port
$('#natlist_port').on('click', '.cancelEdit', function(e) {
e.preventDefault();
var $tr = $(e.currentTarget).parent().parent();
$tr.html(modelNat.savedItem);
});
// addRange
$('#addRange').on('click', function(e) {
e.preventDefault();
var data = $('#rangeForm').serialize();
var validator = FormValidator.checkAll('rangeForm', [
{
name: 'ip',
display :'目标IP',
rules: 'required|valid_ip|callback_no_change'
},
{
name: 'name',
display: '名称',
rules: 'required'
},
{
name: 'fport',
display: '起始端口',
rules: 'required|is_natural|less_than[65536]'
},
{
name: 'tport',
display: '结束端口',
rules: 'required|is_natural|less_than[65536]'
}
]);
if (validator) {
modelNat.addRange(data, 'new');
}
});
// delRange
$('#natlist_range').on('click', '.delRange', function(e) {
e.preventDefault();
var port = $(this).data('port');
modelNat.delRange(port);
});
// editPort
$('#natlist_range').on('click', '.editRange', function(e) {
e.preventDefault();
var item = $(e.currentTarget).data('item');
modelNat.editRange(item, e);
});
// confirmEdit range
$('#natlist_range').on('click', '.confirmEditRange', function(e) {
e.preventDefault();
var data = $(e.target).parents('form').serialize();
var validator = FormValidator.checkAll('rangeFormEdit', [
{
name: 'ip',
display :'目标IP',
rules: 'required|valid_ip|callback_no_change'
},
{
name: 'name',
display: '名称',
rules: 'required'
},
{
name: 'fport',
display: '起始端口',
rules: 'required|is_natural|less_than[65536]'
},
{
name: 'tport',
display: '结束端口',
rules: 'required|is_natural|less_than[65536]'
}
]);
if (validator) {
modelNat.addRange(data, 'edit');
}
e.preventDefault();
});
// cancelEdit range
$('#natlist_range').on('click', '.cancelEditRange', function(e) {
e.preventDefault();
var $tr = $(e.currentTarget).parent().parent();
$tr.html(modelNat.savedItemRange);
});
// apply
$('#apply').on('click', function(e) {
var $btn = $(e.currentTarget);
var dlg = window.top.art.dialog({
title: '端口转发',
content: '规则正在生效中,请等待...',
lock: true,
cancel: false
});
$.getJSON(modelNat.url.applyRedirect, function(rsp) {
if (rsp.code === 0) {
dlg.close();
}
});
});
// init
// ftype: 0/1/2 全部/端口/范围
modelNat.getRedirectPort();
modelNat.getRedirectRange();
},
addPort: function(data, type) {
$.post(modelNat.url.addPort, data, function(rsp) {
if (rsp.code === 0) {
modelNat.getRedirectPort();
if (type === 'new') {
// 成功后清空form
$('#portForm').find('input:not(".dummy")').val('');
}
} else {
window.top.art.dialog({
title: '端口转发',
content: rsp.msg,
lock: true,
time: 5*1000
});
}
}, 'json');
},
addRange: function(data, type) {
$.post(modelNat.url.addRange, data, function(rsp) {
if (rsp.code === 0) {
modelNat.getRedirectRange();
if (type === 'new') {
$('#rangeForm').find('input:not(".dummy")').val('');
}
} else {
window.top.art.dialog({
title: '端口转发',
content: rsp.msg,
lock: true,
time: 5*1000
});
}
}, 'json');
},
delPort: function(port) {
$.post(modelNat.url.delRedirect, 'port=' + port, function(rsp) {
if (rsp.code === 0) {
modelNat.getRedirectPort();
} else {
window.top.art.dialog({
title: '端口转发',
content: rsp.msg,
lock: true,
time: 5*1000
});
}
}, 'json');
},
delRange: function(port) {
$.post(modelNat.url.delRedirect, 'port=' + port, function(rsp) {
if (rsp.code === 0) {
modelNat.getRedirectRange();
} else {
window.top.art.dialog({
title: '端口转发',
content: rsp.msg,
lock: true,
time: 5*1000
});
}
}, 'json');
},
savedItem: '',
savedItemRange: '',
editPort: function(item, e) {
item = QW.JSON.parse(decodeURIComponent(item));
var $tr = $(e.currentTarget).parent().parent();
modelNat.savedItem = $tr.html();
var html = tmpl($('#tpl_tr_port_edit').html(), {item: item});
$tr.replaceWith(html);
//$.selectBeautify();
},
editRange: function(item, e) {
item = QW.JSON.parse(decodeURIComponent(item));
var $tr = $(e.currentTarget).parent().parent();
modelNat.savedItemRange = $tr.html();
var html = tmpl($('#tpl_tr_range_edit').html(), {item: item});
$tr.replaceWith(html);
//$.selectBeautify();
},
getRedirectPort: function() {
$.getJSON(modelNat.url.getRedirect, 'ftype='+1, function(rsp) {
var html;
if (rsp.code === 0) {
if (rsp.list.length !== 0) {
html = StringH.tmpl($('#tpl_tr_port').html(), {arr: rsp.list});
$('#natlist_port').html(html);
} else {
html = '<tr><td style="text-align:center;" colspan="6">暂无添加</td></tr>';
$('#natlist_port').html(html);
}
} else {
window.top.art.dialog({
title: '端口转发',
content: rsp.msg,
lock: true,
time: 5*1000
});
}
});
},
getRedirectRange: function() {
$.getJSON(modelNat.url.getRedirect, 'ftype='+2, function(rsp) {
var html;
if (rsp.code === 0) {
if (rsp.list.length !== 0) {
var html = StringH.tmpl($('#tpl_tr_range').html(), {arr: rsp.list});
$('#natlist_range').html(html);
} else {
html = '<tr><td style="text-align:center;" colspan="6">暂无添加</td></tr>';
$('#natlist_range').html(html);
}
} else {
window.top.art.dialog({
title: '端口转发',
content: rsp.msg,
lock: true,
time: 5*1000
});
}
});
},
url: {
'addPort': '<%=luci.dispatcher.build_url("api", "xqnetwork", "add_redirect")%>',
'addRange': '<%=luci.dispatcher.build_url("api", "xqnetwork", "add_range_redirect")%>',
'delRedirect': '<%=luci.dispatcher.build_url("api", "xqnetwork", "delete_redirect")%>',
'applyRedirect': '<%=luci.dispatcher.build_url("api", "xqnetwork", "redirect_apply")%>',
'getRedirect': '<%=luci.dispatcher.build_url("api", "xqnetwork", "portforward")%>'
}
}
}());
$(function(){
// $.selectBeautify();
modelNat.init();
});
</script>