CrazyIter_Bin 2 anni fa
parent
commit
6f7290a99b

+ 84 - 19
TEAMModelOS.FunctionV4/ServiceBus/ActiveTaskTopic.cs

@@ -41,11 +41,17 @@ using System.Web;
 using System.Net;
 using System.Net.Http.Json;
 using System.Threading;
+using System.Collections.Concurrent;
+using Microsoft.Azure.Amqp.Framing;
+using System.Security.Policy;
 
 namespace TEAMModelOS.FunctionV4.ServiceBus
 {
     public class ActiveTaskTopic
     {
+        public static ConcurrentQueue<(ScreenshotDto screenshotDto, List<StudentArtResult> studentArts)> concurrentQueue
+          = new ConcurrentQueue<(ScreenshotDto screenshotDto, List<StudentArtResult> studentArts)>();
+        public static bool busy = false;
         private readonly AzureCosmosFactory _azureCosmos;
         private readonly DingDing _dingDing;
         private readonly AzureStorageFactory _azureStorage;
@@ -734,12 +740,12 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
             }
         }
         [Function("GenPdf")]
-        public async Task GenPdfFunc([ServiceBusTrigger("%Azure:ServiceBus:GenPdfQueue%", Connection = "Azure:ServiceBus:ConnectionString",IsBatched =false)] string msg  )
+        public async Task GenPdfFunc([ServiceBusTrigger("%Azure:ServiceBus:GenPdfQueue%",  Connection = "Azure:ServiceBus:ConnectionString",IsBatched =false)] string msg  )
         {
             //https://github.com/aafgani/AzFuncWithServiceBus/blob/a0da42f59b5fc45655b73b85bae932e84520db70/ServiceBusTriggerFunction/host.json
             //  messageHandlerOptions 设置
             JsonElement element = msg.ToObject<JsonElement>();
-            // https://dotblogs.com.tw/yc421206/2013/04/25/102300
+            // https://dotblogs.com.tw/yc421206/2013/04/25/102300  // C#  原子操作。Interlocked
             // ConcurrentQueue  http://t.zoukankan.com/hohoa-p-12622459.html
             switch (true)
             {
@@ -752,6 +758,25 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                    // break;
             }
         }
+
+        private async Task<List<string>>   DoPDFTask((ScreenshotDto screenshotDto, List<StudentArtResult> studentArts) datas) {
+            List<string> resUrls = new List<string>();
+            try {
+                var httpResponse = await _httpClient.PostAsJsonAsync("http://cdhabook.teammodel.cn:8805/screen/screenshot-pdf",
+                   datas.screenshotDto
+                );
+                if (httpResponse.StatusCode == HttpStatusCode.OK)
+                {
+                    JsonElement json_res = await httpResponse.Content.ReadFromJsonAsync<JsonElement>();
+                    resUrls = json_res.GetProperty("urls").Deserialize<List<string>>();
+                    await UpdatePdfBlob(datas.studentArts, resUrls);
+                }
+            } catch { 
+            }
+            return resUrls;
+        }
+        private readonly int psize = 20;
+        public static SpinWait spinWait = new SpinWait(); // 构造SpinWait实例
         private async Task GenArtStudentPdf(JsonElement json, string msg) {
             try
             {
@@ -782,27 +807,67 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                 {
                     env = "develop";
                 }
-                int psize = 20;
-                List<string> resUrls = new List<string>();
-                SpinWait spinWait = new SpinWait(); // 构造SpinWait实例
                
-                while (true) {
-                    bool lockKey = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"ArtStudentPdf:Lock");
-                    if (!lockKey) {
-                        //锁不存在,先取20个人的数据执行PDF生成,剩下的放在。
-                        var takes= urls.Take(20);
-                        urls.RemoveAll(z=>takes.Contains(z));
-                        await _azureRedis.GetRedisClient(8).HashSetAsync($"ArtStudentPdf:Lock",new RedisValue($"{_schoolCode}"),new RedisValue (urls.ToJsonString()));
-                        await _azureRedis.GetRedisClient(8).KeyExpireAsync($"ArtStudentPdf:Lock", DateTime.UtcNow.AddHours(15));
+                if (urls.Count <= psize)
+                {
+                    var screenshot = new ScreenshotDto
+                    {
+                        width = 1080,
+                        height = 1920,
+                        urls = urls,
+                        fileNameKey = "pdfpath",
+                        cnt = $"{_schoolCode}",
+                        root = "art",
+                        pagesize = 5,
+                        env = env
+                    };
+                    concurrentQueue.Enqueue((screenshot,artResults));
+                }
+                else {
+                    int pages = (urls.Count + psize) / psize;
+                    for (int i = 0; i < pages; i++)
+                    {
+                        var lists = urls.Skip((i) * psize).Take(psize).ToList();
+                        var screenshot = new ScreenshotDto
+                        {
+                            width = 1080,
+                            height = 1920,
+                            urls = lists,
+                            fileNameKey = "pdfpath",
+                            cnt = $"{_schoolCode}",
+                            root = "art",
+                            pagesize = 5,
+                            env = env
+                        };
+                        concurrentQueue.Enqueue((screenshot, artResults));
                     }
-                    else { 
-                        //锁存在
-                        //锁续期。
+                }
+               
+                while (true) {
+                    if (!busy)
+                    {
+                        if (concurrentQueue.Count > 0)
+                        {
 
+                            if (concurrentQueue.TryDequeue(out (ScreenshotDto screenshotDto, List<StudentArtResult> studentArts) datas))
+                            {
+                                busy = true;
+                                await DoPDFTask(datas);
+                                busy = false;
+                            }
+                            else
+                            {
+                                return;
+                            }
+                        }
+                        else { }
                     }
+                    
                     //空转一次
                     spinWait.SpinOnce();
                 }
+
+                /**
                 if (urls.Count <= psize)
                 {
                     var screenshot = new ScreenshotDto
@@ -823,7 +888,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                     if (httpResponse.StatusCode == HttpStatusCode.OK)
                     {
                         JsonElement json_res = await httpResponse.Content.ReadFromJsonAsync<JsonElement>();
-                        resUrls = json_res.GetProperty("urls").Deserialize<List<string>>();
+                        var  resUrls = json_res.GetProperty("urls").Deserialize<List<string>>();
                         await UpdatePdfBlob(artResults, resUrls);
                     }
                 }
@@ -851,12 +916,12 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                         if (httpResponse.StatusCode == HttpStatusCode.OK)
                         {
                             JsonElement json_res = await httpResponse.Content.ReadFromJsonAsync<JsonElement>();
-                            resUrls = json_res.GetProperty("urls").Deserialize<List<string>>();
+                            var resUrls = json_res.GetProperty("urls").Deserialize<List<string>>();
                             await UpdatePdfBlob(artResults, resUrls);
                         }
                     }
                 }
-               
+               */
             }
             catch (Exception ex)
             {

+ 5 - 5
TEAMModelOS.FunctionV4/TEAMModelOS.FunctionV4.csproj

@@ -46,14 +46,14 @@
 		<!--<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.0.1" />-->
 		<!--<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.3.0" />-->
 		<!--<PackageReference Include="Azure.Messaging.ServiceBus" Version="7.11.0" />-->
-		<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.3.0" OutputItemType="Analyzer" />
-		<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.6.0" />
+		<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.7.0" />
+		<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.10.0" />
 		<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
-		<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage" Version="5.0.0" />
-		<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ServiceBus" Version="5.0.0-beta.6" />
+		<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage" Version="5.0.1" />
+		<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ServiceBus" Version="5.7.0" />
 		<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.CosmosDB" Version="4.0.0-preview2" />
 		<!--<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.CosmosDB" Version="3.0.9" />-->
-		<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs" Version="5.0.0" />
+		<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage.Blobs" Version="5.0.1" />
 		<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" Version="4.1.0" />
 		<PackageReference Include="SPS.SBCompressor" Version="0.6.0" />
 		<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />

+ 55 - 44
TEAMModelOS/Controllers/Both/CourseController.cs

@@ -137,6 +137,7 @@ namespace TEAMModelOS.Controllers
                 }
                 else if ($"{option}".Equals("import")  && $"{scope}".Equals("school", StringComparison.OrdinalIgnoreCase)) {
                     if (!request.TryGetProperty("courses", out JsonElement _courses)) return BadRequest();
+                    School schoolObj = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
                     List<Course> courses = _courses.ToObject<List<Course>>();
                     if (courses.IsNotEmpty())
                     {
@@ -148,62 +149,72 @@ namespace TEAMModelOS.Controllers
                             cos.school = school;
                             cos.creatorId = id;
                             cos.code = $"Course-{school}";
-                            if (cos.scope.Equals("school") && !string.IsNullOrWhiteSpace(cos.period?.id) && !string.IsNullOrWhiteSpace(cos.subject?.id))
+                         
+                            if (cos.scope.Equals("school") && !string.IsNullOrWhiteSpace(cos.period?.id) )
                             {
-                                string sql = $"select top 1  value c from c where c.name ='{cos.name}' and c.period.id='{cos.period.id}' and c.subject.id='{cos.subject.id}'  ";
-                                Course courseDb = null;
-                                await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
-                                    .GetItemQueryIterator<Course>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey(cos.code) }))
-                                {
-                                    courseDb = item;
-                                    break;
+                                if (string.IsNullOrWhiteSpace(cos.subject?.id) && !string.IsNullOrWhiteSpace(cos.subject?.name)) {
+                                    var sub= schoolObj.period.Where(z => z.id.Equals(cos.period.id)).FirstOrDefault()?.subjects.Where(s => s.name.Equals(cos.subject?.name));
+                                    if (sub.Any()) {
+                                        cos.subject.id = sub.First().id;
+                                    }
                                 }
-                                if (courseDb != null)
-                                {
-                                    CourseChange courseChange = new CourseChange { id = courseDb.id, code = courseDb.code, name = courseDb.name, scope = courseDb.scope, school = courseDb.school, creatorId = courseDb.creatorId };
-                                    cos.schedule.ForEach(x =>
+                                if (!string.IsNullOrWhiteSpace(cos.subject?.id)) {
+                                    string sql = $"select top 1  value c from c where c.name ='{cos.name}' and c.period.id='{cos.period.id}' and c.subject.id='{cos.subject.id}'  ";
+                                    Course courseDb = null;
+                                    await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
+                                        .GetItemQueryIterator<Course>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey(cos.code) }))
                                     {
-                                        if (!string.IsNullOrWhiteSpace(x.teacherId))
+                                        courseDb = item;
+                                        break;
+                                    }
+                                    if (courseDb != null)
+                                    {
+                                        CourseChange courseChange = new CourseChange { id = courseDb.id, code = courseDb.code, name = courseDb.name, scope = courseDb.scope, school = courseDb.school, creatorId = courseDb.creatorId };
+                                        cos.schedule.ForEach(x =>
                                         {
-                                            if (!string.IsNullOrWhiteSpace(x.stulist))
+                                            if (!string.IsNullOrWhiteSpace(x.teacherId))
                                             {
-                                                var stulist = courseDb.schedule.FindAll(z => !string.IsNullOrWhiteSpace(z.stulist) && !string.IsNullOrWhiteSpace(z.teacherId) && z.stulist.Equals(x.stulist) && z.teacherId.Equals(x.teacherId));
-                                                if (!stulist.IsNotEmpty())
+                                                if (!string.IsNullOrWhiteSpace(x.stulist))
                                                 {
-                                                    courseDb.schedule.Add(x);
-                                                    courseChange.addList.Add(x.stulist);
+                                                    var stulist = courseDb.schedule.FindAll(z => !string.IsNullOrWhiteSpace(z.stulist) && !string.IsNullOrWhiteSpace(z.teacherId) && z.stulist.Equals(x.stulist) && z.teacherId.Equals(x.teacherId));
+                                                    if (!stulist.IsNotEmpty())
+                                                    {
+                                                        courseDb.schedule.Add(x);
+                                                        courseChange.addList.Add(x.stulist);
+                                                    }
                                                 }
-                                            }
-                                            if (!string.IsNullOrWhiteSpace(x.classId))
-                                            {
-                                                var classId = courseDb.schedule.FindAll(z => !string.IsNullOrWhiteSpace(z.classId) && !string.IsNullOrWhiteSpace(z.teacherId) && z.classId.Equals(x.classId) && z.teacherId.Equals(x.teacherId));
-                                                if (!classId.IsNotEmpty())
+                                                if (!string.IsNullOrWhiteSpace(x.classId))
                                                 {
-                                                    courseDb.schedule.Add(x);
-                                                    courseChange.addClass.Add(x.classId);
+                                                    var classId = courseDb.schedule.FindAll(z => !string.IsNullOrWhiteSpace(z.classId) && !string.IsNullOrWhiteSpace(z.teacherId) && z.classId.Equals(x.classId) && z.teacherId.Equals(x.teacherId));
+                                                    if (!classId.IsNotEmpty())
+                                                    {
+                                                        courseDb.schedule.Add(x);
+                                                        courseChange.addClass.Add(x.classId);
+                                                    }
                                                 }
                                             }
-                                        }
-                                    });
-                                    var messageBlob = new ServiceBusMessage(courseChange.ToJsonString()); ;
-                                    messageBlob.ApplicationProperties.Add("name", "Course");
-                                    var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
-                                    await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
-                                    courseDb = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync(courseDb, courseDb.id, new PartitionKey(courseDb.code));
-                                }
-                                else
-                                {
-                                    cos.id = Guid.NewGuid().ToString();
-                                    CourseChange courseChange = new CourseChange { id = cos.id, code = cos.code, name = cos.name, scope = cos.scope, school = cos.school, creatorId = cos.creatorId };
-                                    courseChange.addClass = cos.schedule.Select(x => x.classId).ToList();
-                                    courseChange.addList = cos.schedule.Select(x => x.stulist).ToList();
-                                    var messageBlob = new ServiceBusMessage(courseChange.ToJsonString()); ;
-                                    messageBlob.ApplicationProperties.Add("name", "Course");
-                                    var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
-                                    await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
-                                    await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync(cos, new PartitionKey(cos.code));
+                                        });
+                                        var messageBlob = new ServiceBusMessage(courseChange.ToJsonString()); ;
+                                        messageBlob.ApplicationProperties.Add("name", "Course");
+                                        var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
+                                        await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
+                                        courseDb = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync(courseDb, courseDb.id, new PartitionKey(courseDb.code));
+                                    }
+                                    else
+                                    {
+                                        cos.id = Guid.NewGuid().ToString();
+                                        CourseChange courseChange = new CourseChange { id = cos.id, code = cos.code, name = cos.name, scope = cos.scope, school = cos.school, creatorId = cos.creatorId };
+                                        courseChange.addClass = cos.schedule.Select(x => x.classId).ToList();
+                                        courseChange.addList = cos.schedule.Select(x => x.stulist).ToList();
+                                        var messageBlob = new ServiceBusMessage(courseChange.ToJsonString()); ;
+                                        messageBlob.ApplicationProperties.Add("name", "Course");
+                                        var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
+                                        await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
+                                        await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync(cos, new PartitionKey(cos.code));
+                                    }
                                 }
                                 
+                                
                             }
                         }
                         return Ok();

+ 4 - 2
TEAMModelOS/Controllers/Both/GroupListController.cs

@@ -331,9 +331,11 @@ namespace TEAMModelOS.Controllers
         /// <param name="json"></param>
         /// <returns></returns>
         [ProducesDefaultResponseType]
-        [AuthToken(Roles = "teacher,admin,student")]
         [HttpPost("get-activity-grouplist")]
+#if !DEBUG
+        [AuthToken(Roles = "teacher,admin,student")]
         [Authorize(Roles = "IES")]
+#endif
         public async Task<IActionResult> GetActivityGrouplist(JsonElement json)
         {
             var client = _azureCosmos.GetCosmosClient();
@@ -356,7 +358,7 @@ namespace TEAMModelOS.Controllers
                     }
                     else if (_type.ValueKind.Equals(JsonValueKind.String))
                     {
-                        types = new List<string> { $"{types}" };
+                        types = new List<string> { $"{_type}" };
                     }
                     if (types.IsEmpty() || types.Contains("class"))
                     {

+ 7 - 7
TEAMModelOS/Controllers/OpenApi/OpenApiService.cs

@@ -1559,30 +1559,30 @@ namespace TEAMModelOS.Controllers
                                     semesterData = okSemesterDatas.ToList(),
                                 });
                             }
-                            var ids = okSemesterDatas.Select(k => $"{k.year}-{k.semesterId}");
+                            var ids = okSemesterDatas.Select(k => $"{k.year}-{k.semesterId}-{studentId}");
                             if (ids.Any())
                             {
                                 List<OverallEducation> overallEducations = new List<OverallEducation>();
                                 string sql = $"select value c from c where c.id in ({string.Join(",", ids.Select(f => $"'{f}'"))})" +
                                     $" and c.studentId ='{studentId}' and c.schoolCode='{schoolCode}' and c.periodId='{periodId}' and c.classId='{classId}'";
                                 await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student)
-                                    .GetItemQueryIterator<OverallEducation>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"OverallEducation-{schoolCode}-{studentId}") }))
+                                    .GetItemQueryIterator<OverallEducation>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"OverallEducation-{schoolCode}") }))
                                 {
                                     overallEducations.Add(item);
                                 }
                                 var nodbids = ids.Except(overallEducations.Select(x => x.id));
-                                var newDatas = semesterDatas.FindAll(k => nodbids.Contains($"{k.year}-{k.semesterId}"));
-                                var updateDatas = semesterDatas.FindAll(k => overallEducations.Select(z => z.id).Contains($"{k.year}-{k.semesterId}"));
+                                var newDatas = semesterDatas.FindAll(k => nodbids.Contains($"{k.year}-{k.semesterId}-{studentId}"));
+                                var updateDatas = semesterDatas.FindAll(k => overallEducations.Select(z => z.id).Contains($"{k.year}-{k.semesterId}-{studentId}"));
                                 List<OverallEducation> newOverallEducations = new List<OverallEducation>();
                                 newDatas.ForEach(z => {
                                     //处理新增的学生学期画像
-                                    var overallEducation = newOverallEducations.Find(o => o.id.Equals($"{z.year}-{z.semesterId}") && o.code.Equals($"{schoolCode}-{studentId}"));
+                                    var overallEducation = newOverallEducations.Find(o => o.id.Equals($"{z.year}-{z.semesterId}-{studentId}") && o.code.Equals($"OverallEducation-{schoolCode}"));
                                     if (overallEducation == null)
                                     {
                                         overallEducation = new OverallEducation
                                         {
-                                            id = $"{z.year}-{z.semesterId}",
-                                            code = $"OverallEducation-{schoolCode}-{studentId}",
+                                            id = $"{z.year}-{z.semesterId}-{studentId}",
+                                            code = $"OverallEducation-{schoolCode}",
                                             pk = "OverallEducation",
                                             ttl = -1,
                                             name = student.name,

+ 20 - 1
TEAMModelOS/Controllers/XTest/FixLessonRecordController.cs

@@ -69,7 +69,26 @@ namespace TEAMModelOS.Controllers.XTest
             _coreAPIHttpService = coreAPIHttpService;
             _httpClient = httpClient;
         }
-
+        /// <summary>
+        ///
+        /// </summary>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("fix-overall-education")]
+        public async Task<IActionResult> FixOverallEducation(JsonElement json)
+        {
+            var client = _azureCosmos.GetCosmosClient();
+            string sql = " SELECT distinct value(c)  FROM c  where c.pk='OverallEducation' and contains(c.code,'OverallEducation-ydzt-') ";
+            List<OverallEducation> overallEducations = new List<OverallEducation>();
+            await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryIterator<OverallEducation>(queryText: sql)) 
+            {
+                overallEducations.Add(item);
+            }
+            foreach (var a in overallEducations) {
+               await client.GetContainer(Constant.TEAMModelOS, Constant.Student).DeleteItemStreamAsync(a.id, new PartitionKey(a.code));
+            }
+            return Ok(overallEducations);
+        }
 
 
         /// <summary>