CrazyIter_Bin vor 4 Monaten
Ursprung
Commit
0927730d3b

+ 11 - 1
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Controllers/IndexController.cs

@@ -34,6 +34,17 @@ namespace IES.ExamServer.Controllers
             _connectionService=connectionService;
             _liteDBFactory=liteDBFactory;
         }
+        [HttpPost("bind-school")]
+        public async Task<IActionResult> BindSchool(JsonNode json) 
+        {
+            string id=$"{json["id"]}";
+            string name= $"{json["name"]}";
+            string picture = $"{json["picture"]}";
+            string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package", "schools.json");
+            string schools = await System.IO.File.ReadAllTextAsync(filePath);
+
+            return Ok();
+        }
         [HttpPost("device")]
         public IActionResult Device(JsonElement json )
         {
@@ -55,7 +66,6 @@ namespace IES.ExamServer.Controllers
                     msg="云端服务未连接!";
                     return Ok(new { code = 200, msg, data = new { hybrid, device,  centerUrl = "", region = "局域网·内网", ip = ip, nowtime= DateTimeOffset.Now.ToUnixTimeMilliseconds(), server } });
                 }
-                
             }
             catch (Exception ex)
             {

+ 148 - 115
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Controllers/ManageController.cs

@@ -41,6 +41,9 @@ namespace IES.ExamServer.Controllers
             _connectionService=connectionService;
             _signalRExamServerHub=signalRExamServerHub;
         }
+        ///通过线上回传数据需要鉴权验证等操作。
+        ///通过离线包回传数据需要加密操作
+        
         /// <summary>
         /// 清理缓存,列出缓存占用空间,type =list列出,type=clear清理,不能清理近期及正在激活的数据,并且提示清理中暂未上传或者导出的数据。
         /// </summary>
@@ -175,30 +178,35 @@ namespace IES.ExamServer.Controllers
                             client.DefaultRequestHeaders.Remove(Constant._X_Auth_AuthToken);
                         }
                         client.DefaultRequestHeaders.Add(Constant._X_Auth_AuthToken, teacher.x_auth_token);
-                        HttpResponseMessage message = await client.PostAsJsonAsync($"{CenterUrl}/evaluation-sync/find-sync-info", new { shortCode, evaluationId });
-                        if (message.IsSuccessStatusCode)
-                        {
-                            string content = await message.Content.ReadAsStringAsync();
-                            JsonNode? jsonNode = content.ToObject<JsonNode>();
-                            if (jsonNode != null)
+                        try {
+                            HttpResponseMessage message = await client.PostAsJsonAsync($"{CenterUrl}/evaluation-sync/find-sync-info", new { shortCode, evaluationId });
+                            if (message.IsSuccessStatusCode)
                             {
-                                centerCode = $"{jsonNode["code"]}";
-                                centerMsg = $"{jsonNode["msg"]}";
-                                if ($"{jsonNode["code"]}".Equals("200"))
+                                string content = await message.Content.ReadAsStringAsync();
+                                JsonNode? jsonNode = content.ToObject<JsonNode>();
+                                if (jsonNode != null)
                                 {
-                                    evaluationCloud = jsonNode["evaluation"]?.ToObject<EvaluationClient>();
+                                    centerCode = $"{jsonNode["code"]}";
+                                    centerMsg = $"{jsonNode["msg"]}";
+                                    if ($"{jsonNode["code"]}".Equals("200"))
+                                    {
+                                        evaluationCloud = jsonNode["evaluation"]?.ToObject<EvaluationClient>();
+                                    }
+                                }
+                                else
+                                {
+                                    centerCode = "500";
+                                    centerMsg = "数据转换异常";
                                 }
                             }
                             else
                             {
-                                centerCode = "500";
-                                centerMsg = "数据转换异常";
+                                centerCode = $"{message.StatusCode}";
+                                centerMsg = "数据中心访问异常";
                             }
-                        }
-                        else
-                        {
-                            centerCode = $"{message.StatusCode}";
-                            centerMsg = "数据中心访问异常";
+                        } catch (Exception ex) {
+                            centerCode = $"500";
+                            centerMsg = $"数据中心访问异常:{ex.Message}";
                         }
                     }
                     else
@@ -291,7 +299,6 @@ namespace IES.ExamServer.Controllers
                 status = 4;
                 _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().Insert(evaluationLocal);
             }
-            List<string> file_error = new List<string>();
             
             if (evaluationLocal!=null)
             {
@@ -301,35 +308,19 @@ namespace IES.ExamServer.Controllers
                 //校验本地文件数据
                 string packagePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "package");
                 if (!Directory.Exists(packagePath))
-                    Directory.CreateDirectory(packagePath);
-                string evaluationPath = Path.Combine(packagePath,"exam", evaluationLocal.id!);
-               // await Task.Delay(DelayMacro);
-              
-                string path_evaluation = Path.Combine(evaluationPath, "evaluation.json");
-                if (!System.IO.File.Exists(path_evaluation))
                 {
-                    file_error.Add("evaluation");
-                    msg_status=Constant._Message_status_error;
-                    checkTotal++;
-                    checkError++;
-                }
-                else 
-                {
-                    msg_status=Constant._Message_status_success;
-                    checkTotal++;
-                    checkSuccess++;
+                    Directory.CreateDirectory(packagePath);
                 }
-                //数据格式:  [消息][信息/错误/警告][15:43]=>[开始检查评测信息文件...]
-                //数据格式:  [检查][成功/失败][15:43]=>[评测数据文件:/wwwroot/package/623a9fe6-5445-0938-ff77-aeb80066ef27/evaluation.json]
-                //数据格式:  [下载][成功/失败][15:43]=>[评测数据文件:/wwwroot/package/623a9fe6-5445-0938-ff77-aeb80066ef27/evaluation.json][1024kb][15ms]
-                await _signalRExamServerHub.SendMessage(_memoryCache,_logger,deviceId, Constant._Message_grant_type_check_file, 
-                    new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType= Constant._Message_type_check, status=msg_status,content=$"评测数据文件:{path_evaluation}" });
+                string evaluationPath = Path.Combine(packagePath, evaluationLocal.id!);
+                string evaluationDataPath = Path.Combine(evaluationPath,"data");
+                // await Task.Delay(DelayMacro);
+
                 //await Task.Delay(DelayMacro);
-                string path_groupList = Path.Combine(evaluationPath, "groupList.json");
+                string path_groupList = Path.Combine(evaluationDataPath, "groupList.json");
                 msg_status =Constant._Message_status_info;
                 if (!System.IO.File.Exists(path_groupList))
                 {
-                    file_error.Add("groupList");
+                    groupList=1;
                     msg_status=Constant._Message_status_error;
                     checkTotal++;
                     checkError++;
@@ -343,11 +334,11 @@ namespace IES.ExamServer.Controllers
                 await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file, 
                     new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType= Constant._Message_type_check, status=msg_status, content=$"评测名单文件:{path_groupList}" });
                 //await Task.Delay(DelayMacro);
-                string path_source = Path.Combine(evaluationPath, "source.json");
+                string path_source = Path.Combine(evaluationDataPath, "source.json");
                 msg_status = Constant._Message_status_info;
                 if (!System.IO.File.Exists(path_source))
                 {
-                    file_error.Add("source");
+                    data=1;
                     msg_status=Constant._Message_status_error;
                     checkTotal++;
                     checkError++;
@@ -360,102 +351,144 @@ namespace IES.ExamServer.Controllers
                 }
                 await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
                     new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType= Constant._Message_type_check, status=msg_status, content=$"评测原始数据:{path_source}" });
-               // await Task.Delay(DelayMacro);
                 msg_status =Constant._Message_status_info;
                 try {
                     //TODO 重整本地文件路径。 文件可能不存在D:\VisualStudioProjects\TEAMModelOS\TEAMModelOS.Extension\IES.Exam\IES.ExamServer\wwwroot\package\exam\6af32bbd-144e-4366-8bc0-61ba4c85677c\evaluation.json
-                    string evaluation_str = await System.IO.File.ReadAllTextAsync(path_evaluation);
-                    JsonNode? evaluation_data = evaluation_str.ToObject<JsonNode>(); 
-                    
-                    if (evaluation_data!=null) 
+                    string path_evaluation = Path.Combine(evaluationDataPath, "evaluation.json");
+                    if (!System.IO.File.Exists(path_evaluation))
+                    {
+                        blob=1;
+                        data=1;
+                        msg_status=Constant._Message_status_error;
+                        checkTotal++;
+                        checkError++;
+                    }
+                    else
                     {
-                        EvaluationClient? evaluationClient = evaluation_data["evaluationClient"]?.ToObject<EvaluationClient>(); 
-                        if (evaluationClient!=null) 
+                        msg_status=Constant._Message_status_success;
+                        checkTotal++;
+                        checkSuccess++;
+                    }
+                    //数据格式:  [消息][信息/错误/警告][15:43]=>[开始检查评测信息文件...]
+                    //数据格式:  [检查][成功/失败][15:43]=>[评测数据文件:/wwwroot/package/623a9fe6-5445-0938-ff77-aeb80066ef27/evaluation.json]
+                    //数据格式:  [下载][成功/失败][15:43]=>[评测数据文件:/wwwroot/package/623a9fe6-5445-0938-ff77-aeb80066ef27/evaluation.json][1024kb][15ms]
+                    await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
+                        new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType= Constant._Message_type_check, status=msg_status, content=$"评测数据文件:{path_evaluation}" });
+                    if (System.IO.File.Exists(path_evaluation)) 
+                    {
+                        string evaluation_str = await System.IO.File.ReadAllTextAsync(path_evaluation);
+                        JsonNode? evaluation_data = evaluation_str.ToObject<JsonNode>();
+                        if (evaluation_data==null)
+                        {
+                            blob=1;
+                            data=1;
+                        }
+                        else
                         {
-                            if ((!string.IsNullOrWhiteSpace(evaluationLocal.blobHash) && evaluationLocal.blobHash.Equals(evaluationClient.blobHash))
-                                &&(evaluationLocal.blobTime==evaluationClient.blobTime)
-                                &&(evaluationLocal.blobCount== evaluationClient.blobCount)
-                                &&(evaluationLocal.blobSize== evaluationClient.blobSize)&& (evaluationLocal.dataTime==evaluationClient.dataTime)
-                                &&(evaluationLocal.dataSize==evaluationClient.dataSize)&&(evaluationLocal.webviewCount==evaluationClient.webviewCount)
-                                &&(evaluationLocal.webviewSize== evaluationClient.webviewSize)
-                                &&(evaluationLocal.webviewTime== evaluationClient.webviewTime)
-                                &&(!string.IsNullOrWhiteSpace(evaluationLocal.webviewPath)&&  evaluationLocal.webviewPath.Equals(evaluationClient.webviewPath)))
+                            EvaluationClient? evaluationClient = evaluation_data["evaluationClient"]?.ToObject<EvaluationClient>();
+                            if (evaluationClient!=null)
                             {
-                                msg_status=Constant._Message_status_info;
+                                if ((!string.IsNullOrWhiteSpace(evaluationLocal.blobHash) && evaluationLocal.blobHash.Equals(evaluationClient.blobHash))
+                                    &&(evaluationLocal.blobTime==evaluationClient.blobTime)
+                                    &&(evaluationLocal.blobCount== evaluationClient.blobCount)
+                                    &&(evaluationLocal.blobSize== evaluationClient.blobSize)&& (evaluationLocal.dataTime==evaluationClient.dataTime)
+                                    &&(evaluationLocal.dataSize==evaluationClient.dataSize)&&(evaluationLocal.webviewCount==evaluationClient.webviewCount)
+                                    &&(evaluationLocal.webviewSize== evaluationClient.webviewSize)
+                                    &&(evaluationLocal.webviewTime== evaluationClient.webviewTime)
+                                    &&(!string.IsNullOrWhiteSpace(evaluationLocal.webviewPath)&&  evaluationLocal.webviewPath.Equals(evaluationClient.webviewPath)))
+                                {
+                                    msg_status=Constant._Message_status_info;
+                                }
+                                else
+                                {
+                                    data=1;
+                                    msg_status=Constant._Message_status_error;
+                                }
+                                await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
+                                    new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType=Constant._Message_type_message, status=msg_status, content="校验本地试卷文件..." });
                             }
-                            else
+                            else { data=1; }
+
+                            List<EvaluationExam>? evaluationExams = evaluation_data["evaluationExams"]?.ToObject<List<EvaluationExam>>();
+                            if (evaluationExams.IsEmpty())
                             {
-                                msg_status=Constant._Message_status_error;
+                                blob=1;
+                                data=1;
                             }
-                            await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
-                                new MessageContent { dataId=evaluationLocal.id, dataName=evaluationLocal.name, messageType=Constant._Message_type_message, status=msg_status, content="校验本地试卷文件..." });
-                        }
-
-                        List<EvaluationExam>? evaluationExams = evaluation_data["evaluationExams"]?.ToObject<List<EvaluationExam>>();
-                        if (evaluationExams.IsNotEmpty()) 
-                        {
-                            string path_papers = Path.Combine(evaluationPath, "papers");
-                            var papers_files = FileHelper.ListAllFiles(path_papers);
-                            foreach (var evaluationExam in evaluationExams!)
+                            else 
                             {
-
-                                int paperIndex = 0;
-                                foreach (var paper in evaluationExam.papers) 
+                                
+                                foreach (var evaluationExam in evaluationExams!)
                                 {
-                                    paperIndex++;
-                                    List<MessageContent> contents = new List<MessageContent>();
-                                    int paper_error_count = 0;
-                                    foreach (var blobInfo in paper.blobs)
+                                    string path_papers = Path.Combine(evaluationPath,  "exams");
+                                    var papers_files = FileHelper.ListAllFiles(path_papers);
+                                    int paperIndex = 0;
+                                    foreach (var paper in evaluationExam.papers)
                                     {
-                                        msg_status=Constant._Message_status_info;
-                                        if (!string.IsNullOrWhiteSpace(blobInfo.path))
+                                        paperIndex++;
+                                        List<MessageContent> contents = new List<MessageContent>();
+                                        int paper_error_count = 0;
+                                        foreach (var blobInfo in paper.blobs)
                                         {
-                                           
-                                            var file = papers_files.Find(x => x.Contains(blobInfo.path));
-                                            if (file!=null)
+                                            msg_status=Constant._Message_status_info;
+                                            if (!string.IsNullOrWhiteSpace(blobInfo.path))
                                             {
-                                                msg_status=1;
-                                                msg_status=Constant._Message_status_success;
+
+                                                var file = papers_files.Find(x => x.Contains(blobInfo.path));
+                                                if (file!=null)
+                                                {
+                                                    msg_status=1;
+                                                    msg_status=Constant._Message_status_success;
+                                                }
+                                                else
+                                                {
+                                                    msg_status=Constant._Message_status_error;
+                                                    paper_error_count++;
+                                                }
+
                                             }
-                                            else {
-                                                msg_status=Constant._Message_status_error;
+                                            else
+                                            {
+                                                msg_status=Constant._Message_status_warning; ;
                                                 paper_error_count++;
                                             }
-
+                                            contents.Add(new MessageContent
+                                            {
+                                                dataId=evaluationLocal.id,
+                                                dataName=evaluationLocal.name,
+                                                messageType=Constant._Message_type_check,
+                                                status=msg_status,
+                                                content=$"试卷文件信息:{paper.paperName}"
+                                            });
+                                        }
+                                        int paper_msg_status = Constant._Message_status_info;
+                                        if (paper_error_count>0)
+                                        {
+                                            blob=1;
+                                            paper_msg_status=Constant._Message_status_error;
                                         }
-                                        else {
-                                            msg_status=Constant._Message_status_warning; ;
-                                            paper_error_count++;
+                                        else
+                                        {
+                                            paper_msg_status=Constant._Message_status_success;
                                         }
-                                        contents.Add(new MessageContent {
-                                            dataId=evaluationLocal.id,
-                                            dataName=evaluationLocal.name,
-                                            messageType=Constant._Message_type_check, status=msg_status, content=$"试卷文件信息:{paper.paperName}" });
-                                    }
-                                    int paper_msg_status = Constant. _Message_status_info;
-                                    if (paper_error_count>0)
-                                    {
-                                        paper_msg_status=Constant._Message_status_error;
-                                    }
-                                    else {
-                                        paper_msg_status=Constant._Message_status_success;
+                                        await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file,
+                                            new MessageContent
+                                            {
+                                                dataId=evaluationLocal.id,
+                                                dataName=evaluationLocal.name,
+                                                messageType=Constant._Message_type_message,
+                                                status=paper_msg_status,
+                                                content=$"试卷名称:[{paperIndex}]{evaluationExam.examName}-{evaluationExam.subjectName}-{paper.paperName}\r\n文件数量:{paper.blobs.Count()},检测成功数量:{contents.Count(x => x.status==Constant._Message_status_success)},检测异常数量{contents.Count(x => x.status==Constant._Message_status_error)}",
+                                                contents=contents
+                                            });
                                     }
-                                    await _signalRExamServerHub.SendMessage(_memoryCache, _logger, deviceId, Constant._Message_grant_type_check_file, 
-                                        new MessageContent {
-                                            dataId=evaluationLocal.id,
-                                            dataName=evaluationLocal.name,
-                                            messageType=Constant._Message_type_message,
-                                            status=paper_msg_status,
-                                            content=$"试卷名称:[{paperIndex}]{evaluationExam.examName}-{evaluationExam.subjectName}-{paper.paperName}\r\n文件数量:{paper.blobs.Count()},检测成功数量:{contents.Count(x => x.status==Constant._Message_status_success)},检测异常数量{contents.Count(x => x.status==Constant._Message_status_error)}",
-                                            contents=contents
-                                        });
                                 }
                             }
                         }
                     }
                 }
-                catch (Exception e) { 
-                
+                catch (Exception e) {
+                    _logger.LogData<object>(new {code=500,msg=e.Message,data = new { content= e.StackTrace } }, evaluationLocal.id!);
                 }
 
                 //检查需要更新的项目:
@@ -540,7 +573,7 @@ namespace IES.ExamServer.Controllers
                 checkTotal,
                 checkSuccess,
                 checkError,
-                checkWarning
+                checkWarning,
             });
         }
 

+ 156 - 0
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/DI/ServiceInitializer.cs

@@ -0,0 +1,156 @@
+using IES.ExamServer.Services;
+using Microsoft.AspNetCore.Hosting.Server.Features;
+using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.Extensions.Caching.Memory;
+using System.Text.Encodings.Web;
+using System.Text.Json.Nodes;
+using System.Text.Json;
+using System.Text.Unicode;
+using IES.ExamServer.Helper;
+using IES.ExamServer.Models;
+
+namespace IES.ExamServer.DI
+{
+    public class ServiceInitializer
+    {
+        private readonly IMemoryCache _cache;
+        private readonly IHttpClientFactory _clientFactory;
+        private readonly LiteDBFactory _liteDBFactory;
+        private readonly IConfiguration _configuration;
+        private readonly DataCenterConnectionService _connectionService;
+        private readonly IHostApplicationLifetime _lifetime;
+        private readonly IServer _server;
+        private readonly ILogger<ServiceInitializer> _logger;
+
+        public ServiceInitializer(IMemoryCache cache,
+        IHttpClientFactory clientFactory,
+        LiteDBFactory liteDBFactory,
+        IConfiguration configuration,
+        DataCenterConnectionService connectionService,
+        IHostApplicationLifetime lifetime,
+        IServer server,
+        ILogger<ServiceInitializer> logger)
+        {
+            _cache = cache;
+            _clientFactory = clientFactory;
+            _liteDBFactory = liteDBFactory;
+            _configuration = configuration;
+            _connectionService = connectionService;
+            _lifetime = lifetime;
+            _server = server;
+            _logger = logger;
+        }
+
+        public async Task InitializeAsync()
+        {
+            JsonNode? data = null;
+            int hybrid = 0;
+            string remote = "127.0.0.1";
+            string region = "局域网·内网";
+
+            try
+            {
+                string? centerUrl = _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(Constant._KeyServerCenter, data);
+                    remote = $"{data["ip"]}";
+                    region = $"{data["region"]}";
+                    hybrid = 1;
+                }
+            }
+            catch (Exception ex)
+            {
+                // 云端服务连接失败
+                hybrid = 0;
+            }
+            if (hybrid==1)
+            {
+                string? centerUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
+                var httpClient = _clientFactory.CreateClient();
+                httpClient.Timeout = TimeSpan.FromSeconds(10);
+                HttpResponseMessage message = await httpClient.GetAsync("https://teammodelos.blob.core.chinacloudapi.cn/0-public/schools.json");
+                if (message.IsSuccessStatusCode)
+                {
+                    // 读取响应内容
+                    string content = await message.Content.ReadAsStringAsync();
+                    // 保存文件的路径
+                    string filePath = Path.Combine(Directory.GetCurrentDirectory(),"wwwroot", "package", "schools.json");
+                    // 确保目录存在
+                    Directory.CreateDirectory(Path.GetDirectoryName(filePath)!);
+                    // 将内容写入文件
+                    await File.WriteAllTextAsync(filePath, content);
+                }
+                else
+                {
+                    throw new Exception($"Failed to download data. Status code: {message.StatusCode}");
+                }
+            }
+
+            // 单例模式存储云端数据中心连接状态
+            _connectionService.centerUrl = hybrid == 1 ? $"{data?["centerUrl"]}" : null;
+            _connectionService.dataCenterIsConnected = hybrid == 1;
+
+            _lifetime.ApplicationStarted.Register(() =>
+            {
+                var addresses = _server.Features.Get<IServerAddressesFeature>()?.Addresses;
+                ServerDevice serverDevice = IndexService.GetServerDevice(remote, region, addresses);
+                IEnumerable<School> schools = _liteDBFactory.GetLiteDatabase().GetCollection<School>().FindAll();
+                School? school = schools?.FirstOrDefault();
+                serverDevice.school = school;
+                //int domainStatus =0;
+                //string domain = builder.Configuration.GetValue<string>("ExamClient:Domain");
+                //foreach (var network in serverDevice.networks) 
+                //{
+                //    try
+                //    {
+                //        string domain_entry = $"{network.ip}    {domain}";
+                //        string hostsFilePath = @"C:\Windows\System32\drivers\etc\hosts";
+                //        string content = File.ReadAllText(hostsFilePath, Encoding.UTF8);
+                //        if (!content.Contains(domain_entry))
+                //        {
+                //            content += Environment.NewLine + domain_entry;
+                //            // 使用管理员权限运行此程序,不然会抛出UnauthorizedAccessException
+                //            File.WriteAllText(hostsFilePath, content, Encoding.UTF8);
+                //            domainStatus=1;
+                //            // Console.WriteLine("Hosts file updated successfully.");
+                //        }
+                //        else
+                //        {
+                //            domainStatus=1;
+                //            //Console.WriteLine("The entry already exists in the hosts file.");
+                //        }
+                //    }
+                //    catch (UnauthorizedAccessException)
+                //    {
+                //        domainStatus=2;
+                //        // Console.WriteLine("You need to run this program with administrative privileges to modify the hosts file.");
+                //    }
+                //    catch (Exception ex)
+                //    {
+                //        domainStatus=0;
+                //        // Console.WriteLine($"An error occurred: {ex.Message}");
+                //    }
+                //}
+                //serverDevice.domainStatus=domainStatus;
+                //serverDevice.domain=domain;
+                _logger.LogInformation($"服务端设备信息:{JsonSerializer.Serialize(serverDevice, options: new JsonSerializerOptions { Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) })}");
+                _cache.Set(Constant._KeyServerDevice, serverDevice);
+            });
+
+            // 退出程序
+            _lifetime.ApplicationStopping.Register(() =>
+            {
+                Console.WriteLine("The application is stopping. Performing cleanup...");
+                // 在这里添加清理资源、保存数据等逻辑
+            });
+        }
+    }
+}

+ 3 - 1
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/IES.ExamServer.csproj

@@ -19,7 +19,6 @@
 	</PropertyGroup>-->
 	<ItemGroup>
 		<Folder Include="Logs\DataLogs\" />
-		<Folder Include="wwwroot\package\" />
 	</ItemGroup>
 	
 	<ItemGroup>
@@ -50,6 +49,9 @@
 	  <Content Update="wwwroot">
 	    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
 	  </Content>
+	  <Content Update="wwwroot\package\schools.json">
+	    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+	  </Content>
 	</ItemGroup>
 
 	<ItemGroup>

+ 76 - 0
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Models/ServerDevice.cs

@@ -0,0 +1,76 @@
+using IES.ExamServer.Services;
+
+namespace IES.ExamServer.Models
+{
+   
+    public class ServerDevice
+    {
+        public School? school { get; set; }
+        /// <summary>
+        /// 设备id
+        /// </summary>
+        public string? deviceId { get; set; }
+        public string? userName { get; set; }
+        /// <summary>
+        /// 机器名
+        /// </summary>
+        public string? name { get; set; }
+        /// <summary>
+        /// 操作系统
+        /// </summary>
+        public string? os { get; set; }
+        /// <summary>
+        /// 操作系统位数 64位/32位
+        /// </summary>
+        public string? bit { get; set; }
+        /// <summary>
+        /// 操作系统指令架构 x86/x64, arm arm64 其他
+        /// </summary>
+        public string? arch { get; set; }
+        /// <summary>
+        /// CPU核心数量
+        /// </summary>
+        public int cpu { get; set; }
+
+        public List<CPUInfo> cpuInfos { get; set; } = new List<CPUInfo>();
+        /// <summary>
+        /// 内存大小
+        /// </summary>
+        public long ram { get; set; }
+        /// <summary>
+        /// 远程ip
+        /// </summary>
+        public string? remote { get; set; }
+        /// <summary>
+        /// 端口,可能有多个端口
+        /// </summary>
+        public List<UriInfo> uris { get; set; } = new List<UriInfo>();
+        /// <summary>
+        /// 地区
+        /// </summary>
+        public string? region { get; set; }
+        /// <summary>
+        /// 网卡 IP信息
+        /// </summary>
+        public List<Network> networks { get; set; } = new List<Network>();
+        /// <summary>
+        /// 本地域名
+        /// </summary>
+       // public string? domain {  get; set; }
+        /// <summary>
+        /// 域名状态 0:未注册,1:正常,2:未授权,需要手动设置或管理员运行
+        /// </summary>
+        //public int domainStatus { get; set; }
+    }
+    public class CPUInfo
+    {
+        public string? name { get; set; }
+        public string? hz { get; set; }
+    }
+    public class Network
+    {
+        public string? name { get; set; }
+        public string? mac { get; set; }
+        public string? ip { get; set; }
+    }
+}

+ 4 - 96
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Program.cs

@@ -79,6 +79,7 @@ namespace IES.ExamServer
             builder.Services.AddMemoryCache();
             // 注册 ConnectionService 为单例
             builder.Services.AddSingleton<DataCenterConnectionService>();
+            builder.Services.AddSingleton<ServiceInitializer>();
             builder.Services.AddCors(options =>
             {
                 options.AddDefaultPolicy(
@@ -168,104 +169,11 @@ namespace IES.ExamServer
 //                endpoints.MapFallbackToFile("index.html");
 //#endif
             });
-            IMemoryCache? cache = app.Services.GetRequiredService<IMemoryCache>();
-            IHttpClientFactory? clientFactory = app.Services.GetRequiredService<IHttpClientFactory>();
-            LiteDBFactory liteDBFactory = app.Services.GetRequiredService<LiteDBFactory>();
-            JsonNode? data = null;
-            int hybrid = 0;
-            string remote = "127.0.0.1";
-            string region = "局域网·内网";
-            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(Constant._KeyServerCenter, data);
-                    remote=$"{data["ip"]}";
-                    region=$"{data["region"]}";
-                    hybrid =1;
-                }
-            }
-            catch (Exception ex)
-            {
-                //云端服务连接失败
-                hybrid = 0;
-            }
-            //单例模式存储云端数据中心连接状态
-            DataCenterConnectionService connectionService=  app.Services.GetRequiredService<DataCenterConnectionService>();
-            connectionService.centerUrl = hybrid == 1 ? $"{data?["centerUrl"]}" : null;
-            connectionService.dataCenterIsConnected = hybrid==1 ? true : false;
-            var lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
-            lifetime.ApplicationStarted.Register(() =>
-            {
-               
-                var server = app.Services.GetService<IServer>();
-                var logger = app.Services.GetRequiredService<ILogger<Program>>();
-                var d = server?.Features.Get<IServerAddressesFeature>();
-                IEnumerable<string>? _url = server?.Features.Get<IServerAddressesFeature>()?.Addresses;
-                ServerDevice serverDevice = IndexService.GetServerDevice(remote, region, _url);
-                //int domainStatus =0;
-                //string domain = builder.Configuration.GetValue<string>("ExamClient:Domain");
-                //foreach (var network in serverDevice.networks) 
-                //{
-                //    try
-                //    {
-                //        string domain_entry = $"{network.ip}    {domain}";
-                //        string hostsFilePath = @"C:\Windows\System32\drivers\etc\hosts";
-                //        string content = File.ReadAllText(hostsFilePath, Encoding.UTF8);
-                //        if (!content.Contains(domain_entry))
-                //        {
-                //            content += Environment.NewLine + domain_entry;
-                //            // 使用管理员权限运行此程序,不然会抛出UnauthorizedAccessException
-                //            File.WriteAllText(hostsFilePath, content, Encoding.UTF8);
-                //            domainStatus=1;
-                //            // Console.WriteLine("Hosts file updated successfully.");
-                //        }
-                //        else
-                //        {
-                //            domainStatus=1;
-                //            //Console.WriteLine("The entry already exists in the hosts file.");
-                //        }
-                //    }
-                //    catch (UnauthorizedAccessException)
-                //    {
-                //        domainStatus=2;
-                //        // Console.WriteLine("You need to run this program with administrative privileges to modify the hosts file.");
-                //    }
-                //    catch (Exception ex)
-                //    {
-                //        domainStatus=0;
-                //        // Console.WriteLine($"An error occurred: {ex.Message}");
-                //    }
-                //}
-                //serverDevice.domainStatus=domainStatus;
-                //serverDevice.domain=domain;
-                logger.LogInformation($"服务端设备信息:{JsonSerializer.Serialize(serverDevice,options: new JsonSerializerOptions { Encoder =JavaScriptEncoder.Create(UnicodeRanges.All)})}");
-                cache.Set(Constant._KeyServerDevice, serverDevice);
-            });
-
-            // 退出程序
-            lifetime.ApplicationStopping.Register(() =>
-            {
-                Console.WriteLine("The application is stopping. Performing cleanup...");
-                // 在这里添加清理资源、保存数据等逻辑
-            });
-            app.MapGet("/hello",   (ILogger<Program> logger) =>
-            {
-                logger.LogInformation("This is an information log.");
-                logger.LogError("This is an error log.");
 
-                var data = new { Id = 123, Name = "Test Data服务端设备信息" };
-                  logger.LogData(data, data.Id.ToString());
 
-                return "Hello World!";
-            });
+            // 获取 ServiceInitializer 实例并初始化
+            var connectionManager = app.Services.GetRequiredService<ServiceInitializer>();
+            await connectionManager.InitializeAsync();
             await app.RunAsync();
         }
         //static void OnExit(object sender, EventArgs e)

+ 2 - 71
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Services/IndexService.cs

@@ -8,6 +8,7 @@ using System.Text.Json;
 using System.Text.Json.Nodes;
 using System.Text.RegularExpressions;
 using System.Management;
+using IES.ExamServer.Models;
 
 namespace IES.ExamServer.Services
 {
@@ -376,76 +377,6 @@ namespace IES.ExamServer.Services
     {
         public string? protocol { get; set; }
         public int port { get; set; }
-       
-    }
-    public class ServerDevice
-    { 
-        
-        /// <summary>
-        /// 设备id
-        /// </summary>
-        public string? deviceId { get; set; }
-        public string? userName {  get; set; }
-        /// <summary>
-        /// 机器名
-        /// </summary>
-        public string? name { get; set; }
-        /// <summary>
-        /// 操作系统
-        /// </summary>
-        public string? os { get; set; }
-        /// <summary>
-        /// 操作系统位数 64位/32位
-        /// </summary>
-        public string? bit {  get; set; }
-        /// <summary>
-        /// 操作系统指令架构 x86/x64, arm arm64 其他
-        /// </summary>
-        public  string? arch { get; set; }
-        /// <summary>
-        /// CPU核心数量
-        /// </summary>
-        public int cpu { get; set; }
-
-        public List<CPUInfo> cpuInfos { get; set; } = new List<CPUInfo>();
-        /// <summary>
-        /// 内存大小
-        /// </summary>
-        public long ram { get; set;}
-        /// <summary>
-        /// 远程ip
-        /// </summary>
-        public string? remote { get; set; }
-        /// <summary>
-        /// 端口,可能有多个端口
-        /// </summary>
-        public List<UriInfo> uris { get; set; } = new List<UriInfo>();
-        /// <summary>
-        /// 地区
-        /// </summary>
-        public string? region { get; set; }
-        /// <summary>
-        /// 网卡 IP信息
-        /// </summary>
-        public List<Network> networks { get; set; } = new List<Network>();
-        /// <summary>
-        /// 本地域名
-        /// </summary>
-       // public string? domain {  get; set; }
-        /// <summary>
-        /// 域名状态 0:未注册,1:正常,2:未授权,需要手动设置或管理员运行
-        /// </summary>
-        //public int domainStatus { get; set; }
-    }
-    public class CPUInfo 
-    {
-        public string? name { get; set; }
-        public string? hz { get; set; }
-    }
-    public class Network
-    {
-        public string? name { get; set; }
-        public string? mac { get; set; }
-        public string? ip { get; set; }
     }
+   
 }

+ 4 - 3
TEAMModelOS.SDK/Models/Service/EvaluationSyncInfoService.cs

@@ -501,9 +501,10 @@ namespace TEAMModelOS.SDK.Models.Service
                 string evaluationSyncInfoSJson = evaluationSyncInfo.ToJsonString();
                 dataSize+= Encoding.UTF8.GetByteCount(evaluationSyncInfoSJson);
                 evaluationClient.dataSize = dataSize;
-                await azureStorage.GetBlobContainerClient(ownerId).UploadFileByContainer(sourceJson, $"package/exam/{id}", "source.json");
-                await azureStorage.GetBlobContainerClient(ownerId).UploadFileByContainer(groupListJson, $"package/exam/{id}", "grouplist.json");
-                await azureStorage.GetBlobContainerClient(ownerId).UploadFileByContainer(new { evaluationClient, evaluationExams }.ToJsonString(), $"package/exam/{id}", "evaluation.json");
+                await azureStorage.GetBlobContainerClient(ownerId).UploadFileByContainer(sourceJson, $"package/{id}/data", "source.json");
+                await azureStorage.GetBlobContainerClient(ownerId).UploadFileByContainer(groupListJson, $"package/{id}/data", "grouplist.json");
+                await azureStorage.GetBlobContainerClient(ownerId).UploadFileByContainer(new { evaluationClient, evaluationExams }.ToJsonString(), $"package/{id}/data", "evaluation.json");
+
                 evaluationSyncInfo.dataSize = dataSize;
               
                 await azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).UpsertItemAsync<EvaluationSyncInfo>(evaluationSyncInfo, new PartitionKey("EvaluationSyncInfo"));

+ 3 - 3
TEAMModelOS/Controllers/Both/EvaluationSyncInfoController.cs

@@ -130,7 +130,7 @@ namespace TEAMModelOS.Controllers.Both
             EvaluationClient evaluationClient = null;
             try 
             {
-                BlobDownloadResult downloadResult = await _azureStorage.GetBlobContainerClient(evaluationSyncInfo.ownerId).GetBlobClient($"package/exam/{evaluationSyncInfo.id}/evaluation.json").DownloadContentAsync();
+                BlobDownloadResult downloadResult = await _azureStorage.GetBlobContainerClient(evaluationSyncInfo.ownerId).GetBlobClient($"package/{evaluationSyncInfo.id}/data/evaluation.json").DownloadContentAsync();
                 var evaluationData = JsonDocument.Parse(downloadResult.Content).RootElement;
                  evaluationClient= evaluationData.GetProperty("evaluationClient").ToObject<EvaluationClient>();
                 List<EvaluationExam> evaluationExams = evaluationData.GetProperty("evaluationExams").ToObject<List<EvaluationExam>>();
@@ -151,7 +151,7 @@ namespace TEAMModelOS.Controllers.Both
                     evaluationClient.grouplistHash=listInfo.newGrouplistHash;
                     evaluationClient.studentCount=evaluationSyncInfo.studentCount;
                     evaluationClient.grouplist=evaluationSyncInfo.grouplist;
-                    await _azureStorage.GetBlobContainerClient(evaluationClient.ownerId).UploadFileByContainer(new { evaluationClient, evaluationExams }.ToJsonString(), $"package/exam/{evaluationClient.id}", "evaluation.json");
+                    await _azureStorage.GetBlobContainerClient(evaluationClient.ownerId).UploadFileByContainer(new { evaluationClient, evaluationExams }.ToJsonString(), $"package/{evaluationSyncInfo.id}/data", "evaluation.json");
                 }
                 else {
                     if (!evaluationClient.grouplistHash.Equals(evaluationSyncInfo.grouplistHash))
@@ -174,7 +174,7 @@ namespace TEAMModelOS.Controllers.Both
                 }
                 else 
                 {
-                    BlobDownloadResult downloadResult = await _azureStorage.GetBlobContainerClient(evaluationSyncInfo.ownerId).GetBlobClient($"package/exam/{evaluationSyncInfo.id}/grouplist.json").DownloadContentAsync();
+                    BlobDownloadResult downloadResult = await _azureStorage.GetBlobContainerClient(evaluationSyncInfo.ownerId).GetBlobClient($"package/{evaluationSyncInfo.id}/data/grouplist.json").DownloadContentAsync();
                     var grouplistJson = JsonDocument.Parse(downloadResult.Content).RootElement;
                     var groupList = grouplistJson.GetProperty("groupList").ToObject<List<RGroupList>>();
                     StringBuilder groupListData = new StringBuilder();