IndexController.cs 42 KB

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