CrazyIter_Bin 5 months ago
parent
commit
fe549e8d6a

+ 60 - 5
IES.ExamServer/App.xaml.cs

@@ -1,14 +1,20 @@
-using IES.ExamServer.DI.SignalRHost;
+using IES.ExamServer.DI;
+using IES.ExamServer.DI.SignalRHost;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.StaticFiles;
+using Microsoft.Extensions.Caching.Memory;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection.Extensions;
+using System.Configuration;
 using System.IO;
+using System.Net.Http;
+using System.Net.Http.Json;
+using System.Text.Json;
+using System.Text.Json.Nodes;
 using System.Windows;
-using TEAMModelOS.SDK;
-using TEAMModelOS.SDK.DI;
+using System.Windows.Interop;
 
 namespace IES.ExamServer
 {
@@ -31,7 +37,6 @@ namespace IES.ExamServer
             var builder = WebApplication.CreateBuilder(Environment.GetCommandLineArgs());
             builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
             //builder.WebHost.UseUrls("http://*:5000;https://*:5001");
-          
             // 注册主窗口和其他服务
             builder.Services.AddControllersWithViews();
             builder.Services.AddSingleton<MainWindow>();
@@ -39,6 +44,20 @@ namespace IES.ExamServer
             builder.Services.AddHttpClient();
             builder.Services.AddSignalR();
             builder.Services.AddHttpContextAccessor();
+            string localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+            string dbpath = $"{localAppDataPath}\\ExamServer\\LiteDB";
+            if (!System.IO.Directory.Exists(dbpath))
+            {
+                System.IO.Directory.CreateDirectory(dbpath);
+            }
+            string liteDBPath = $"Filename={dbpath}\\data.db;Connection=shared";
+            
+            var connections_LiteDB = new List<LiteDBFactoryOptions>
+            {
+                new LiteDBFactoryOptions { Name = "Master", Connectionstring = liteDBPath}
+            };
+            builder.Services.AddLiteDB(connections_LiteDB);
+            builder.Services.AddMemoryCache();
             string path = $"{builder.Environment.ContentRootPath}/Configs";
             builder.Services.AddCors(options =>
             {
@@ -55,6 +74,7 @@ namespace IES.ExamServer
             // 这里是文件类型映射,如果你的静态文件在浏览器中加载报 404,那么需要在这里注册,这里我加载一个 3D 场景文件的类型
             var contentTypeProvider = new FileExtensionContentTypeProvider();
             contentTypeProvider.Mappings[".glb"] = "model/gltf-binary";
+            app.UseDefaultFiles();
             app.UseStaticFiles(new StaticFileOptions
             {
                 ContentTypeProvider = contentTypeProvider,
@@ -62,7 +82,6 @@ namespace IES.ExamServer
             // 你如果使用了 Vue Router 或者其他前端路由了,需要在这里添加这句话让路由返回前端,而不是 ASP.NET Core 处理
             app.MapFallbackToFile("/index.html");
             //PRODUCTION uses webpack static files
-
             app.UseRouting();
             app.UseHttpsRedirection(); //開發中暫時關掉
             //如果应用使用身份验证/授权功能(如 AuthorizePage 或 [Authorize]),请将对 UseAuthentication 和 UseAuthorization的
@@ -77,7 +96,43 @@ namespace IES.ExamServer
             // 显示主窗口
             MainWindow = app.Services.GetRequiredService<MainWindow>();
             MainWindow.Show();
+            IMemoryCache? cache = app.Services.GetRequiredService<IMemoryCache>();
+            IHttpClientFactory? clientFactory = app.Services.GetRequiredService<IHttpClientFactory>();
+            LiteDBFactory liteDBFactory = app.Services.GetRequiredService<LiteDBFactory>();
+            JsonNode? data = null;
+            try
+            {
+                string? CenterUrl = builder.Configuration.GetValue<string>("ExamServer:CenterUrl");
+                var httpclient = clientFactory.CreateClient();
+                httpclient.Timeout=  TimeSpan.FromSeconds(10);
+                HttpResponseMessage message = await httpclient.PostAsJsonAsync($"{CenterUrl}/core/system-info", new { });
+                if (message.IsSuccessStatusCode)
+                {
+                    string content = await message.Content.ReadAsStringAsync();
+                    data = JsonSerializer.Deserialize<JsonNode>(content);
+                    data!["centerUrl"]=CenterUrl;
+                    cache.Set("Server:Center:Data", data);
+                    SystemInfo? system= JsonSerializer.Deserialize<SystemInfo>(data);
+                    system!.id= $"{DateTimeOffset.Now.ToUnixTimeMilliseconds()}";
+                    liteDBFactory.GetLiteDatabase().GetCollection<SystemInfo>("System").Insert(system);
+                }
+            }
+            catch (Exception ex)
+            {
+            }
             await app.RunAsync().ConfigureAwait(false);
         }
     }
+    public class SystemInfo 
+    {
+        public string? id { get; set; }
+        public string? version {  get; set; }
+        public string? description { get; set; }
+        public long nowtime { get; set; }
+        public string? region { get; set; }
+        public string? ip { get; set; }
+        public string? date { get; set; }
+        public string? centerUrl { get; set; }
+        
+    }
 }

+ 25 - 10
IES.ExamServer/Controllers/HomeController.cs

@@ -1,5 +1,6 @@
 using Microsoft.AspNetCore.Http.HttpResults;
 using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Memory;
 using Microsoft.Extensions.Configuration;
 using System;
 using System.Collections.Generic;
@@ -19,10 +20,12 @@ namespace IES.ExamServer.Controllers
     {
         private readonly IConfiguration _configuration;
         private readonly IHttpClientFactory _httpClientFactory;
-        public HomeController(IConfiguration configuration,IHttpClientFactory httpClientFactory) 
+        private readonly IMemoryCache _memoryCache;
+        public HomeController(IConfiguration configuration,IHttpClientFactory httpClientFactory, IMemoryCache memoryCache) 
         {
             _configuration=configuration;
             _httpClientFactory=httpClientFactory;
+            _memoryCache=memoryCache;
         }
         [HttpGet("/init")]
         public async Task<IActionResult> Init() 
@@ -30,21 +33,18 @@ namespace IES.ExamServer.Controllers
             int code =0;
             string msg = string.Empty;
             try {
-                string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
-                var httpclient = _httpClientFactory.CreateClient();
-                httpclient.Timeout=  TimeSpan.FromSeconds(10);
-                HttpResponseMessage message =  await httpclient.PostAsJsonAsync($"{CenterUrl}/core/system-info", new { });
-                if (message.IsSuccessStatusCode)
+
+                _memoryCache.TryGetValue("Server:Center:Data", out JsonNode? data);
+                if (data!=null)
                 {
-                    string content = await message.Content.ReadAsStringAsync();
-                    var data = JsonSerializer.Deserialize<JsonNode>(content);
-                    data!["centerUrl"]=CenterUrl;
-                    return Ok(new { code=200, msg="云端服务连接成功!", data = data });
+                    return Ok(new { code = 200, msg = "云端服务连接成功!", data = data });
                 }
                 else {
                     code=500;
                     msg="云端服务未连接!";
                 }
+               
+               
             } catch (Exception ex) 
             {
                 code=500;
@@ -52,6 +52,21 @@ namespace IES.ExamServer.Controllers
             }
             return Ok(new { code,msg} );
         }
+        [HttpGet("/mobile-login")]
+        public async Task<IActionResult> MobileLogin() 
+        {
+            return Ok();
+        }
+        [HttpGet("/qrcode-login")]
+        public async Task<IActionResult> QRcodeLogin()
+        {
+            return Ok();
+        }
+        [HttpGet("/qrcode-gen")]
+        public async Task<IActionResult> QRcodeGen()
+        {
+            return Ok();
+        }
         [HttpGet("/hello")]
         public string Get() => "Hello World";
     }

+ 68 - 0
IES.ExamServer/DI/LiteDBFactory.cs

@@ -0,0 +1,68 @@
+using LiteDB;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace IES.ExamServer.DI
+{
+    public class LiteDBFactory
+    {
+        private readonly IServiceProvider _services;
+        private readonly IOptionsMonitor<LiteDBFactoryOptions> _optionsMonitor;
+        private readonly ILogger _logger;
+        private ConcurrentDictionary<string, LiteDatabase> LiteDatabases { get; } = new ConcurrentDictionary<string, LiteDatabase>();
+        public LiteDBFactory(IServiceProvider services, IOptionsMonitor<LiteDBFactoryOptions> optionsMonitor, ILogger<LiteDBFactory> logger)
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));
+            if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor));
+
+            _services = services;
+            _optionsMonitor = optionsMonitor;
+            _logger = logger;
+        }
+
+        public LiteDatabase GetLiteDatabase(string name = "Master")
+        {
+            try
+            {
+                var DB = LiteDatabases.GetOrAdd(name, x => new LiteDatabase(_optionsMonitor.Get(name).Connectionstring));
+                return DB;
+            }
+            catch (Exception e)
+            {
+                _logger?.LogWarning(e, e.Message);
+                return null;
+            }
+        }
+    }
+    public class LiteDBFactoryOptions
+    {
+        public string? Name { get; set; }
+        public string? Connectionstring { get; set; }
+    }
+    public static class LiteDBFactoryExtensions
+    {
+        public static IServiceCollection AddLiteDB(this IServiceCollection services, List<LiteDBFactoryOptions> connectionstrings)
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));
+            if (connectionstrings == null) throw new ArgumentNullException(nameof(connectionstrings));
+
+
+            services.TryAddSingleton<LiteDBFactory>();
+            //多个连接字符串注入
+            connectionstrings.ForEach(connection =>
+            {
+                services.Configure<LiteDBFactoryOptions>(connection.Name, o => { o.Name = connection.Name; o.Connectionstring = connection.Connectionstring; });
+            });
+
+            return services;
+        }
+    }
+}

+ 9 - 6
IES.ExamServer/DI/SignalRHost/SignalRExamServerHub.cs

@@ -1,11 +1,5 @@
 using Microsoft.AspNetCore.SignalR;
 using Microsoft.Extensions.Logging;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK;
 
 
 namespace IES.ExamServer.DI.SignalRHost
@@ -62,4 +56,13 @@ namespace IES.ExamServer.DI.SignalRHost
         public virtual MessageType message_type { get; set; }
 
     }
+    public enum MessageType
+    {
+        conn_success,//连接成功
+        conn_error,// 连接失败
+        task_send_success,// 任务发送成功
+        task_send_error,// 任务发送失败
+        task_execute_success,// 任务执行成功
+        task_execute_error,// 任务执行失败
+    }
 }

+ 5 - 5
IES.ExamServer/IES.ExamServer.csproj

@@ -7,7 +7,6 @@
     <ImplicitUsings>enable</ImplicitUsings>
     <UseWPF>true</UseWPF>
   </PropertyGroup>
-
   <ItemGroup>
     <None Remove="Configs\latlng.json" />
   </ItemGroup>
@@ -19,20 +18,18 @@
       <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
     </Content>
   </ItemGroup>
-
   <ItemGroup>
+    <PackageReference Include="LiteDB" Version="5.0.21" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
     <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
     <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />
     <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
     <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2903.40" />
+    <PackageReference Include="ZXing.Net" Version="0.16.9" />
   </ItemGroup>
   <ItemGroup>
 	<FrameworkReference Include="Microsoft.AspNetCore.App" />
   </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\TEAMModelOS.SDK\TEAMModelOS.SDK.csproj" />
-  </ItemGroup>
   <ItemGroup>
 	<!-- 这里模仿 ASP.NET Core,将 SPA 资源文件存于 wwwroot 文件夹下 -->
 	<None Update="wwwroot\**">
@@ -44,4 +41,7 @@
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Helper\" />
+  </ItemGroup>
 </Project>

+ 16 - 5
IES.ExamServer/MainWindow.xaml

@@ -6,12 +6,23 @@
         xmlns:local="clr-namespace:IES.ExamServer"
         xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
         mc:Ignorable="d"
-        Title="醍摩豆局域网评测服务端" Height="450" Width="800" SnapsToDevicePixels="True"    ShowInTaskbar="True" WindowStyle="None"
-        WindowStartupLocation="CenterScreen" Topmost="False" AllowsTransparency="True"  Background="White">
+        Title="评测服务端" Height="900" Width="1600" SnapsToDevicePixels="True"    ShowInTaskbar="True" WindowStyle="ToolWindow"
+        WindowStartupLocation="CenterScreen" Topmost="False" AllowsTransparency="False"  Background="White">
     <!-- 在上面加入 xmlns:wv2 属性用于引用 WebView2 控件 -->
     <Grid>
-        <!-- 这里插入 WebView2 控件,我们默认可以让 Source 是 http://localhost:5000,这是 ASP.NET Core 的默认监听地址 -->
-        <wv2:WebView2 Name="webView"
-          Source="{Binding SourceUrl, FallbackValue='https://localhost:5000/hello'}" AllowDrop="True" SnapsToDevicePixels="True"/>
+       
+            <StackPanel Grid.Row="0">
+                <WrapPanel Height="50">
+                    
+                </WrapPanel>
+                <StackPanel Height="850" >
+                    <WrapPanel Height="850" Width="1500" >
+                        <!-- 这里插入 WebView2 控件,我们默认可以让 Source 是 http://localhost:5000,这是 ASP.NET Core 的默认监听地址 -->
+                        <wv2:WebView2 Height="850" Width="1500" Name="webView" Source="{Binding SourceUrl, FallbackValue='https://localhost:5000'}" AllowDrop="True" SnapsToDevicePixels="True"/>
+                    </WrapPanel>
+                </StackPanel>
+            </StackPanel>
+            
+        
     </Grid>
 </Window>

+ 15 - 1
IES.ExamServer/MainWindow.xaml.cs

@@ -14,6 +14,9 @@ using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Shapes;
+using Microsoft.Web.WebView2.Core;
+using Microsoft.Web.WebView2.Wpf;
+using Microsoft.Web.WebView2.WinForms;
 
 namespace IES.ExamServer
 {
@@ -28,9 +31,20 @@ namespace IES.ExamServer
             InitializeComponent();
             // 这里通过注入的 IServer 对象来获取监听的 Url
             var addresses = server.Features.Get<IServerAddressesFeature>()?.Addresses;
-            SourceUrl = addresses is not null ? (addresses.FirstOrDefault() ?? "https://localhost:5001/hello") : "https://localhost:5001/hello";
+            SourceUrl = addresses is not null ? (addresses.FirstOrDefault() ?? "https://localhost:5001") : "https://localhost:5001";
             // 无 VM,用自身当 VM
             DataContext = this;
+            
+            webView.NavigationStarting += WebView2_NavigationStarting;
+        }
+
+        
+
+        private async void WebView2_NavigationStarting(object? sender, CoreWebView2NavigationStartingEventArgs e)
+        {
+            var userDataFolder =  System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "ExamServer\\Temp\\webview2_temp");
+            var environment = await CoreWebView2Environment.CreateAsync(null, userDataFolder);
+            await webView.EnsureCoreWebView2Async();
         }
     }
 }

+ 1 - 1
TEAMModelOS.Extension/Contest.Client/Contest.Client.esproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.VisualStudio.JavaScript.Sdk/0.5.128-alpha">
+<Project Sdk="Microsoft.VisualStudio.JavaScript.Sdk/0.5.128-alpha">
   <PropertyGroup>
     <StartupCommand>npm run dev</StartupCommand>
     <JavaScriptTestRoot>.\</JavaScriptTestRoot>

+ 5 - 1
TEAMModelOS/Controllers/Both/CourseBaseController.cs

@@ -2088,7 +2088,11 @@ namespace TEAMModelOS.Controllers.Both
     "semesterId": "08b81e76-e7d2-4001-8b4c-e7c789ef4bs1"
 }
          */
-        //http://localhost:5000/course-base/student
+        //个人,
+        //学校,
+        //助教,学校。
+        //助教,个人。
+        //
         /// <summary>
         /// 教师任教的课程
         /// </summary>

+ 2 - 1
ies.examwebview/IES.ExamWebview.esproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.VisualStudio.JavaScript.Sdk/1.0.1184077">
+<Project Sdk="Microsoft.VisualStudio.JavaScript.Sdk/1.0.2125207">
   <PropertyGroup>
     <StartupCommand>npm run dev</StartupCommand>
     <JavaScriptTestRoot>.\</JavaScriptTestRoot>
@@ -7,5 +7,6 @@
     <ShouldRunBuildScript>false</ShouldRunBuildScript>
     <!-- Folder where production build objects will be placed -->
     <BuildOutputFolder>$(MSBuildProjectDirectory)\dist</BuildOutputFolder>
+	<PublishAssetsDirectory>$(MSBuildProjectDirectory)\dist</PublishAssetsDirectory>
   </PropertyGroup>
 </Project>

+ 1 - 0
ies.examwebview/index.html

@@ -7,6 +7,7 @@
     <title>Vite App</title>
   </head>
   <body>
+      <div>1234</div>
     <div id="app"></div>
     <script type="module" src="/src/main.js"></script>
   </body>