IndexController.cs 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  1. using IES.ExamServer.Models;
  2. using Microsoft.AspNetCore.Mvc;
  3. using Microsoft.Extensions.Caching.Memory;
  4. using System.Diagnostics;
  5. using System.Text.Json.Nodes;
  6. using System.Text.Json;
  7. using IES.ExamServer.Helper;
  8. using System.IdentityModel.Tokens.Jwt;
  9. using IES.ExamServer.Services;
  10. using IES.ExamServer.DI;
  11. using IES.ExamServer.Helpers;
  12. using IES.ExamLibrary.Models;
  13. using System.Threading.Tasks;
  14. using Hardware.Info;
  15. using System.Net.NetworkInformation;
  16. using System.Text.RegularExpressions;
  17. namespace IES.ExamServer.Controllers
  18. {
  19. [ApiController]
  20. [Route("index")]
  21. public class IndexController : BaseController
  22. {
  23. private readonly IConfiguration _configuration;
  24. private readonly IHttpClientFactory _httpClientFactory;
  25. private readonly IMemoryCache _memoryCache;
  26. private readonly ILogger<IndexController> _logger;
  27. private readonly CenterServiceConnectionService _connectionService;
  28. private readonly LiteDBFactory _liteDBFactory;
  29. private readonly IHostApplicationLifetime _hostApplicationLifetime;
  30. public IndexController(ILogger<IndexController> logger, IConfiguration configuration, IHttpClientFactory httpClientFactory,
  31. IMemoryCache memoryCache,CenterServiceConnectionService connectionService, LiteDBFactory liteDBFactory, IHostApplicationLifetime hostApplicationLifetime)
  32. {
  33. _hostApplicationLifetime = hostApplicationLifetime;
  34. _logger = logger;
  35. _configuration=configuration;
  36. _httpClientFactory=httpClientFactory;
  37. _memoryCache=memoryCache;
  38. _connectionService=connectionService;
  39. _liteDBFactory=liteDBFactory;
  40. }
  41. [HttpGet("hardware")]
  42. public IActionResult hardware()
  43. {
  44. IHardwareInfo? hardwareInfo = null;
  45. try
  46. {
  47. hardwareInfo = new HardwareInfo();
  48. //hardwareInfo.RefreshOperatingSystem();
  49. //.....
  50. //刷新所有硬件信息
  51. hardwareInfo.RefreshAll();
  52. }
  53. catch (Exception ex)
  54. {
  55. Console.WriteLine(ex);
  56. }
  57. Console.WriteLine("输出操作系统信息" + Environment.NewLine);
  58. Console.WriteLine(hardwareInfo.OperatingSystem);
  59. Console.WriteLine("输出内存状态信息" + Environment.NewLine);
  60. Console.WriteLine(hardwareInfo.MemoryStatus);
  61. Console.WriteLine("输出电池信息" + Environment.NewLine);
  62. foreach (var hardware in hardwareInfo.BatteryList)
  63. Console.WriteLine(hardware);
  64. Console.WriteLine("输出 BIOS 信息" + Environment.NewLine);
  65. foreach (var hardware in hardwareInfo.BiosList)
  66. Console.WriteLine(hardware);
  67. Console.WriteLine("输出计算机系统信息" + Environment.NewLine);
  68. foreach (var hardware in hardwareInfo.ComputerSystemList)
  69. Console.WriteLine(hardware);
  70. Console.WriteLine("输出 CPU 信息" + Environment.NewLine);
  71. foreach (var cpu in hardwareInfo.CpuList)
  72. {
  73. Console.WriteLine(cpu);
  74. Console.WriteLine("输出 CPU 核心信息" + Environment.NewLine);
  75. foreach (var cpuCore in cpu.CpuCoreList)
  76. Console.WriteLine(cpuCore);
  77. }
  78. Console.WriteLine("输出磁盘驱动器信息" + Environment.NewLine);
  79. foreach (var drive in hardwareInfo.DriveList)
  80. {
  81. Console.WriteLine(drive);
  82. Console.WriteLine("输出驱动器分区信息" + Environment.NewLine);
  83. foreach (var partition in drive.PartitionList)
  84. {
  85. Console.WriteLine(partition);
  86. Console.WriteLine("输出分区卷信息" + Environment.NewLine);
  87. foreach (var volume in partition.VolumeList)
  88. Console.WriteLine(volume);
  89. }
  90. }
  91. Console.WriteLine("输出键盘信息" + Environment.NewLine);
  92. foreach (var hardware in hardwareInfo.KeyboardList)
  93. Console.WriteLine(hardware);
  94. Console.WriteLine("输出内存信息" + Environment.NewLine);
  95. foreach (var hardware in hardwareInfo.MemoryList)
  96. Console.WriteLine(hardware);
  97. Console.WriteLine("输出显示器信息" + Environment.NewLine);
  98. foreach (var hardware in hardwareInfo.MonitorList)
  99. Console.WriteLine(hardware);
  100. Console.WriteLine("输出主板信息" + Environment.NewLine);
  101. foreach (var hardware in hardwareInfo.MotherboardList)
  102. Console.WriteLine(hardware);
  103. Console.WriteLine("输出鼠标信息" + Environment.NewLine);
  104. foreach (var hardware in hardwareInfo.MouseList)
  105. Console.WriteLine(hardware);
  106. Console.WriteLine("输出网络适配器信息" + Environment.NewLine);
  107. foreach (var hardware in hardwareInfo.NetworkAdapterList)
  108. Console.WriteLine(hardware);
  109. Console.WriteLine("输出打印机信息" + Environment.NewLine);
  110. foreach (var hardware in hardwareInfo.PrinterList)
  111. Console.WriteLine(hardware);
  112. Console.WriteLine("输出声音设备信息" + Environment.NewLine);
  113. foreach (var hardware in hardwareInfo.SoundDeviceList)
  114. Console.WriteLine(hardware);
  115. Console.WriteLine("输出显卡信息" + Environment.NewLine);
  116. foreach (var hardware in hardwareInfo.VideoControllerList)
  117. Console.WriteLine(hardware);
  118. Console.WriteLine("输出 Ethernet 类型并且状态为 Up 的本地 IPv4 地址" + Environment.NewLine);
  119. foreach (var address in HardwareInfo.GetLocalIPv4Addresses(NetworkInterfaceType.Ethernet, OperationalStatus.Up))
  120. Console.WriteLine(address);
  121. Console.WriteLine();
  122. Console.WriteLine("输出 Wireless80211 类型的本地 IPv4 地址" + Environment.NewLine);
  123. foreach (var address in HardwareInfo.GetLocalIPv4Addresses(NetworkInterfaceType.Wireless80211))
  124. Console.WriteLine(address);
  125. Console.WriteLine();
  126. Console.WriteLine("输出状态为 Up 的网络接口卡的本地 IPv4 地址" + Environment.NewLine);
  127. foreach (var address in HardwareInfo.GetLocalIPv4Addresses(OperationalStatus.Up))
  128. Console.WriteLine(address);
  129. Console.WriteLine();
  130. Console.WriteLine("输出所有网络接口卡的本地 IPv4 地址" + Environment.NewLine);
  131. foreach (var address in HardwareInfo.GetLocalIPv4Addresses())
  132. Console.WriteLine(address);
  133. Console.WriteLine();
  134. Console.WriteLine("输出计算机当前时间" + Environment.NewLine);
  135. Console.WriteLine(DateTime.Now);
  136. Console.WriteLine("输出系统启动时间" + Environment.NewLine);
  137. Console.WriteLine(Environment.TickCount);
  138. return Ok();
  139. }
  140. /// <summary>
  141. /// 关闭当前进程的接口
  142. /// </summary>
  143. /// <returns></returns>
  144. [HttpGet("music")]
  145. public async Task<IActionResult> Music()
  146. {
  147. string e = await System.IO.File.ReadAllTextAsync("F:\\cer\\e.txt");
  148. e=AESHelper.Decrypt(e);
  149. string d = await System.IO.File.ReadAllTextAsync("F:\\cer\\d.txt");
  150. d=AESHelper.Decrypt(d);
  151. //https://musicapi.winteach.cn/api/v1/musicLocalCache/auth/sts get
  152. //响应内容:
  153. //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=
  154. /*
  155. {
  156. "code": 200,
  157. "success": 1,
  158. "time": "2025-02-23 21:37:02",
  159. "msg": "\u64CD\u4F5C\u6210\u529F",
  160. "data": {
  161. "accessKeyId": "STS.NUsHMfsmRf9koezhD3JHsbDSq",
  162. "accessKeySecret": "DdUrM2f137i6kmg7Nk3EsV9tzJrTRWZnDvjfADKBUmoZ",
  163. "bucket": "teammodel",
  164. "ossEndpoint": "oss-cn-chengdu.aliyuncs.com",
  165. "securityToken": "CAISwAJ1q6Ft5B2yfSjIr5bGA/fSnrJz0fuAbUPLjERmRsdfjYH4kzz2IHhMe3hrA\u002B4YsvU3nGBW7PsYlqNJQppiXlf4YNBstlbIbPIaOdivgde8yJBZor/HcDHhJnyW9cvWZPqDP7G5U/yxalfCuzZuyL/hD1uLVECkNpv74vwOLK5gPG\u002BCYCFBGc1dKyZ7tcYeLgGxD/u2NQPwiWeiZygB\u002BCgE0D8vtPTkmZPDs0eE1QKkkNV4/dqhfsKWCOB3J4p6XtuP2\u002Bh7S7HMyiY46WIRrP8p3fcep2mb74nFUwcLvk\u002BcUfDd99p0NxN0fbQqkS2SJSl/LJeS086kdOSfo34lVYk92BSCRz5EY\u002BXurEK45HtIlKd6SpU86Kr7ErPfnW3aj/y12q3k1bTfBIEOJ\u002BLiKFX4bpvD0jSsxm\u002BMzX/TjsleuRqAAQESLkjMgQqt24ftPT2C8DVe2hJ\u002BPIDPN60GaKfzXipCwtKpe2I33Bdz04US8s3Rh5TbD0MmG0K0Ms8/8rNr3z\u002B12OXfuzltmkIUHImV8kmP1omIlYxOvDrsKkabhah0LWrGQ7DLIWz\u002BGxfU82DjsyQ4TDcC4Xw/2Hu3l8ma1scuIAA=",
  166. "region": "oss-cn-chengdu",
  167. "routeType": "RamOssTest",
  168. "expiration": "2025-02-23T14:37:02Z"
  169. }
  170. }
  171. */
  172. 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=");
  173. //thirdLocalCacheConfig
  174. //请求加密: yWm8geklutVm87JFcvA6WxOoCMQQSyXpr28uJ5d7lVSDU3CQpgPR3q/Clk7YPYeK
  175. //响应解密 : T6RiMezIVman5LYBlSMDVkd20Jrca/M/fguhdGlKyiqW+6HSs0K5SWT2hXaGb5O740ew8U1tQF0ac9F33RpLQV1MmceaCvnQCrx8AJCpF4hx3SlQnX2Tt5o3JZIN3MJDz/XNr/ipGIl+3f36y3YSdMbInLx2coxnJtKfLoW/Cu+XK6VvyHYiavd8uk6xkIXpGDzgHfrw6oqjnknWm2fXBaqlAdnx8l7p4aZfXTVjqJAmJQuUPDId3H2LI7w1HRwq6L3OvXdNvF9X0rFYWATKca1ABB/rqRYNaO9ZtAJ3tMCJpY3AmU5lc/ozikbzu+2qVKdN9rKUtt2Xl2Yqm9eN4R6Sr1yf98eKDqJF/Xk9h8gxS3qZYGP6rkoJSecWpA1UiQhZOu6n2/FKPZsj8FdbES8dEGQjxl3cFme8eiGU4urGH+in4VsBpE3FGjdHkpxxOrzBzID8KtvzqF77f0WK7utkLN1/yBSidwe6YB29uETzXiNBe0iqjHdZbmrjmkO+
  176. //thirdLocalCacheConfig
  177. //请求:L6nzwg2xImbjoqyIZgaZ/w==
  178. //解密:T6RiMezIVman5LYBlSMDVkd20Jrca/M/fguhdGlKyiqUHPIitU/Lb9N1WxTC+Gccw0Jima9mdCFyjic883n8FEnAq89rkDNUwRbvxI8IDzcujTnLF3EBGujS5qKRj836HWDc4g+n3QLnSKLRieUxi/ToG23yX1syZpBiWZz28qNJu5YuGl4Iy5/9MEyQOe8xmIpvrU6Se3NbRmITSJrnAHV2ByDWSc4oq/JFYr3CpJvL+t9oJ5yABgQH7UrXaWFrkXIvEQIKu9JVAy2Jsr+pb5az0cLIlqppprt8TrtLHxfxxTJS7NMvmn98lnEjxBBZcXKdGhgicAmuUyvpA16BLlui1UW/Ub2St9f2oOrT9+SnidtvP0yt9WoJ119Ls6trWelRpcBeSwg/bNuID0qsG1Wyltgk/UiqdLASE/54XmngYmP+rR3m9rxl5uqJ+/a8FxwaFmC8l6SWXC3X4XKCuQzuedE0yFTXGFSANDPgTW7QlXI0xYpEWSMsT9oXR51N
  179. //thirdLocalCacheConfig
  180. //请求:l4/OnnDqsVaprrMwLQYUqS/B1BdBv5QYaGOvqwDdFvg=
  181. //解密:T6RiMezIVman5LYBlSMDVkd20Jrca/M/fguhdGlKyipAsCbSWRX7XfCnLNoQZUI3q9pdC2powS0VPMlIPufIdO3ch0Y15x1INJJNI/1m8xem72F5Oe+wWb0gnc+Sl3tisXsny+mA7k/LnGOOzr/6NC44ETAwd+hP17XoLYbaiBvXKE10ifVtVrSCkj5Zo+4QDK2+up6WSbePVkss9e9QZEgP3VYdlMlkiSsAc/ZN2SdkrPjzhu0nxSt3lYCYkS30XejBr6qC8GzrJ7OVWHdUjZKt4Rf5PHHE0AOWPxxK4bKtOOD6p1oCWJIRWqh0i/sY8NtbO0fJw/YtnWuL6Y0pJmfmn5gb8uVsdX46rk5cipLSHUjesnLZ3L7eiEgXvYUrZrLBP3jkpO3GvaP307GvjStlcK600z9k9AEQaprOm+nDoeEwx5u+5c0sakRvOrENYZ9BqfOaTJUvSSgarWbgXqrA9fQp6CE+8rXKJ9IzybudsVa3nr+3IJA9X3lG1XkT
  182. // string ens = AESHelper.Encrypt("{}");
  183. // string des = AESHelper.Decrypt("L6nzwg2xImbjoqyIZgaZ/w==");// {} 心跳检测
  184. // string des = AESHelper.Decrypt("yWm8geklutVm87JFcvA6WxOoCMQQSyXpr28uJ5d7lVSDU3CQpgPR3q/Clk7YPYeK");// {"localCacheIp":"https://192.168.56.1:7071"} 设置本地服务的IP地址
  185. string des = AESHelper.Decrypt("l4/OnnDqsVaprrMwLQYUqS/B1BdBv5QYaGOvqwDdFvg=");//{"cacheStatus":1}//设置本地缓存状态
  186. string ens = AESHelper.Encrypt(des);
  187. var (content,code)= await IndexService.GetMusicServer_thirdLocalCacheConfig(_httpClientFactory, _connectionService, ens);
  188. content=content.Replace("\"", "");
  189. content= AESHelper.Decrypt(content);
  190. /*
  191. {
  192. "code": 200,
  193. "success": 1,
  194. "time": "2025-02-23 21:17:07",
  195. "msg": "操作成功",
  196. "data": {
  197. "id": 95,
  198. "name": "醍摩豆研发学校",
  199. "contactName": "",
  200. "phoneNumber": "habook",
  201. "code": "ha",
  202. "type": "1",
  203. "serialNumber": 1,
  204. "province": "四川省",
  205. "city": "成都市",
  206. "county": "锦江区",
  207. "address": "",
  208. "localCacheIp": "https://192.168.56.1:7071",
  209. "cacheStatus": 1,
  210. "heartTime": "2025-02-23T21:16:06.000+08:00"
  211. }
  212. }
  213. */
  214. return Ok(content);
  215. }
  216. private static bool _isShuttingDown = false;
  217. /// <summary>
  218. /// 关闭当前进程的接口
  219. /// </summary>
  220. /// <returns></returns>
  221. [HttpGet("shutdown")]
  222. public IActionResult Shutdown(int delay = 200)
  223. {
  224. try
  225. {
  226. if (_isShuttingDown)
  227. {
  228. return Ok("Shutdown process is already initiated.");
  229. }
  230. _isShuttingDown = true;
  231. //_ = Task.Delay(delay).ContinueWith(_ =>
  232. //{
  233. // try
  234. // {
  235. // // 关闭前清理资源
  236. // CleanupResources();
  237. // // 停止应用程序
  238. // _hostApplicationLifetime.StopApplication();
  239. // }
  240. // catch (Exception ex)
  241. // {
  242. // Console.Error.WriteLine($"Error during shutdown: {ex.Message}");
  243. // }
  244. //});
  245. try
  246. {
  247. // 关闭前清理资源
  248. CleanupResources();
  249. // 停止应用程序
  250. _hostApplicationLifetime.StopApplication();
  251. }
  252. catch (Exception ex)
  253. {
  254. Console.Error.WriteLine($"Error during shutdown: {ex.Message}");
  255. }
  256. return Ok("Shutdown process has been initiated.");
  257. }
  258. catch (Exception ex)
  259. {
  260. return StatusCode(500, $"Failed to initiate the shutdown process: {ex.Message}");
  261. }
  262. }
  263. private void CleanupResources()
  264. {
  265. // Console.WriteLine("Cleaning up resources...");
  266. }
  267. [HttpGet("nowtime")]
  268. public async Task<IActionResult> NowTime()
  269. {
  270. if (_connectionService.centerIsConnected)
  271. {
  272. HttpResponseMessage response = await _httpClientFactory.CreateClient().GetAsync($"{_connectionService.centerUrl}/core/nowtime");
  273. if (response.IsSuccessStatusCode)
  274. {
  275. string content = await response.Content.ReadAsStringAsync();
  276. return Ok(content);
  277. }
  278. else {
  279. DateTimeOffset utc = DateTimeOffset.UtcNow;
  280. long timeStampUTC = utc.ToUnixTimeMilliseconds();
  281. return Ok(new { time = timeStampUTC });
  282. }
  283. }
  284. else {
  285. DateTimeOffset utc = DateTimeOffset.UtcNow;
  286. long timeStampUTC = utc.ToUnixTimeMilliseconds();
  287. return Ok(new { time = timeStampUTC });
  288. }
  289. }
  290. [HttpGet("health")]
  291. public IActionResult Health()
  292. {
  293. return Ok(new { code=200});
  294. }
  295. /// <summary>
  296. /// 修改Hosts文件的 局域网域名IP映射
  297. /// </summary>
  298. /// <param name="ip"></param>
  299. /// <returns></returns>
  300. [HttpGet("modify-hosts")]
  301. public async Task<IActionResult> ModifyHosts([FromQuery] string ip )
  302. {
  303. try
  304. {
  305. ServerDevice serverDevice = _memoryCache.Get<ServerDevice>(Constant._KeyServerDevice);
  306. if (serverDevice != null && serverDevice.networks.IsNotEmpty())
  307. {
  308. var network = serverDevice.networks.Find(x => ip.Equals(x.ip));
  309. if (network != null && !string.IsNullOrWhiteSpace(network.ip))
  310. {
  311. string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "modify_hosts.bat");
  312. string text = await System.IO.File.ReadAllTextAsync(pathBat);
  313. // 使用正则表达式替换 IP 地址
  314. string pattern = @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b";
  315. string result = Regex.Replace(text, pattern, network.ip);
  316. string pathCertificateBat = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "certificate.bat");
  317. await System.IO.File.WriteAllTextAsync(pathCertificateBat, result);
  318. return Ok(new { code = 200, msg = "执行成功。", bat = "package/certificate.bat" });
  319. }
  320. else
  321. {
  322. msg = "未找到匹配的IP。";
  323. }
  324. }
  325. else
  326. {
  327. msg = "服务端设备未找到,或网卡设备不存在。";
  328. }
  329. }
  330. catch (Exception ex)
  331. {
  332. _logger.LogError($"域名IP绑定错误。{ex.Message},{ex.StackTrace}");
  333. msg = $"域名IP绑定错误,{ex.Message}";
  334. }
  335. return Ok(new { code = 400, msg = msg });
  336. }
  337. [HttpGet("install-certificate")]
  338. public IActionResult InstallCertificate()
  339. {
  340. try
  341. {
  342. string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "install_certificate.bat");
  343. // 创建一个新的 ProcessStartInfo 对象
  344. ProcessStartInfo startInfo = new ProcessStartInfo
  345. {
  346. // 指定要执行的 BAT 文件的路径
  347. FileName = "cmd.exe",
  348. // 设置命令行参数,使用 /c 表示执行命令后关闭命令提示符窗口
  349. Arguments = $"/c {pathBat}",
  350. // 设置是否使用操作系统 shell 启动进程
  351. UseShellExecute = false,
  352. // 设置是否创建新的窗口
  353. CreateNoWindow = true,
  354. // 重定向标准输出和标准错误输出
  355. RedirectStandardOutput = true,
  356. RedirectStandardError = true
  357. };
  358. // 创建一个新的 Process 对象
  359. using (Process process = new Process())
  360. {
  361. // 将 ProcessStartInfo 对象分配给 Process 对象
  362. process.StartInfo = startInfo;
  363. // 启动进程
  364. process.Start();
  365. // 读取标准输出和标准错误输出
  366. string output = process.StandardOutput.ReadToEnd();
  367. string error = process.StandardError.ReadToEnd();
  368. // 等待进程执行完成
  369. process.WaitForExit();
  370. // 输出执行结果
  371. if (!string.IsNullOrEmpty(output))
  372. {
  373. // Console.WriteLine("标准输出:");
  374. // Console.WriteLine(output);
  375. if (output.Contains("successfully", StringComparison.OrdinalIgnoreCase))
  376. {
  377. msg = $"证书安装成功!";
  378. code = 200;
  379. }
  380. else {
  381. msg = $"证书安装异常:{output}";
  382. code = 1;
  383. }
  384. }
  385. if (!string.IsNullOrEmpty(error))
  386. {
  387. // Console.WriteLine("错误输出:");
  388. // Console.WriteLine(error);
  389. msg = $"执行失败:{error}";
  390. code = 2;
  391. }
  392. }
  393. }
  394. catch (Exception ex)
  395. {
  396. _logger.LogError($"证书安装错误。{ex.Message},{ex.StackTrace}");
  397. msg = $"证书安装错误,{ex.Message}";
  398. code = 500;
  399. }
  400. return Ok(new { code = code, msg = msg });
  401. }
  402. [HttpPost("generate-certificate")]
  403. public async Task<IActionResult> GenerateCertificate(JsonNode json)
  404. {
  405. try {
  406. ServerDevice serverDevice = _memoryCache.Get<ServerDevice>(Constant._KeyServerDevice);
  407. if (serverDevice!=null && serverDevice.networks.IsNotEmpty())
  408. {
  409. string mac = $"{json["mac"]}";
  410. var network = serverDevice.networks.Find(x => mac.Equals(x.mac));
  411. if (network!=null)
  412. {
  413. string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "certificate.bat");
  414. string pathCer = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "certificate.cer");
  415. string text = await System.IO.File.ReadAllTextAsync(pathBat);
  416. text = text.Replace("192.168.8.132", network.ip);
  417. string pathCertificateBat = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "certificate.bat");
  418. await System.IO.File.WriteAllTextAsync(pathCertificateBat, text);
  419. string pathCertificateCer = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "certificate.cer");
  420. System.IO.File.Copy(pathCer, pathCertificateCer);
  421. return Ok(new { code = 200, msg = "生成成功。", bat = "package/certificate.bat", cer = "package/certificate.cer" });
  422. }
  423. else
  424. {
  425. msg="未找到匹配的网卡设备。";
  426. }
  427. }
  428. else
  429. {
  430. msg="服务端设备未找到,或网卡设备不存在。";
  431. }
  432. } catch (Exception ex)
  433. {
  434. _logger.LogError($"生成证书和自定义域名映射脚本错误。{ex.Message},{ex.StackTrace}");
  435. msg=$"服务端错误,{ex.Message}";
  436. }
  437. return Ok(new { code = 400, msg = msg });
  438. }
  439. [HttpPost("list-schools")]
  440. public async Task<IActionResult> ListSchool(JsonNode json)
  441. {
  442. string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "schools.json");
  443. string schoolText = await System.IO.File.ReadAllTextAsync(filePath);
  444. JsonNode? node = schoolText.ToObject<JsonNode>();
  445. return Ok(new {code =200, schools= node?["schools"] });
  446. }
  447. [HttpPost("bind-school")]
  448. public async Task<IActionResult> BindSchool(JsonNode json)
  449. {
  450. string id=$"{json["id"]}";
  451. string name= $"{json["name"]}";
  452. string fp = $"{json["fp"]}";
  453. if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(fp))
  454. {
  455. string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "schools.json");
  456. string schoolText = await System.IO.File.ReadAllTextAsync(filePath);
  457. List<School>? schools = schoolText.ToObject<JsonNode>()?["schools"]?.ToObject<List<School>>();
  458. School? school = schools?.Find(x => id.Equals(x.id) && name.Equals(x.name));
  459. if (school!=null)
  460. {
  461. _liteDBFactory.GetLiteDatabase().GetCollection<School>().DeleteAll();
  462. _liteDBFactory.GetLiteDatabase().GetCollection<School>().Upsert(school);
  463. IEnumerable<School> schoolsDb = _liteDBFactory.GetLiteDatabase().GetCollection<School>().FindAll();
  464. School? schoolDb = schools?.FirstOrDefault();
  465. _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
  466. if (server!=null)
  467. {
  468. server.school = school;
  469. }
  470. string ip = GetIP();
  471. var device = IndexService.GetDeviceInit(HttpContext, $"{fp}", ip, _memoryCache);
  472. int hybrid = 0;
  473. _memoryCache.Set(Constant._KeyServerDevice, server);
  474. _memoryCache.TryGetValue(Constant._KeyServerCenter, out JsonNode? data);
  475. _memoryCache.TryGetValue(Constant._KeyServerDevice, out server);
  476. if (data!=null)
  477. {
  478. hybrid=1;
  479. msg="云端服务连接成功!";
  480. return Ok(new { code = 200, msg, data = new { hybrid, device, centerUrl = data["centerUrl"], region = data["region"], ip = data["ip"], nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } });
  481. }
  482. else
  483. {
  484. msg="云端服务未连接!";
  485. return Ok(new { code = 200, msg, data = new { hybrid, device, centerUrl = "", region = "局域网·内网", ip = ip, nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } });
  486. }
  487. }
  488. else
  489. {
  490. return Ok(new { code = 400, msg = "绑定失败!" });
  491. }
  492. }
  493. else {
  494. return Ok(new { code = 400, msg = "参数错误!" });
  495. }
  496. }
  497. [HttpPost("device")]
  498. public IActionResult Device(JsonElement json )
  499. {
  500. try
  501. {
  502. string ip= GetIP();
  503. json.TryGetProperty("fp", out JsonElement fp);
  504. var device = IndexService.GetDeviceInit(HttpContext, $"{fp}", ip, _memoryCache);
  505. int hybrid = 0, notify = 0 ;
  506. _memoryCache.TryGetValue(Constant._KeyServerCenter, out JsonNode? data);
  507. _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
  508. if (_connectionService.notifyIsConnected)
  509. {
  510. notify=1;
  511. }
  512. if (_connectionService.centerIsConnected)
  513. {
  514. hybrid=1;
  515. }
  516. msg="服务端检测成功!";
  517. return Ok(new { code = 200, msg, data = new {
  518. notify,
  519. hybrid,
  520. device,
  521. centerUrl = hybrid==1 ? _connectionService.centerUrl : "",
  522. notifyUrl = notify==1 ? _connectionService.notifyUrl : "",
  523. region = data?["region"],
  524. ip = data!=null ? data?["ip"] : ip,
  525. nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
  526. server
  527. } });
  528. }
  529. catch (Exception ex)
  530. {
  531. code=500;
  532. msg="服务端异常!";
  533. }
  534. return Ok(new { code, msg });
  535. }
  536. /**
  537. {
  538. "type":"sms",//qrcode二维码扫码登录:randomCode必传; sms 短信验证登录:randomCode必传,mobile必传
  539. "randomCode",
  540. "mobile":"1528377****"
  541. }
  542. **/
  543. /// <summary>
  544. /// 登录验证
  545. /// </summary>
  546. /// <param name="randomCode"></param>
  547. /// <returns></returns>
  548. [HttpPost("login-check")]
  549. public async Task<IActionResult> LoginCheck(JsonNode json)
  550. {
  551. try
  552. {
  553. var type = json["type"];
  554. string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  555. if (!string.IsNullOrWhiteSpace($"{type}"))
  556. {
  557. TmdidImplicit? token = null;
  558. string x_auth_token = string.Empty;
  559. List<School>? schools = null;
  560. JsonNode? jsonNode = null;
  561. long time = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  562. _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
  563. School? school = null;
  564. if (server!=null)
  565. {
  566. school = server.school;
  567. }
  568. switch (true)
  569. {
  570. //跳过忽略,但是仍然要以访客身份登录
  571. case bool when $"{type}".Equals(ExamConstant.ScopeVisitor):
  572. {
  573. string id = $"{DateTimeOffset.Now.ToUnixTimeSeconds()}";
  574. string name = $"{school?.name}教师-{Random.Shared.Next(100, 999)}";
  575. x_auth_token = JwtAuthExtension.CreateAuthToken("www.teammodel.cn",id ,name,picture: school?.picture
  576. , ExamConstant.JwtSecretKey,ExamConstant.ScopeVisitor,8,schoolID:school?.id,new string[] { "visitor" }, expire: 1);
  577. // _memoryCache.Set($"Teacher:{id}", new Teacher { id = id, name = $"{name}", implicit_token = token, picture = null, schools = schools, x_auth_token = x_auth_token });
  578. _liteDBFactory.GetLiteDatabase().GetCollection<Teacher>().Upsert(new Teacher { id = id, name = $"{name}", implicit_token = token, picture = null, schools = schools, x_auth_token = x_auth_token,loginTime=time });
  579. _connectionService.loginToken = x_auth_token;
  580. return Ok(new { code = 200,x_auth_token = x_auth_token });
  581. }
  582. case bool when $"{type}".Equals("qrcode"):
  583. {
  584. string randomCode = $"{json["randomCode"]}";
  585. System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
  586. var rc= _memoryCache.Get<string>($"Login:ExamServer:{school?.id}:{randomCode}");
  587. if (!string.IsNullOrWhiteSpace(rc))
  588. {
  589. var response = await _httpClientFactory.CreateClient().GetAsync($"{CenterUrl}/core/qrcode/check?randomcode={randomCode}&school={school?.id}&client=ExamServer");
  590. if (response.IsSuccessStatusCode)
  591. {
  592. string content = await response.Content.ReadAsStringAsync();
  593. if (!string.IsNullOrWhiteSpace(content))
  594. {
  595. jsonNode = content.ToObject<JsonNode>();
  596. }
  597. else
  598. {
  599. code=400;
  600. msg="随机码验证失败";
  601. }
  602. }
  603. else
  604. {
  605. code=400;
  606. msg="随机码验证错误";
  607. }
  608. }
  609. else
  610. {
  611. code=400;
  612. msg="二维码过期";
  613. }
  614. break;
  615. }
  616. case bool when $"{type}".Equals("smspin"):
  617. {
  618. string pin_code = $"{json["pin_code"]}";
  619. string account = $"{json["account"]}";
  620. var response = await _httpClientFactory.CreateClient().PostAsJsonAsync($"{CenterUrl}/core/sendsms/check", new { pin_code, account,school=school?.id });
  621. if (response.IsSuccessStatusCode)
  622. {
  623. string content = await response.Content.ReadAsStringAsync();
  624. if (!string.IsNullOrWhiteSpace(content))
  625. {
  626. jsonNode = content.ToObject<JsonNode>();
  627. }
  628. else
  629. {
  630. code=400;
  631. msg="短信验证返回结果为空";
  632. }
  633. }
  634. else
  635. {
  636. code=400;
  637. msg="短信验证错误";
  638. }
  639. break;
  640. }
  641. }
  642. if (jsonNode != null && $"{jsonNode["code"]}".Equals("200"))
  643. {
  644. token =jsonNode["implicit_token"]?.ToObject<TmdidImplicit>();
  645. x_auth_token = $"{jsonNode["x_auth_token"]}";
  646. schools =jsonNode["schools"]?.ToObject<List<School>>();
  647. var jwt = new JwtSecurityToken(token?.id_token);
  648. var id = jwt.Payload.Sub;
  649. jwt.Payload.TryGetValue("name", out object? name);
  650. jwt.Payload.TryGetValue("picture", out object? picture);
  651. //_memoryCache.Set($"Teacher:{id}", new Teacher { id=id, name=$"{name}", implicit_token= token, picture=$"{picture}", schools=schools, x_auth_token=x_auth_token });
  652. _liteDBFactory.GetLiteDatabase().GetCollection<Teacher>().Upsert(new Teacher { id=id, name=$"{name}", implicit_token= token, picture=$"{picture}", schools=schools, x_auth_token=x_auth_token ,loginTime=time });
  653. _connectionService.loginToken = x_auth_token;
  654. return Ok(new { code=200,/* implicit_token = token, schools = schools , */ x_auth_token = x_auth_token });
  655. }
  656. else
  657. {
  658. code=400;
  659. msg="验证失败";
  660. }
  661. }
  662. else
  663. {
  664. code=400;
  665. msg="参数错误";
  666. }
  667. }
  668. catch (Exception ex)
  669. {
  670. code=500;
  671. msg="异常错误";
  672. }
  673. return Ok(new { code = code,msg });
  674. }
  675. /*
  676. */
  677. /// <summary>
  678. /// 登录模式初始化
  679. /// </summary>
  680. /// <returns></returns>
  681. [HttpPost("login-init")]
  682. public async Task<IActionResult> LoginInit(JsonNode json)
  683. {
  684. var type = json["type"];
  685. string qrcode = string.Empty;
  686. string randomcode = "";
  687. _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
  688. School? school = null;
  689. if (server != null)
  690. {
  691. school = server.school;
  692. }
  693. if (school != null)
  694. {
  695. switch (true)
  696. {
  697. case bool when $"{type}".Equals("qrcode"):
  698. {
  699. //.NET Core使用SkiaSharp快速生成二维码 https://cloud.tencent.com/developer/article/2336486
  700. // 生成二维码图片
  701. Random random = new Random();
  702. randomcode = $"{random.Next(1000, 9999)}";
  703. string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  704. CenterUrl = CenterUrl.Equals("https://localhost:5001") ? "https://www.teammodel.cn" : CenterUrl;
  705. 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";
  706. var str = QRCodeHelper.GenerateQRCode(content, 300, 300, QRCodeHelper.logo);
  707. qrcode = $"data:image/png;base64,{str}";
  708. int ttl = 180;
  709. string key = $"Login:ExamServer:{school?.id}:{randomcode}";
  710. _memoryCache.Set(key, randomcode, TimeSpan.FromSeconds(ttl));
  711. var device =IndexService.GetDevice(HttpContext,_memoryCache);
  712. _memoryCache.Set($"device:{key}", device);
  713. try {
  714. if (_connectionService.notifyIsConnected && _connectionService.serverDevice!=null)
  715. {
  716. string url = $"{_connectionService.notifyUrl!}/third/ies/qrcode-login-register";
  717. //扫描登录,远端设备登记临时随机码
  718. await _httpClientFactory.CreateClient().PostAsJsonAsync(url,new { randomcode= key, deviceid = _connectionService .serverDevice.deviceId});
  719. }
  720. } catch (Exception e) {
  721. _logger.LogError($"{e.Message},{e.StackTrace}");
  722. }
  723. return Ok(new { ttl,code = 200, randomCode = randomcode, qrcode, type });
  724. }
  725. //case bool when $"{type}".Equals("xqrcode"):
  726. // {
  727. // // 生成二维码图片
  728. // Random random = new Random();
  729. // randomcode = $"{random.Next(1000, 9999)}";
  730. // string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  731. // CenterUrl = CenterUrl.Equals("https://localhost:5001") ? "https://www.teammodel.cn" : CenterUrl;
  732. // 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";
  733. // Bitmap qrCodeImage = QRCodeHelper.GetBitmap(content, 200, 200);
  734. // using (MemoryStream stream = new MemoryStream())
  735. // {
  736. // qrCodeImage.Save(stream, ImageFormat.Png);
  737. // byte[] data = stream.ToArray();
  738. // qrcode = $"data:image/png;base64,{Convert.ToBase64String(data)}";
  739. // }
  740. // int ttl = 60;
  741. // _memoryCache.Set($"Login:ExamServer:{school?.id}:{randomcode}", randomcode, TimeSpan.FromSeconds(ttl));
  742. // return Ok(new {ttl, code = 200, randomCode = randomcode, qrcode, type });
  743. // }
  744. case bool when $"{type}".Equals("smspin"):
  745. {
  746. int send = 0;
  747. if (!string.IsNullOrWhiteSpace($"{json["area"]}") && !string.IsNullOrWhiteSpace($"{json["to"]}"))
  748. {
  749. string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  750. string url = $"{CenterUrl}/core/sendsms/pin";
  751. HttpResponseMessage message = await _httpClientFactory.CreateClient().PostAsJsonAsync(url, new { area = json["area"], to = json["to"], lang = "zh-cn" });
  752. if (message.IsSuccessStatusCode)
  753. {
  754. string content = await message.Content.ReadAsStringAsync();
  755. JsonNode? jsonNode = content?.ToObject<JsonNode>();
  756. if (jsonNode != null && int.TryParse($"{jsonNode["send"]}", out int s))
  757. {
  758. send = s;
  759. }
  760. }
  761. }
  762. return Ok(new { code = 200, send, type });
  763. }
  764. }
  765. }
  766. else if (school == null)
  767. {
  768. return Ok(new { code = 400,msg="未绑定学校" });
  769. }
  770. return Ok(new { code = 400 });
  771. }
  772. }
  773. }