forwardList.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. <div class="layui-tab layui-tab-card" lay-filter="tabForwardList">
  2. <ul class="layui-tab-title">
  3. <li class="layui-this">端口转发列表</li>
  4. <li>快捷功能</li>
  5. <li>帮助说明</li>
  6. </ul>
  7. <div class="layui-tab-content" style="height: auto;">
  8. <div class="layui-tab-item layui-show">
  9. <div class="layui-form layui-card-header layuiadmin-card-header-auto" lay-filter="app-content-list">
  10. <div class="layui-form-item">
  11. <div class="layui-inline">
  12. <label class="layui-form-label">本地端口</label>
  13. <div class="layui-input-inline">
  14. <input type="text" id="port" name="port" placeholder="本地监听端口" autocomplete="off" class="layui-input">
  15. </div>
  16. </div>
  17. <div class="layui-inline">
  18. <label class="layui-form-label">目标地址</label>
  19. <div class="layui-input-inline">
  20. <input type="text" id="targetAddr" name="targetAddr" placeholder="转发到地址" autocomplete="off" class="layui-input">
  21. </div>
  22. </div>
  23. <div class="layui-inline">
  24. <label class="layui-form-label">目标端口</label>
  25. <div class="layui-input-inline">
  26. <input type="text" id="targetPort" name="targetPort" placeholder="转发到端口" autocomplete="off" class="layui-input">
  27. </div>
  28. </div>
  29. <div class="layui-inline">
  30. <button class="layui-btn layuiadmin-btn-list" onclick="query(1);">
  31. 查询
  32. </button>
  33. </div>
  34. </div>
  35. </div>
  36. <button class="layui-btn layui-btn-small" onclick="addForward();"><i class="layui-icon"></i> 添加转发</button>
  37. <button class="layui-btn layui-btn-small" onclick="delForward();"><i class="layui-icon"></i> 批量删除</button>
  38. <button class="layui-btn layui-btn-small layui-btn-normal" onclick="AddBatchForward();"><i class="layui-icon"></i> 快速批量添加</button>
  39. <button class="layui-btn layui-btn-small layui-btn-normal" onclick="ImportForward();"><i class="layui-icon"></i> 批量导入</button>
  40. <div class="layui-form">
  41. <table class="layui-table">
  42. <colgroup>
  43. <col width="20">
  44. <col width="50">
  45. <col width="300">
  46. <col width="150">
  47. <col width="120">
  48. <col width="150">
  49. <col width="50">
  50. <col width="150">
  51. <col width="100">
  52. <col width="70">
  53. <col width="200">
  54. </colgroup>
  55. <thead>
  56. <tr>
  57. <th>
  58. <input type="checkbox" name="" lay-skin="primary" lay-filter="allChoose">
  59. </th>
  60. <th>ID</th>
  61. <th>名称</th>
  62. <th>本地监听地址</th>
  63. <th>本地监听端口</th>
  64. <th>转发方式</th>
  65. <th>协议</th>
  66. <th>转发到地址</th>
  67. <th>转发到端口</th>
  68. <th>状态</th>
  69. <th>操作</th>
  70. </tr>
  71. </thead>
  72. <tbody id="gridBody">
  73. </tbody>
  74. </table>
  75. </div>
  76. <div id="pagination"></div>
  77. </div>
  78. <div class="layui-tab-item layui-form">
  79. <div class="layui-card">
  80. <div class="layui-card-body">
  81. <div class="layui-form-item text-right">
  82. <div class="layui-inline pull-left">
  83. <button class="layui-btn layui-btn-small layui-btn-danger" onclick="OpenAllForward();">一键开启</button>
  84. <button class="layui-btn layui-btn-small layui-btn-danger" onclick="CloseAllForward();">一键关闭</button>
  85. </div>
  86. </div>
  87. </div>
  88. <pre class="layui-code text-right">
  89. 一键开启说明:
  90. 1、不需要批量勾选规则,只要规则设置了支持“一键开启”都会被一键开启转发。
  91. 2、通过在配置文件中添加 onstart.forward = "true" ,可让程序每次运行后就开始转发该规则。
  92. 3、也可以通过在列表页面通过点击“一键开启” “一键关闭”来开启/关闭所有转发。
  93. </pre>
  94. <div class="layui-card-body">
  95. <div class="layui-form-item text-right">
  96. <div class="layui-inline pull-left">
  97. <label class="layui-form-label">详细日志</label>
  98. <div class="layui-input-block">
  99. <input type="checkbox" name="debugStatus" lay-skin="switch" {{if eq .ForWardDebug true}} checked {{end}} lay-filter="ForWardDebug" lay-text="ON|OFF">
  100. </div>
  101. </div>
  102. </div>
  103. </div>
  104. <pre class="layui-code text-right">
  105. 详细日志开关说明:
  106. 1、主要对网络流量突然增大时,连接多、日志多,这个时候不想打印太多日志,可以临时关闭。
  107. 2、详细日志开启时,日志文件会记录较多的后台处理信息,可以帮助分析问题。
  108. 3、开源版本的详细日志,默认开启,只能临时关闭。
  109. </pre>
  110. </div>
  111. </div>
  112. <div class="layui-tab-item">
  113. <pre class="layui-code">
  114. 说明文档请访问:<a href="https://gitee.com/tavenli/port-forward" target="_blank">https://gitee.com/tavenli/port-forward</a>
  115. 使用问题或个性化需求可加QQ号:17020415 (申请时请备注:端口转发)
  116. </pre>
  117. </div>
  118. </div>
  119. </div>
  120. <script id="grid_tpl" type="text/html">
  121. {Start{# if(d.Data === null || d.Data.length === 0){ }End}
  122. <tr>
  123. <td colspan="10">
  124. 查询转发配置规则结果为空
  125. </td>
  126. </tr>
  127. {Start{# } else { }End} {Start{# layui.each(d.Data, function(index, item){ }End}
  128. <tr>
  129. <td>
  130. <input type="checkbox" name="id" lay-skin="primary" value="{Start{ item.Id }End}">
  131. </td>
  132. <td>{Start{ item.Id }End}</td>
  133. <td>{Start{ item.Name }End}</td>
  134. <td>{Start{ fmtAddr(item.Addr) }End}</td>
  135. <td>{Start{ item.Port }End}</td>
  136. <td>{Start{ fmtFType(item.FType) }End}</td>
  137. <td>{Start{ item.Protocol }End}</td>
  138. <td>{Start{ item.TargetAddr }End}</td>
  139. <td>{Start{ item.TargetPort }End}</td>
  140. <td>{Start{ fmtStatus(item.Status) }End}</td>
  141. <td>{Start{ oprFormatLink(item.Status,item) }End}</td>
  142. </tr>
  143. {Start{# }); }End} {Start{# } }End}
  144. </script>
  145. <script type="text/javascript">
  146. $(document).ready(function() {
  147. layui.use(["jquery", "layer", "form", "element", "laytpl", "laypage"], function() {
  148. var $ = layui.jquery,
  149. layer = layui.layer,
  150. form = layui.form,
  151. laytpl = layui.laytpl,
  152. laypage = layui.laypage;
  153. var element = layui.element;
  154. //全选
  155. form.on('checkbox(allChoose)', function(data) {
  156. var child = $(data.elem).parents('table').find('tbody input[type="checkbox"]');
  157. child.each(function(index, item) {
  158. item.checked = data.elem.checked;
  159. });
  160. form.render('checkbox');
  161. });
  162. layui.laytpl.config({
  163. open: "{Start{",
  164. close: "}End}"
  165. });
  166. element.on('tab(tabForwardList)', function(data){
  167. console.log(data);
  168. form.render('checkbox');
  169. form.render();
  170. });
  171. form.on('checkbox()', function(data){
  172. console.log(data.elem); //得到checkbox原始DOM对象
  173. console.log(data.elem.checked); //是否被选中,true或者false
  174. console.log(data.value); //复选框value值,也可以通过data.elem.value得到
  175. console.log(data.othis); //得到美化后的DOM对象
  176. });
  177. form.on('switch(ForWardDebug)', function(data){
  178. $.get("/u/ChangeForwardDebug", {
  179. rnd: Math.random(),
  180. status: data.elem.checked?1:0
  181. }, function(json) {
  182. }, 'json');
  183. });
  184. //
  185. form.render('checkbox');
  186. form.render();
  187. //
  188. query(1);
  189. });
  190. });
  191. function query(pIndex) {
  192. // var columnFiled = $("#columnFiled").val();
  193. // var keyWord = $("#keyWord").val();
  194. var port = $("#port").val();
  195. var targetAddr = $("#targetAddr").val();
  196. var targetPort = $("#targetPort").val();
  197. $.post("ForwardList/json", {
  198. port: port,
  199. targetAddr: targetAddr,
  200. targetPort: targetPort,
  201. pIndex: pIndex,
  202. pSize: 10
  203. }, function(json) {
  204. if (json.Code == 0) { //成功
  205. renderGrid(json.Data);
  206. var totalPages = json.Data.Pages;
  207. var totalRows = json.Data.TotalRows;
  208. //显示分页
  209. layui.laypage.render({
  210. elem: 'pagination', //容器
  211. pages: totalPages, //通过后台拿到的总页数
  212. count: totalRows,
  213. limit: 10,
  214. limits: [10, 20, 30, 50, 100],
  215. groups: 5, //连续分页数
  216. skin: "#51b921", //控制分页皮肤。目前支持:molv、yahei、flow 除此之外,还支持16进制颜色值,如:skin:'#c00'
  217. curr: pIndex || 1, //当前页
  218. skip: true,
  219. layout: ['count','prev', 'page', 'next', 'skip'],
  220. jump: function(obj, first) { //触发分页后的回调
  221. if (!first) { //点击跳页触发函数自身,并传递当前页:obj.curr
  222. query(obj.curr);
  223. }
  224. }
  225. });
  226. layui.form.render('checkbox');
  227. } else { //失败
  228. layui.layer.alert("失败:" + json.Msg, {
  229. icon: 2
  230. });
  231. }
  232. }, 'json');
  233. }
  234. function renderGrid(data) {
  235. var grid_tpl = document.getElementById('grid_tpl').innerHTML;
  236. layui.laytpl(grid_tpl).render(data, function(html) {
  237. $("#gridBody").html(html);
  238. });
  239. }
  240. function oprFormatLink(val, row) {
  241. var html = "";
  242. if (row.Status == 1) {
  243. html += "<button class='layui-btn layui-btn-small layui-btn-danger' onclick='CloseForward(" + row.Id + ");'><i class='layui-icon'></i></button>";
  244. } else {
  245. html += "<button class='layui-btn layui-btn-small layui-btn-normal' onclick='OpenForward(" + row.Id + ");'><i class='layui-icon'></i></button>";
  246. }
  247. html += "<button class='layui-btn layui-btn-small' onclick='editForward(" + row.Id + ");'><i class='layui-icon'></i></button>";
  248. return html;
  249. }
  250. function fmtAddr(val) {
  251. if (val == "") {
  252. return "监听所有地址";
  253. } else {
  254. return val;
  255. }
  256. }
  257. function fmtFType(val) {
  258. var html = "";
  259. switch (val) {
  260. case 0:
  261. html = "<font color='blue'>端口到端口映射</font>";
  262. break;
  263. case 1:
  264. html = "<font color='orange'>内网映射 S->C</font>";
  265. break;
  266. case 2:
  267. html = "<font color='red'>内网反向映射 C->S</font>";
  268. break;
  269. default:
  270. html = "<font color='gray'>其它:" + val + "</font>";
  271. break;
  272. }
  273. return html;
  274. }
  275. function fmtStatus(val) {
  276. var html = "";
  277. switch (val) {
  278. case 0:
  279. html = "<font color='red'>停止</font>";
  280. break;
  281. case 1:
  282. html = "<font color='green'>转发中</font>";
  283. break;
  284. default:
  285. html = "<font color='gray'>其它:" + val + "</font>";
  286. break;
  287. }
  288. return html;
  289. }
  290. function addForward() {
  291. $.get('/u/AddForward', {
  292. rnd: Math.random()
  293. }, function(html) {
  294. layer.open({
  295. type: 1, //page层
  296. area: ['400px', '450px'],
  297. title: '添加网络转发端口',
  298. shade: 0.6, //遮罩透明度
  299. moveType: 1, //拖拽风格,0是默认,1是传统拖动
  300. shift: -1, //0-6的动画形式,-1不开启
  301. maxmin: false,
  302. content: html,
  303. btn: ['保存配置', '取消'],
  304. yes: function(index, layero) {
  305. submitForm(index);
  306. },
  307. btn2: function(index) {
  308. layer.close(index);
  309. },
  310. cancel: function(index) {
  311. layer.close(index);
  312. }
  313. });
  314. });
  315. }
  316. function editForward(id) {
  317. $.get('/u/EditForward', {
  318. rnd: Math.random(),
  319. id: id
  320. }, function(html) {
  321. layer.open({
  322. type: 1, //page层
  323. area: ['600px', '550px'],
  324. title: '编辑网络转发端口',
  325. shade: 0.6, //遮罩透明度
  326. moveType: 1, //拖拽风格,0是默认,1是传统拖动
  327. shift: -1, //0-6的动画形式,-1不开启
  328. maxmin: false,
  329. content: html,
  330. btn: ['保存配置', '取消'],
  331. yes: function(index, layero) {
  332. submitForm(index);
  333. },
  334. btn2: function(index) {
  335. layer.close(index);
  336. },
  337. cancel: function(index) {
  338. layer.close(index);
  339. }
  340. });
  341. });
  342. }
  343. function delForward() {
  344. var selectedItems = getChkValues("id");
  345. if (selectedItems.length == 0) {
  346. layer.alert("没有勾选要批量操作的数据.", {
  347. icon: 3,
  348. title: "警告信息"
  349. });
  350. return;
  351. }
  352. var ids = selectedItems.join(',');
  353. layer.confirm("确定批量删除勾选的数据吗?", {
  354. btn: ['确定', '取消'] //按钮
  355. }, function(index, layero) {
  356. $.post("/u/DelForward", {
  357. rnd: Math.random(),
  358. ids: ids
  359. }, function(json) {
  360. if (json.Code == 0) { //成功
  361. layer.msg("执行成功.");
  362. layer.close(index);
  363. query(1);
  364. } else { //失败
  365. layer.alert(json.Msg, {
  366. icon: 2
  367. });
  368. query(1);
  369. }
  370. }, 'json');
  371. });
  372. }
  373. function AddBatchForward() {
  374. $.get('/u/AddBatchForward', {
  375. rnd: Math.random()
  376. }, function(html) {
  377. layer.open({
  378. type: 1, //page层
  379. area: ['1200px', '700px'],
  380. title: '批量添加规则',
  381. shade: 0.6, //遮罩透明度
  382. moveType: 1, //拖拽风格,0是默认,1是传统拖动
  383. shift: -1, //0-6的动画形式,-1不开启
  384. maxmin: false,
  385. content: html,
  386. btn: ['保存', '取消'],
  387. yes: function(index, layero) {
  388. submitForm(index);
  389. },
  390. cancel: function(index) {
  391. layer.close(index);
  392. }
  393. });
  394. });
  395. }
  396. function ImportForward() {
  397. $.get('/u/ImportForward', {
  398. rnd: Math.random()
  399. }, function(html) {
  400. layer.open({
  401. type: 1, //page层
  402. area: ['750px', '500px'],
  403. title: '批量导入规则',
  404. shade: 0.6, //遮罩透明度
  405. moveType: 1, //拖拽风格,0是默认,1是传统拖动
  406. shift: -1, //0-6的动画形式,-1不开启
  407. maxmin: false,
  408. content: html,
  409. btn: ['保存', '取消'],
  410. yes: function(index, layero) {
  411. submitForm(index);
  412. },
  413. cancel: function(index) {
  414. layer.close(index);
  415. }
  416. });
  417. });
  418. }
  419. function refreshGrid() {
  420. query(1);
  421. }
  422. function OpenForward(id) {
  423. $.post("/u/OpenForward", {
  424. rnd: Math.random(),
  425. id: id
  426. }, function(json) {
  427. if (json.Code == 0) { //成功
  428. //layer.msg("执行成功.");
  429. //layer.close(index);
  430. query(1);
  431. } else { //失败
  432. layer.alert(json.Msg, {
  433. icon: 2
  434. });
  435. query(1);
  436. }
  437. }, 'json');
  438. }
  439. function CloseForward(id) {
  440. $.post("/u/CloseForward", {
  441. rnd: Math.random(),
  442. id: id
  443. }, function(json) {
  444. if (json.Code == 0) { //成功
  445. //layer.msg("执行成功.");
  446. //layer.close(index);
  447. query(1);
  448. } else { //失败
  449. layer.alert(json.Msg, {
  450. icon: 2
  451. });
  452. query(1);
  453. }
  454. }, 'json');
  455. }
  456. function OpenForward2(id) {
  457. layer.confirm("确定启动该转发吗?", {
  458. btn: ['确定', '取消'] //按钮
  459. }, function(index, layero) {
  460. $.post("/u/OpenForward", {
  461. rnd: Math.random(),
  462. id: id
  463. }, function(json) {
  464. if (json.Code == 0) { //成功
  465. layer.msg("执行成功.");
  466. layer.close(index);
  467. query(1);
  468. } else { //失败
  469. layer.alert(json.Msg, {
  470. icon: 2
  471. });
  472. query(1);
  473. }
  474. }, 'json');
  475. });
  476. }
  477. function CloseForward2(id) {
  478. layer.confirm("确定停止该转发吗?", {
  479. btn: ['确定', '取消'] //按钮
  480. }, function(index, layero) {
  481. $.post("/u/CloseForward", {
  482. rnd: Math.random(),
  483. id: id
  484. }, function(json) {
  485. if (json.Code == 0) { //成功
  486. layer.msg("执行成功.");
  487. layer.close(index);
  488. query(1);
  489. } else { //失败
  490. layer.alert(json.Msg, {
  491. icon: 2
  492. });
  493. query(1);
  494. }
  495. }, 'json');
  496. });
  497. }
  498. function OpenAllForward() {
  499. layer.confirm("确定一键开启所有转发吗?", {
  500. btn: ['确定', '取消'] //按钮
  501. }, function(index, layero) {
  502. $.post("/u/OpenAllForward", {
  503. rnd: Math.random()
  504. }, function(json) {
  505. if (json.Code == 0) { //成功
  506. layer.msg("执行成功.");
  507. layer.close(index);
  508. query(1);
  509. } else { //失败
  510. layer.alert(json.Msg, {
  511. icon: 2
  512. });
  513. query(1);
  514. }
  515. }, 'json');
  516. });
  517. }
  518. function CloseAllForward() {
  519. layer.confirm("确定一键关闭所有转发吗?", {
  520. btn: ['确定', '取消'] //按钮
  521. }, function(index, layero) {
  522. $.post("/u/CloseAllForward", {
  523. rnd: Math.random()
  524. }, function(json) {
  525. if (json.Code == 0) { //成功
  526. layer.msg("执行成功.");
  527. layer.close(index);
  528. query(1);
  529. } else { //失败
  530. layer.alert(json.Msg, {
  531. icon: 2
  532. });
  533. query(1);
  534. }
  535. }, 'json');
  536. });
  537. }
  538. </script>
粤ICP备19079148号