IndexController.cs 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  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. /// 更新学校
  297. /// </summary>
  298. /// <param name="ip"></param>
  299. /// <returns></returns>
  300. [HttpGet("update-schools")]
  301. public async Task<IActionResult> UpdateSchools()
  302. {
  303. try {
  304. var httpClient = _httpClientFactory.CreateClient();
  305. httpClient.Timeout = TimeSpan.FromSeconds(10);
  306. HttpResponseMessage message = await httpClient.GetAsync("https://teammodelos.blob.core.chinacloudapi.cn/0-public/schools.json");
  307. if (message.IsSuccessStatusCode)
  308. {
  309. // 读取响应内容
  310. string content = await message.Content.ReadAsStringAsync();
  311. // 保存文件的路径
  312. string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "schools.json");
  313. // 确保目录存在
  314. Directory.CreateDirectory(Path.GetDirectoryName(filePath)!);
  315. // 将内容写入文件
  316. await System.IO.File.WriteAllTextAsync(filePath, content);
  317. return Ok(new { code=200,msg="更新成功"});
  318. }
  319. else
  320. {
  321. return Ok(new { code = (int)message.StatusCode, msg = "更新成功" });
  322. }
  323. } catch (Exception ex) {
  324. return Ok(new { code =500, msg = ex.Message });
  325. }
  326. }
  327. /// <summary>
  328. /// 修改Hosts文件的 局域网域名IP映射
  329. /// </summary>
  330. /// <param name="ip"></param>
  331. /// <returns></returns>
  332. [HttpGet("modify-hosts")]
  333. public async Task<IActionResult> ModifyHosts([FromQuery] string? ip=null )
  334. {
  335. try
  336. {
  337. var data = await IndexService. ModifyHosts(ip,_memoryCache,_liteDBFactory,_connectionService);
  338. return Ok(new { data.code,data.code_zip,data.code_cer,data.code_hosts,data.msg});
  339. }
  340. catch (Exception ex)
  341. {
  342. code = 500;
  343. _logger.LogError($"域名IP绑定错误。{ex.Message},{ex.StackTrace}");
  344. msg = $"域名IP绑定错误,{ex.Message}";
  345. }
  346. return Ok(new { code = 400, msg = msg });
  347. }
  348. /// <summary>
  349. /// 强制重新安装证书
  350. /// </summary>
  351. /// <returns></returns>
  352. [HttpGet("install-certificate")]
  353. public IActionResult InstallCertificate()
  354. {
  355. try
  356. {
  357. string pathCerNew = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "batscript", "certificate.cer");
  358. string pathBatNew = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "batscript", "install_certificate.bat");
  359. string pathCer = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "certificate.cer");
  360. System.IO.File.Copy(pathCer, pathCerNew);
  361. string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "install_certificate.bat");
  362. System.IO.File.Copy(pathBat, pathBatNew);
  363. var res = ProcessHelper.ExecuteProcess(pathBatNew);
  364. return Ok(new {code= res.code, msg= res.msg });
  365. }
  366. catch (Exception ex)
  367. {
  368. _logger.LogError($"证书安装错误。{ex.Message},{ex.StackTrace}");
  369. msg = $"证书安装错误,{ex.Message}";
  370. code = 500;
  371. }
  372. return Ok(new { code = code, msg = msg });
  373. }
  374. /// <summary>
  375. ///
  376. /// </summary>
  377. /// <param name="json"></param>
  378. /// <returns></returns>
  379. [HttpPost("download-primary")]
  380. public async Task<IActionResult> DownloadPrimary(JsonNode json)
  381. {
  382. try {
  383. ServerDevice serverDevice = _memoryCache.Get<ServerDevice>(Constant._KeyServerDevice);
  384. if (serverDevice!=null && serverDevice.networks.IsNotEmpty())
  385. {
  386. string mac = $"{json["mac"]}";
  387. var network = serverDevice.networks.Find(x => mac.Equals(x.mac));
  388. if (network!=null)
  389. {
  390. string pathBat = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "certificate.bat");
  391. string pathCer = Path.Combine(Directory.GetCurrentDirectory(), "Configs", "cer", "certificate.cer");
  392. string text = await System.IO.File.ReadAllTextAsync(pathBat);
  393. text = text.Replace("192.168.8.132", network.ip);
  394. string pathCertificateBat = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "certificate.bat");
  395. await System.IO.File.WriteAllTextAsync(pathCertificateBat, text);
  396. string pathCertificateCer = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "certificate.cer");
  397. System.IO.File.Copy(pathCer, pathCertificateCer);
  398. return Ok(new { code = 200, msg = "生成成功。", bat = "package/certificate.bat", cer = "package/certificate.cer" });
  399. }
  400. else
  401. {
  402. msg="未找到匹配的网卡设备。";
  403. }
  404. }
  405. else
  406. {
  407. msg="服务端设备未找到,或网卡设备不存在。";
  408. }
  409. } catch (Exception ex)
  410. {
  411. _logger.LogError($"生成证书和自定义域名映射脚本错误。{ex.Message},{ex.StackTrace}");
  412. msg=$"服务端错误,{ex.Message}";
  413. }
  414. return Ok(new { code = 400, msg = msg });
  415. }
  416. [HttpPost("list-schools")]
  417. public async Task<IActionResult> ListSchool(JsonNode json)
  418. {
  419. string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "schools.json");
  420. string schoolText = await System.IO.File.ReadAllTextAsync(filePath);
  421. JsonNode? node = schoolText.ToObject<JsonNode>();
  422. return Ok(new {code =200, schools= node?["schools"] });
  423. }
  424. [HttpPost("bind-school")]
  425. public async Task<IActionResult> BindSchool(JsonNode json)
  426. {
  427. string id=$"{json["id"]}";
  428. string name= $"{json["name"]}";
  429. string fp = $"{json["fp"]}";
  430. if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(fp))
  431. {
  432. string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "schools.json");
  433. string schoolText = await System.IO.File.ReadAllTextAsync(filePath);
  434. List<School>? schools = schoolText.ToObject<JsonNode>()?["schools"]?.ToObject<List<School>>();
  435. School? school = schools?.Find(x => id.Equals(x.id) && name.Equals(x.name));
  436. if (school!=null)
  437. {
  438. _liteDBFactory.GetLiteDatabase().GetCollection<School>().DeleteAll();
  439. _liteDBFactory.GetLiteDatabase().GetCollection<School>().Upsert(school);
  440. IEnumerable<School> schoolsDb = _liteDBFactory.GetLiteDatabase().GetCollection<School>().FindAll();
  441. School? schoolDb = schools?.FirstOrDefault();
  442. _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
  443. if (server!=null)
  444. {
  445. server.school = school;
  446. }
  447. string ip = GetIP();
  448. var device = IndexService.GetDeviceInit(HttpContext, $"{fp}", ip, _memoryCache);
  449. int hybrid = 0;
  450. _memoryCache.Set(Constant._KeyServerDevice, server);
  451. _memoryCache.TryGetValue(Constant._KeyServerCenter, out JsonNode? data);
  452. _memoryCache.TryGetValue(Constant._KeyServerDevice, out server);
  453. if (data!=null)
  454. {
  455. hybrid=1;
  456. msg="云端服务连接成功!";
  457. return Ok(new { code = 200, msg, data = new { hybrid, device, centerUrl = data["centerUrl"], region = data["region"], ip = data["ip"], nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } });
  458. }
  459. else
  460. {
  461. msg="云端服务未连接!";
  462. return Ok(new { code = 200, msg, data = new { hybrid, device, centerUrl = "", region = "局域网·内网", ip = ip, nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } });
  463. }
  464. }
  465. else
  466. {
  467. return Ok(new { code = 400, msg = "绑定失败!" });
  468. }
  469. }
  470. else {
  471. return Ok(new { code = 400, msg = "参数错误!" });
  472. }
  473. }
  474. [HttpPost("device")]
  475. public IActionResult Device(JsonElement json )
  476. {
  477. try
  478. {
  479. string ip= GetIP();
  480. json.TryGetProperty("fp", out JsonElement fp);
  481. var device = IndexService.GetDeviceInit(HttpContext, $"{fp}", ip, _memoryCache);
  482. int hybrid = 0, notify = 0 ;
  483. _memoryCache.TryGetValue(Constant._KeyServerCenter, out JsonNode? data);
  484. _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
  485. if (_connectionService.notifyIsConnected)
  486. {
  487. notify=1;
  488. }
  489. if (_connectionService.centerIsConnected)
  490. {
  491. hybrid=1;
  492. }
  493. msg="服务端检测成功!";
  494. return Ok(new { code = 200, msg, data = new {
  495. notify,
  496. hybrid,
  497. device,
  498. centerUrl = hybrid==1 ? _connectionService.centerUrl : "",
  499. notifyUrl = notify==1 ? _connectionService.notifyUrl : "",
  500. region = data?["region"],
  501. ip = data!=null ? data?["ip"] : ip,
  502. nowtime = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
  503. server
  504. } });
  505. }
  506. catch (Exception ex)
  507. {
  508. code=500;
  509. msg="服务端异常!";
  510. }
  511. return Ok(new { code, msg });
  512. }
  513. /**
  514. {
  515. "type":"sms",//qrcode二维码扫码登录:randomCode必传; sms 短信验证登录:randomCode必传,mobile必传
  516. "randomCode",
  517. "mobile":"1528377****"
  518. }
  519. **/
  520. /// <summary>
  521. /// 登录验证
  522. /// </summary>
  523. /// <param name="randomCode"></param>
  524. /// <returns></returns>
  525. [HttpPost("login-check")]
  526. public async Task<IActionResult> LoginCheck(JsonNode json)
  527. {
  528. try
  529. {
  530. var type = json["type"];
  531. string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  532. if (!string.IsNullOrWhiteSpace($"{type}"))
  533. {
  534. TmdidImplicit? token = null;
  535. string x_auth_token = string.Empty;
  536. List<School>? schools = null;
  537. JsonNode? jsonNode = null;
  538. long time = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  539. _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
  540. School? school = null;
  541. if (server!=null)
  542. {
  543. school = server.school;
  544. }
  545. switch (true)
  546. {
  547. //跳过忽略,但是仍然要以访客身份登录
  548. case bool when $"{type}".Equals(ExamConstant.ScopeVisitor):
  549. {
  550. string id = $"{DateTimeOffset.Now.ToUnixTimeSeconds()}";
  551. string name = $"{school?.name}教师-{Random.Shared.Next(100, 999)}";
  552. x_auth_token = JwtAuthExtension.CreateAuthToken("www.teammodel.cn",id ,name,picture: school?.picture
  553. , ExamConstant.JwtSecretKey,ExamConstant.ScopeVisitor,8,schoolID:school?.id,new string[] { "visitor" }, expire: 1);
  554. // _memoryCache.Set($"Teacher:{id}", new Teacher { id = id, name = $"{name}", implicit_token = token, picture = null, schools = schools, x_auth_token = x_auth_token });
  555. _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 });
  556. _connectionService.loginToken = x_auth_token;
  557. return Ok(new { code = 200,x_auth_token = x_auth_token });
  558. }
  559. case bool when $"{type}".Equals("qrcode"):
  560. {
  561. string randomCode = $"{json["randomCode"]}";
  562. System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
  563. var rc= _memoryCache.Get<string>($"Login:ExamServer:{school?.id}:{randomCode}");
  564. if (!string.IsNullOrWhiteSpace(rc))
  565. {
  566. var response = await _httpClientFactory.CreateClient().GetAsync($"{CenterUrl}/core/qrcode/check?randomcode={randomCode}&school={school?.id}&client=ExamServer");
  567. if (response.IsSuccessStatusCode)
  568. {
  569. string content = await response.Content.ReadAsStringAsync();
  570. if (!string.IsNullOrWhiteSpace(content))
  571. {
  572. jsonNode = content.ToObject<JsonNode>();
  573. }
  574. else
  575. {
  576. code=400;
  577. msg="随机码验证失败";
  578. }
  579. }
  580. else
  581. {
  582. code=400;
  583. msg="随机码验证错误";
  584. }
  585. }
  586. else
  587. {
  588. code=400;
  589. msg="二维码过期";
  590. }
  591. break;
  592. }
  593. case bool when $"{type}".Equals("smspin"):
  594. {
  595. string pin_code = $"{json["pin_code"]}";
  596. string account = $"{json["account"]}";
  597. var response = await _httpClientFactory.CreateClient().PostAsJsonAsync($"{CenterUrl}/core/sendsms/check", new { pin_code, account,school=school?.id });
  598. if (response.IsSuccessStatusCode)
  599. {
  600. string content = await response.Content.ReadAsStringAsync();
  601. if (!string.IsNullOrWhiteSpace(content))
  602. {
  603. jsonNode = content.ToObject<JsonNode>();
  604. }
  605. else
  606. {
  607. code=400;
  608. msg="短信验证返回结果为空";
  609. }
  610. }
  611. else
  612. {
  613. code=400;
  614. msg="短信验证错误";
  615. }
  616. break;
  617. }
  618. }
  619. if (jsonNode != null && $"{jsonNode["code"]}".Equals("200"))
  620. {
  621. token =jsonNode["implicit_token"]?.ToObject<TmdidImplicit>();
  622. x_auth_token = $"{jsonNode["x_auth_token"]}";
  623. schools =jsonNode["schools"]?.ToObject<List<School>>();
  624. var jwt = new JwtSecurityToken(token?.id_token);
  625. var id = jwt.Payload.Sub;
  626. jwt.Payload.TryGetValue("name", out object? name);
  627. jwt.Payload.TryGetValue("picture", out object? picture);
  628. //_memoryCache.Set($"Teacher:{id}", new Teacher { id=id, name=$"{name}", implicit_token= token, picture=$"{picture}", schools=schools, x_auth_token=x_auth_token });
  629. _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 });
  630. _connectionService.loginToken = x_auth_token;
  631. return Ok(new { code=200,/* implicit_token = token, schools = schools , */ x_auth_token = x_auth_token });
  632. }
  633. else
  634. {
  635. code=400;
  636. msg="验证失败";
  637. }
  638. }
  639. else
  640. {
  641. code=400;
  642. msg="参数错误";
  643. }
  644. }
  645. catch (Exception ex)
  646. {
  647. code=500;
  648. msg="异常错误";
  649. }
  650. return Ok(new { code = code,msg });
  651. }
  652. /*
  653. */
  654. /// <summary>
  655. /// 登录模式初始化
  656. /// </summary>
  657. /// <returns></returns>
  658. [HttpPost("login-init")]
  659. public async Task<IActionResult> LoginInit(JsonNode json)
  660. {
  661. var type = json["type"];
  662. string qrcode = string.Empty;
  663. string randomcode = "";
  664. _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
  665. School? school = null;
  666. if (server != null)
  667. {
  668. school = server.school;
  669. }
  670. if (school != null)
  671. {
  672. switch (true)
  673. {
  674. case bool when $"{type}".Equals("qrcode"):
  675. {
  676. //.NET Core使用SkiaSharp快速生成二维码 https://cloud.tencent.com/developer/article/2336486
  677. // 生成二维码图片
  678. Random random = new Random();
  679. randomcode = $"{random.Next(1000, 9999)}";
  680. string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  681. CenterUrl = CenterUrl.Equals("https://localhost:5001") ? "https://www.teammodel.cn" : CenterUrl;
  682. 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";
  683. var str = QRCodeHelper.GenerateQRCode(content, 300, 300, QRCodeHelper.logo);
  684. qrcode = $"data:image/png;base64,{str}";
  685. int ttl = 180;
  686. string key = $"Login:ExamServer:{school?.id}:{randomcode}";
  687. _memoryCache.Set(key, randomcode, TimeSpan.FromSeconds(ttl));
  688. var device =IndexService.GetDevice(HttpContext,_memoryCache);
  689. _memoryCache.Set($"device:{key}", device);
  690. try {
  691. if (_connectionService.notifyIsConnected && _connectionService.serverDevice!=null)
  692. {
  693. string url = $"{_connectionService.notifyUrl!}/third/ies/qrcode-login-register";
  694. //扫描登录,远端设备登记临时随机码
  695. await _httpClientFactory.CreateClient().PostAsJsonAsync(url,new { randomcode= key, deviceid = _connectionService .serverDevice.deviceId});
  696. }
  697. } catch (Exception e) {
  698. _logger.LogError($"{e.Message},{e.StackTrace}");
  699. }
  700. return Ok(new { ttl,code = 200, randomCode = randomcode, qrcode, type });
  701. }
  702. //case bool when $"{type}".Equals("xqrcode"):
  703. // {
  704. // // 生成二维码图片
  705. // Random random = new Random();
  706. // randomcode = $"{random.Next(1000, 9999)}";
  707. // string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  708. // CenterUrl = CenterUrl.Equals("https://localhost:5001") ? "https://www.teammodel.cn" : CenterUrl;
  709. // 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";
  710. // Bitmap qrCodeImage = QRCodeHelper.GetBitmap(content, 200, 200);
  711. // using (MemoryStream stream = new MemoryStream())
  712. // {
  713. // qrCodeImage.Save(stream, ImageFormat.Png);
  714. // byte[] data = stream.ToArray();
  715. // qrcode = $"data:image/png;base64,{Convert.ToBase64String(data)}";
  716. // }
  717. // int ttl = 60;
  718. // _memoryCache.Set($"Login:ExamServer:{school?.id}:{randomcode}", randomcode, TimeSpan.FromSeconds(ttl));
  719. // return Ok(new {ttl, code = 200, randomCode = randomcode, qrcode, type });
  720. // }
  721. case bool when $"{type}".Equals("smspin"):
  722. {
  723. int send = 0;
  724. if (!string.IsNullOrWhiteSpace($"{json["area"]}") && !string.IsNullOrWhiteSpace($"{json["to"]}"))
  725. {
  726. string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
  727. string url = $"{CenterUrl}/core/sendsms/pin";
  728. HttpResponseMessage message = await _httpClientFactory.CreateClient().PostAsJsonAsync(url, new { area = json["area"], to = json["to"], lang = "zh-cn" });
  729. if (message.IsSuccessStatusCode)
  730. {
  731. string content = await message.Content.ReadAsStringAsync();
  732. JsonNode? jsonNode = content?.ToObject<JsonNode>();
  733. if (jsonNode != null && int.TryParse($"{jsonNode["send"]}", out int s))
  734. {
  735. send = s;
  736. }
  737. }
  738. }
  739. return Ok(new { code = 200, send, type });
  740. }
  741. }
  742. }
  743. else if (school == null)
  744. {
  745. return Ok(new { code = 400,msg="未绑定学校" });
  746. }
  747. return Ok(new { code = 400 });
  748. }
  749. }
  750. }