This commit is contained in:
c
2023-07-29 21:59:37 +08:00
parent ce27f1d693
commit 15c0aa1c5c
12 changed files with 367 additions and 65 deletions

View File

@@ -11,16 +11,17 @@ namespace NetPanel.Bl
public class ExecuteBl public class ExecuteBl
{ {
public static string Exec(string command)
public static string Exec(string fileName,string command)
{ {
if (OperatingSystem.IsWindows()) // 检查当前操作系统是否为 Windows if (OperatingSystem.IsWindows()) // 检查当前操作系统是否为 Windows
{ {
return ExecuteCommandOnWindows(command); return ExecuteCommandOnWindows(fileName, command);
} }
else if (OperatingSystem.IsLinux()) // 检查当前操作系统是否为 Linux else if (OperatingSystem.IsLinux()) // 检查当前操作系统是否为 Linux
{ {
return ExecuteCommandOnLinux(command); return ExecuteCommandOnLinux(fileName, command);
} }
else else
{ {
@@ -28,20 +29,21 @@ namespace NetPanel.Bl
} }
} }
/// <summary> /// <summary>
/// win 执行命令 /// win 执行命令
/// </summary> /// </summary>
/// <param name="command"></param> /// <param name="command"></param>
/// <returns></returns> /// <returns></returns>
private static string ExecuteCommandOnWindows(string command) private static string ExecuteCommandOnWindows(string fileName ,string command)
{ {
using var process = new Process using var process = new Process
{ {
StartInfo = new ProcessStartInfo StartInfo = new ProcessStartInfo
{ {
FileName = "cmd.exe", FileName = fileName,
Arguments = "/C " + command, Arguments = command,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true, RedirectStandardError = true,
//StandardErrorEncoding = Encoding.UTF8, //StandardErrorEncoding = Encoding.UTF8,
@@ -65,15 +67,15 @@ namespace NetPanel.Bl
/// linux 执行命令 /// linux 执行命令
/// </summary> /// </summary>
/// <param name="command"></param> /// <param name="command"></param>
private static string ExecuteCommandOnLinux(string command) private static string ExecuteCommandOnLinux(string fileName ,string command)
{ {
using var process = new Process using var process = new Process
{ {
StartInfo = new ProcessStartInfo StartInfo = new ProcessStartInfo
{ {
FileName = "/bin/bash", FileName = fileName,
Arguments = "-c \"" + command + "\"", Arguments = command,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true, RedirectStandardError = true,
//StandardErrorEncoding = Encoding.UTF8, //StandardErrorEncoding = Encoding.UTF8,

24
NetPanel.Help/LogHeler.cs Normal file
View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace NetPanel.Help
{
public class LogHeler
{
public static void Set(string name, string str)
{
string sPath = AppContext.BaseDirectory + "/Log";
File.AppendAllText(sPath + "/"+ name + "_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", "[" + DateTime.Now.ToString() + "]:" + str + "\r\n", Encoding.UTF8);
}
public static void SelErrt(string str)
{
Set("Errt",str);
}
}
}

View File

@@ -1,9 +1,12 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NetPanel.Bl;
using NetPanel.Entity; using NetPanel.Entity;
using NetPanel.Help;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -18,6 +21,83 @@ namespace NetPanel.Controllers
} }
/// <summary>
/// 获取概况
/// </summary>
/// <returns></returns>
public IActionResult GetOverview()
{
ReturnMsg returnMsg = new ReturnMsg();
try
{
#region
string output = ExecuteBl.Exec("free", "-m");
// 解析输出行
string[] lines = output.Split('\n');
string[] memoryInfo = lines[1].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
// 获取已使用和总内存大小
float totalMemory = float.Parse(memoryInfo[1]);
float usedMemory = float.Parse(memoryInfo[2]);
LogHeler.SelErrt("[HomeController-GetOverview]" + output);
#endregion
#region
output = ExecuteBl.Exec("df", "-h ./");
lines = output.Split('\n');
memoryInfo = lines[1].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
// 转换为GB单位
double totalSizeInGB = memoryInfo[1].Replace("G", "").ToDouble();
double availableFreeSpaceInGB = memoryInfo[2].Replace("G", "").ToDouble();
#endregion
#region Cpu使用率
output = ExecuteBl.Exec("/usr/bin/top", "-b -n 1");
string cpuLine = output.Split('\n')[2];
string[] cpuValues = cpuLine.Split(' ', StringSplitOptions.RemoveEmptyEntries);
double cpuUsage = double.Parse(cpuValues[1]);
#endregion
var data = new
{
//cpu
Cpu = new { Total = 100, Used = cpuUsage },
//内存
Ram = new { Total = totalMemory, Used = usedMemory },
Size = new { Total = totalSizeInGB, Used = availableFreeSpaceInGB },
};
//var data = new
//{
// //cpu
// Cpu = new { Total = 100, Used = new Random().Next(0, 100) },
// //内存
// Ram = new { Total = 1000, Used = new Random().Next(0, 1000) },
// //内存
// Size = new { Total = 2000, Used = new Random().Next(0, 2000) },
//};
returnMsg.Code = 1;
returnMsg.Obj = data;
}
catch (Exception es)
{
LogHeler.SelErrt("[HomeController-GetOverview]" + es.ToString());
}
return Ok(returnMsg);
}
public IActionResult Index() public IActionResult Index()
{ {

View File

@@ -57,6 +57,8 @@ namespace NetPanel.Controllers
enReturnMsg.Msg = "用户名,密码错误!"; enReturnMsg.Msg = "用户名,密码错误!";
return Json(enReturnMsg); return Json(enReturnMsg);
} }
HttpContext.Session.SetString("user", JsonConvert.SerializeObject(userAdmin.UserName));
enReturnMsg.Code = 1; enReturnMsg.Code = 1;
enReturnMsg.Msg = "成功!"; enReturnMsg.Msg = "成功!";
return Json(enReturnMsg); return Json(enReturnMsg);

View File

@@ -0,0 +1,54 @@
using Microsoft.AspNetCore.Mvc.Filters;
using NetPanel.Help;
namespace NetPanel.Filter
{
public class ActionFilter : IAuthorizationFilter
{
private readonly IConfiguration _configuration;
public ActionFilter(IConfiguration configuration)
{
_configuration = configuration;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
//(1). 方法1
// string c= context.ActionDescriptor.RouteValues["area"].ToString();
// context.ActionDescriptor.RouteValues[“controller”].ToString();
// context.ActionDescriptor.RouteValues[“action”].ToString();
// (2). 方法2
// context.RouteData.Values[“controller”].ToString();
// context.RouteData.Values[“action”].ToString();
// context.HttpContext.Connection.RemoteIpAddress
string isAdmin = _configuration.GetConnectionString("IsAdmin");
if (isAdmin == "1")
{
return;
}
//控制器名称
string controllerName = context.ActionDescriptor.RouteValues["controller"].ToString();
string action = context.ActionDescriptor.RouteValues["action"].ToString();
if (controllerName == "Login" || controllerName == "Api" || (controllerName == "Home" && action == "Error"))
{
return;
}
string sUser = context.HttpContext.Session.GetString("user");
if (sUser.IsNull())
{
context.Result = new Microsoft.AspNetCore.Mvc.RedirectResult("/Login/Login");
}
}
}
}

View File

@@ -1,12 +1,21 @@
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
// Add services to the container. // Add services to the container.
builder.Services.AddControllersWithViews(); services.AddControllersWithViews();
builder.Services.AddControllers().AddJsonOptions(options => services.AddControllers().AddJsonOptions(options =>
{ {
options.JsonSerializerOptions.PropertyNamingPolicy = null; options.JsonSerializerOptions.PropertyNamingPolicy = null;
}); });
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromDays(1);
});
services.AddControllersWithViews(o =>
{
o.Filters.Add<NetPanel.Filter.ActionFilter>();
});
var app = builder.Build(); var app = builder.Build();
@@ -17,11 +26,11 @@ if (!app.Environment.IsDevelopment())
app.UseExceptionHandler("/Home/Error"); app.UseExceptionHandler("/Home/Error");
} }
app.UseStaticFiles(); app.UseStaticFiles();
app.UseSession();
app.UseCookiePolicy();
app.UseRouting(); app.UseRouting();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllerRoute( app.MapControllerRoute(
name: "default", name: "default",
pattern: "{controller=Login}/{action=Login}/{id?}"); pattern: "{controller=Login}/{action=Login}/{id?}");

View File

@@ -19,33 +19,23 @@
<!-- Preloader --> <!-- Preloader -->
@*<div class="preloader flex-column justify-content-center align-items-center"> @*<div class="preloader flex-column justify-content-center align-items-center">
<img class="animation__shake" src="dist/img/AdminLTELogo.png" alt="AdminLTELogo" height="60" width="60"> <img class="animation__shake" src="dist/img/AdminLTELogo.png" alt="AdminLTELogo" height="60" width="60">
</div>*@ </div>*@
@Html.Partial("Top") @Html.Partial("Top")
@Html.Partial("Menu") @Html.Partial("Menu")
<center>
<table height="150px" border="0" id='waitPage' style="display:none">
<tr>
<td>
<img width='28' height='28' id='myImage' src="/AdminLTE/dist/img/onload.gif" />
</td>
<td>加载中,请等待...</td>
</tr>
</table>
</center>
<div class="content-wrapper"> <div class="content-wrapper">
<div id="waitPage" style=" position:absolute;text-align:center;height:30px; top:0px;bottom: 20%; left: 0px;right: 0px;margin:auto;">
<img width='28' height='28' id='myImage' src="/AdminLTE/dist/img/onload.gif" />
加载中,请等待...
</div>
<iframe id="iframeBody" name="iframeLeft" src="" frameborder="0" seamless></iframe> <iframe id="iframeBody" name="iframeLeft" src="" frameborder="0" seamless></iframe>
</div> </div>
<!-- /.content-wrapper --> <!-- /.content-wrapper -->
<!--<footer class="main-footer"> <!--<footer class="main-footer">
<strong>Copyright &copy; 2014-2021 <a href="https://adminlte.io">AdminLTE.io</a>.</strong> <strong>Copyright &copy; 2014-2021 <a href="https://adminlte.io">AdminLTE.io</a>.</strong>
@@ -57,42 +47,37 @@
</div> </div>
<script type="text/javascript">
// localStorage.setItem('AdminLTE:IFrame:Options', JSON.stringify({ autoIframeMode: false, autoItemActive: false }))
</script>
<!-- ./wrapper --> <!-- ./wrapper -->
@Html.Partial("UiJs") @Html.Partial("UiJs")
<script type="text/javascript"> <script type="text/javascript">
var iframe = document.getElementById("iframeBody"); var iframe = document.getElementById("iframeBody");
var hash = window.location.hash; var hash = window.location.hash;
if (hash != '') { if (hash != '') {
iframe.src = hash.replace('#', ''); iframe.src = hash.replace('#', '');
} }
$('#iframeBody').height(document.documentElement.clientHeight - 70); $('#iframeBody').height(document.documentElement.clientHeight - 70);
$('.menu').click(function () { $('.menu').click(function () {
var url = $(this).attr("data-Url"); var url = $(this).attr("data-Url");
$("#waitPage").show(); $("#waitPage").show();
iframe.style.display = "none";
iframe.src = url; iframe.src = url;
if (iframe.attachEvent) {
iframe.attachEvent("onload", function () {
$("#waitPage").hide();
iframe.show();
iframe.style.display = "block";
});
} else {
iframe.onload = function () {
$("#waitPage").hide();
iframe.style.display = "block";
};
}
return false; return false;
}) })
iframe.addEventListener('load', function () {
$("#waitPage").hide();
});
$(window).resize(function () { $(window).resize(function () {
$('#iframeBody').height(document.documentElement.clientHeight - 70); $('#iframeBody').height(document.documentElement.clientHeight - 70);
}); });
</script> </script>
</body> </body>

View File

@@ -21,21 +21,15 @@
<!-- /.card-header --> <!-- /.card-header -->
<div class="card-body"> <div class="card-body">
<div class="form-group"> <div class="row">
@* <div id="main1" style="height:250px;" class="col-3"></div>
<div id="main2" style="height:250px;" class="col-3"></div>
<div id="main3" style="height:250px;" class="col-3"></div>
<div id="main4" style="height:250px;" class="col-3"></div>*@
<div id="main1" style="height:250px;" class="col-3"></div>
<div id="main2" style="height:250px;" class="col-3"></div>
<div id="main3" style="height:250px;" class="col-3"></div>
</div> </div>
<table class="table table-bordered">
<thead>
<tr>
<th>路径</th>
<th>状态</th>
<th>时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
</div> </div>
<!-- /.card-body --> <!-- /.card-body -->
@@ -49,9 +43,156 @@
</div> </div>
<!-- /.container-fluid --> <!-- /.container-fluid -->
</section> </section>
<script src="/AdminLTE/plugins/echarts/echarts.min.js"></script>
<script> <script>
var option = {
series: [
{
type: 'gauge',
center: ['50%', '60%'],
startAngle: 200,
endAngle: -20,
height: 250,
min: 0,
max: 2018,
progress: {
show: true,
width: 30
},
pointer: {
show: false
},
axisLine: {
lineStyle: {
width: 30
}
},
axisTick: {
distance: -45,
splitNumber: 2,
lineStyle: {
width: 2,
}
},
splitLine: {
distance: -52,
length: 14,
lineStyle: {
width: 2,
}
},
axisLabel: {
distance: -10,
fontSize: 10,
formatter: function (v) {
return v.toFixed(0);
},
},
anchor: {
show: true
},
title: {
show: true
},
detail: {
valueAnimation: true,
width: '60%',
lineHeight: 40,
borderRadius: 8,
offsetCenter: [0, '-15%'],
fontSize: 20,
fontWeight: 'bolder',
formatter: '{value}',
color: 'inherit',
show: true
},
data: [
{
name: 'SCORE',
value: 0
}
]
}
]
};
var myChart1 = null;
var myChart2 = null;
var myChart3 = null;
//window.onresize = function () {
// myChart1 = echarts.init(document.getElementById('main1'));
// myChart2 = echarts.init(document.getElementById('main2'));
// myChart3 = echarts.init(document.getElementById('main3'));
// GetOverview();
// setInterval(function () {
// GetOverview();
// }, 3000)
//}
$(function () {
myChart1 = echarts.init(document.getElementById('main1'));
myChart2 = echarts.init(document.getElementById('main2'));
myChart3 = echarts.init(document.getElementById('main3'));
// GetOverview();
setInterval(function () {
GetOverview();
}, 1000)
})
//$(window).resize(function () {
// myChart1 = echarts.init(document.getElementById('main1'));
// myChart2 = echarts.init(document.getElementById('main2'));
// myChart3 = echarts.init(document.getElementById('main3'));
// GetOverview();
// setInterval(function () {
// GetOverview();
// }, 3000)
//});
function GetOverview() {
$.ajax({
url: "/Home/GetOverview",
type: 'get',
dataType: "json",
success: function (msg) {
if (msg.Code == 1) {
option.series[0].detail.formatter = '{value} %';
option.series[0].max = msg.Obj.Cpu.Total;
option.series[0].data[0].name = 'CPU';
option.series[0].data[0].value = msg.Obj.Cpu.Used;
myChart1.setOption(option);
option.series[0].detail.formatter = '{value} MB';
option.series[0].max = msg.Obj.Ram.Total;
option.series[0].data[0].name = 'Ram';
option.series[0].data[0].value = msg.Obj.Ram.Used;
myChart2.setOption(option);
option.series[0].detail.formatter = '{value} G';
option.series[0].max = msg.Obj.Size.Total;
option.series[0].data[0].name = 'Size';
option.series[0].data[0].value = msg.Obj.Size.Used;
myChart3.setOption(option);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
},
complete: function () {
}
});
}
</script> </script>

View File

@@ -73,7 +73,7 @@
success: function (msg) { success: function (msg) {
if (msg.Code == 1) { if (msg.Code == 1) {
window.location.href = "/Home/Index"; window.location.href = "/Home/Index#/Home/Overview";
} else { } else {
alert(msg.Msg); alert(msg.Msg);
} }

View File

@@ -5,5 +5,8 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"ConnectionStrings": {
"IsAdmin": "1"
}
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long