using IES.ExamServer.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using System.Diagnostics; using System.Text.Json.Nodes; using System.Text.Json; using IES.ExamServer.Helper; using System.IdentityModel.Tokens.Jwt; using IES.ExamServer.Services; using IES.ExamServer.DI; using IES.ExamServer.Helpers; using IES.ExamLibrary.Models; using System.Threading.Tasks; using Hardware.Info; using System.Net.NetworkInformation; using System.Text.RegularExpressions; namespace IES.ExamServer.Controllers { [ApiController] [Route("index")] public class IndexController : BaseController { private readonly IConfiguration _configuration; private readonly IHttpClientFactory _httpClientFactory; private readonly IMemoryCache _memoryCache; private readonly ILogger _logger; private readonly CenterServiceConnectionService _connectionService; private readonly LiteDBFactory _liteDBFactory; private readonly IHostApplicationLifetime _hostApplicationLifetime; public IndexController(ILogger logger, IConfiguration configuration, IHttpClientFactory httpClientFactory, IMemoryCache memoryCache,CenterServiceConnectionService connectionService, LiteDBFactory liteDBFactory, IHostApplicationLifetime hostApplicationLifetime) { _hostApplicationLifetime = hostApplicationLifetime; _logger = logger; _configuration=configuration; _httpClientFactory=httpClientFactory; _memoryCache=memoryCache; _connectionService=connectionService; _liteDBFactory=liteDBFactory; } [HttpGet("hardware")] public IActionResult hardware() { IHardwareInfo? hardwareInfo = null; try { hardwareInfo = new HardwareInfo(); //hardwareInfo.RefreshOperatingSystem(); //..... //刷新所有硬件信息 hardwareInfo.RefreshAll(); } catch (Exception ex) { Console.WriteLine(ex); } Console.WriteLine("输出操作系统信息" + Environment.NewLine); Console.WriteLine(hardwareInfo.OperatingSystem); Console.WriteLine("输出内存状态信息" + Environment.NewLine); Console.WriteLine(hardwareInfo.MemoryStatus); Console.WriteLine("输出电池信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.BatteryList) Console.WriteLine(hardware); Console.WriteLine("输出 BIOS 信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.BiosList) Console.WriteLine(hardware); Console.WriteLine("输出计算机系统信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.ComputerSystemList) Console.WriteLine(hardware); Console.WriteLine("输出 CPU 信息" + Environment.NewLine); foreach (var cpu in hardwareInfo.CpuList) { Console.WriteLine(cpu); Console.WriteLine("输出 CPU 核心信息" + Environment.NewLine); foreach (var cpuCore in cpu.CpuCoreList) Console.WriteLine(cpuCore); } Console.WriteLine("输出磁盘驱动器信息" + Environment.NewLine); foreach (var drive in hardwareInfo.DriveList) { Console.WriteLine(drive); Console.WriteLine("输出驱动器分区信息" + Environment.NewLine); foreach (var partition in drive.PartitionList) { Console.WriteLine(partition); Console.WriteLine("输出分区卷信息" + Environment.NewLine); foreach (var volume in partition.VolumeList) Console.WriteLine(volume); } } Console.WriteLine("输出键盘信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.KeyboardList) Console.WriteLine(hardware); Console.WriteLine("输出内存信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.MemoryList) Console.WriteLine(hardware); Console.WriteLine("输出显示器信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.MonitorList) Console.WriteLine(hardware); Console.WriteLine("输出主板信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.MotherboardList) Console.WriteLine(hardware); Console.WriteLine("输出鼠标信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.MouseList) Console.WriteLine(hardware); Console.WriteLine("输出网络适配器信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.NetworkAdapterList) Console.WriteLine(hardware); Console.WriteLine("输出打印机信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.PrinterList) Console.WriteLine(hardware); Console.WriteLine("输出声音设备信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.SoundDeviceList) Console.WriteLine(hardware); Console.WriteLine("输出显卡信息" + Environment.NewLine); foreach (var hardware in hardwareInfo.VideoControllerList) Console.WriteLine(hardware); Console.WriteLine("输出 Ethernet 类型并且状态为 Up 的本地 IPv4 地址" + Environment.NewLine); foreach (var address in HardwareInfo.GetLocalIPv4Addresses(NetworkInterfaceType.Ethernet, OperationalStatus.Up)) Console.WriteLine(address); Console.WriteLine(); Console.WriteLine("输出 Wireless80211 类型的本地 IPv4 地址" + Environment.NewLine); foreach (var address in HardwareInfo.GetLocalIPv4Addresses(NetworkInterfaceType.Wireless80211)) Console.WriteLine(address); Console.WriteLine(); Console.WriteLine("输出状态为 Up 的网络接口卡的本地 IPv4 地址" + Environment.NewLine); foreach (var address in HardwareInfo.GetLocalIPv4Addresses(OperationalStatus.Up)) Console.WriteLine(address); Console.WriteLine(); Console.WriteLine("输出所有网络接口卡的本地 IPv4 地址" + Environment.NewLine); foreach (var address in HardwareInfo.GetLocalIPv4Addresses()) Console.WriteLine(address); Console.WriteLine(); Console.WriteLine("输出计算机当前时间" + Environment.NewLine); Console.WriteLine(DateTime.Now); Console.WriteLine("输出系统启动时间" + Environment.NewLine); Console.WriteLine(Environment.TickCount); return Ok(); } /// /// 关闭当前进程的接口 /// /// [HttpGet("music")] public async Task Music() { string e = await System.IO.File.ReadAllTextAsync("F:\\cer\\e.txt"); e=AESHelper.Decrypt(e); string d = await System.IO.File.ReadAllTextAsync("F:\\cer\\d.txt"); d=AESHelper.Decrypt(d); //https://musicapi.winteach.cn/api/v1/musicLocalCache/auth/sts get //响应内容: //T6RiMezIVman5LYBlSMDVkd20Jrca/M/fguhdGlKyiofU8h329wNXxzsHO2FBdUIol1S+7CK7F7S6H5u7/FY9peTLO8sYUoNdGo3Q0r7eX7Sx6Ie0W8d2YGKXTqOZ/Fn8mmE58nORPgUsYR1c1LPOdTsRPJNaHTU8ExAYqsci778DuDT+gyZqA7zsRbf311qQJPGYFpYPibdx3rP4wpoppsAP7CibbTWmt4fFEnGeFqqrLZ+1Mm76+6rSdMNGFYaI3aH20fdT4CKaX7yKInU6Fzb2EdgYmsJd9unnq6kgWIAVz8XnNxKgKUGXnbp3NFDkYOVCl/eNo+NOpFU9CrVdCMY+7fURr1mPTSMzVWLhlYRysOJGIJyQi4SaAwnRA1faFYI1d5hGYfQajfGrwQAWnmOBaqxucMaVMb3YtPE9O6B1INeITT+MQKStYWa1WVDC4u2gdR77Dkz7INNV1qtYdIs5dn3BgMwFQjEtXMDu9Ms9Ls+4TQMq4bUSKbY0Fzu5bHNQbV/Ob9JPiw76Ka7eMfwA0PJMiupOE5HX2fdHEDoX2DKjLmRrfzx3JVguT9nT+efn4jcts4Egb3PTxlGcV56C1u+C43ze24rIhkAwMUehY/h3t7TcbZdASCNaJO53uYJF3t3FW5TxLfPZ0AXML8akd4QNwyjOeSjnkwfBrMIvH9SYtJUcIC4TUBOXN/8CrpaTT/Rs5noAMMuF028SYUxqEfQjd23ypd0jICRMx0meefdPz1gnJMukFWJL4sn5GQb72X0ck+zQsbWGgfIXXGpWnhIa7OxX2Hgz6iajqYIIkZDw22UWKc12hgJINaItSWNLx6yeMmbJ6V3aWJ63KZJ6LHqPK/6ikn7XQSAe6nNQp7rLNPTQqfnpyZCMisvePHWaz//E2oYAUqMX/glFUk22ZOjosFO8vFZFz2VN+UWdnOFrvvx7tolPHa2NRRsnwIkzoeV6rXDZ4DgEhnW5rWrtjMz14stXeYa5xg6rIY0uQtKREc5zE0qyxC7akqjywwb1pAc5yKC7mKLK6VLd/+kLsqr+6yuYpAZHzBxjZmElP48GDZxEbdIwFDU7LZ3Z94g2u3KiWtJJnx31lraRRorcOGW2yC+PvRBPV9s12z+SuBIgElFq4bUO2pwYPHs2arL39RvaMr+jl7cv2l3x0fvT1PP7QUsqA6oDP0cVpyWtlTZzfdFZmqcVo2pryXrZhDKEwjxH+q6GHERkfCGnUEcqEgU/qfTvTsOpEaIthbiuckmOssokXSN+5rxxOp0Arwi1SkoF1P0W0SS0VJe2kcGBMGh5Ud6AUqhPtt7Qw8= /* { "code": 200, "success": 1, "time": "2025-02-23 21:37:02", "msg": "\u64CD\u4F5C\u6210\u529F", "data": { "accessKeyId": "STS.NUsHMfsmRf9koezhD3JHsbDSq", "accessKeySecret": "DdUrM2f137i6kmg7Nk3EsV9tzJrTRWZnDvjfADKBUmoZ", "bucket": "teammodel", "ossEndpoint": "oss-cn-chengdu.aliyuncs.com", "securityToken": "CAISwAJ1q6Ft5B2yfSjIr5bGA/fSnrJz0fuAbUPLjERmRsdfjYH4kzz2IHhMe3hrA\u002B4YsvU3nGBW7PsYlqNJQppiXlf4YNBstlbIbPIaOdivgde8yJBZor/HcDHhJnyW9cvWZPqDP7G5U/yxalfCuzZuyL/hD1uLVECkNpv74vwOLK5gPG\u002BCYCFBGc1dKyZ7tcYeLgGxD/u2NQPwiWeiZygB\u002BCgE0D8vtPTkmZPDs0eE1QKkkNV4/dqhfsKWCOB3J4p6XtuP2\u002Bh7S7HMyiY46WIRrP8p3fcep2mb74nFUwcLvk\u002BcUfDd99p0NxN0fbQqkS2SJSl/LJeS086kdOSfo34lVYk92BSCRz5EY\u002BXurEK45HtIlKd6SpU86Kr7ErPfnW3aj/y12q3k1bTfBIEOJ\u002BLiKFX4bpvD0jSsxm\u002BMzX/TjsleuRqAAQESLkjMgQqt24ftPT2C8DVe2hJ\u002BPIDPN60GaKfzXipCwtKpe2I33Bdz04US8s3Rh5TbD0MmG0K0Ms8/8rNr3z\u002B12OXfuzltmkIUHImV8kmP1omIlYxOvDrsKkabhah0LWrGQ7DLIWz\u002BGxfU82DjsyQ4TDcC4Xw/2Hu3l8ma1scuIAA=", "region": "oss-cn-chengdu", "routeType": "RamOssTest", "expiration": "2025-02-23T14:37:02Z" } } */ string dss = AESHelper.Decrypt("T6RiMezIVman5LYBlSMDVkd20Jrca/M/fguhdGlKyiofU8h329wNXxzsHO2FBdUIol1S+7CK7F7S6H5u7/FY9peTLO8sYUoNdGo3Q0r7eX7Sx6Ie0W8d2YGKXTqOZ/Fn8mmE58nORPgUsYR1c1LPOdTsRPJNaHTU8ExAYqsci778DuDT+gyZqA7zsRbf311qQJPGYFpYPibdx3rP4wpoppsAP7CibbTWmt4fFEnGeFqqrLZ+1Mm76+6rSdMNGFYaI3aH20fdT4CKaX7yKInU6Fzb2EdgYmsJd9unnq6kgWIAVz8XnNxKgKUGXnbp3NFDkYOVCl/eNo+NOpFU9CrVdCMY+7fURr1mPTSMzVWLhlYRysOJGIJyQi4SaAwnRA1faFYI1d5hGYfQajfGrwQAWnmOBaqxucMaVMb3YtPE9O6B1INeITT+MQKStYWa1WVDC4u2gdR77Dkz7INNV1qtYdIs5dn3BgMwFQjEtXMDu9Ms9Ls+4TQMq4bUSKbY0Fzu5bHNQbV/Ob9JPiw76Ka7eMfwA0PJMiupOE5HX2fdHEDoX2DKjLmRrfzx3JVguT9nT+efn4jcts4Egb3PTxlGcV56C1u+C43ze24rIhkAwMUehY/h3t7TcbZdASCNaJO53uYJF3t3FW5TxLfPZ0AXML8akd4QNwyjOeSjnkwfBrMIvH9SYtJUcIC4TUBOXN/8CrpaTT/Rs5noAMMuF028SYUxqEfQjd23ypd0jICRMx0meefdPz1gnJMukFWJL4sn5GQb72X0ck+zQsbWGgfIXXGpWnhIa7OxX2Hgz6iajqYIIkZDw22UWKc12hgJINaItSWNLx6yeMmbJ6V3aWJ63KZJ6LHqPK/6ikn7XQSAe6nNQp7rLNPTQqfnpyZCMisvePHWaz//E2oYAUqMX/glFUk22ZOjosFO8vFZFz2VN+UWdnOFrvvx7tolPHa2NRRsnwIkzoeV6rXDZ4DgEhnW5rWrtjMz14stXeYa5xg6rIY0uQtKREc5zE0qyxC7akqjywwb1pAc5yKC7mKLK6VLd/+kLsqr+6yuYpAZHzBxjZmElP48GDZxEbdIwFDU7LZ3Z94g2u3KiWtJJnx31lraRRorcOGW2yC+PvRBPV9s12z+SuBIgElFq4bUO2pwYPHs2arL39RvaMr+jl7cv2l3x0fvT1PP7QUsqA6oDP0cVpyWtlTZzfdFZmqcVo2pryXrZhDKEwjxH+q6GHERkfCGnUEcqEgU/qfTvTsOpEaIthbiuckmOssokXSN+5rxxOp0Arwi1SkoF1P0W0SS0VJe2kcGBMGh5Ud6AUqhPtt7Qw8="); //thirdLocalCacheConfig //请求加密: yWm8geklutVm87JFcvA6WxOoCMQQSyXpr28uJ5d7lVSDU3CQpgPR3q/Clk7YPYeK //响应解密 : T6RiMezIVman5LYBlSMDVkd20Jrca/M/fguhdGlKyiqW+6HSs0K5SWT2hXaGb5O740ew8U1tQF0ac9F33RpLQV1MmceaCvnQCrx8AJCpF4hx3SlQnX2Tt5o3JZIN3MJDz/XNr/ipGIl+3f36y3YSdMbInLx2coxnJtKfLoW/Cu+XK6VvyHYiavd8uk6xkIXpGDzgHfrw6oqjnknWm2fXBaqlAdnx8l7p4aZfXTVjqJAmJQuUPDId3H2LI7w1HRwq6L3OvXdNvF9X0rFYWATKca1ABB/rqRYNaO9ZtAJ3tMCJpY3AmU5lc/ozikbzu+2qVKdN9rKUtt2Xl2Yqm9eN4R6Sr1yf98eKDqJF/Xk9h8gxS3qZYGP6rkoJSecWpA1UiQhZOu6n2/FKPZsj8FdbES8dEGQjxl3cFme8eiGU4urGH+in4VsBpE3FGjdHkpxxOrzBzID8KtvzqF77f0WK7utkLN1/yBSidwe6YB29uETzXiNBe0iqjHdZbmrjmkO+ //thirdLocalCacheConfig //请求:L6nzwg2xImbjoqyIZgaZ/w== //解密:T6RiMezIVman5LYBlSMDVkd20Jrca/M/fguhdGlKyiqUHPIitU/Lb9N1WxTC+Gccw0Jima9mdCFyjic883n8FEnAq89rkDNUwRbvxI8IDzcujTnLF3EBGujS5qKRj836HWDc4g+n3QLnSKLRieUxi/ToG23yX1syZpBiWZz28qNJu5YuGl4Iy5/9MEyQOe8xmIpvrU6Se3NbRmITSJrnAHV2ByDWSc4oq/JFYr3CpJvL+t9oJ5yABgQH7UrXaWFrkXIvEQIKu9JVAy2Jsr+pb5az0cLIlqppprt8TrtLHxfxxTJS7NMvmn98lnEjxBBZcXKdGhgicAmuUyvpA16BLlui1UW/Ub2St9f2oOrT9+SnidtvP0yt9WoJ119Ls6trWelRpcBeSwg/bNuID0qsG1Wyltgk/UiqdLASE/54XmngYmP+rR3m9rxl5uqJ+/a8FxwaFmC8l6SWXC3X4XKCuQzuedE0yFTXGFSANDPgTW7QlXI0xYpEWSMsT9oXR51N //thirdLocalCacheConfig //请求:l4/OnnDqsVaprrMwLQYUqS/B1BdBv5QYaGOvqwDdFvg= //解密:T6RiMezIVman5LYBlSMDVkd20Jrca/M/fguhdGlKyipAsCbSWRX7XfCnLNoQZUI3q9pdC2powS0VPMlIPufIdO3ch0Y15x1INJJNI/1m8xem72F5Oe+wWb0gnc+Sl3tisXsny+mA7k/LnGOOzr/6NC44ETAwd+hP17XoLYbaiBvXKE10ifVtVrSCkj5Zo+4QDK2+up6WSbePVkss9e9QZEgP3VYdlMlkiSsAc/ZN2SdkrPjzhu0nxSt3lYCYkS30XejBr6qC8GzrJ7OVWHdUjZKt4Rf5PHHE0AOWPxxK4bKtOOD6p1oCWJIRWqh0i/sY8NtbO0fJw/YtnWuL6Y0pJmfmn5gb8uVsdX46rk5cipLSHUjesnLZ3L7eiEgXvYUrZrLBP3jkpO3GvaP307GvjStlcK600z9k9AEQaprOm+nDoeEwx5u+5c0sakRvOrENYZ9BqfOaTJUvSSgarWbgXqrA9fQp6CE+8rXKJ9IzybudsVa3nr+3IJA9X3lG1XkT // string ens = AESHelper.Encrypt("{}"); // string des = AESHelper.Decrypt("L6nzwg2xImbjoqyIZgaZ/w==");// {} 心跳检测 // string des = AESHelper.Decrypt("yWm8geklutVm87JFcvA6WxOoCMQQSyXpr28uJ5d7lVSDU3CQpgPR3q/Clk7YPYeK");// {"localCacheIp":"https://192.168.56.1:7071"} 设置本地服务的IP地址 string des = AESHelper.Decrypt("l4/OnnDqsVaprrMwLQYUqS/B1BdBv5QYaGOvqwDdFvg=");//{"cacheStatus":1}//设置本地缓存状态 string ens = AESHelper.Encrypt(des); var (content,code)= await IndexService.GetMusicServer_thirdLocalCacheConfig(_httpClientFactory, _connectionService, ens); content=content.Replace("\"", ""); content= AESHelper.Decrypt(content); /* { "code": 200, "success": 1, "time": "2025-02-23 21:17:07", "msg": "操作成功", "data": { "id": 95, "name": "醍摩豆研发学校", "contactName": "", "phoneNumber": "habook", "code": "ha", "type": "1", "serialNumber": 1, "province": "四川省", "city": "成都市", "county": "锦江区", "address": "", "localCacheIp": "https://192.168.56.1:7071", "cacheStatus": 1, "heartTime": "2025-02-23T21:16:06.000+08:00" } } */ return Ok(content); } private static bool _isShuttingDown = false; /// /// 关闭当前进程的接口 /// /// [HttpGet("shutdown")] public IActionResult Shutdown(int delay = 200) { try { if (_isShuttingDown) { return Ok("Shutdown process is already initiated."); } _isShuttingDown = true; //_ = Task.Delay(delay).ContinueWith(_ => //{ // try // { // // 关闭前清理资源 // CleanupResources(); // // 停止应用程序 // _hostApplicationLifetime.StopApplication(); // } // catch (Exception ex) // { // Console.Error.WriteLine($"Error during shutdown: {ex.Message}"); // } //}); try { // 关闭前清理资源 CleanupResources(); // 停止应用程序 _hostApplicationLifetime.StopApplication(); } catch (Exception ex) { Console.Error.WriteLine($"Error during shutdown: {ex.Message}"); } return Ok("Shutdown process has been initiated."); } catch (Exception ex) { return StatusCode(500, $"Failed to initiate the shutdown process: {ex.Message}"); } } private void CleanupResources() { // Console.WriteLine("Cleaning up resources..."); } [HttpGet("nowtime")] public async Task NowTime() { if (_connectionService.centerIsConnected) { HttpResponseMessage response = await _httpClientFactory.CreateClient().GetAsync($"{_connectionService.centerUrl}/core/nowtime"); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); return Ok(content); } else { DateTimeOffset utc = DateTimeOffset.UtcNow; long timeStampUTC = utc.ToUnixTimeMilliseconds(); return Ok(new { time = timeStampUTC }); } } else { DateTimeOffset utc = DateTimeOffset.UtcNow; long timeStampUTC = utc.ToUnixTimeMilliseconds(); return Ok(new { time = timeStampUTC }); } } [HttpGet("health")] public IActionResult Health() { return Ok(new { code=200}); } /// /// 修改Hosts文件的 局域网域名IP映射 /// /// /// [HttpGet("modify-hosts")] public async Task ModifyHosts([FromQuery] string ip ) { try { ServerDevice serverDevice = _memoryCache.Get(Constant._KeyServerDevice); if (serverDevice != null && serverDevice.networks.IsNotEmpty()) { var network = serverDevice.networks.Find(x => ip.Equals(x.ip)); if (network != null && !string.IsNullOrWhiteSpace(network.ip)) { string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "modify_hosts.bat"); string text = await System.IO.File.ReadAllTextAsync(pathBat); // 使用正则表达式替换 IP 地址 string pattern = @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"; string result = Regex.Replace(text, pattern, network.ip); string pathCertificateBat = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "certificate.bat"); await System.IO.File.WriteAllTextAsync(pathCertificateBat, result); return Ok(new { code = 200, msg = "执行成功。", bat = "package/certificate.bat" }); } else { msg = "未找到匹配的IP。"; } } else { msg = "服务端设备未找到,或网卡设备不存在。"; } } catch (Exception ex) { _logger.LogError($"域名IP绑定错误。{ex.Message},{ex.StackTrace}"); msg = $"域名IP绑定错误,{ex.Message}"; } return Ok(new { code = 400, msg = msg }); } [HttpGet("install-certificate")] public IActionResult InstallCertificate() { try { string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "install_certificate.bat"); // 创建一个新的 ProcessStartInfo 对象 ProcessStartInfo startInfo = new ProcessStartInfo { // 指定要执行的 BAT 文件的路径 FileName = "cmd.exe", // 设置命令行参数,使用 /c 表示执行命令后关闭命令提示符窗口 Arguments = $"/c {pathBat}", // 设置是否使用操作系统 shell 启动进程 UseShellExecute = false, // 设置是否创建新的窗口 CreateNoWindow = true, // 重定向标准输出和标准错误输出 RedirectStandardOutput = true, RedirectStandardError = true }; // 创建一个新的 Process 对象 using (Process process = new Process()) { // 将 ProcessStartInfo 对象分配给 Process 对象 process.StartInfo = startInfo; // 启动进程 process.Start(); // 读取标准输出和标准错误输出 string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); // 等待进程执行完成 process.WaitForExit(); // 输出执行结果 if (!string.IsNullOrEmpty(output)) { // Console.WriteLine("标准输出:"); // Console.WriteLine(output); if (output.Contains("successfully", StringComparison.OrdinalIgnoreCase)) { msg = $"证书安装成功!"; code = 200; } else { msg = $"证书安装异常:{output}"; code = 1; } } if (!string.IsNullOrEmpty(error)) { // Console.WriteLine("错误输出:"); // Console.WriteLine(error); msg = $"执行失败:{error}"; code = 2; } } } catch (Exception ex) { _logger.LogError($"证书安装错误。{ex.Message},{ex.StackTrace}"); msg = $"证书安装错误,{ex.Message}"; code = 500; } return Ok(new { code = code, msg = msg }); } [HttpPost("generate-certificate")] public async Task GenerateCertificate(JsonNode json) { try { ServerDevice serverDevice = _memoryCache.Get(Constant._KeyServerDevice); if (serverDevice!=null && serverDevice.networks.IsNotEmpty()) { string mac = $"{json["mac"]}"; var network = serverDevice.networks.Find(x => mac.Equals(x.mac)); if (network!=null) { string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "certificate.bat"); string pathCer = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "certificate.cer"); string text = await System.IO.File.ReadAllTextAsync(pathBat); text = text.Replace("192.168.8.132", network.ip); string pathCertificateBat = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "certificate.bat"); await System.IO.File.WriteAllTextAsync(pathCertificateBat, text); string pathCertificateCer = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "certificate.cer"); System.IO.File.Copy(pathCer, pathCertificateCer); return Ok(new { code = 200, msg = "生成成功。", bat = "package/certificate.bat", cer = "package/certificate.cer" }); } else { msg="未找到匹配的网卡设备。"; } } else { msg="服务端设备未找到,或网卡设备不存在。"; } } catch (Exception ex) { _logger.LogError($"生成证书和自定义域名映射脚本错误。{ex.Message},{ex.StackTrace}"); msg=$"服务端错误,{ex.Message}"; } return Ok(new { code = 400, msg = msg }); } [HttpPost("list-schools")] public async Task ListSchool(JsonNode json) { string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "schools.json"); string schoolText = await System.IO.File.ReadAllTextAsync(filePath); JsonNode? node = schoolText.ToObject(); return Ok(new {code =200, schools= node?["schools"] }); } [HttpPost("bind-school")] public async Task BindSchool(JsonNode json) { string id=$"{json["id"]}"; string name= $"{json["name"]}"; string fp = $"{json["fp"]}"; if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(fp)) { string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "schools.json"); string schoolText = await System.IO.File.ReadAllTextAsync(filePath); List? schools = schoolText.ToObject()?["schools"]?.ToObject>(); School? school = schools?.Find(x => id.Equals(x.id) && name.Equals(x.name)); if (school!=null) { _liteDBFactory.GetLiteDatabase().GetCollection().DeleteAll(); _liteDBFactory.GetLiteDatabase().GetCollection().Upsert(school); IEnumerable schoolsDb = _liteDBFactory.GetLiteDatabase().GetCollection().FindAll(); School? schoolDb = schools?.FirstOrDefault(); _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server); if (server!=null) { server.school = school; } string ip = GetIP(); var device = IndexService.GetDeviceInit(HttpContext, $"{fp}", ip, _memoryCache); int hybrid = 0; _memoryCache.Set(Constant._KeyServerDevice, server); _memoryCache.TryGetValue(Constant._KeyServerCenter, out JsonNode? data); _memoryCache.TryGetValue(Constant._KeyServerDevice, out server); if (data!=null) { hybrid=1; msg="云端服务连接成功!"; return Ok(new { code = 200, msg, data = new { hybrid, device, centerUrl = data["centerUrl"], region = data["region"], ip = data["ip"], nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } }); } else { msg="云端服务未连接!"; return Ok(new { code = 200, msg, data = new { hybrid, device, centerUrl = "", region = "局域网·内网", ip = ip, nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } }); } } else { return Ok(new { code = 400, msg = "绑定失败!" }); } } else { return Ok(new { code = 400, msg = "参数错误!" }); } } [HttpPost("device")] public IActionResult Device(JsonElement json ) { try { string ip= GetIP(); json.TryGetProperty("fp", out JsonElement fp); var device = IndexService.GetDeviceInit(HttpContext, $"{fp}", ip, _memoryCache); int hybrid = 0, notify = 0 ; _memoryCache.TryGetValue(Constant._KeyServerCenter, out JsonNode? data); _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server); if (_connectionService.notifyIsConnected) { notify=1; } if (_connectionService.centerIsConnected) { hybrid=1; } msg="服务端检测成功!"; return Ok(new { code = 200, msg, data = new { notify, hybrid, device, centerUrl = hybrid==1 ? _connectionService.centerUrl : "", notifyUrl = notify==1 ? _connectionService.notifyUrl : "", region = data?["region"], ip = data!=null ? data?["ip"] : ip, nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } }); } catch (Exception ex) { code=500; msg="服务端异常!"; } return Ok(new { code, msg }); } /** { "type":"sms",//qrcode二维码扫码登录:randomCode必传; sms 短信验证登录:randomCode必传,mobile必传 "randomCode", "mobile":"1528377****" } **/ /// /// 登录验证 /// /// /// [HttpPost("login-check")] public async Task LoginCheck(JsonNode json) { try { var type = json["type"]; string? CenterUrl = _configuration.GetValue("ExamServer:CenterUrl"); if (!string.IsNullOrWhiteSpace($"{type}")) { TmdidImplicit? token = null; string x_auth_token = string.Empty; List? schools = null; JsonNode? jsonNode = null; long time = DateTimeOffset.Now.ToUnixTimeMilliseconds(); _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server); School? school = null; if (server!=null) { school = server.school; } switch (true) { //跳过忽略,但是仍然要以访客身份登录 case bool when $"{type}".Equals(ExamConstant.ScopeVisitor): { string id = $"{DateTimeOffset.Now.ToUnixTimeSeconds()}"; string name = $"{school?.name}教师-{Random.Shared.Next(100, 999)}"; x_auth_token = JwtAuthExtension.CreateAuthToken("www.teammodel.cn",id ,name,picture: school?.picture , ExamConstant.JwtSecretKey,ExamConstant.ScopeVisitor,8,schoolID:school?.id,new string[] { "visitor" }, expire: 1); // _memoryCache.Set($"Teacher:{id}", new Teacher { id = id, name = $"{name}", implicit_token = token, picture = null, schools = schools, x_auth_token = x_auth_token }); _liteDBFactory.GetLiteDatabase().GetCollection().Upsert(new Teacher { id = id, name = $"{name}", implicit_token = token, picture = null, schools = schools, x_auth_token = x_auth_token,loginTime=time }); _connectionService.loginToken = x_auth_token; return Ok(new { code = 200,x_auth_token = x_auth_token }); } case bool when $"{type}".Equals("qrcode"): { string randomCode = $"{json["randomCode"]}"; System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; var rc= _memoryCache.Get($"Login:ExamServer:{school?.id}:{randomCode}"); if (!string.IsNullOrWhiteSpace(rc)) { var response = await _httpClientFactory.CreateClient().GetAsync($"{CenterUrl}/core/qrcode/check?randomcode={randomCode}&school={school?.id}&client=ExamServer"); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); if (!string.IsNullOrWhiteSpace(content)) { jsonNode = content.ToObject(); } else { code=400; msg="随机码验证失败"; } } else { code=400; msg="随机码验证错误"; } } else { code=400; msg="二维码过期"; } break; } case bool when $"{type}".Equals("smspin"): { string pin_code = $"{json["pin_code"]}"; string account = $"{json["account"]}"; var response = await _httpClientFactory.CreateClient().PostAsJsonAsync($"{CenterUrl}/core/sendsms/check", new { pin_code, account,school=school?.id }); if (response.IsSuccessStatusCode) { string content = await response.Content.ReadAsStringAsync(); if (!string.IsNullOrWhiteSpace(content)) { jsonNode = content.ToObject(); } else { code=400; msg="短信验证返回结果为空"; } } else { code=400; msg="短信验证错误"; } break; } } if (jsonNode != null && $"{jsonNode["code"]}".Equals("200")) { token =jsonNode["implicit_token"]?.ToObject(); x_auth_token = $"{jsonNode["x_auth_token"]}"; schools =jsonNode["schools"]?.ToObject>(); var jwt = new JwtSecurityToken(token?.id_token); var id = jwt.Payload.Sub; jwt.Payload.TryGetValue("name", out object? name); jwt.Payload.TryGetValue("picture", out object? picture); //_memoryCache.Set($"Teacher:{id}", new Teacher { id=id, name=$"{name}", implicit_token= token, picture=$"{picture}", schools=schools, x_auth_token=x_auth_token }); _liteDBFactory.GetLiteDatabase().GetCollection().Upsert(new Teacher { id=id, name=$"{name}", implicit_token= token, picture=$"{picture}", schools=schools, x_auth_token=x_auth_token ,loginTime=time }); _connectionService.loginToken = x_auth_token; return Ok(new { code=200,/* implicit_token = token, schools = schools , */ x_auth_token = x_auth_token }); } else { code=400; msg="验证失败"; } } else { code=400; msg="参数错误"; } } catch (Exception ex) { code=500; msg="异常错误"; } return Ok(new { code = code,msg }); } /* */ /// /// 登录模式初始化 /// /// [HttpPost("login-init")] public async Task LoginInit(JsonNode json) { var type = json["type"]; string qrcode = string.Empty; string randomcode = ""; _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server); School? school = null; if (server != null) { school = server.school; } if (school != null) { switch (true) { case bool when $"{type}".Equals("qrcode"): { //.NET Core使用SkiaSharp快速生成二维码 https://cloud.tencent.com/developer/article/2336486 // 生成二维码图片 Random random = new Random(); randomcode = $"{random.Next(1000, 9999)}"; string? CenterUrl = _configuration.GetValue("ExamServer:CenterUrl"); CenterUrl = CenterUrl.Equals("https://localhost:5001") ? "https://www.teammodel.cn" : CenterUrl; string content = $"{CenterUrl}/qrcodelogin?randomcode=Login:ExamServer:{school?.id}:{randomcode}&m=%E6%89%AB%E7%A0%81%E7%99%BB%E5%BD%95&o=1"; var str = QRCodeHelper.GenerateQRCode(content, 300, 300, QRCodeHelper.logo); qrcode = $"data:image/png;base64,{str}"; int ttl = 180; string key = $"Login:ExamServer:{school?.id}:{randomcode}"; _memoryCache.Set(key, randomcode, TimeSpan.FromSeconds(ttl)); var device =IndexService.GetDevice(HttpContext,_memoryCache); _memoryCache.Set($"device:{key}", device); try { if (_connectionService.notifyIsConnected && _connectionService.serverDevice!=null) { string url = $"{_connectionService.notifyUrl!}/third/ies/qrcode-login-register"; //扫描登录,远端设备登记临时随机码 await _httpClientFactory.CreateClient().PostAsJsonAsync(url,new { randomcode= key, deviceid = _connectionService .serverDevice.deviceId}); } } catch (Exception e) { _logger.LogError($"{e.Message},{e.StackTrace}"); } return Ok(new { ttl,code = 200, randomCode = randomcode, qrcode, type }); } //case bool when $"{type}".Equals("xqrcode"): // { // // 生成二维码图片 // Random random = new Random(); // randomcode = $"{random.Next(1000, 9999)}"; // string? CenterUrl = _configuration.GetValue("ExamServer:CenterUrl"); // CenterUrl = CenterUrl.Equals("https://localhost:5001") ? "https://www.teammodel.cn" : CenterUrl; // string content = $"{CenterUrl}/qrcodelogin?randomcode=Login:ExamServer:{school?.id}:{randomcode}&m=%E6%89%AB%E7%A0%81%E7%99%BB%E5%BD%95&o=1"; // Bitmap qrCodeImage = QRCodeHelper.GetBitmap(content, 200, 200); // using (MemoryStream stream = new MemoryStream()) // { // qrCodeImage.Save(stream, ImageFormat.Png); // byte[] data = stream.ToArray(); // qrcode = $"data:image/png;base64,{Convert.ToBase64String(data)}"; // } // int ttl = 60; // _memoryCache.Set($"Login:ExamServer:{school?.id}:{randomcode}", randomcode, TimeSpan.FromSeconds(ttl)); // return Ok(new {ttl, code = 200, randomCode = randomcode, qrcode, type }); // } case bool when $"{type}".Equals("smspin"): { int send = 0; if (!string.IsNullOrWhiteSpace($"{json["area"]}") && !string.IsNullOrWhiteSpace($"{json["to"]}")) { string? CenterUrl = _configuration.GetValue("ExamServer:CenterUrl"); string url = $"{CenterUrl}/core/sendsms/pin"; HttpResponseMessage message = await _httpClientFactory.CreateClient().PostAsJsonAsync(url, new { area = json["area"], to = json["to"], lang = "zh-cn" }); if (message.IsSuccessStatusCode) { string content = await message.Content.ReadAsStringAsync(); JsonNode? jsonNode = content?.ToObject(); if (jsonNode != null && int.TryParse($"{jsonNode["send"]}", out int s)) { send = s; } } } return Ok(new { code = 200, send, type }); } } } else if (school == null) { return Ok(new { code = 400,msg="未绑定学校" }); } return Ok(new { code = 400 }); } } }