CrazyIter_Bin 11 月之前
父節點
當前提交
c90242002f
共有 52 個文件被更改,包括 6563 次插入294 次删除
  1. 0 7
      TEAMModelBI/Controllers/Census/SchoolController.cs
  2. 1 1
      TEAMModelBI/TEAMModelBI.csproj
  3. 0 10
      TEAMModelBI/Tool/CosmosBank/StatsWay.cs
  4. 1 1
      TEAMModelContest/Contest.Server/Contest.Server.csproj
  5. 264 0
      TEAMModelOS.Function/.gitignore
  6. 863 0
      TEAMModelOS.Function/CosmosDBTriggers/TriggerArt.cs
  7. 457 0
      TEAMModelOS.Function/CosmosDBTriggers/TriggerCorrect.cs
  8. 2225 0
      TEAMModelOS.Function/CosmosDBTriggers/TriggerExam.cs
  9. 176 0
      TEAMModelOS.Function/CosmosDBTriggers/TriggerExamImport.cs
  10. 224 0
      TEAMModelOS.Function/CosmosDBTriggers/TriggerExamLite.cs
  11. 412 0
      TEAMModelOS.Function/CosmosDBTriggers/TriggerHomework.cs
  12. 240 0
      TEAMModelOS.Function/CosmosDBTriggers/TriggerQuotaImport.cs
  13. 280 0
      TEAMModelOS.Function/CosmosDBTriggers/TriggerStudy.cs
  14. 530 0
      TEAMModelOS.Function/CosmosDBTriggers/TriggerSurvey.cs
  15. 422 0
      TEAMModelOS.Function/CosmosDBTriggers/TriggerVote.cs
  16. 51 0
      TEAMModelOS.Function/DI/BackgroundWorkerQueue.cs
  17. 135 0
      TEAMModelOS.Function/IESCosmosDBTrigger.cs
  18. 24 0
      TEAMModelOS.Function/IESHttpTrigger.cs
  19. 37 0
      TEAMModelOS.Function/IESServiceBusTrigger.cs
  20. 27 0
      TEAMModelOS.Function/IESTimerTrigger.cs
  21. 43 0
      TEAMModelOS.Function/Program.cs
  22. 9 0
      TEAMModelOS.Function/Properties/launchSettings.json
  23. 12 0
      TEAMModelOS.Function/Properties/serviceDependencies.json
  24. 11 0
      TEAMModelOS.Function/Properties/serviceDependencies.local.json
  25. 14 0
      TEAMModelOS.Function/Properties/serviceDependencies.teammodelosfunction-test - Zip Deploy.json
  26. 36 0
      TEAMModelOS.Function/TEAMModelOS.Function.csproj
  27. 12 0
      TEAMModelOS.Function/host.json
  28. 11 0
      TEAMModelOS.Function/readme.md
  29. 0 2
      TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosExtensions.cs
  30. 9 7
      TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosFactory.cs
  31. 0 2
      TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusExtensions.cs
  32. 0 8
      TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusFactory.cs
  33. 0 1
      TEAMModelOS.SDK/DI/HttpTrigger/WebHookHttpTrigger.cs
  34. 9 3
      TEAMModelOS.SDK/DI/Multiple/MultipleAzureCosmosFactoryExtensions.cs
  35. 0 46
      TEAMModelOS.SDK/Helper/Common/JsonHelper/JsonPatchHelper.cs
  36. 0 3
      TEAMModelOS.SDK/Helper/Common/StringHelper/PingYinHelper.cs
  37. 1 2
      TEAMModelOS.SDK/Models/Cosmos/Common/StudentScoreRecord.cs
  38. 1 5
      TEAMModelOS.SDK/Models/Service/BI/BICommonWay.cs
  39. 0 2
      TEAMModelOS.SDK/Models/Service/BI/BIStats.cs
  40. 0 13
      TEAMModelOS.SDK/Models/Service/StudentService.cs
  41. 0 14
      TEAMModelOS.SDK/Models/Service/SystemService.cs
  42. 12 12
      TEAMModelOS.SDK/TEAMModelOS.SDK.csproj
  43. 1 1
      TEAMModelOS.TEST/TEAMModelOS.TEST.csproj
  44. 6 0
      TEAMModelOS.sln
  45. 1 40
      TEAMModelOS/Controllers/Both/ScoreCalcController.cs
  46. 0 1
      TEAMModelOS/Controllers/Client/HiTeachController.cs
  47. 1 22
      TEAMModelOS/Controllers/Common/ArtController.cs
  48. 1 10
      TEAMModelOS/Controllers/School/ImportExamController.cs
  49. 0 31
      TEAMModelOS/Controllers/System/BillController.cs
  50. 0 36
      TEAMModelOS/Controllers/XTest/TestController.cs
  51. 1 11
      TEAMModelOS/Filter/RequestAuditFilter.cs
  52. 3 3
      TEAMModelOS/TEAMModelOS.csproj

+ 0 - 7
TEAMModelBI/Controllers/Census/SchoolController.cs

@@ -1,17 +1,11 @@
 using Azure.Core;
 using Azure.Core;
 using Azure.Cosmos;
 using Azure.Cosmos;
-using Azure.Storage.Blobs;
-using DocumentFormat.OpenXml.Bibliography;
-using DocumentFormat.OpenXml.Spreadsheet;
-using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
-using NUnit.Framework.Constraints;
 using Pipelines.Sockets.Unofficial.Arenas;
 using Pipelines.Sockets.Unofficial.Arenas;
 using StackExchange.Redis;
 using StackExchange.Redis;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Diagnostics;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;
 using System.Text.Json;
 using System.Text.Json;
@@ -20,7 +14,6 @@ using TEAMModelBI.Models;
 using TEAMModelBI.Tool;
 using TEAMModelBI.Tool;
 using TEAMModelBI.Tool.CosmosBank;
 using TEAMModelBI.Tool.CosmosBank;
 using TEAMModelOS.Models;
 using TEAMModelOS.Models;
-using TEAMModelOS.SDK.Context.BI;
 using TEAMModelOS.SDK.Context.Constant;
 using TEAMModelOS.SDK.Context.Constant;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;

+ 1 - 1
TEAMModelBI/TEAMModelBI.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
 
 	<PropertyGroup>
 	<PropertyGroup>
-		<TargetFramework>net6.0</TargetFramework>
+		<TargetFramework>net8.0</TargetFramework>
 		<RootNamespace>TEAMModelBI</RootNamespace>
 		<RootNamespace>TEAMModelBI</RootNamespace>
 	</PropertyGroup>
 	</PropertyGroup>
 
 

+ 0 - 10
TEAMModelBI/Tool/CosmosBank/StatsWay.cs

@@ -1,23 +1,13 @@
 using Azure.Cosmos;
 using Azure.Cosmos;
-using DocumentFormat.OpenXml.Bibliography;
-using DocumentFormat.OpenXml.Math;
-using DocumentFormat.OpenXml.Office2010.Excel;
-using Microsoft.OData.Edm;
-using NUnit.Framework.Constraints;
-using OpenXmlPowerTools;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text.Json;
 using System.Text.Json;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using TEAMModelBI.Models;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models.Cosmos.BI;
 using TEAMModelOS.SDK.Models.Cosmos.BI;
-using TEAMModelOS.SDK.Models.Cosmos.BI.BITable;
 using TEAMModelOS.SDK.Models.Service.BI;
 using TEAMModelOS.SDK.Models.Service.BI;
-using TEAMModelOS.SDK.Models.Service.BIStatsWay;
-using static TEAMModelBI.Tool.CosmosBank.StatsWay;
 
 
 namespace TEAMModelBI.Tool.CosmosBank
 namespace TEAMModelBI.Tool.CosmosBank
 {
 {

+ 1 - 1
TEAMModelContest/Contest.Server/Contest.Server.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
 
   <PropertyGroup>
   <PropertyGroup>
-    <TargetFramework>net6.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
     <Nullable>enable</Nullable>
     <Nullable>enable</Nullable>
     <ImplicitUsings>enable</ImplicitUsings>
     <ImplicitUsings>enable</ImplicitUsings>
     <SpaRoot>..\contest.client</SpaRoot>
     <SpaRoot>..\contest.client</SpaRoot>

+ 264 - 0
TEAMModelOS.Function/.gitignore

@@ -0,0 +1,264 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# Azure Functions localsettings file
+local.settings.json
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc

+ 863 - 0
TEAMModelOS.Function/CosmosDBTriggers/TriggerArt.cs

@@ -0,0 +1,863 @@
+using Azure.Messaging.ServiceBus;
+using HTEXLib.COMM.Helpers;
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK;
+using Azure.Cosmos;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+
+using TEAMModelOS.Function;
+
+namespace TEAMModelOS.CosmosDBTriggers
+{
+    public class TriggerArt
+    {
+        public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
+            CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis, IConfiguration _configuration, HttpTrigger _httpTrigger)
+        {
+            try
+            {
+                if ((tdata.status != null && tdata.status.Value == 404))
+                {
+                    await client.GetContainer(Constant.TEAMModelOS, "Common").DeleteItemStreamAsync(tdata.id, new PartitionKey(tdata.code));
+                    ActivityList data = input.ToObject<ActivityList>();
+                    //删除blob 相关资料
+                    await _azureStorage.GetBlobServiceClient().DeleteBlobs(_dingDing, tdata.school, new List<string> { $"art/{tdata.id}" });
+                   // await IESActivityService.DeleteActivity(_coreAPIHttpService, client, _dingDing, data);
+                    var table_cancel = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                    List<ChangeRecord> records = await table_cancel.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id } });
+                    foreach (var record in records)
+                    {
+                        try
+                        {
+                            await table_cancel.DeleteSingle<ChangeRecord>(record.PartitionKey, record.RowKey);
+                            await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber);
+                        }
+                        catch (Exception)
+                        {
+                            continue;
+                        }
+                    }
+                    return;
+                }
+                var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                var adid = tdata.id;
+                var adcode = "";
+                string blobcntr = null;
+                if (tdata.scope.Equals("school"))
+                {
+                    adcode = $"Activity-{tdata.school}";
+                    blobcntr = tdata.school;
+                }
+                else
+                {
+                    adcode = $"Activity-{tdata.creatorId}";
+                    blobcntr = tdata.creatorId;
+                }
+                ArtEvaluation art = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ArtEvaluation>(tdata.id, new Azure.Cosmos.PartitionKey($"{tdata.code}"));
+
+                if (art != null)
+                {
+                    string PartitionKey = string.Format("{0}{1}{2}", art.code, "-", art.progress);
+                    List<ChangeRecord> voteRecords = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id }, { "PartitionKey", PartitionKey } });
+                    switch (art.progress)
+                    {
+                        case "pending":
+                            var messageVote = new ServiceBusMessage(new { tdata.id, progress = "going", code = tdata.code }.ToJsonString());
+                            messageVote.ApplicationProperties.Add("name", "Art");
+                            if (voteRecords.Count > 0)
+                            {
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVote, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                try
+                                {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), voteRecords[0].sequenceNumber);
+                                }
+                                catch (Exception)
+                                {
+                                }
+                                voteRecords[0].sequenceNumber = start;
+                                await table.SaveOrUpdate<ChangeRecord>(voteRecords[0]);
+                            }
+                            else
+                            {
+
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVote, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                ChangeRecord changeRecord = new ChangeRecord
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = start,
+                                    msgId = messageVote.MessageId
+                                };
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+                            break;
+                        case "going":
+                            /*
+                             if (art.classes.Count > 0)
+                            {
+
+                               List<string> classes = ExamService.getClasses(art.classes, art.stuLists);
+                               (List<RMember> tmdIds, List<RGroupList> classLists) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classes, art.school, null);
+                               var addStudentsCls = tmdIds.FindAll(x => x.type == 2);
+                               var addTmdidsCls = tmdIds.FindAll(x => x.type == 1);
+                               List<string> tmds = new List<string>();
+                               if (addTmdidsCls.IsNotEmpty())
+                               {
+                                   tmds.AddRange(addTmdidsCls.Select(x => x.id).ToList());
+                               }
+                               List<StuActivity> stuActivities = new List<StuActivity>();
+                               List<StuActivity> tmdActivities = new List<StuActivity>();
+                               List<StuActivity> tchActivities = new List<StuActivity>();
+                               List<string> sub = new();
+                               if (art.subjects.Count > 0)
+                               {
+                                   foreach (var course in art.subjects)
+                                   {
+                                       sub.Add(course.id);
+                                   }
+                               }
+                               if (tmds.IsNotEmpty())
+                               {
+                                   tmds.ForEach(x =>
+                                   {
+                                       HashSet<string> classIds = new HashSet<string>();
+                                       classLists.ForEach(z =>
+                                       {
+                                           z.members.ForEach(y =>
+                                           {
+                                               if (y.id.Equals(x) && y.type == 1)
+                                               {
+                                                   classIds.Add(z.id);
+                                               }
+                                           });
+                                       });
+                                       tmdActivities.Add(new StuActivity
+                                       {
+                                           pk = "Activity",
+                                           id = art.id,
+                                           code = $"Activity-{x}",
+                                           type = "Art",
+                                           name = art.name,
+                                           startTime = art.startTime,
+                                           endTime = art.endTime,
+                                           scode = art.code,
+                                           scope = art.scope,
+                                           school = art.school,
+                                           creatorId = art.creatorId,
+                                           subjects = sub,
+                                           blob = null,
+                                           owner = art.owner,
+                                           createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                           ext = new Dictionary<string, JsonElement>() { { "subjects", art.subjects.ToJsonString().ToObject<JsonElement>() } },
+                                           taskStatus = -1,
+                                           classIds = classIds.ToList()
+                                       });
+                                   });
+                               }
+                               if (addStudentsCls.IsNotEmpty())
+                               {
+                                   addStudentsCls.ForEach(x =>
+                                   {
+                                       HashSet<string> classIds = new HashSet<string>();
+                                       classLists.ForEach(z =>
+                                       {
+                                           z.members.ForEach(y =>
+                                           {
+                                               if (y.id.Equals(x.id) && y.code.Equals(art.school) && y.type == 2)
+                                               {
+                                                   classIds.Add(z.id);
+                                               }
+                                           });
+                                       });
+                                       stuActivities.Add(new StuActivity
+                                       {
+                                           pk = "Activity",
+                                           id = art.id,
+                                           code = $"Activity-{x.code.Replace("Base-", "")}-{x.id}",
+                                           type = "Art",
+                                           name = art.name,
+                                           startTime = art.startTime,
+                                           endTime = art.endTime,
+                                           scode = art.code,
+                                           scope = art.scope,
+                                           school = art.school,
+                                           creatorId = art.creatorId,
+                                           subjects = sub,
+                                           blob = null,
+                                           owner = art.owner,
+                                           createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                           ext = new Dictionary<string, JsonElement>() { { "subjects", art.subjects.ToJsonString().ToObject<JsonElement>() } },
+                                           taskStatus = -1,
+                                           classIds = classIds.ToList()
+                                       });
+                                   });
+                               }
+                               await IESActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
+
+
+                           }*/
+                            try
+                            {
+                                var messageVoteEnd = new ServiceBusMessage(new { tdata.id, progress = "finish", tdata.code }.ToJsonString());
+                                messageVoteEnd.ApplicationProperties.Add("name", "Art");
+                                if (voteRecords.Count > 0)
+                                {
+                                    long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVoteEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                    try
+                                    {
+                                        await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), voteRecords[0].sequenceNumber);
+                                    }
+                                    catch (Exception)
+                                    {
+                                    }
+                                    voteRecords[0].sequenceNumber = end;
+                                    await table.SaveOrUpdate<ChangeRecord>(voteRecords[0]);
+                                }
+                                else
+                                {
+                                    long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVoteEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                    ChangeRecord changeRecord = new()
+                                    {
+                                        RowKey = tdata.id,
+                                        PartitionKey = PartitionKey,
+                                        sequenceNumber = end,
+                                        msgId = messageVoteEnd.MessageId
+                                    };
+                                    await table.Save<ChangeRecord>(changeRecord);
+                                }
+
+                            }
+                            catch (Exception e)
+                            {
+                                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-艺术评测going{e.Message}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                            }
+                            finally {
+                                string pkey = string.Format("{0}{1}{2}", art.code, "-", "pending");
+                                await table.DeleteSingle<ChangeRecord>(pkey, tdata.id);
+                            }
+                            
+
+                            break;
+                        case "finish":
+
+                            //判定是否是区级创建的活动内容
+                            /* if (art.lost.Count == 0 && art.pass == 0)
+                             {
+                                 if (art.owner.Equals("area") && string.IsNullOrEmpty(art.pId))
+                                 {
+                                     *//* List<(string id, string code, List<Tasks> settings)> artSchools = new();
+                                      string ql = $"select c.id,c.school,c.settings,c.classes from c where  c.pk = 'Art' and c.pId = '{art.id}'";
+                                      await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: ql))
+                                      {
+                                          using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                                          if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                                          {
+                                              var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
+                                              while (accounts.MoveNext())
+                                              {
+                                                  JsonElement account = accounts.Current;
+                                                  List<Tasks> settings = account.GetProperty("settings").ToObject<List<Tasks>>();
+                                                  artSchools.Add((account.GetProperty("id").GetString(), account.GetProperty("school").GetString(), settings));
+
+                                              }
+                                          }
+                                      }
+                                      foreach (var (id, code, settings) in artSchools)
+                                      {
+                                          List<(string eId, string sId)> ids = new();
+                                          var examIds = settings.SelectMany(s => s.task).Where(a => a.type == 1).Select(z => new { z.acId, z.subject }).ToList();
+                                          examIds.ForEach(x =>
+                                          {
+                                              ids.Add((x.acId, x.subject));
+                                          });
+                                          List<(string code, string sub, List<string> stu)> stuInfo = await getLostAsync(ids, client, code);
+                                          List<string> stus = new();
+                                          foreach (var lost in stuInfo)
+                                          {
+                                              if (stus.Count == 0)
+                                              {
+                                                  stus = stus.Union(lost.stu).ToList();
+                                              }
+                                              else {
+                                                  stus = stus.Intersect(lost.stu).ToList();
+                                              }                                          
+                                              LostStudent lostStudent = new()
+                                              {
+                                                  code = lost.code,
+                                                  subject = lost.sub,
+                                                  stu = lost.stu.Count
+                                              };
+                                              art.lost.Add(lostStudent);
+                                          }
+                                          art.miss.Add(stus.Count);
+
+                                      }
+                                      art.pass = 1;
+                                      await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ArtEvaluation>(art, art.id, new PartitionKey(art.code));*//*
+                                 }
+                                 else
+                                 {
+                                     //获取当前艺术评价相关评测ID目前暂时排除区级发布的评测信息
+
+                                     *//*List<(string eId, string sId)> ids = new();
+                                     var examId = art.settings.SelectMany(x => x.task).Where(c => c.type == 1).Select(z => new { z.acId, z.subject }).ToList();
+                                     examId.ForEach(x =>
+                                     {
+                                         ids.Add((x.acId, x.subject));
+                                     });
+                                     List<(string code, string sub, List<string> stu)> stuInfo = await getLostAsync(ids, client, art.school);
+                                     List<string> stus = new();
+                                     foreach (var (code, sub, stu) in stuInfo)
+                                     {
+                                         if (stus.Count == 0)
+                                         {
+                                             stus = stus.Union(stu).ToList();
+                                         }
+                                         else
+                                         {
+                                             stus = stus.Intersect(stu).ToList();
+                                         }
+                                         LostStudent lostStudent = new()
+                                         {
+                                             code = code,
+                                             subject = sub,
+                                             stu = stu.Count
+                                         };
+                                         art.lost.Add(lostStudent);
+                                     }
+                                     art.miss.Add(stus.Count);
+                                     //art.miss = stus.Count;
+                                     art.pass = 1;
+                                     await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ArtEvaluation>(art, art.id, new PartitionKey(art.code));*//*
+                                 }
+                             }*/
+                            //根据学校编码去获取区级ID
+                            try {
+                                School scInfo = new();
+                                //School scInfo = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>($"{art.school}", partitionKey: new Azure.Cosmos.PartitionKey("Base"));
+                                var response = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync($"{art.school}", partitionKey: new Azure.Cosmos.PartitionKey("Base"));
+                                if (response.Status == 200)
+                                {
+                                    using var cJson = await JsonDocument.ParseAsync(response.ContentStream);
+                                    scInfo = cJson.ToObject<School>();
+                                }
+                                ArtSetting setting = new();
+                                try
+                                {
+                                    var artResponse = await client.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync($"{scInfo.areaId}", partitionKey: new Azure.Cosmos.PartitionKey("ArtSetting"));
+                                    if (response.Status == 200)
+                                    {
+                                        using var json = await JsonDocument.ParseAsync(artResponse.ContentStream);
+                                        setting = json.ToObject<ArtSetting>();
+                                    }
+                                }
+                                catch (Exception e)
+                                {
+
+                                }
+                                if (art.classes.Any())
+                                {
+                                    //获取该艺术评测的评测Id
+                                    List<(string id, string subjectId)> ids = new();
+                                    List<ExamClassResult> examClassResults = new();
+                                    var examId = art.settings.SelectMany(x => x.task).Where(c => c.type == 1).Select(z => new { z.acId, z.subject }).ToList();
+                                    examId.ForEach(x =>
+                                    {
+                                        ids.Add((x.acId, x.subject));
+                                    });
+                                    List<string> results = new();
+                                    results = ids.Select(x => x.id).ToList();
+                                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.examId in ({string.Join(",", results.Select(x => $"'{x}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{art.school}") }))
+                                    {
+                                        using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                                        {
+                                            foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                                            {
+                                                examClassResults.Add(obj.ToObject<ExamClassResult>());
+                                            }
+                                        }
+                                    }
+                                    //获取该艺术评测下面的评测活动
+                                    List<ExamInfo> exams = new();
+                                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Common).GetItemQueryIterator<ExamInfo>(queryText: $"select value(c) from c where c.pk = 'Exam' and c.id in ({string.Join(",", results.Select(o => $"'{o}'"))})"))
+                                    {
+                                        exams.Add(item);
+                                    }
+                                    var sta = examClassResults.SelectMany(x => x.status).ToList();
+                                    var ansCount = sta.Where(x => x == 0).ToList();
+                                    var persent = ansCount.Count * 1.0 / sta.Count * 100;
+                                    var period = scInfo.period.Where(x => x.id.Equals(art.period.id))?.FirstOrDefault();
+
+                                    List<StudentArtResult> studentArtResults = new();
+                                    string sql = $"SELECT value c FROM c   where  c.pk='ArtResult' ";
+                                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student)
+                                        .GetItemQueryIterator<StudentArtResult>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtResult-{art.id}") }))
+                                    {
+                                        studentArtResults.Add(item);
+                                    }
+                                    List<Task<ItemResponse<StudentArtResult>>> tasks = new List<Task<ItemResponse<StudentArtResult>>>();
+                                    //新增数据推送 obj => Portrait
+                                    Portrait portrait = new()
+                                    {
+                                        schoolCode = art.school,
+                                        periodId = art.period?.id,
+                                        subjectId = "subject_art"
+                                    };
+                                    //var period = scInfo.period.Where(x => x.id.Equals(art.period.id)).FirstOrDefault();
+                                    List<(string ptype, string subId, List<(string name, List<string> kno)> knos)> knoledge = new();
+                                    //List<string> subs = new List<string> { "subject_painting", "subject_music" };
+                                    if (exams.Count == 0) return;
+                                    foreach (var ss in art.subjects)
+                                    {
+                                        if (string.IsNullOrEmpty(exams[0].papers[0].periodId))
+                                        {
+
+                                            knoledge.Add(await getKnowledge("university", "hbcn", client, ss.id, "be32942d-97a9-52ba-45d6-2e5b722583f5"));
+                                        }
+                                        else
+                                        {
+                                            knoledge.Add(await getKnowledge(art.periodType, exams.Where(c => c.subjects[0].id.Equals(ss.id))?.FirstOrDefault().papers[0].code, client, ss.id, exams.Where(c => c.subjects[0].id.Equals(ss.id))?.FirstOrDefault().papers[0].periodId));
+                                        }
+
+                                    }
+
+                                    List<(string name, double score, double aver, string subject)> blockScore = new();
+                                    List<(List<(string name, double score, double point, string subject)> studentScore, string stuId)> studentScores = new();
+                                    foreach (var exam in exams)
+                                    {
+                                        HashSet<string> knowledge = new HashSet<string>();
+                                        List<double> point = new List<double>();
+                                        List<List<double>> result = new List<List<double>>();
+                                        List<ClassRange> classes = new List<ClassRange>();
+                                        //求单个知识点所占分数
+                                        List<string> per = new List<string>();
+
+                                        if (exam.papers[0].knowledge != null && exam.papers[0].knowledge.Count > 0)
+                                        {
+                                            exam.papers[0].knowledge.ForEach(k =>
+                                            {
+                                                k.ForEach(e =>
+                                                {
+                                                    knowledge.Add(e);
+                                                });
+                                            });
+                                        }
+                                        point = exam.papers[0].point;
+
+                                        List<string> knowledgeName = new List<string>();
+                                        foreach (string cla in knowledge)
+                                        {
+                                            knowledgeName.Add(cla);
+                                        }
+                                        for (int k = 0; k < knowledgeName.Count; k++)
+                                        {
+                                            if (null == knowledgeName[k])
+                                            {
+                                                knowledgeName.Remove(knowledgeName[k]);
+                                            }
+                                        }
+                                        List<double> Score = new List<double>();
+                                        //List<(string name, double score, string subject)> pointScore = new();
+                                        List<string> stus = examClassResults.Where(c => c.examId.Equals(exam.id)).SelectMany(z => z.studentIds).ToList();
+                                        List<List<double>> stuScores = examClassResults.Where(c => c.examId.Equals(exam.id)).SelectMany(z => z.studentScores).ToList();
+                                        foreach (string id in stus)
+                                        {
+                                            //double scores = 0;
+                                            List<(string name, double score, double point, string subject)> studentScore = new();
+                                            for (int k = 0; k < knowledgeName.Count; k++)
+                                            {
+                                                int n = 0;
+                                                double OnePoint = 0;
+                                                double scores = 0;
+                                                exam.papers[0].knowledge.ForEach(kno =>
+                                                {
+                                                    if (kno.Contains(knowledgeName[k]))
+                                                    {
+                                                        var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
+                                                        OnePoint += point[n] * itemPersent;
+                                                        int index = stus.IndexOf(id);
+                                                        if (stuScores[index][n] > 0)
+                                                        {
+                                                            scores += stuScores[index][n] * itemPersent;
+                                                        }
+                                                    }
+                                                    n++;
+                                                });
+                                                studentScore.Add((knowledgeName[k], Math.Round(scores, 2), OnePoint, exam.subjects[0].id));
+                                            }
+                                            studentScores.Add((studentScore, id));
+                                        }
+                                        for (int k = 0; k < knowledgeName.Count; k++)
+                                        {
+                                            double OnePoint = 0;
+                                            int n = 0;
+                                            double scores = 0;
+                                            exam.papers[0].knowledge.ForEach(kno =>
+                                            {
+                                                if (kno.Contains(knowledgeName[k]))
+                                                {
+                                                    var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
+                                                    OnePoint += point[n] * itemPersent;
+                                                    foreach (string id in stus)
+                                                    {
+                                                        int index = stus.IndexOf(id);
+                                                        if (stuScores[index][n] > 0)
+                                                        {
+                                                            scores += stuScores[index][n] * itemPersent;
+                                                        }
+                                                    }
+                                                }
+                                                n++;
+                                            });
+                                            double sc = stus.Count > 0 ? Math.Round(scores * 1.0 / stus.Count, 2) : 0;
+                                            blockScore.Add((knowledgeName[k], OnePoint, sc, exam.subjects[0].id));
+                                            //blockScore.AddRange(pointScore);
+                                        }
+                                    }
+                                    var bls = blockScore.GroupBy(x => x.subject).Select(v => new
+                                    {
+                                        subjectId = v.Key,
+                                        knoScore = v.ToList().GroupBy(k => k.name).Select(z => new
+                                        {
+                                            knoName = z.Key,
+                                            score = z.ToList().Sum(j => j.score),
+                                            aver = z.ToList().Sum(j => j.aver)
+                                        })
+                                    });
+                                    //List<(string subId,List<(string name, List<string> kno)>)> subjectKnow = knoledge.Select(x => new { x.subId, x.knos }).ToList();
+                                    //var subjectKnow;
+                                    var subjectKnow = string.IsNullOrEmpty(exams[0].papers[0].periodId) ? knoledge.Select(x => new { x.subId, x.knos }).ToList() : knoledge.Where(c => c.ptype.Equals(art.periodType)).Select(x => new { x.subId, x.knos }).ToList();
+                                    /*if (string.IsNullOrEmpty(exams[0].papers[0].periodId))
+                                    {
+                                        var subjectKnow = knoledge.Select(x => new { x.subId, x.knos }).ToList();
+                                    }
+                                    else {
+                                        var subjectKnow = knoledge.Where(c => c.ptype.Equals(art.periodType)).Select(x => new { x.subId, x.knos }).ToList();
+                                    }*/
+                                    List<(string subjectId, List<(string name, double score, double persent, double aver, List<string> dim)> bks)> bs = new();
+                                    List<(string subjectId, List<(string stuId, List<(string name, double score, double point, List<string> dim)> values)> stuBks)> sbs = new();
+                                    List<(string name, double score, double av, string sId)> stuBlockScore = new();
+                                    foreach (var bb in subjectKnow)
+                                    {
+                                        var kno1 = bls.Where(c => c.subjectId.Equals(bb.subId)).SelectMany(x => x.knoScore).ToList();
+                                        var stuInfo = studentScores.Select(c => new
+                                        {
+                                            c.stuId,
+                                            subInfo = c.studentScore.Where(x => x.subject.Equals(bb.subId)).ToList()
+                                        }).Where(z => z.subInfo.Count > 0).ToList();
+                                        //var kno2 = dimensions.Where(c => c.subjectBind.Equals(bb.subId)).Select(x => new { x.dimension,x.blocks}).ToList();
+                                        List<(string name, double score, double aver)> blockScores = new();
+                                        foreach (var k2 in bb.knos)
+                                        {
+                                            double bsc = 0;
+                                            double avs = 0;
+                                            foreach (var k3 in kno1)
+                                            {
+                                                if (null != k2.kno && k2.kno.Contains(k3.knoName))
+                                                {
+                                                    bsc += k3.score;
+                                                    avs += k3.aver;
+                                                }
+                                            }
+                                            foreach (var stu in stuInfo)
+                                            {
+                                                double realScore = 0;
+                                                double realPoint = 0;
+                                                foreach (var subScore in stu.subInfo)
+                                                {
+                                                    if (null != k2.kno && k2.kno.Contains(subScore.name))
+                                                    {
+                                                        realScore = subScore.score;
+                                                        realPoint = subScore.point;
+                                                    }
+                                                }
+                                                stuBlockScore.Add((k2.name, realScore, realPoint, stu.stuId));
+                                            }
+                                            blockScores.Add((k2.name, bsc, avs));
+                                        }
+
+
+                                        var stuBlock = stuBlockScore.GroupBy(x => (x.sId)).Select(c => new
+                                        {
+                                            stuId = c.Key,
+                                            block = c.ToList().GroupBy(b => b.name).Select(q => new
+                                            {
+                                                name = q.Key,
+                                                score = q.ToList().Sum(q => q.score),
+                                                point = q.ToList().Sum(q => q.av),
+                                                dimension = setting.dimensions.Where(s => s.blocks.Contains(q.Key)).Select(x => x.dimension).ToList()
+                                            })
+                                        }).ToList();
+                                        var blk = blockScores.Select(x => new
+                                        {
+                                            x.name,
+                                            x.score,
+                                            persent = Math.Round(x.aver > 0 ? x.aver / x.score : 0, 2),
+                                            x.aver,
+                                            dimension = setting.dimensions.Where(s => s.blocks.Contains(x.name)).Select(x => x.dimension)
+                                        });
+                                        List<(string name, double score, double persent, double aver, List<string> dim)> bks = new();
+                                        List<(string stuId, List<(string name, double score, double point, List<string> dim)> values)> stuBks = new();
+                                        foreach (var bk in blk)
+                                        {
+                                            bks.Add((bk.name, bk.score, bk.persent, bk.aver, bk.dimension.ToList()));
+                                        }
+                                        foreach (var stuBlk in stuBlock)
+                                        {
+                                            List<(string name, double score, double point, List<string> dim)> values = new();
+                                            foreach (var lk in stuBlk.block)
+                                            {
+                                                values.Add((lk.name, lk.score, lk.point, lk.dimension));
+                                            }
+                                            stuBks.Add((stuBlk.stuId, values));
+                                        }
+                                        bs.Add((bb.subId, bks));
+                                        sbs.Add((bb.subId, stuBks));
+                                    }
+
+                                    var blocks = bs.Select(x => new
+                                    {
+                                        x.subjectId,
+                                        dim = x.bks.Select(z => new
+                                        {
+                                            z.name,
+                                            z.score,
+                                            z.persent,
+                                            z.aver,
+                                            z.dim
+                                        })
+                                    });
+                                    var stuBlocks = sbs.Select(x => new {
+                                        x.subjectId,
+                                        dim = x.stuBks.Select(z => new {
+                                            z.stuId,
+                                            blk = z.values.Select(c => new {
+                                                c.name,
+                                                c.score,
+                                                c.point,
+                                                c.dim
+                                            })
+                                        })
+                                    });
+                                    //获取维度得分率
+                                    var dim = setting.dimensions.GroupBy(a => a.subjectBind).Select(x => new
+                                    {
+                                        x.Key,
+                                        dim = x.ToList().Select(c => new
+                                        {
+                                            c.dimension,
+                                            persent = Math.Round(c.blocks.Select(z => new
+                                            {
+                                                persent = Math.Round(bs.Where(z => z.subjectId.Equals(x.Key)).SelectMany(k => k.bks).Where(q => q.name.Equals(z)).Sum(h => h.score) > 0 ?
+                                                bs.Where(z => z.subjectId.Equals(x.Key)).SelectMany(k => k.bks).Where(q => q.name.Equals(z)).Sum(h => h.aver) /
+                                                bs.Where(z => z.subjectId.Equals(x.Key)).SelectMany(k => k.bks).Where(q => q.name.Equals(z)).Sum(h => h.score) : 0, 2)
+                                            }).Sum(o => o.persent) / c.blocks.Count, 2)
+                                        })
+                                    });
+
+                                    //获取学期信息
+
+                                    var (currSemester, studyYear, currSemesterDate, date, nextSemester) = SchoolService.GetSemester(period, art.startTime);
+                                    //总分的占比情况
+
+                                    foreach (var rs in studentArtResults)
+                                    {
+                                        foreach (var res in rs.results)
+                                        {
+                                            if (res.quotaId.Equals("quota_21") && res.score > -1 && res.score < 95)
+                                            {
+                                                /*res.score *= 1.5;
+                                                if (res.score >= 95) {
+                                                    res.score = new Random().Next(90, 99);
+                                                }*/
+                                                //res.score = Math.Round(res.score);
+                                            }
+                                        }
+
+                                        //if (rs.totalScore == 0)
+                                        //{
+                                        foreach (var sc in rs.subjectScores)
+                                        {
+                                            //if (sc.score == 0)
+                                            //{
+                                            /* var subjectMore = rs.results.GroupBy(x => x.subjectId).Select(c => new { subject = c.Key, list = c.ToList().Select(m => new { m.quotaId,m.score}) });
+                                             var totalScore = subjectMore.Select(x => new { 
+                                                 x.subject,
+                                                 quotaScroe =  x.list.Select(c => new {
+                                                     c.quotaId,
+                                                     c.score
+                                                 }),
+                                             });*/
+                                            var quotaPercent = setting.quotas.Select(x => new
+                                            {
+                                                x.id,
+                                                x.percent,
+                                                score = x.children.Select(c => new
+                                                {
+                                                    real = rs.results.Where(r => r.quotaId.Equals(c.id) && r.subjectId.Equals(sc.subjectId) && r.score > -1).FirstOrDefault()?.score * c.percent * 0.01,
+                                                    score = c.children.Select(s => new
+                                                    {
+                                                        real = rs.results.Where(r => r.quotaId.Equals(s.id) && r.subjectId.Equals(sc.subjectId) && r.score > -1).FirstOrDefault()?.score * s.percent * 0.01
+                                                    }).Sum(n => n.real) * c.percent * 0.01
+                                                }).Sum(n => n.real + n.score) * x.percent * 0.01
+                                            });
+                                            double realScore = Math.Round((double)quotaPercent.Sum(c => c.score), 2);
+                                            sc.score = realScore;
+                                            //}
+                                        }
+                                        rs.totalScore = Math.Round(rs.subjectScores.Where(m => m.score >= 0).Sum(z => z.score), 2);
+                                        tasks.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).ReplaceItemAsync(rs, rs.id, new PartitionKey(rs.code)));
+
+                                        PortraitStudent student = new()
+                                        {
+                                            studentId = rs.studentId,
+                                            name = rs.studentName,
+                                            classId = rs.classIds[0]
+                                        };
+                                        SemesterData semesterData = new()
+                                        {
+                                            examName = art.name,
+                                            examId = art.id,
+                                            examDate = art.startTime,
+                                            examType = "",
+                                            year = studyYear,
+                                            semesterId = currSemester.id,
+                                            totalScore = 200,
+                                            sumScore = rs.totalScore,
+                                            excellenceRate = 0,
+                                            passRate = 0,
+                                        };
+                                        int index = 0;
+                                        foreach (var sj in art.subjects)
+                                        {
+                                            ItemScore item = new()
+                                            {
+                                                name = sj.name,
+                                                score = rs.subjectScores.Where(x => x.subjectId.Equals(sj.id)).FirstOrDefault().score,
+                                                time = art.startTime,
+                                                totalScore = 100,
+                                                id = sj.id,
+                                                type = sj.id,
+                                                block = stuBlocks.Where(c => c.subjectId.Equals(sj.id)).SelectMany(x => x.dim).Where(z => z.stuId.Equals(rs.studentId))?.FirstOrDefault().blk,
+                                                kno = studentScores.Where(c => c.stuId.Equals(rs.studentId)).SelectMany(c => c.studentScore).Where(
+                                                    p => p.subject.Equals(sj.id)).Select(z => new
+                                                    {
+                                                        z.name,
+                                                        z.score,
+                                                        z.point,
+                                                        block = subjectKnow.Where(v => v.subId.Equals(sj.id)).SelectMany(k => k.knos).Where(c => null != c.kno && c.kno.Contains(z.name)).Select(x => x.name)
+                                                    }),
+                                                dim = dim.Where(c => c.Key.Equals(sj.id))?.FirstOrDefault().dim
+                                            };
+                                            index++;
+                                            semesterData.itemScore.Add(item);
+                                        }
+                                        student.semesterData.Add(semesterData);
+
+                                        portrait.students.Add(student);
+                                        //}
+                                    }
+                                    if (tasks.Count > 0)
+                                    {
+                                        await Task.WhenAll(tasks);
+                                    }
+                                    //获取学生信息
+                                    //(List<RMember> rmembers, List<RGroupList> groups) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, art.classes, art.school);
+                                    /* foreach (var member in studentArtResults)
+                                     {                                
+
+                                     }*/
+                                    if (null != period && persent >= 60)
+                                    {
+                                        string location = $"{Environment.GetEnvironmentVariable("Option:Location")}";
+                                        var responseData = await _httpTrigger.RequestHttpTrigger(portrait, location, "upsert-student-portrait");
+                                    }
+                                }
+                            } catch (Exception e) {
+                                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-艺术评测finish{e.Message}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                            }
+                            finally
+                            {
+                                string pk = string.Format("{0}{1}{2}", art.code, "-", "going");
+                                await table.DeleteSingle<ChangeRecord>(pk, tdata.id);
+                            }
+                            
+
+                            break;
+                    }
+                }
+            }
+            catch (CosmosException e)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-CosmosDB异常{e.Message}\n{e.StackTrace}\n{e.Status}", GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}艺术评价异常{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+            }
+
+        }
+
+        private static async Task<(string key, string subId, List<(string name, List<string> kno)>)> getKnowledge(string key, string school, CosmosClient client, string subjectBid, string pId)
+        {
+            try
+            {
+                var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school, new PartitionKey($"Base"));
+                string subjectId = string.Empty;
+                List<Knowledge> knowledges = new();
+                List<(string name, List<string> kno)> blocks = new();
+                if (response.Status == 200)
+                {
+                    using var json = await JsonDocument.ParseAsync(response.ContentStream);
+                    School sc = json.ToObject<School>();
+                    var subjects = sc.period.Where(p => p.id.Equals(pId)).Select(x => x.subjects);
+                    foreach (var sj in subjects)
+                    {
+                        foreach (var s in sj)
+                        {
+                            if (!string.IsNullOrWhiteSpace(s.bindId) && s.bindId.Equals(subjectBid))
+                            {
+                                subjectId = s.id;
+                            }
+                        }
+                    }
+
+                    string code = $"Knowledge-{school}-{subjectId}";
+                    StringBuilder sql = new StringBuilder($"select value(c) from c");
+                    if (!string.IsNullOrWhiteSpace(pId))
+                    {
+                        sql.Append($" where c.periodId = '{pId}'");
+                    }
+
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Knowledge>(queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
+                    {
+                        knowledges.Add(item);
+                    }
+                }
+                foreach (var know in knowledges)
+                {
+                    foreach (var block in know.blocks)
+                    {
+                        blocks.Add((block.name, block.points));
+                    }
+                }
+                return (key, subjectBid, blocks);
+            }
+            catch (Exception e)
+            {
+                return (null, null, null);
+            }
+        }
+
+    }
+}

+ 457 - 0
TEAMModelOS.Function/CosmosDBTriggers/TriggerCorrect.cs

@@ -0,0 +1,457 @@
+using Azure.Cosmos;
+using Azure.Messaging.ServiceBus;
+using System.Text.Json;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+using HTEXLib.COMM.Helpers;
+using TEAMModelOS.Function;
+
+
+namespace TEAMModelOS.CosmosDBTriggers
+{
+    public static class TriggerCorrect
+    {
+        public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
+           CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis)
+        {
+            if ((tdata.status != null && tdata.status.Value == 404))
+            {
+                await client.GetContainer(Constant.TEAMModelOS, "Common").DeleteItemStreamAsync(tdata.id, new PartitionKey(tdata.code));
+                ActivityList data = input.ToObject<ActivityList>();
+                //await IESActivityService.DeleteActivity(_coreAPIHttpService, client, _dingDing, data);
+                var table_cancel = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                List<ChangeRecord> records = await table_cancel.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id } });
+                foreach (var record in records)
+                {
+                    try
+                    {
+                        await table_cancel.DeleteSingle<ChangeRecord>(record.PartitionKey, record.RowKey);
+                        await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber);
+                    }
+                    catch (Exception)
+                    {
+                        continue;
+                    }
+                }
+                return;
+            }
+            var adid = tdata.id;
+            var adcode = "";
+            string blobcntr = null;
+            if (tdata.scope.Equals("school"))
+            {
+                adcode = $"Activity-{tdata.school}";
+                blobcntr = tdata.school;
+            }
+            else
+            {
+                return;
+            }
+            //await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}阅卷配置【{tdata.name}-{tdata.id}-ttl={tdata.ttl}】正在执行", GroupNames.醍摩豆服務運維群組);
+
+            var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+
+            try {
+                Correct correct = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<Correct>(tdata.id, new Azure.Cosmos.PartitionKey($"{tdata.code}"));
+
+                if (correct != null)
+                {
+                    string PartitionKey = string.Format("{0}{1}{2}", correct.code, "-", correct.progress);
+                    List<ChangeRecord> correctRecords = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id }, { "PartitionKey", PartitionKey } });
+                    switch (correct.progress)
+                    {
+                        case "pending":
+                            var messageCorrect = new ServiceBusMessage(new { id = tdata.id, progress = "going", code = tdata.code }.ToJsonString());
+                            messageCorrect.ApplicationProperties.Add("name", "Correct");
+                            if (correctRecords.Count > 0)
+                            {
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageCorrect, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                try
+                                {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), correctRecords[0].sequenceNumber);
+                                }
+                                catch (Exception)
+                                {
+                                }
+                                correctRecords[0].sequenceNumber = start;
+                                await table.SaveOrUpdate<ChangeRecord>(correctRecords[0]);
+                            }
+                            else
+                            {
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageCorrect, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                ChangeRecord changeRecord = new ChangeRecord
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = start,
+                                    msgId = messageCorrect.MessageId
+                                };
+                                
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+                            break;
+                        case "going":
+                            //评测id
+                            string eid = correct.id;
+                            //评测的分区键
+                            string ecode = correct.scode;
+                            ExamInfo info = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ExamInfo>(tdata.id, new Azure.Cosmos.PartitionKey($"{ecode}"));
+                            if (correct.subs.IsNotEmpty())
+                            {
+
+                                foreach (var sub in correct.subs)
+                                {
+                                    ///生成阅卷教师的阅卷任务列表
+                                    if (sub.markers.IsNotEmpty())
+                                    {
+                                        foreach (var marker in sub.markers)
+                                        {
+                                            CorrectTask task = new CorrectTask
+                                            {
+                                                ttl = -1,
+                                                pk = "CorrectTask",
+                                                code = "CorrectTask-" + marker.id,
+
+                                                id = Guid.NewGuid().ToString(),
+                                                //评测id 或者阅卷配置id
+                                                cid = correct.id,
+                                                //科目
+                                                subject = sub.id,
+                                                //科目名称
+                                                subjectName = sub.name,
+                                                //评测code
+                                                ecode = correct.scode,
+                                                //阅卷配置code
+                                                scode = correct.code,
+                                                //任务名称
+                                                name = correct.name,
+                                                progress = "going",
+                                                //开始时间
+                                                startTime = correct.startTime,
+                                                //结束时间
+                                                endTime = correct.endTime,
+                                                //批改数量
+                                                count = marker.count,
+                                                //按题阅卷时,题号
+                                                qu = marker.qu,
+                                                //模块数
+                                                model = sub.model,
+                                                type = 1,
+                                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                                source = info.source
+                                            };
+                                            await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<CorrectTask>(task, new Azure.Cosmos.PartitionKey(task.code));
+                                        }
+                                    }
+
+
+                                    //生成异常卷处理人员
+                                    if (sub.err.IsNotEmpty())
+                                    {
+
+                                        foreach (var tId in sub.err)
+                                        {
+                                            CorrectTask task = new CorrectTask
+                                            {
+                                                ttl = -1,
+                                                pk = "CorrectTask",
+                                                code = "CorrectTask-" + tId,
+
+                                                id = Guid.NewGuid().ToString(),
+                                                //评测id 或者阅卷配置id
+                                                cid = correct.id,
+                                                //科目
+                                                subject = sub.id,
+                                                //科目名称
+                                                subjectName = sub.name,
+                                                //评测code
+                                                ecode = correct.scode,
+                                                //阅卷配置code
+                                                scode = correct.code,
+                                                progress = "going",
+                                                //任务名称
+                                                name = correct.name,
+                                                //开始时间
+                                                startTime = correct.startTime,
+                                                //结束时间
+                                                endTime = correct.endTime,
+                                                //模块数
+                                                model = sub.model,
+                                                type = 2,
+                                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
+                                            };
+                                            await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<CorrectTask>(task, new Azure.Cosmos.PartitionKey(task.code));
+                                        }
+
+
+                                    }
+
+                                    //生成仲裁人员
+
+                                    if (sub.arb.IsNotEmpty())
+                                    {
+
+                                        foreach (var tId in sub.arb)
+                                        {
+                                            CorrectTask task = new CorrectTask
+                                            {
+                                                ttl = -1,
+                                                pk = "CorrectTask",
+                                                code = "CorrectTask-" + tId,
+
+                                                id = Guid.NewGuid().ToString(),
+                                                //评测id 或者阅卷配置id
+                                                cid = correct.id,
+                                                //科目
+                                                subject = sub.id,
+                                                //科目名称
+                                                subjectName = sub.name,
+                                                progress = "going",
+                                                //评测code
+                                                ecode = correct.scode,
+                                                //阅卷配置code
+                                                scode = correct.code,
+                                                //任务名称
+                                                name = correct.name,
+                                                //开始时间
+                                                startTime = correct.startTime,
+                                                //结束时间
+                                                endTime = correct.endTime,
+                                                //模块数
+                                                model = sub.model,
+                                                type = 3,
+                                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
+                                            };
+                                            await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<CorrectTask>(task, new Azure.Cosmos.PartitionKey(task.code));
+                                        }
+
+
+                                    }
+                                    //评测科目
+                                    string subjectId = sub.id;
+                                    //生成临时作答数据存放到redis
+                                    //var redisClient = _azureRedis.GetRedisClient(8);
+                                    //ExamInfo info = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ExamInfo>(eid, new Azure.Cosmos.PartitionKey(ecode));
+                                    List<ExamClassResult> classResults = new List<ExamClassResult>();
+                                    //获取原题配分
+                                    int paperIndex = 0;
+                                    foreach (ExamSubject subject in info.subjects)
+                                    {
+                                        if (subject.id.Equals(subjectId))
+                                        {
+                                            break;
+                                        }
+                                        else
+                                        {
+                                            paperIndex++;
+                                        }
+                                    }
+                                    List<double> paperPoint = info.papers[paperIndex].point;
+                                    List<List<string>> ans = info.papers[paperIndex].answers;
+                                    if (info.scope.Equals("school"))
+                                    {
+
+                                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamClassResult>(
+                                        queryText: $"select value(c) from c where c.examId = '{eid}' and c.subjectId = '{subjectId}'",
+                                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{info.school}") }))
+                                        {
+                                            classResults.Add(item);
+                                        }
+                                    }
+                                    else
+                                    {
+                                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamClassResult>(
+                                            queryText: $"select value(c) from c where c.examId = '{eid}' and c.subjectId = '{subjectId}'",
+                                            requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{info.creatorId}") }))
+                                        {
+                                            classResults.Add(item);
+                                        }
+                                    }
+                                    List<Task<ItemResponse<SDK.Models.Cosmos.Common.Scoring>>> tasks = new List<Task<ItemResponse<SDK.Models.Cosmos.Common.Scoring>>>();
+                                    //初始化老师阅卷记录
+                                    //List<string> tmds = new List<string>();
+                                    /*                                List<string> marks = new List<string>();
+                                                                    for (int i = 0; i < correct.num; i++)
+                                                                    {
+                                                                        marks.Add("");
+                                                                    }*/
+                                    foreach (ExamClassResult examClass in classResults)
+                                    {
+                                        foreach (string stuId in examClass.studentIds)
+                                        {
+                                            int index = examClass.studentIds.IndexOf(stuId);
+                                            if (index > -1)
+                                            {
+                                                List<double> scc = examClass.studentScores[index];
+                                                List<Item> items = new List<Item>();
+                                                List<Qs> qss = new List<Qs>();
+                                                int itemIndex = 0;
+                                                foreach (double psc in scc)
+                                                {
+                                                    //初始化异常卷信息,初始化仲裁卷信息
+                                                    Qs qs = new Qs();
+                                                    List<Info> infos = new List<Info>();
+                                                    Item item = new Item
+                                                    {
+                                                        ssc = paperPoint[itemIndex],
+                                                        scores = infos
+                                                    };
+                                                    itemIndex++;
+                                                    items.Add(item);
+                                                    qss.Add(qs);
+                                                }
+                                                //处理学生未作答 生成阅卷数据时 客观题分数为-1的情况
+                                                List<double> scores = new List<double>();
+                                                int n = 0;
+                                                foreach (List<string> answer in ans)
+                                                {
+                                                    var scs = examClass.studentScores[index][n];
+
+                                                    if (answer.Count > 0)
+                                                    {
+                                                        if (scs == -1)
+                                                        {
+                                                            scores.Add(0);
+                                                        }
+                                                        else
+                                                        {
+                                                            scores.Add(scs);
+                                                        }
+                                                    }
+                                                    else
+                                                    {
+                                                        scores.Add(scs);
+                                                    }
+                                                    n++;
+                                                }
+                                                SDK.Models.Cosmos.Common.Scoring sc = new SDK.Models.Cosmos.Common.Scoring
+                                                {
+                                                    id = Guid.NewGuid().ToString(),
+                                                    code = "Scoring-" + info.school,
+                                                    blob = examClass.studentAnswers[index].Count > 0 ? examClass.studentAnswers[index][0] : "",
+                                                    stuId = stuId,
+                                                    examId = eid,
+                                                    subjectId = subjectId,
+                                                    scores = scores,
+                                                    count = correct.num,
+                                                    //marks = marks,
+                                                    items = items,
+                                                    qs = qss,
+                                                    //endTime = correct.endTime,
+                                                    model = sub.model
+
+                                                };
+                                                tasks.Add(client.GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<SDK.Models.Cosmos.Common.Scoring>(sc, new Azure.Cosmos.PartitionKey(sc.code)));
+                                            }
+                                            //tasks.Add(redisClient.HashSetAsync($"Exam:Scoring:{eid}-{subjectId}", stuId, new { tmdId = tmds, ans = examClass.studentAnswers[index].Count > 0 ? examClass.studentAnswers[index][0] : "", score = examClass.studentScores[index] }.ToJsonString()));
+                                        }
+
+                                    }
+                                    await Task.WhenAll(tasks);
+                                }
+                            }
+                            var messageCorrectEnd = new ServiceBusMessage(new { id = tdata.id, progress = "finish", code = tdata.code }.ToJsonString());
+                            messageCorrectEnd.ApplicationProperties.Add("name", "Correct");
+                            if (correctRecords.Count > 0)
+                            {
+                                long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageCorrectEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                try
+                                {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), correctRecords[0].sequenceNumber);
+                                }
+                                catch (Exception)
+                                {
+                                }
+                                correctRecords[0].sequenceNumber = end;
+                                await table.SaveOrUpdate<ChangeRecord>(correctRecords[0]);
+                            }
+                            else
+                            {
+                                long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageCorrectEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                ChangeRecord changeRecord = new ChangeRecord
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = end,
+                                    msgId = messageCorrectEnd.MessageId
+                                };
+                                
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+                            break;
+                        case "finish":
+                            foreach (var sub in correct.subs)
+                            {
+                                List<string> ids = new List<string>();
+                                ///阅卷教师的阅卷任务列表
+                                if (sub.markers.IsNotEmpty())
+                                {
+                                    foreach (var marker in sub.markers)
+                                    {
+                                        ids.Add(marker.id);
+                                        //await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<CorrectTask>(task, new Azure.Cosmos.PartitionKey(task.code),new ItemRequestOptions().PostTriggers);
+                                    }
+                                }
+                                //异常卷处理人员
+                                if (sub.err.IsNotEmpty())
+                                {
+
+                                    foreach (var tId in sub.err)
+                                    {
+                                        if (!ids.Contains(tId))
+                                        {
+                                            ids.Add(tId);
+                                        }
+                                    }
+                                }
+
+                                //仲裁人员
+
+                                if (sub.arb.IsNotEmpty())
+                                {
+                                    foreach (var tId in sub.arb)
+                                    {
+                                        if (!ids.Contains(tId))
+                                        {
+                                            ids.Add(tId);
+                                        }
+                                    }
+                                }
+                                List<CorrectTask> corrects = new List<CorrectTask>();
+                                foreach (string id in ids)
+                                {
+                                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<CorrectTask>(
+                                          queryText: $"select value(c) from c where c.cid = '{correct.id}'",
+                                          requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"CorrectTask-{id}") }))
+                                    {
+                                        corrects.Add(item);
+                                    }
+                                }
+                                List<Task<ItemResponse<CorrectTask>>> tasks = new List<Task<ItemResponse<CorrectTask>>>();
+                                foreach (CorrectTask task in corrects)
+                                {
+                                    task.progress = "finish";
+                                    tasks.Add(client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync(task, task.id, new Azure.Cosmos.PartitionKey(task.code)));
+                                }
+                                await Task.WhenAll(tasks);
+                            }
+                            break;
+                    }
+                }
+            }
+            catch (CosmosException e)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-CosmosDB异常{e.Message}\n{e.StackTrace}\n{e.Status}", GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception e)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-阅卷异常{e.Message}\n{e.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
+            }
+            
+        }
+    }
+}

File diff suppressed because it is too large
+ 2225 - 0
TEAMModelOS.Function/CosmosDBTriggers/TriggerExam.cs


+ 176 - 0
TEAMModelOS.Function/CosmosDBTriggers/TriggerExamImport.cs

@@ -0,0 +1,176 @@
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK;
+using Azure.Cosmos;
+using System.Net.Http;
+using TEAMModelOS.SDK.Models.Cosmos.School;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models;
+using HTEXLib.COMM.Helpers;
+using TEAMModelOS.Function;
+namespace TEAMModelOS.CosmosDBTriggers
+{
+    public class TriggerExamImport
+    {
+        public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
+            CosmosClient client, JsonElement input, TriggerData data, IHttpClientFactory _httpClient, IConfiguration _configuration,AzureRedisFactory _azureRedis)
+        { 
+            ExamImport examImport= input.ToObject<ExamImport>();
+            if (examImport != null) {
+                HashSet<string> ids = new HashSet<string>();
+                foreach (var x in examImport.subjects)
+                {
+                    foreach (var y in x.students)
+                    {
+                        string id = $"{examImport.year}-{examImport.semesterId}-{y.id}";
+                        ids.Add(id);
+                    }
+                }
+                HashSet<OverallEducation> overallEducations = new HashSet<OverallEducation>();
+                string sql = $"select value c from  c where c.id in ({string.Join(",", ids.Select(z => $"'{z}'"))}) and c.periodId='{examImport.periodId}' ";
+                var result = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<OverallEducation>(sql, $"OverallEducation-{examImport.school}");
+                IEnumerable<string> notInDbIds = null;
+                if (result.list.IsNotEmpty())
+                {
+                    notInDbIds= ids.Except(result.list.Select(x => x.id));
+                    overallEducations = new HashSet<OverallEducation>(result.list);
+                }
+                else {
+                    notInDbIds = ids;
+                }
+
+                HashSet<OverallEducation> overallEducationChanged = new HashSet<OverallEducation>();
+                foreach (var x in examImport.subjects)
+                {
+                    foreach (var y in x.students)
+                    {
+                        string id = $"{examImport.year}-{examImport.semesterId}-{y.id}";
+                        var overallEducation =  overallEducations.Where(z => z.id.Equals(id)).FirstOrDefault();
+                        if (overallEducation != null)
+                        {
+                            EducationScore exam = null;
+                            if (x.id.Equals("subject_music") || x.id.Equals("subject_painting"))
+                            {
+                                exam = overallEducation.art.Find(f => f.examId.Equals(examImport.id));
+                            }
+                            else {
+                                 exam = overallEducation.intelligence.Find(f => f.examId.Equals(examImport.id));
+                            }
+                            if (exam != null)
+                            {
+                                var item = exam.itemScore.Find(f => f.id.Equals(x.id));
+                                if (item != null)
+                                {
+                                    item.name= x.name;
+                                    if (item.score != y.score) {
+                                        overallEducationChanged.Add(overallEducation);
+                                        item.score = y.score;
+                                    }
+                                    if (item.totalScore != x.items.Sum(b => b.score)) {
+                                        overallEducationChanged.Add(overallEducation);
+                                        item.totalScore = x.items.Sum(b => b.score);
+                                    }
+                                    item.type = x.name;
+                                }
+                                else {
+                                    overallEducationChanged.Add(overallEducation);
+                                    exam.itemScore.Add(new ItemScore { name = x.name, score = y.score, totalScore = x.items.Sum(b => b.score), type = x.name, id = x.id , time=examImport.time});
+                                }
+                                if (exam.sumScore != exam.itemScore.Sum(x => x.score)) {
+                                    overallEducationChanged.Add(overallEducation);
+                                    //exam.sumScore = examImport.subjects.SelectMany(z => z.students).Where(b => b.id.Equals(y.id)).Sum(v => v.score);
+                                    exam.sumScore = exam.itemScore.Sum(x => x.score);
+                                }
+                                if (exam.totalScore != exam.itemScore.Sum(x => x.totalScore))
+                                {
+                                    overallEducationChanged.Add(overallEducation);
+                                    exam.totalScore = exam.itemScore.Sum(x => x.totalScore);
+                                    // exam.totalScore = examImport.subjects.SelectMany(t => t.items).Sum(n => n.score);
+                                }
+                                if (exam.rate != examImport.subjects.SelectMany(z => z.students).Where(b => b.id.Equals(y.id)).Sum(v => v.score) * 1.0 / examImport.subjects.SelectMany(t => t.items).Sum(n => n.score))
+                                {
+                                    overallEducationChanged.Add(overallEducation);
+                                    exam.rate = examImport.subjects.SelectMany(z => z.students).Where(b => b.id.Equals(y.id)).Sum(v => v.score) * 1.0 / examImport.subjects.SelectMany(t => t.items).Sum(n => n.score);
+                                }
+                                exam.examType = examImport.type;
+                                exam.examDate = examImport.time;
+                                exam.examName=examImport.name;
+                            }
+                            else {
+
+                                exam = new EducationScore
+                                {
+                                    examName = examImport.name,
+                                    examId = examImport.id,
+                                    examDate = examImport.time,
+                                    examType = examImport.type,
+                                    //totalScore = examImport.subjects.SelectMany(t => t.items).Sum(n => n.score),
+                                    //sumScore = examImport.subjects.SelectMany(z => z.students).Where(b => b.id.Equals(y.id)).Sum(v => v.score),
+                                    rate = examImport.subjects.SelectMany(z => z.students).Where(b => b.id.Equals(y.id)).Sum(v => v.score) * 1.0 / examImport.subjects.SelectMany(t => t.items).Sum(n => n.score),
+                                    itemScore = new List<ItemScore> { new ItemScore { name = x.name, score = y.score, totalScore = x.items.Sum(b => b.score), type = x.name, time = examImport.time, id = x.id } }
+                                };
+                                exam.totalScore = exam.itemScore.Sum(x => x.totalScore);
+                                exam.sumScore = exam.itemScore.Sum(x => x.score);
+                                if (x.id.Equals("subject_music") || x.id.Equals("subject_painting"))
+                                {
+                                    overallEducation.art.Add(exam);
+                                }
+                                else
+                                {
+                                    overallEducation.intelligence.Add(exam);
+                                }
+                                
+                                overallEducationChanged.Add(overallEducation);
+                            }
+                        }
+                        else {
+
+                            EducationScore exam = new EducationScore
+                            {
+                                examName = examImport.name,
+                                examId = examImport.id,
+                                examDate = examImport.time,
+                                examType = examImport.type,
+                                //totalScore = examImport.subjects.SelectMany(t => t.items).Sum(n => n.score),
+                                //sumScore = examImport.subjects.SelectMany(z => z.students).Where(b => b.id.Equals(y.id)).Sum(v => v.score),
+                                rate = examImport.subjects.SelectMany(z => z.students).Where(b => b.id.Equals(y.id)).Sum(v => v.score) * 1.0 / examImport.subjects.SelectMany(t => t.items).Sum(n => n.score),
+                                itemScore = new List<ItemScore> { new ItemScore { id = x.id, time = examImport.time, name = x.name, score = y.score, totalScore = x.items.Sum(b => b.score), type = x.name } }
+                            };
+                            exam.totalScore = exam.itemScore.Sum(x => x.totalScore);
+                            exam.sumScore = exam.itemScore.Sum(x => x.score);
+                            overallEducation = new OverallEducation {
+                                id = id,
+                                code = $"OverallEducation-{examImport.school}",
+                                pk = "OverallEducation",
+                                periodId = examImport.periodId,
+                                year = examImport.year,
+                                semesterId = examImport.semesterId,
+                                schoolCode = examImport.school,
+                                studentId = y.id,
+                                name = y.name,
+                                classId = y.classId,
+                                stuYear = y.stuYear,
+                                intelligence = x.id.Equals("subject_music") || x.id.Equals("subject_painting") ? new List<EducationScore> { }:new List<EducationScore> { exam },
+                                art= x.id.Equals("subject_music") || x.id.Equals("subject_painting") ? new List<EducationScore> { exam } : new List<EducationScore> {  },
+                            };
+                            overallEducationChanged.Add(overallEducation);
+                            overallEducations.Add(overallEducation);
+                        }
+                    }
+                }
+                foreach (var item in overallEducationChanged) { 
+                    await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS,Constant.Student).UpsertItemAsync(item,new PartitionKey(item.code));
+                    string key = $"OverallEducation:{item.schoolCode}:{item.periodId}:{item.year}:{item.semesterId}:{item.classId}";
+                    await _azureRedis.GetRedisClient(8).HashSetAsync(key, item.studentId, item.ToJsonString());
+                    await _azureRedis.GetRedisClient(8).KeyExpireAsync(key, new TimeSpan(180 * 24, 0, 0));
+                }
+            }
+        }
+    }
+}

+ 224 - 0
TEAMModelOS.Function/CosmosDBTriggers/TriggerExamLite.cs

@@ -0,0 +1,224 @@
+using Azure.Cosmos;
+using Azure.Messaging.ServiceBus;
+using HTEXLib.COMM.Helpers;
+using Microsoft.Azure.Documents;
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Service;
+using TEAMModelOS.Function;
+namespace TEAMModelOS.CosmosDBTriggers
+{
+    public static class TriggerExamLite
+    {
+        public static async Task Trigger (CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
+                    CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis, IConfiguration _configuration)
+        {
+            try
+            {
+                if ((tdata.status != null && tdata.status.Value == 404))
+                {
+                    await client.GetContainer(Constant.TEAMModelOS, "Common").DeleteItemStreamAsync(tdata.id, new PartitionKey(tdata.code));
+                    ActivityList data = input.ToObject<ActivityList>();
+                   // await IESActivityService.DeleteActivity(_coreAPIHttpService, client, _dingDing, data);
+                    var table_cancel = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                    List<ChangeRecord> records = await table_cancel.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id } });
+                    foreach (var record in records)
+                    {
+                        try
+                        {
+                            await table_cancel.DeleteSingle<ChangeRecord>(record.PartitionKey, record.RowKey);
+                            await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber);
+                           
+                        }
+                        catch (Exception)
+                        {
+                            continue;
+                        }
+                    }
+                    return;
+                }
+                var adid = tdata.id;
+                var adcode = "";
+                string blobcntr = null;
+                if (tdata.scope.Equals("school"))
+                {
+                    adcode = $"Activity-{tdata.school}";
+                    blobcntr = tdata.school;
+                }
+                else
+                {
+                    adcode = $"Activity-{tdata.creatorId}";
+                    blobcntr = tdata.creatorId;
+                }
+               // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修评测活动【{tdata.name}-{tdata.id}-ttl={tdata.ttl}】正在操作", GroupNames.醍摩豆服務運維群組);
+                ExamLite lite = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamLite>(tdata.id, new Azure.Cosmos.PartitionKey($"{tdata.code}"));
+                var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                if (lite != null)
+                {
+                    string PartitionKey = string.Format("{0}{1}{2}", lite.code, "-", lite.progress);
+                    List<ChangeRecord> changeRecords = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id }, { "PartitionKey", PartitionKey } });
+                    switch (lite.progress)
+                    {
+                        case "pending":
+                            var messageWork = new ServiceBusMessage(new { id = tdata.id, progress = "going", code = tdata.code }.ToJsonString());
+                            messageWork.ApplicationProperties.Add("name", "ExamLite");
+                            if (changeRecords.Count > 0)
+                            {
+                                try
+                                {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber);
+                                }
+                                catch (Exception)
+                                {
+                                }
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWork, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                changeRecords[0].sequenceNumber = start;
+                                await table.SaveOrUpdate<ChangeRecord>(changeRecords[0]);
+                            }
+                            else
+                            {
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWork, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                ChangeRecord changeRecord = new()
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = start,
+                                    msgId = messageWork.MessageId
+                                };                                
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+                            break;
+                        case "going":
+                            List<(string pId, List<string> gid)> ps = new();
+                            if (lite.groupLists.Count > 0)
+                            {
+                                var group = lite.groupLists;
+                                foreach (var gp in group)
+                                {
+                                    foreach (KeyValuePair<string, List<string>> pp in gp)
+                                    {
+                                        ps.Add((pp.Key, pp.Value));
+                                    }
+                                }
+                            }
+                            (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, lite.tchLists, lite.school, ps);
+                            //List<StuActivity> tchActivities = new();
+                            (string standard, List<string> tmdids, string school, List<string> update, int statistics)  list =    (null,null, null, new List<string> { StatisticsService.TeacherExamLite }, 0)  ;
+                            if (tchList.IsNotEmpty())
+                            {
+                                list.tmdids = tchList.Select(x => x.id).ToList();
+                                School school = null;
+                                if (!string.IsNullOrEmpty(lite.school))
+                                {
+                                    school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(lite.school, new Azure.Cosmos.PartitionKey("Base"));
+                                    list.school = school.id;
+                                    list.standard = school.standard;
+                                }
+                                //tchList.ForEach(x =>
+                                //{
+                                //    tchActivities.Add(new StuActivity
+                                //    {
+                                //        pk = "Activity",
+                                //        id = lite.id,
+                                //        code = $"Activity-{x.id}",
+                                //        type = "ExamLite",
+                                //        name = lite.name,
+                                //        startTime = lite.startTime,
+                                //        endTime = lite.endTime,
+                                //        scode = lite.code,
+                                //        scope = lite.scope,
+                                //        school = lite.school,
+                                //        creatorId = lite.creatorId,
+                                //        subjects = new List<string> { "" },
+                                //        blob = null,
+                                //        owner = lite.owner,
+                                //        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                //        taskStatus = -1,
+                                //        classIds = lite.tchLists
+                                //    });
+                                //});
+                              
+                            }
+                            //await IESActivityService.SaveStuActivity(client, _dingDing, null, null, tchActivities);
+                            await StatisticsService.SendServiceBus(list, _configuration, _serviceBus,   client);
+                            var messageWorkEnd = new ServiceBusMessage(new { id = tdata.id, progress = "finish", code = tdata.code }.ToJsonString());
+                            messageWorkEnd.ApplicationProperties.Add("name", "ExamLite");
+                            if (changeRecords.Count > 0)
+                            {
+                                long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWorkEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                try
+                                {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber);
+                                }
+                                catch (Exception)
+                                {
+                                }
+                                changeRecords[0].sequenceNumber = end;
+                                await table.SaveOrUpdate<ChangeRecord>(changeRecords[0]);
+                            }
+                            else
+                            {
+                                long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWorkEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                ChangeRecord changeRecord = new()
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = end,
+                                    msgId = messageWorkEnd.MessageId
+                                };                                
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+                            break;
+                        case "finish":
+
+                            List<(string pId, List<string> gid)> gls = new List<(string pId, List<string> gid)>();
+                            if (lite.groupLists.Count > 0)
+                            {
+                                var group = lite.groupLists;
+                                foreach (var gp in group)
+                                {
+                                    foreach (KeyValuePair<string, List<string>> pp in gp)
+                                    {
+                                        gls.Add((pp.Key, pp.Value));
+                                    }
+                                }
+                            }
+                            if (lite.staffIds.Count == 0)
+                            {
+                            // 处理试卷练习活动结束统计账户信息
+                                List<FMember> idList = await GroupListService.GetFinishMemberInfo(_coreAPIHttpService, client, _dingDing, lite.school, lite.classes, lite.stuLists, lite.tchLists, gls);
+                                lite.staffIds = idList;
+
+                                await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<ExamLite>(lite, lite.id, new Azure.Cosmos.PartitionKey(lite.code));
+                            }
+                                
+
+                            break;
+                    }
+
+
+                }
+
+            }
+            catch (CosmosException e)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-CosmosDB异常{e.Message}\n{e.StackTrace}\n{e.Status}", GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修评测异常{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+            }
+
+        }
+    }
+}

+ 412 - 0
TEAMModelOS.Function/CosmosDBTriggers/TriggerHomework.cs

@@ -0,0 +1,412 @@
+using Azure.Cosmos;
+using Azure.Messaging.ServiceBus;
+using HTEXLib.COMM.Helpers;
+using Microsoft.Azure.Documents;
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Service;
+using TEAMModelOS.SDK.Models.Service.BI;
+using TEAMModelOS.Function;
+namespace TEAMModelOS.CosmosDBTriggers
+{
+    public static class TriggerHomework
+    {
+        public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
+                    CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis, IConfiguration _configuration)
+        {
+            try
+            {
+                if ((tdata.status != null && tdata.status.Value == 404))
+                {
+                    await client.GetContainer(Constant.TEAMModelOS, "Common").DeleteItemStreamAsync(tdata.id, new PartitionKey(tdata.code));
+                    ActivityList data = input.ToObject<ActivityList>();
+                    //await IESActivityService.DeleteActivity(_coreAPIHttpService, client, _dingDing, data);
+                    var table_cancel = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                    List<ChangeRecord> records = await table_cancel.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id } });
+                    foreach (var record in records)
+                    {
+                        try
+                        {
+                            await table_cancel.DeleteSingle<ChangeRecord>(record.PartitionKey, record.RowKey);
+                            await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber);
+
+                        }
+                        catch (Exception)
+                        {
+                            continue;
+                        }
+                    }
+
+                    await BIStats.SetTypeAddStats(client, _dingDing, tdata.school, "Homework", -1, careDate: tdata.startTime);//BI统计增/减量
+                    return;
+                }
+                var adid = tdata.id;
+                var adcode = "";
+                string blobcntr = null;
+                if (tdata.scope.Equals("school"))
+                {
+                    adcode = $"Activity-{tdata.school}";
+                    blobcntr = tdata.school;
+                }
+                else
+                {
+                    adcode = $"Activity-{tdata.creatorId}";
+                    blobcntr = tdata.creatorId;
+                }
+                //await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}作业活动【{tdata.name}-{tdata.id}-ttl={tdata.ttl}】正在操作", GroupNames.醍摩豆服務運維群組);
+                Homework work = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Homework>(tdata.id, new Azure.Cosmos.PartitionKey($"{tdata.code}"));
+                var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                if (work != null)
+                {
+                    string PartitionKey = string.Format("{0}{1}{2}", work.code, "-", work.progress);
+                    List<ChangeRecord> changeRecords = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id }, { "PartitionKey", PartitionKey } });
+                    switch (work.progress)
+                    {
+                        case "pending":
+                            var messageWork = new ServiceBusMessage(new { tdata.id, progress = "going", tdata.code }.ToJsonString());
+                            messageWork.ApplicationProperties.Add("name", "Homework");
+                            if (changeRecords.Count > 0)
+                            {
+                                try
+                                {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber);
+                                }
+                                catch (Exception)
+                                {
+                                }
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWork, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                changeRecords[0].sequenceNumber = start;
+                                await table.SaveOrUpdate<ChangeRecord>(changeRecords[0]);
+                            }
+                            else
+                            {
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWork, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                ChangeRecord changeRecord = new()
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = start,
+                                    msgId = messageWork.MessageId
+                                };
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+
+                            break;
+                        case "going":
+                            try {
+                                await Activity(_coreAPIHttpService, _serviceBus, _dingDing, client, _configuration, work);
+                                var messageWorkEnd = new ServiceBusMessage(new { id = tdata.id, progress = "finish", code = tdata.code }.ToJsonString());
+                                messageWorkEnd.ApplicationProperties.Add("name", "Homework");
+                                if (changeRecords.Count > 0)
+                                {
+                                    long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWorkEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                    try
+                                    {
+                                        await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber);
+                                    }
+                                    catch (Exception)
+                                    {
+                                    }
+                                    changeRecords[0].sequenceNumber = end;
+                                    await table.SaveOrUpdate<ChangeRecord>(changeRecords[0]);
+                                }
+                                else
+                                {
+                                    long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWorkEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                    ChangeRecord changeRecord = new()
+                                    {
+                                        RowKey = tdata.id,
+                                        PartitionKey = PartitionKey,
+                                        sequenceNumber = end,
+                                        msgId = messageWorkEnd.MessageId
+                                    };
+                                    await table.Save<ChangeRecord>(changeRecord);
+                                }
+                                if (work!=null && work.scope.Equals("private"))
+                                {
+                                    await SystemService.RecordAccumulateData(_azureRedis, _dingDing, new SDK.Models.Dtos.Accumulate { client="web", count=1, id=work.id, key="homework-going", name=work.name, scope="teacher", target=work.creatorId });
+                                }
+                            } catch (Exception e) {
+                                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修作业活动going{e.Message}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                            }
+                            finally {
+                                string pkey = string.Format("{0}{1}{2}", work.code, "-", "pending");
+                                await table.DeleteSingle<ChangeRecord>(pkey, tdata.id);
+                            }
+                            
+                            
+                            //if (bustasks.IsNotEmpty())
+                            //{
+                            //    await Task.WhenAll(bustasks);
+                            //}
+                            break;
+                        case "finish":
+                            try {
+                                await Activity(_coreAPIHttpService, _serviceBus, _dingDing, client, _configuration, work);
+                                List<(string pId, List<string> gid)> gls = new List<(string pId, List<string> gid)>();
+                                if (work.groupLists.Count > 0)
+                                {
+                                    var group = work.groupLists;
+                                    foreach (var gp in group)
+                                    {
+                                        foreach (KeyValuePair<string, List<string>> pp in gp)
+                                        {
+                                            gls.Add((pp.Key, pp.Value));
+                                        }
+                                    }
+                                }
+                                //处理家庭作业活动结束统计账户信息
+                                if (work.staffIds.Count == 0)
+                                {
+                                    List<FMember> idsList = await GroupListService.GetFinishMemberInfo(_coreAPIHttpService, client, _dingDing, work.school, work.classes, work.stuLists, work.tchLists, gls);
+                                    work.staffIds = idsList;
+
+                                    await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<Homework>(work, work.id, new Azure.Cosmos.PartitionKey(work.code));
+                                }
+                            } catch (Exception e) {
+                                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修作业活动finish{e.Message}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
+
+                            } finally {
+                                string pk = string.Format("{0}{1}{2}", work.code, "-", "going");
+                                await table.DeleteSingle<ChangeRecord>(pk, tdata.id);
+                            }
+                            
+                                                
+                            break;
+                    }
+
+                }
+            }
+            catch (CosmosException e)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-CosmosDB异常{e.Message}\n{e.StackTrace}\n{e.Status}", GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修作业活动异常{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+            }
+        }
+
+        private static async Task Activity(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, DingDing _dingDing, CosmosClient client, IConfiguration _configuration, Homework work)
+        {
+            List<(string pId, List<string> gid)> ps = new List<(string pId, List<string> gid)>();
+            if (work.groupLists.Count > 0)
+            {
+                var group = work.groupLists;
+                foreach (var gp in group)
+                {
+                    foreach (KeyValuePair<string, List<string>> pp in gp)
+                    {
+                        ps.Add((pp.Key, pp.Value));
+                    }
+                }
+            }
+            List<string> classes = ExamService.getClasses(work.classes, work.stuLists);
+            (List<RMember> tmdids, List<RGroupList> classLists) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classes, work.school, ps);
+            var addStudentsCls = tmdids.FindAll(x => x.type == 2);
+            var addTmdidsCls = tmdids.FindAll(x => x.type == 1);
+            //List<StuActivity> stuActivities = new();
+            //List<StuActivity> tmdActivities = new();
+            //List<StuActivity> tchActivities = new();
+            //List<StuActivity> tac = new();
+            List<string> tIds = addStudentsCls.Select(x => x.id).ToList();
+            /*
+                         await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<StuActivity>(queryText: $"select value(c) from c where c.id ='{work.id}' and c.type = 'Homework'"))
+            {
+                tac.Add(item);
+
+            }
+            await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<StuActivity>(queryText: $"select value(c) from c where c.id ='{work.id}' and c.type = 'Homework'"))
+            {
+                tac.Add(item);
+
+            }
+            List<string> sub = new();
+            if (work.tchLists.Count == 0)
+            {
+                if (work.targets.Count > 0)
+                {
+                    foreach (var course in work.targets)
+                    {
+                        var info = course.ToObject<List<string>>();
+                        if (info.Count > 1)
+                        {
+                            sub.Add(info[0]);
+                        }
+                    }
+                }
+            }
+
+            if (addTmdidsCls.IsNotEmpty())
+            {
+                addTmdidsCls.ForEach(x =>
+                {
+                    HashSet<string> classIds = new HashSet<string>();
+                    classLists.ForEach(z =>
+                    {
+                        z.members.ForEach(y =>
+                        {
+                            if (y.id.Equals(x.id) && y.type == 1)
+                            {
+                                classIds.Add(z.id);
+                            }
+                        });
+                    });
+                    int sta = -1;
+                    if (tac.Count > 0)
+                    {
+                        StuActivity activity = tac.Where(t => t.code.Equals($"Activity-{x.id}")).FirstOrDefault();
+                        if (activity != null)
+                        {
+                            sta = activity.taskStatus;
+                        }
+                    }
+                    tmdActivities.Add(new StuActivity
+                    {
+                        pk = "Activity",
+                        id = work.id,
+                        code = $"Activity-{x.id}",
+                        type = "Homework",
+                        name = work.name,
+                        startTime = work.startTime,
+                        endTime = work.endTime,
+                        scode = work.code,
+                        scope = work.scope,
+                        school = work.school,
+                        creatorId = work.creatorId,
+                        subjects = sub,
+                        blob = work.blob,
+                        owner = work.owner,
+                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                        taskStatus = sta,
+                        mustSubmit = work.mustSubmit,
+                        classIds = classIds.ToList()
+                    });
+                });
+            }
+            if (addStudentsCls.IsNotEmpty())
+            {
+                addStudentsCls.ForEach(x =>
+                {
+                    HashSet<string> classIds = new HashSet<string>();
+                    classLists.ForEach(z =>
+                    {
+                        z.members.ForEach(y =>
+                        {
+                            if (y.id.Equals(x.id) && y.type == 2)
+                            {
+                                classIds.Add(z.id);
+                            }
+                        });
+                    });
+                    int sta = -1;
+                    if (tac.Count > 0)
+                    {
+                        StuActivity activity = tac.Where(t => t.code.Equals($"Activity-{x.code.Replace("Base-", "")}-{x.id}")).FirstOrDefault();
+                        if (activity != null)
+                        {
+                            sta = activity.taskStatus;
+                        }
+                    }
+
+                    stuActivities.Add(new StuActivity
+                    {
+                        pk = "Activity",
+                        id = work.id,
+                        code = $"Activity-{x.code.Replace("Base-", "")}-{x.id}",
+                        type = "Homework",
+                        name = work.name,
+                        startTime = work.startTime,
+                        endTime = work.endTime,
+                        scode = work.code,
+                        scope = work.scope,
+                        school = work.school,
+                        creatorId = work.creatorId,
+                        subjects = sub,
+                        blob = work.blob,
+                        owner = work.owner,
+                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                        taskStatus = sta,
+                        classIds = classIds.ToList(),
+                        mustSubmit = work.mustSubmit
+                    });
+                });
+            }
+             */
+            (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, work.tchLists, work.school, ps);
+            (string standard, List<string> tmdids, string school, List<string> update, int statistics) list = (null, null, null, new List<string> { StatisticsService.OfflineRecord }, 0);
+            if (tchList.IsNotEmpty())
+            {
+                list.tmdids = tchList.Select(x => x.id).ToList();
+                School school = null;
+                if (!string.IsNullOrEmpty(work.school))
+                {
+                    school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(work.school, new Azure.Cosmos.PartitionKey("Base"));
+                    list.school = school.id;
+                    list.standard = school.standard;
+                }
+                /*
+                 tchList.ForEach(x =>
+                {
+                    HashSet<string> classIds = new();
+                    classInfos.ForEach(z =>
+                    {
+                        z.members.ForEach(y =>
+                        {
+                            if (y.id.Equals(x.id) && y.type == 1)
+                            {
+                                classIds.Add(z.id);
+                            }
+                        });
+                    });
+                    int sta = -1;
+                    if (tac.Count > 0)
+                    {
+                        StuActivity activity = tac.Where(t => t.code.Equals($"Activity-{x.id}")).FirstOrDefault();
+                        if (activity != null)
+                        {
+                            sta = activity.taskStatus;
+                        }
+                    }
+                    tchActivities.Add(new StuActivity
+                    {
+                        pk = "Activity",
+                        id = work.id,
+                        code = $"Activity-{x.id}",
+                        type = "Homework",
+                        name = work.name,
+                        startTime = work.startTime,
+                        endTime = work.endTime,
+                        scode = work.code,
+                        scope = work.scope,
+                        school = work.school,
+                        creatorId = work.creatorId,
+                        subjects = new List<string> { "" },
+                        blob = work.blob,
+                        owner = work.owner,
+                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                        taskStatus = sta,
+                        classIds = classIds.ToList()
+                    });
+
+                });
+                 */
+            }
+            //await IESActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
+            await StatisticsService.SendServiceBus(list, _configuration, _serviceBus, client);
+
+        }
+
+    }
+}
+

+ 240 - 0
TEAMModelOS.Function/CosmosDBTriggers/TriggerQuotaImport.cs

@@ -0,0 +1,240 @@
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK;
+using Azure.Cosmos;
+using TEAMModelOS.SDK.Models.Cosmos.School;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Extension;
+using HTEXLib.COMM.Helpers;
+using OpenXmlPowerTools;
+using Microsoft.OData.Edm;
+using TEAMModelOS.Function;
+namespace TEAMModelOS.CosmosDBTriggers
+{
+    public class TriggerQuotaImport
+    {
+        public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
+           CosmosClient client, JsonElement input, TriggerData data, IHttpClientFactory _httpClient, IConfiguration _configuration,AzureRedisFactory _azureRedis)
+        {
+            QuotaImport quotaImport = input.ToObject<QuotaImport>();
+            if (quotaImport != null)
+            {
+                HashSet<string> ids = new HashSet<string>();
+                foreach (var x in quotaImport.students)
+                {
+                    string id = $"{quotaImport.year}-{quotaImport.semesterId}-{x.id}";
+                    ids.Add(id);
+                }
+                HashSet<OverallEducation> overallEducations = new HashSet<OverallEducation>();
+                string sql = $"select value c from  c where c.id in ({string.Join(",", ids.Select(z => $"'{z}'"))}) and c.periodId='{quotaImport.periodId}' ";
+                var result = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<OverallEducation>(sql, $"OverallEducation-{quotaImport.school}");
+                IEnumerable<string> notInDbIds = null;
+                if (result.list.IsNotEmpty())
+                {
+                    notInDbIds = ids.Except(result.list.Select(x => x.id));
+                    overallEducations = new HashSet<OverallEducation>(result.list);
+                }
+                else
+                {
+                    notInDbIds = ids;
+                }
+                HashSet<OverallEducation> overallEducationChanged = new HashSet<OverallEducation>();
+                foreach (var y in quotaImport.students)
+                {
+                    string id = $"{quotaImport.year}-{quotaImport.semesterId}-{y.id}";
+                    var overallEducation = overallEducations.Where(z => z.id.Equals(id)).FirstOrDefault();
+                    if (overallEducation != null)
+                    {
+                        EducationScore quota = null;
+                        if (quotaImport.dimension.Equals("virtue"))
+                        {
+                            quota = overallEducation.virtue.Find(f => f.examId.Equals($"{overallEducation.stuYear}-{overallEducation.semesterId}"));
+                        }
+                        else if (quotaImport.dimension.Equals("labour")) {
+                            quota = overallEducation.labour.Find(f => f.examId.Equals($"{overallEducation.stuYear}-{overallEducation.semesterId}"));
+                        }
+                        else if (quotaImport.dimension.Equals("sports"))
+                        {
+                            quota = overallEducation.sports.Find(f => f.examId.Equals($"{overallEducation.stuYear}-{overallEducation.semesterId}"));
+                        }
+                        if (quota != null)
+                        {
+                            //体育成绩直接覆盖
+                            if (quotaImport.dimension.Equals("sports"))
+                            {
+                                List<ItemScore> itemScores = y.items.Select(z => new ItemScore
+                                {
+                                    totalScore = !quotaImport.dimension.Equals("sports") ? 0 : 100,
+                                    name = z.code,
+                                    score = z.value,
+                                    type = z.code,
+                                    id = !quotaImport.dimension.Equals("sports") ? $"{y.date}-{z.code}" : z.code,
+                                    time = y.time
+                                }).ToList();
+                                quota.itemScore = itemScores;
+                                overallEducationChanged.Add(overallEducation);
+                            }
+                            else {
+                                y.items.ForEach(z => {
+                                    var item = quota.itemScore.Find(f => f.id.Equals(!quotaImport.dimension.Equals("sports") ? $"{y.date}-{z.code}" : z.code));
+                                    if (item != null)
+                                    {
+                                        item.name = z.code;
+                                        if (item.score != z.value)
+                                        {
+                                            item.score = z.value;
+
+
+                                            overallEducationChanged.Add(overallEducation);
+                                        }
+                                        item.totalScore = !quotaImport.dimension.Equals("sports") ? 0 : 100;
+                                        item.type = z.code;
+                                        item.time = y.time;
+                                        item.id = !quotaImport.dimension.Equals("sports") ? $"{y.date}-{z.code}" : z.code;
+                                    }
+                                    else
+                                    {
+                                        overallEducationChanged.Add(overallEducation);
+                                        quota.itemScore.Add(new ItemScore
+                                        {
+                                            totalScore = !quotaImport.dimension.Equals("sports") ? 0 : 100,
+                                            name = z.code,
+                                            score = z.value,
+                                            type = z.code,
+                                            id = id = !quotaImport.dimension.Equals("sports") ? $"{y.date}-{z.code}" : z.code,
+                                            time = y.time
+                                        });
+                                    }
+
+                                });
+                            }
+
+                            if (quota.sumScore != quota.itemScore.Sum(z => z.score)) {
+                                overallEducationChanged.Add(overallEducation);
+                                quota.sumScore = quota.itemScore.Sum(z => z.score);
+                            }
+                            if (quota.totalScore != quota.itemScore.Sum(z => z.totalScore))
+                            {
+                                overallEducationChanged.Add(overallEducation);
+                                quota.totalScore = quota.itemScore.Sum(z => z.totalScore);
+                            }
+                            quota.rate = quotaImport.dimension.Equals("sports") && quota.itemScore.Sum(z => z.totalScore) > 0 ? quota.itemScore.Sum(z => z.score) * 1.0 / quota.itemScore.Sum(z => z.totalScore) : 0;
+                            quota.excellenceRate = quotaImport.dimension.Equals("sports") && quota.itemScore.Sum(z => z.totalScore) > 0 ? quota.itemScore.Where(z => z.score >= 90).Sum(z => z.score) * 1.0 / quota.itemScore.Sum(z => z.totalScore) : 0;
+                            quota.passRate = quotaImport.dimension.Equals("sports") && quota.itemScore.Sum(z => z.totalScore) > 0 ? quota.itemScore.Where(z => z.score >= 60).Sum(z => z.score) * 1.0 / quota.itemScore.Sum(z => z.totalScore) : 0;
+                            quota.examType = quotaImport.type;
+                            quota.examDate = quotaImport.time;
+                            quota.examName = $"{overallEducation.stuYear}-{overallEducation.semesterId}";
+                        }
+                        else
+                        {
+                            List<ItemScore> itemScores = y.items.Select(z =>new ItemScore {
+                                totalScore = !quotaImport.dimension.Equals("sports")  ? 0 : 100,
+                                name = z.code,
+                                score = z.value,
+                                type = z.code,
+                                id = !quotaImport.dimension.Equals("sports")  ? $"{y.date}-{z.code}" : z.code,
+                                time = y.time
+                            }).ToList();
+                            EducationScore educationScore = new EducationScore
+                            {
+                                examName = $"{overallEducation.stuYear}-{overallEducation.semesterId}",
+                                examId = $"{overallEducation.stuYear}-{overallEducation.semesterId}",
+                                examDate = quotaImport.time,
+                                examType = quotaImport.type,
+                                sumScore = itemScores.Sum(z => z.score),
+                                itemScore = itemScores,
+                                totalScore = itemScores.Sum(z => z.totalScore),
+                                rate = quotaImport.dimension.Equals("sports") && itemScores.Sum(z => z.totalScore) > 0 ? itemScores.Sum(z => z.score) * 1.0 / itemScores.Sum(z => z.totalScore) : 0,
+                                excellenceRate = quotaImport.dimension.Equals("sports") && itemScores.Sum(z => z.totalScore) > 0 ? itemScores.Where(z => z.score >= 90).Sum(z => z.score) * 1.0 / itemScores.Sum(z => z.totalScore) : 0,
+                                passRate = quotaImport.dimension.Equals("sports") && itemScores.Sum(z => z.totalScore) > 0 ? itemScores.Where(z => z.score >= 60).Sum(z => z.score) * 1.0 / itemScores.Sum(z => z.totalScore) : 0,
+                            };
+                            if (quotaImport.dimension.Equals("virtue"))
+                            {
+                                overallEducation.virtue.Add(educationScore);
+                            }
+                            else if (quotaImport.dimension.Equals("labour"))
+                            {
+                                overallEducation.labour.Add(educationScore);
+                            }
+                            else if (quotaImport.dimension.Equals("sports"))
+                            {
+                                overallEducation.sports.Add(educationScore);
+                            }
+                            overallEducationChanged.Add(overallEducation);
+                        }
+                    }
+                    else
+                    {
+                        
+                        List<ItemScore> itemScores = y.items.Select(z => new ItemScore {
+                            totalScore = !quotaImport.dimension.Equals("sports")  ? 0 : 100,
+                            name = z.code,
+                            score = z.value,
+                            type = z.code,
+                            id = !quotaImport.dimension.Equals("sports")  ? $"{y.date}-{z.code}" : z.code,
+                            time = y.time
+                        }
+                        ).ToList();
+                        var educationScores = new List<EducationScore>
+                        {
+                            new EducationScore
+                            {
+                                examName=$"{y.stuYear}-{quotaImport.semesterId}",
+                                examId =$"{y.stuYear}-{quotaImport.semesterId}",
+                                examDate=quotaImport.time,
+                                examType=quotaImport.type,
+                                sumScore = itemScores.Sum(z => z.score),
+                                itemScore = itemScores,
+                                totalScore = itemScores.Sum(z => z.totalScore),
+                                rate= quotaImport.dimension.Equals("sports") && itemScores.Sum(z => z.totalScore)>0 ? itemScores.Sum(z => z.score) *1.0 / itemScores.Sum(z => z.totalScore):0,
+                                excellenceRate=quotaImport.dimension.Equals("sports")&& itemScores.Sum(z => z.totalScore)>0 ? itemScores.Where(z => z.score >= 90).Sum(z => z.score) *1.0 / itemScores.Sum(z => z.totalScore):0,
+                                passRate= quotaImport.dimension.Equals("sports") && itemScores.Sum(z => z.totalScore)>0 ? itemScores.Where(z => z.score >= 60).Sum(z => z.score) *1.0 / itemScores.Sum(z => z.totalScore):0,
+                            }
+                        };
+                        overallEducation = new OverallEducation
+                        {
+                            id = id,
+                            code = $"OverallEducation-{quotaImport.school}",
+                            pk = "OverallEducation",
+                            periodId = quotaImport.periodId,
+                            year = quotaImport.year,
+                            semesterId = quotaImport.semesterId,
+                            schoolCode = quotaImport.school,
+                            studentId = y.id,
+                            name = y.name,
+                            classId = y.classId,
+                            stuYear = y.stuYear
+                        };
+                        if (quotaImport.dimension.Equals("virtue"))
+                        {
+                            overallEducation.virtue= educationScores;
+                        }
+                        else if (quotaImport.dimension.Equals("labour"))
+                        {
+                            overallEducation.labour= educationScores;
+                        }
+                        else if (quotaImport.dimension.Equals("sports"))
+                        {
+                            overallEducation.sports= educationScores;
+                        }
+                        overallEducationChanged.Add(overallEducation);
+                        overallEducations.Add(overallEducation);
+                    }
+                }
+                foreach (var item in overallEducationChanged) { 
+                    await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS,Constant.Student).UpsertItemAsync(item,new PartitionKey (item.code));
+                    string key = $"OverallEducation:{item.schoolCode}:{item.periodId}:{item.year}:{item.semesterId}:{item.classId}";
+                    await _azureRedis.GetRedisClient(8).HashSetAsync(key, item.studentId, item.ToJsonString());
+                    await _azureRedis.GetRedisClient(8).KeyExpireAsync(key, new TimeSpan(180 * 24, 0, 0));
+                }
+            }
+        }
+    }
+}

+ 280 - 0
TEAMModelOS.Function/CosmosDBTriggers/TriggerStudy.cs

@@ -0,0 +1,280 @@
+using Azure.Cosmos;
+using Azure.Messaging.ServiceBus;
+using DocumentFormat.OpenXml.Bibliography;
+using DocumentFormat.OpenXml.Office2013.Excel;
+using DocumentFormat.OpenXml.Spreadsheet;
+using DocumentFormat.OpenXml.VariantTypes;
+using DocumentFormat.OpenXml.Vml;
+using HTEXLib.COMM.Helpers;
+using Microsoft.Azure.Documents;
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Service;
+using TEAMModelOS.SDK.Models.Service.BI;
+using TEAMModelOS.Function;
+namespace TEAMModelOS.CosmosDBTriggers
+{
+    public static class TriggerStudy
+    {
+        public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
+                    CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis, IConfiguration _configuration)
+        {
+            try
+            {
+                if ((tdata.status != null && tdata.status.Value == 404)  || tdata.publish == 1)
+                {
+                    await client.GetContainer(Constant.TEAMModelOS, "Common").DeleteItemStreamAsync(tdata.id, new PartitionKey(tdata.code));
+                    ActivityList data = input.ToObject<ActivityList>();
+                    //await IESActivityService.DeleteActivity(_coreAPIHttpService, client, _dingDing, data);
+                    var table_cancel = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                    List<ChangeRecord> records = await table_cancel.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id } });
+                    foreach (var record in records)
+                    {
+                        try
+                        {
+                            await table_cancel.DeleteSingle<ChangeRecord>(record.PartitionKey, record.RowKey);
+                            await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber);
+                          
+                        }
+                        catch (Exception ) {
+                            continue;
+                        }
+                    }
+
+                    await BIStats.SetTypeAddStats(client, _dingDing, tdata.school, "Study", -1, careDate: tdata.startTime);//BI统计增/减量
+                    return;
+                }
+                var adid = tdata.id;
+                var adcode = "";
+                string blobcntr = null;
+                if (tdata.scope.Equals("school"))
+                {
+                    adcode = $"Activity-{tdata.school}";
+                    blobcntr = tdata.school;
+                }
+                else
+                {
+                    adcode = $"Activity-{tdata.creatorId}";
+                    blobcntr = tdata.creatorId;
+                }
+              
+                Study study = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Study>(tdata.id, new Azure.Cosmos.PartitionKey($"{tdata.code}"));
+                
+                if (study != null)
+                {
+                    string PartitionKey = string.Format("{0}{1}{2}", study.code, "-", study.progress);
+                    var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                    List<ChangeRecord> changeRecords = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id }, { "PartitionKey", PartitionKey } });
+                    switch (study.progress)
+                    {
+                        case "pending":
+                            var messageWork = new ServiceBusMessage(new { id = tdata.id, progress = "going", code = tdata.code }.ToJsonString());
+                            messageWork.ApplicationProperties.Add("name", "Study");
+                            if (changeRecords.Count > 0)
+                            {
+                                try
+                                {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber);
+                                }
+                                catch (Exception)
+                                {
+                                }
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWork, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                changeRecords[0].sequenceNumber = start;
+                                await table.SaveOrUpdate<ChangeRecord>(changeRecords[0]);
+                            }
+                            else
+                            {
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWork, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                ChangeRecord changeRecord = new()
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = start,
+                                    msgId = messageWork.MessageId
+                                };                                
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+                            break;
+                        case "going":
+                            try
+                            {
+                                List<(string pId, List<string> gid)> ps = new List<(string pId, List<string> gid)>();
+                                if (study.groupLists.Count > 0)
+                                {
+                                    var group = study.groupLists;
+                                    foreach (var gp in group)
+                                    {
+                                        foreach (KeyValuePair<string, List<string>> pp in gp)
+                                        {
+                                            ps.Add((pp.Key, pp.Value));
+                                        }
+                                    }
+                                }
+                                (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, study.tchLists, study.school, ps);
+                                List<StuActivity> tchActivities = new List<StuActivity>();
+                                (string standard, List<string> tmdids, string school, List<string> update, int statistics) list = (null, null, null, new List<string> { StatisticsService.OfflineRecord }, 0);
+                                if (tchList.IsNotEmpty())
+                                {
+                                    list.tmdids = tchList.Select(x => x.id).ToList();
+                                    School school = null;
+                                    if (!string.IsNullOrEmpty(study.school))
+                                    {
+                                        school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(study.school, new Azure.Cosmos.PartitionKey("Base"));
+                                        list.school = school.id;
+                                        list.standard = school.standard;
+                                    }
+                                    string queryScore = $" select c.id from c where c.id ='{study.id}' and c.pk = 'Activity' ";
+                                    List<string> ids = new();
+                                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetItemQueryStreamIterator
+                                        (queryText: queryScore))
+                                    {
+                                        using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                                        {
+                                            foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                                            {
+                                                if (obj.TryGetProperty("id", out JsonElement acId))
+                                                {
+                                                    ids.Add(acId.GetString());
+                                                }
+                                            }
+                                        }
+                                    }
+
+
+                                    if (ids.Count == 0)
+                                    {
+                                        tchList.ForEach(x =>
+                                        {
+                                            tchActivities.Add(new StuActivity
+                                            {
+                                                pk = "Activity",
+                                                id = study.id,
+                                                code = $"Activity-{x.id}",
+                                                type = "Study",
+                                                name = study.name,
+                                                startTime = study.startTime,
+                                                endTime = study.endTime,
+                                                scode = study.code,
+                                                scope = study.scope,
+                                                school = study.school,
+                                                creatorId = study.creatorId,
+                                                subjects = new List<string> { "" },
+                                                blob = null,
+                                                owner = study.owner,
+                                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                                taskStatus = -1,
+                                                classIds = study.tchLists
+                                            });
+                                        });
+                                    }
+
+                                }
+                                await IESActivityService.SaveStuActivity(client, _dingDing, null, null, tchActivities);
+                                await StatisticsService.SendServiceBus(list, _configuration, _serviceBus, client);
+                                var messageWorkEnd = new ServiceBusMessage(new { id = tdata.id, progress = "finish", code = tdata.code }.ToJsonString());
+                                messageWorkEnd.ApplicationProperties.Add("name", "Study");
+                                if (study.teacIds != null && study.teacIds.Count == 0)
+                                {
+                                    study.teacIds = list.tmdids;
+                                    await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(study, study.id, new PartitionKey($"{study.code}"));
+                                }
+
+                                if (changeRecords.Count > 0)
+                                {
+                                    long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWorkEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                    try
+                                    {
+                                        await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber);
+                                    }
+                                    catch (Exception)
+                                    {
+                                    }
+                                    changeRecords[0].sequenceNumber = end;
+                                    await table.SaveOrUpdate<ChangeRecord>(changeRecords[0]);
+                                }
+                                else
+                                {
+                                    long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWorkEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                    ChangeRecord changeRecord = new()
+                                    {
+                                        RowKey = tdata.id,
+                                        PartitionKey = PartitionKey,
+                                        sequenceNumber = end,
+                                        msgId = messageWorkEnd.MessageId
+                                    };
+                                    await table.Save<ChangeRecord>(changeRecord);
+                                }
+
+                            }
+                            catch (Exception ex)
+                            {
+                                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修活动异常-going {ex.Message}\n{ex.StackTrace}{tdata.ToJsonString()}{input}", GroupNames.醍摩豆服務運維群組);
+                            }
+                            finally {
+                                string pk = string.Format("{0}{1}{2}", study.code, "-", "pending");
+                                await table.DeleteSingle<ChangeRecord>(pk, tdata.id);
+                            }
+                           
+                            break;
+                        case "finish":
+                            try
+                            {
+                                List<(string pId, List<string> gid)> gls = new List<(string pId, List<string> gid)>();
+                                if (study.groupLists.Count > 0)
+                                {
+                                    var group = study.groupLists;
+                                    foreach (var gp in group)
+                                    {
+                                        foreach (KeyValuePair<string, List<string>> pp in gp)
+                                        {
+                                            gls.Add((pp.Key, pp.Value));
+                                        }
+                                    }
+                                }
+                                //处理教研活动结束统计账户信息
+                                if (study.staffIds.Count == 0)
+                                {
+                                    List<FMember> idList = await GroupListService.GetFinishMemberInfo(_coreAPIHttpService, client, _dingDing, study.school, study.classes, study.stuLists, study.tchLists, gls);
+                                    study.staffIds = idList;
+                                    await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<Study>(study, study.id, new Azure.Cosmos.PartitionKey(study.code));
+
+                                }
+
+                            }
+                            catch (Exception e)
+                            {
+                                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修活动异常-finish {e.Message}\n{e.StackTrace}{tdata.ToJsonString()}{input}", GroupNames.醍摩豆服務運維群組);
+                            }
+                            finally {
+                                string pk = string.Format("{0}{1}{2}", study.code, "-", "going");
+                                await table.DeleteSingle<ChangeRecord>(pk, tdata.id);
+                            }
+                            break;
+                    }
+                }
+
+            }
+            catch (CosmosException e)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-CosmosDB异常{e.Message}\n{e.StackTrace}\n{e.Status}", GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修活动异常{ex.Message}\n{ex.StackTrace}{tdata.ToJsonString()}{input}", GroupNames.醍摩豆服務運維群組);
+            }
+
+        }
+    }
+}

+ 530 - 0
TEAMModelOS.Function/CosmosDBTriggers/TriggerSurvey.cs

@@ -0,0 +1,530 @@
+using Azure.Cosmos;
+using Azure.Messaging.ServiceBus;
+using Azure.Storage.Blobs.Models;
+using Azure.Storage.Sas;
+using Microsoft.Azure.Documents;
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Cosmos.Common.Inner;
+using TEAMModelOS.SDK.Module.AzureBlob.Configuration;
+using TEAMModelOS.SDK.Models.Service;
+using HTEXLib.COMM.Helpers;
+using Microsoft.Extensions.Configuration;
+using System.Linq;
+using TEAMModelOS.SDK.Models.Service.BI;
+using TEAMModelOS.Function;
+namespace TEAMModelOS.CosmosDBTriggers
+{
+    public class TriggerSurvey
+    {
+        public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService,AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
+               CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis, IConfiguration _configuration)
+        {
+            try
+            {
+                if ((tdata.status != null && tdata.status.Value == 404) )
+                {
+                    await client.GetContainer(Constant.TEAMModelOS, "Common").DeleteItemStreamAsync(tdata.id, new PartitionKey(tdata.code));
+                    ActivityList data = input.ToObject<ActivityList>();
+                    //await IESActivityService.DeleteActivity(_coreAPIHttpService, client, _dingDing, data);
+                    _azureRedis.GetRedisClient(8).KeyDelete($"Survey:Record:{tdata.id}");
+                    _azureRedis.GetRedisClient(8).KeyDelete($"Survey:Submit:{tdata.id}");
+                    var table_cancel = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                    List<ChangeRecord> records = await table_cancel.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id } });
+                    foreach (var record in records)
+                    {
+                        try
+                        {
+                            await table_cancel.DeleteSingle<ChangeRecord>(record.PartitionKey, record.RowKey);
+                            await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber);
+                         
+                        }
+                        catch (Exception)
+                        {
+                            continue;
+                        }
+                    }
+
+                    await BIStats.SetTypeAddStats(client, _dingDing, tdata.school, "Survey", -1, careDate: tdata.startTime);//BI统计增/减量
+                    return;
+                }
+                var adid = tdata.id;
+                var adcode = "";
+                string blobcntr = null;
+                if (tdata.scope.Equals("school"))
+                {
+                    adcode = $"Activity-{tdata.school}";
+                    blobcntr = tdata.school;
+                }
+                else
+                {
+                    adcode = $"Activity-{tdata.creatorId}";
+                    blobcntr = tdata.creatorId;
+                }
+                Survey survey = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<Survey>(tdata.id, new Azure.Cosmos.PartitionKey($"{tdata.code}"));
+
+                if (survey != null)
+                {
+                    var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                    string PartitionKey = string.Format("{0}{1}{2}", survey.code, "-", survey.progress);
+                    List<ChangeRecord> changeRecords = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id }, { "PartitionKey", PartitionKey } });
+                    switch (survey.progress)
+                    {
+                        case "pending":
+                            var messageSurvey = new ServiceBusMessage(new { tdata.id, progress = "going", tdata.code }.ToJsonString());
+                            messageSurvey.ApplicationProperties.Add("name", "Survey");
+                            if (changeRecords.Count > 0)
+                            {
+                                try
+                                {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber);
+                                }
+                                catch (Exception)
+                                {
+                                }
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageSurvey, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                changeRecords[0].sequenceNumber = start;
+                                await table.SaveOrUpdate<ChangeRecord>(changeRecords[0]);
+                            }
+                            else
+                            {
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageSurvey, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                ChangeRecord changeRecord = new()
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = start,
+                                    msgId = messageSurvey.MessageId
+                                };                                
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+                            break;
+                        case "going":                           
+                            List<(string pId, List<string> gid)> ps = new List<(string pId, List<string> gid)>();
+                            if (survey.groupLists.Count > 0)
+                            {
+                                var group = survey.groupLists;
+                                foreach (var gp in group)
+                                {
+                                    foreach (KeyValuePair<string, List<string>> pp in gp)
+                                    {
+                                        ps.Add((pp.Key, pp.Value));
+                                    }
+                                }
+                            }
+                            List<string> classes = ExamService.getClasses(survey.classes, survey.stuLists);
+                            (List<RMember> tmdIds, List<RGroupList> classLists) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classes, survey.school);
+                            var addStudentsCls = tmdIds.FindAll(x => x.type == 2);
+                            var addTmdidsCls = tmdIds.FindAll(x => x.type == 1);
+#if DEBUG
+                            await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查{tdata.id}写入学生表作为活动列表!", GroupNames.醍摩豆服務運維群組);
+#endif
+                            List<StuActivity> stuActivities = new List<StuActivity>();
+                            List<StuActivity> tmdActivities = new List<StuActivity>();
+                            List<StuActivity> tchActivities = new List<StuActivity>();
+                            /*
+                              
+                              List<string> sub = new();
+                              if (survey.tchLists.Count == 0) {
+                                  if (survey.targets.Count > 0)
+                                  {
+                                      foreach (var course in survey.targets)
+                                      {
+                                          var info = course.ToObject<List<string>>();
+                                          if (info.Count > 1)
+                                          {
+                                              sub.Add(info[0]);
+                                          }
+                                      }
+                                  }
+                              }
+
+                              if (addTmdidsCls.IsNotEmpty())
+                              {
+                                  addTmdidsCls.ForEach(x =>
+                                  {
+                                      HashSet<string> classIds = new HashSet<string>();
+                                      classLists.ForEach(z => {
+                                          z.members.ForEach(y => {
+                                              if (y.id.Equals(x.id)&& y.type==1) 
+                                              {
+                                                  classIds.Add(z.id);
+                                              }
+                                          });
+                                      });
+                                      tmdActivities.Add(new StuActivity
+                                      {
+                                          pk = "Activity",
+                                          id = survey.id,
+                                          code = $"Activity-{x.id}",
+                                          type = "Survey",
+                                          name = survey.name,
+                                          startTime = survey.startTime,
+                                          endTime = survey.endTime,
+                                          scode = survey.code,
+                                          scope = survey.scope,
+                                          school = survey.school,
+                                          creatorId = survey.creatorId,
+                                          subjects = sub,
+                                          blob = survey.blob,
+                                          owner = survey.owner,
+                                          isSub = survey.isSub,
+                                          createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                          taskStatus = -1,
+                                          classIds = classIds.ToList()
+                                      });
+                                  });
+                              }
+                              if (addStudentsCls.IsNotEmpty())
+                              {
+                                  addStudentsCls.ForEach(x =>
+                                  {
+                                      HashSet<string> classIds = new HashSet<string>();
+                                      classLists.ForEach(z => {
+                                          z.members.ForEach(y => {
+                                              if (y.id.Equals(x.id)&& y.code.Equals(survey.school) && y.type == 2)
+                                              {
+                                                  classIds.Add(z.id);
+                                              }
+                                          });
+                                      });
+                                      stuActivities.Add(new StuActivity
+                                      {
+                                          pk = "Activity",
+                                          id = survey.id,
+                                          code = $"Activity-{x.code.Replace("Base-", "")}-{x.id}",
+                                          type = "Survey",
+                                          name = survey.name,
+                                          startTime = survey.startTime,
+                                          endTime = survey.endTime,
+                                          scode = survey.code,
+                                          scope = survey.scope,
+                                          school = survey.school,
+                                          creatorId = survey.creatorId,
+                                          subjects = sub,
+                                          blob = survey.blob,
+                                          owner = survey.owner,
+                                          isSub = survey.isSub,
+                                          createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                          taskStatus = -1,
+                                          classIds = classIds.ToList()
+                                      }); 
+                                  });
+                              }
+                             */
+                            (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, survey.tchLists, survey.school, ps);
+                            (string standard, List<string> tmdids, string school, List<string> update, int statistics) list = (null, null, null, new List<string> { StatisticsService.TeacherSurvey }, 0);
+                            if (tchList.IsNotEmpty())
+                            {
+                                list.tmdids = tchList.Select(x => x.id).ToList();
+                                School school = null;
+                                if (!string.IsNullOrEmpty(survey.school))
+                                {
+                                    school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(survey.school, new Azure.Cosmos.PartitionKey("Base"));
+                                    list.school = school.id;
+                                    list.standard = school.standard;
+                                }
+
+                                tchList.ForEach(x =>
+                               {
+                                   HashSet<string> classIds = new HashSet<string>();
+                                   classInfos.ForEach(z =>
+                                   {
+                                       z.members.ForEach(y =>
+                                       {
+                                           if (y.id.Equals(x.id) && y.type == 1)
+                                           {
+                                               classIds.Add(z.id);
+                                           }
+                                       });
+                                   });
+                                   tchActivities.Add(new StuActivity
+                                   {
+                                       pk = "Activity",
+                                       id = survey.id,
+                                       code = $"Activity-{x.id}",
+                                       type = "Survey",
+                                       name = survey.name,
+                                       startTime = survey.startTime,
+                                       endTime = survey.endTime,
+                                       scode = survey.code,
+                                       scope = survey.scope,
+                                       school = survey.school,
+                                       creatorId = survey.creatorId,
+                                       subjects = new List<string> { "" },
+                                       blob = survey.blob,
+                                       owner = survey.owner,
+                                       isSub = survey.isSub,
+                                       createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                       taskStatus = -1,
+                                       classIds = classIds.ToList()
+                                   });
+                               });
+
+
+                            }
+                            await IESActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
+                            await StatisticsService.SendServiceBus(list, _configuration, _serviceBus, client);
+                            //向学生或醍摩豆账号发起通知
+                            #region
+                            //Notice notice = new Notice()
+                            //{
+                            //    creation = survey.startTime,
+                            //    expire = survey.endTime,
+                            //    creatorId = survey.creatorId,
+                            //    stuids = students,
+                            //    tmdids = tmdids,
+                            //    type = "notice",//问卷参加参加通知
+                            //    priority = "normal",
+                            //    //data = new { }.ToJsonString()
+                            //    msgId = survey.id,
+                            //    school = survey.school,
+                            //    scope = survey.scope,
+                            //    body = new Body { sid = survey.id, scode = survey.code, spk = survey.pk, biztype = "survey-join" }
+
+                            //};
+                            //var messageBlob = new ServiceBusMessage(notice.ToJsonString());
+                            //messageBlob.ApplicationProperties.Add("name", "Notice");
+                            //await _serviceBus.GetServiceBusClient().SendMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageBlob);
+                            #endregion
+#if DEBUG
+                            await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查{tdata.id}写入完成!", GroupNames.醍摩豆服務運維群組);
+#endif                           
+                            var messageSurveyEnd = new ServiceBusMessage(new { id = tdata.id, progress = "finish", code = tdata.code }.ToJsonString());
+                            messageSurveyEnd.ApplicationProperties.Add("name", "Survey");
+                            string pkey = string.Format("{0}{1}{2}", survey.code, "-", "pending");
+                            await table.DeleteSingle<ChangeRecord>(pkey, tdata.id);
+                            if (changeRecords.Count > 0)
+                            {
+                                long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageSurveyEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                try
+                                {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber);
+                                }
+                                catch (Exception)
+                                {
+                                }
+                                changeRecords[0].sequenceNumber = end;
+                                await table.SaveOrUpdate<ChangeRecord>(changeRecords[0]);
+                            }
+                            else
+                            {
+                                long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageSurveyEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                ChangeRecord changeRecord = new ChangeRecord
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = end,
+                                    msgId = messageSurveyEnd.MessageId
+                                };
+                                
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+#if DEBUG
+                            await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查{tdata.id}将于:{tdata.endTime}完成并结算!", GroupNames.醍摩豆服務運維群組);
+#endif
+                            break;
+                        case "finish":
+                            
+#if DEBUG
+                            await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查{tdata.id}开始结算{tdata.endTime}!", GroupNames.醍摩豆服務運維群組);
+#endif
+                            var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync($"Survey:Record:{survey.id}");
+                            var submits = await _azureRedis.GetRedisClient(8).SetMembersAsync($"Survey:Submit:{survey.id}");
+                            List<dynamic> recs = new List<dynamic>();
+                            foreach (var rcd in records)
+                            {
+                                var value = rcd.Value.ToString().ToObject<JsonElement>();
+                                recs.Add(new { index = rcd.Name.ToString(), ans = value });
+                            }
+
+                            List<dynamic> userids = new List<dynamic>();
+                            foreach (var submit in submits)
+                            {
+                                var value = submit.ToString();
+                                userids.Add(value);
+                            }
+
+                            List<QuestionRecord> questionRecords = new List<QuestionRecord>();
+                            //结算每道题的答题情况
+                            var ContainerClient = _azureStorage.GetBlobContainerClient(blobcntr);
+                            List<Task<string>> tasks = new List<Task<string>>();
+                            //获取
+                            List<SurveyRecord> surveyRecords = new List<SurveyRecord>();
+                            try
+                            {
+                                List<string> items = await ContainerClient.List($"survey/{survey.id}/urecord");
+
+                                foreach (string item in items)
+                                {
+                                    var Download = await _azureStorage.GetBlobContainerClient(blobcntr).GetBlobClient(item).DownloadAsync();
+                                    var json = await JsonDocument.ParseAsync(Download.Value.Content);
+                                    var Record = json.RootElement.ToObject<SurveyRecord>();
+                                    surveyRecords.Add(Record);
+                                }
+#if DEBUG
+                                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查问题结算数据{surveyRecords.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+#endif
+                                for (int index = 0; index < survey.answers.Count; index++)
+                                {
+                                    string url = $"{survey.id}/qrecord/{index}.json";
+                                    QuestionRecord question = new QuestionRecord() { index = index };
+                                    foreach (SurveyRecord record in surveyRecords)
+                                    {
+                                        if (record.ans.Count == survey.answers.Count)
+                                        {
+                                            foreach (var an in record.ans[index])
+                                            {
+                                                //
+                                                if (question.opt.ContainsKey(an))
+                                                {
+                                                    if (question.opt[an] != null)
+                                                    {
+                                                        question.opt[an].Add(record.userid);
+                                                    }
+                                                    else
+                                                    {
+                                                        question.opt[an] = new HashSet<string>() { record.userid };
+                                                    }
+                                                }
+                                                else
+                                                {
+                                                    if (survey.answers[index].Contains(an))
+                                                    {
+                                                        //如果是客观题code
+                                                        question.opt.Add(an, new HashSet<string> { record.userid });
+                                                    }
+                                                    else
+                                                    {
+                                                        //如果不是客观code
+                                                        question.other[record.userid] = an;
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                    questionRecords.Add(question);
+                                    tasks.Add(_azureStorage.GetBlobContainerClient(blobcntr).UploadFileByContainer(question.ToJsonString(), "survey", url));
+                                }
+                                await Task.WhenAll(tasks);
+                            }
+                            catch (Exception ex)
+                            {
+                                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查问题结算异常{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
+                            }
+
+                            List<AnswerRecord> answerRecords = new List<AnswerRecord>();
+                            if (questionRecords.IsNotEmpty())
+                            {
+
+                               
+                                foreach (var questionRecord in questionRecords)
+                                {
+                                    AnswerRecord answerRecord = new AnswerRecord();
+                                    answerRecord.index = questionRecord.index.ToString();
+
+                                    foreach (var opt in questionRecord.opt)
+                                    {
+                                        if (!answerRecord.ans.ContainsKey(opt.Key))
+                                        {
+                                            answerRecord.ans[opt.Key] = 0;
+                                        }
+                                        answerRecord.ans[opt.Key] += opt.Value.Count;
+                                    }
+
+                                    answerRecords.Add(answerRecord);
+                                }
+                                //string resultJson = JsonConvert.SerializeObject(answerRecords, Formatting.Indented);
+                            }
+                            var cods = new { records = answerRecords, userids, question = questionRecords, urecord = surveyRecords };
+                            //问卷整体情况
+                            await _azureStorage.GetBlobContainerClient(blobcntr).UploadFileByContainer(cods.ToJsonString(), "survey", $"{survey.id}/record.json");
+
+                            List<(string pId, List<string> gid)> gls = new List<(string pId, List<string> gid)>();
+                            if (survey.groupLists.Count > 0)
+                            {
+                                var group = survey.groupLists;
+                                foreach (var gp in group)
+                                {
+                                    foreach (KeyValuePair<string, List<string>> pp in gp)
+                                    {
+                                        gls.Add((pp.Key, pp.Value));
+                                    }
+                                }
+                            }
+                            //处理问卷调查活动结束统计账户信息
+                            List<FMember> idsList = await GroupListService.GetFinishMemberInfo(_coreAPIHttpService, client, _dingDing, survey.school, survey.classes, survey.stuLists, survey.tchLists,gls);
+                            survey.staffIds = idsList;
+
+                            if (string.IsNullOrEmpty(survey.recordUrl))
+                            {
+                                survey.recordUrl = $"/survey/{survey.id}/record.json";
+                                await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<Survey>(survey, survey.id, new Azure.Cosmos.PartitionKey(survey.code));
+                            }
+                            else
+                            {
+                                _azureRedis.GetRedisClient(8).KeyDelete($"Survey:Record:{survey.id}");
+                                _azureRedis.GetRedisClient(8).KeyDelete($"Survey:Submit:{survey.id}");
+                                break;
+                            }
+                            string pk = string.Format("{0}{1}{2}", survey.code, "-", "going");
+                            await table.DeleteSingle<ChangeRecord>(pk, tdata.id);
+                            //更新结束状态
+                            //data.progress = "finish";
+                            //if (survey.scope .Equals("school"))
+                            //{
+                            //    await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<ActivityData>(data, data.id, new Azure.Cosmos.PartitionKey(data.code));
+                            //}
+                            //else if (survey.scope .Equals("private"))
+                            //{
+                            //    await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<ActivityData>(data, data.id, new Azure.Cosmos.PartitionKey(data.code));
+                            //}
+
+                            break;
+                    }
+                }
+            }
+
+            catch (CosmosException e)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-CosmosDB异常{e.Message}\n{e.StackTrace}\n{e.Status}", GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}问卷调查{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
+
+            }
+        }
+    }
+    /**
+     * {survey.id}/qrecord/{index}.json
+        {
+            "opt": {
+                "A": [
+                    "userid1",
+                    "userid2",
+                    "userid3"
+                ],
+                "B": [
+                    "userid1",
+                    "userid2",
+                    "userid3"
+                ]
+            },
+            "other": {
+                "userid1": "建议XXXX1",
+                "userid2": "建议XXXX2"
+            }
+        }
+     **/
+}

+ 422 - 0
TEAMModelOS.Function/CosmosDBTriggers/TriggerVote.cs

@@ -0,0 +1,422 @@
+using Azure.Cosmos;
+using Azure.Messaging.ServiceBus;
+using Microsoft.Azure.Documents;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Cosmos.Common.Inner;
+using TEAMModelOS.SDK.Models.Service;
+using HTEXLib.COMM.Helpers;
+using Microsoft.Extensions.Configuration;
+using DocumentFormat.OpenXml.Office2013.Excel;
+using DocumentFormat.OpenXml.Vml;
+using TEAMModelOS.SDK.Models.Service.BI;
+using TEAMModelOS.Function;
+namespace TEAMModelOS.CosmosDBTriggers
+{
+    public static class TriggerVote
+    {
+
+        public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
+            CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis, IConfiguration _configuration)
+        {
+            try
+            {
+                if ((tdata.status != null && tdata.status.Value == 404) )
+                {
+                    await client.GetContainer(Constant.TEAMModelOS, "Common").DeleteItemStreamAsync(tdata.id, new PartitionKey(tdata.code));
+                    ActivityList data = input.ToObject<ActivityList>();
+                   // await IESActivityService. DeleteActivity(_coreAPIHttpService, client, _dingDing, data);
+                    _azureRedis.GetRedisClient(8).KeyDelete($"Vote:Record:{tdata.id}");
+                    _azureRedis.GetRedisClient(8).KeyDelete($"Vote:Count:{tdata.id}");
+                    var table_cancel = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                    List<ChangeRecord> records = await table_cancel.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id } });
+                    foreach (var record in records)
+                    {
+                        try
+                        {
+                            await table_cancel.DeleteSingle<ChangeRecord>(record.PartitionKey, record.RowKey);
+                            await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber);
+                        }
+                        catch (Exception)
+                        {
+                            continue;
+                        }
+                    }
+
+                    await BIStats.SetTypeAddStats(client, _dingDing, tdata.school, "Vote", -1, careDate: tdata.startTime);//BI统计增/减量
+                    return;
+                }
+                var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
+                var adid = tdata.id;
+                var adcode = "";
+                string blobcntr = null;
+                if (tdata.scope.Equals("school"))
+                {
+                    adcode = $"Activity-{tdata.school}";
+                    blobcntr = tdata.school;
+                }
+                else
+                {
+                    adcode = $"Activity-{tdata.creatorId}";
+                    blobcntr = tdata.creatorId;
+                }
+               // await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}投票活动【{tdata.name}-{tdata.id}-ttl={tdata.ttl}】正在操作", GroupNames.醍摩豆服務運維群組);
+                Vote vote = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Vote>(tdata.id, new Azure.Cosmos.PartitionKey($"{tdata.code}"));
+
+                if (vote != null)
+                {
+                    string PartitionKey = string.Format("{0}{1}{2}", vote.code, "-", vote.progress);
+                    List<ChangeRecord> voteRecords = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id }, { "PartitionKey", PartitionKey } });
+                    switch (vote.progress)
+                    {
+                        case "pending":
+                            var messageVote = new ServiceBusMessage(new { id = tdata.id, progress = "going", code = tdata.code }.ToJsonString());
+                            messageVote.ApplicationProperties.Add("name", "Vote");
+                            if (voteRecords.Count > 0)
+                            {
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVote, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                try {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), voteRecords[0].sequenceNumber);
+                                } catch (Exception) { 
+                                }
+                                voteRecords[0].sequenceNumber = start;
+                                await table.SaveOrUpdate<ChangeRecord>(voteRecords[0]);
+                            }
+                            else
+                            {
+                                long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVote, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
+                                ChangeRecord changeRecord = new ChangeRecord
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = start,
+                                    msgId = messageVote.MessageId
+                                };                                
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+                            break;
+                        case "going":
+
+                            List<(string pId, List<string> gid)> ps = new List<(string pId, List<string> gid)>();
+                            if (vote.groupLists.Count > 0)
+                            {
+                                var group = vote.groupLists;
+                                foreach (var keys in group)
+                                {
+                                    foreach (KeyValuePair<string, List<string>> pp in keys)
+                                    {
+                                        ps.Add((pp.Key, pp.Value));
+                                    }
+                                }
+                            }
+                            List<string> classes = ExamService.getClasses(vote.classes, vote.stuLists);
+                            (List<RMember> tmdIds, List<RGroupList> classLists) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classes, vote.school, ps);
+                            var addStudentsCls = tmdIds.FindAll(x => x.type == 2);
+                            var addTmdidsCls = tmdIds.FindAll(x => x.type == 1);
+                            //await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}投票活动" +
+                            //    $"{tmdids.ToJsonString()}\n" +
+                            //    $"{students.ToJsonString()}\n" +
+                            //    $"{classLists.ToJsonString()}\n" +
+                            //    $"{classes.ToJsonString()}\n", GroupNames.醍摩豆服務運維群組);
+                            List<string> tmds = new List<string>();
+                            if (addTmdidsCls.IsNotEmpty())
+                            {
+                                tmds.AddRange(addTmdidsCls.Select(x => x.id).ToList());
+                            }
+                            List<StuActivity> stuActivities = new();
+                            List<StuActivity> tmdActivities = new();
+                            List<StuActivity> tchActivities = new();
+                            /*
+                           
+                           
+                            List<string> sub = new();
+                            if (vote.tchLists.Count == 0)
+                            {
+                                if (vote.targets.Count > 0)
+                                {
+                                    foreach (var course in vote.targets)
+                                    {
+                                        var info = course.ToObject<List<string>>();
+                                        if (info.Count > 1)
+                                        {
+                                            sub.Add(info[0]);
+                                        }
+                                    }
+                                }
+                            }
+
+                            if (tmds.IsNotEmpty())
+                            {
+                                tmds.ForEach(x =>
+                                {
+                                    HashSet<string> classIds = new HashSet<string>();
+                                    classLists.ForEach(z =>
+                                    {
+                                        z.members.ForEach(y =>
+                                        {
+                                            if (y.id.Equals(x) && y.type == 1)
+                                            {
+                                                classIds.Add(z.id);
+                                            }
+                                        });
+                                    });
+                                    tmdActivities.Add(new StuActivity
+                                    {
+                                        pk = "Activity",
+                                        id = vote.id,
+                                        code = $"Activity-{x}",
+                                        type = "Vote",
+                                        name = vote.name,
+                                        startTime = vote.startTime,
+                                        endTime = vote.endTime,
+                                        scode = vote.code,
+                                        scope = vote.scope,
+                                        school = vote.school,
+                                        creatorId = vote.creatorId,
+                                        subjects = sub,
+                                        blob = null,
+                                        owner = vote.owner,
+                                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                        taskStatus = -1,
+                                        classIds = classIds.ToList()
+                                    });
+                                });
+                            }
+                            if (addStudentsCls.IsNotEmpty())
+                            {
+                                addStudentsCls.ForEach(x =>
+                                {
+                                    HashSet<string> classIds = new HashSet<string>();
+                                    classLists.ForEach(z =>
+                                    {
+                                        z.members.ForEach(y =>
+                                        {
+                                            if (y.id.Equals(x.id) && y.code.Equals(vote.school) && y.type == 2)
+                                            {
+                                                classIds.Add(z.id);
+                                            }
+                                        });
+                                    });
+                                    stuActivities.Add(new StuActivity
+                                    {
+                                        pk = "Activity",
+                                        id = vote.id,
+                                        code = $"Activity-{x.code.Replace("Base-", "")}-{x.id}",
+                                        type = "Vote",
+                                        name = vote.name,
+                                        startTime = vote.startTime,
+                                        endTime = vote.endTime,
+                                        scode = vote.code,
+                                        scope = vote.scope,
+                                        school = vote.school,
+                                        creatorId = vote.creatorId,
+                                        subjects = sub,
+                                        blob = null,
+                                        owner = vote.owner,
+                                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                        taskStatus = -1,
+                                        classIds = classIds.ToList()
+                                    });
+                                });
+                            }
+                             */
+                            (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, vote.tchLists, vote.school, ps);
+                            (string standard, List<string> tmdids, string school, List<string> update, int statistics) list = (null, null, null, new List<string> { StatisticsService.TeacherVote }, 0);
+                            if (tchList.IsNotEmpty())
+                            {
+                                list.tmdids = tchList.Select(x => x.id).ToList();
+                                School school = null;
+                                if (!string.IsNullOrEmpty(vote.school))
+                                {
+                                    school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(vote.school, new Azure.Cosmos.PartitionKey("Base"));
+                                    list.school = school.id;
+                                    list.standard = school.standard;
+                                }
+
+                                tchList.ForEach(x =>
+                               {
+                                   HashSet<string> classIds = new HashSet<string>();
+                                   classInfos.ForEach(z =>
+                                   {
+                                       z.members.ForEach(y =>
+                                       {
+                                           if (y.id.Equals(x.id) && y.type == 1)
+                                           {
+                                               classIds.Add(z.id);
+                                           }
+                                       });
+                                   });
+                                   tchActivities.Add(new StuActivity
+                                   {
+                                       pk = "Activity",
+                                       id = vote.id,
+                                       code = $"Activity-{x.id}",
+                                       type = "Vote",
+                                       name = vote.name,
+                                       startTime = vote.startTime,
+                                       endTime = vote.endTime,
+                                       scode = vote.code,
+                                       scope = vote.scope,
+                                       school = vote.school,
+                                       creatorId = vote.creatorId,
+                                       subjects = new List<string> { "" },
+                                       blob = null,
+                                       owner = vote.owner,
+                                       createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                       taskStatus = -1,
+                                       classIds = classIds.ToList()
+                                   });
+                               });
+
+
+                            }
+                            await IESActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
+                            await StatisticsService.SendServiceBus(list, _configuration, _serviceBus, client);
+                            //向学生或醍摩豆账号发起通知
+                            #region
+                            //Notice notice = new Notice()
+                            //{
+
+                            //    creation = vote.startTime,
+                            //    expire = vote.endTime,
+                            //    creatorId = vote.creatorId,
+                            //    stuids = students,
+                            //    tmdids = tmdids,
+                            //    type = "notice",//问卷参加参加通知
+                            //    priority = "normal",
+                            //    msgId=vote.id,
+                            //    school = vote.school,
+                            //    scope = vote.scope,
+                            //    //data = new { }.ToJsonString()
+                            //    body = new Body { sid = vote.id, scode = vote.code, spk = vote.pk,  biztype = "vote-join" }
+
+                            //};
+
+                            //var messageBlob = new ServiceBusMessage(notice.ToJsonString());
+                            //messageBlob.ApplicationProperties.Add("name", "Notice");
+                            //await _serviceBus.GetServiceBusClient().SendMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:NoticeTask"), messageBlob);
+                            #endregion
+                            var messageVoteEnd = new ServiceBusMessage(new { id = tdata.id, progress = "finish", code = tdata.code }.ToJsonString());
+                            messageVoteEnd.ApplicationProperties.Add("name", "Vote");
+                            string pk = string.Format("{0}{1}{2}", vote.code, "-", "pending");
+                            await table.DeleteSingle<ChangeRecord>(pk, tdata.id);
+                            if (voteRecords.Count > 0)
+                            {
+                                long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVoteEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                try
+                                {
+                                    await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), voteRecords[0].sequenceNumber);
+                                }
+                                catch (Exception)
+                                {
+                                }
+                                voteRecords[0].sequenceNumber = end;
+                                await table.SaveOrUpdate<ChangeRecord>(voteRecords[0]);
+                            }
+                            else
+                            {
+                                long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageVoteEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
+                                ChangeRecord changeRecord = new()
+                                {
+                                    RowKey = tdata.id,
+                                    PartitionKey = PartitionKey,
+                                    sequenceNumber = end,
+                                    msgId = messageVoteEnd.MessageId
+                                };                                
+                                await table.Save<ChangeRecord>(changeRecord);
+                            }
+#if DEBUG
+                            await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}投票活动{tdata.id}将于:{tdata.endTime}完成并结算!", GroupNames.醍摩豆服務運維群組);
+#endif
+                            break;
+                        case "finish":
+                           
+#if DEBUG
+                            await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}投票活动{tdata.id}开始结算{tdata.endTime}!", GroupNames.醍摩豆服務運維群組);
+#endif
+                            //获取投票活动的所有投票记录
+                            string pkey = string.Format("{0}{1}{2}", vote.code, "-", "going");
+                            await table.DeleteSingle<ChangeRecord>(pkey, tdata.id);
+                            var records = await _azureRedis.GetRedisClient(8).HashGetAllAsync($"Vote:Record:{vote.id}");
+                            //获取投票活动的选项及投票数
+                            var counts = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Vote:Count:{vote.id}");
+                            List<dynamic> countcds = new List<dynamic>();
+                            if (counts != null && counts.Length > 0)
+                            {
+                                foreach (var count in counts)
+                                {
+                                    countcds.Add(new { code = count.Element.ToString(), count = (int)count.Score });
+                                }
+                            }
+                            List<Task<string>> tasks = new();
+                            List<VoteRecord> recordsBlob = new();
+                            foreach (var rcd in records)
+                            {
+                                var value = rcd.Value.ToString().ToObject<VoteRecord>();
+                                recordsBlob.Add(value);
+                            }
+                            //分组每个人的 
+                            var gp = recordsBlob.GroupBy(x => x.userid).Select(x => new { key = x.Key, list = x.ToList() });
+                            foreach (var g in gp)
+                            {
+                                tasks.Add(_azureStorage.GetBlobContainerClient(blobcntr).UploadFileByContainer(g.list.ToJsonString(), "vote", $"{vote.id}/urecord/{g.key}.json"));
+                            }
+                            //处理活动方的记录, 
+                            string url = $"/vote/{vote.id}/record.json";
+                            tasks.Add(_azureStorage.GetBlobContainerClient(blobcntr).UploadFileByContainer(new { options = countcds, records = recordsBlob }.ToJsonString(), "vote", $"{vote.id}/record.json"));
+                            //处理投票者的记录
+                            List<(string pId, List<string> gid)> gls = new List<(string pId, List<string> gid)>();
+                            if (vote.groupLists.Count > 0)
+                            {
+                                var group = vote.groupLists;
+                                foreach (var gro in group)
+                                {
+                                    foreach (KeyValuePair<string, List<string>> pp in gro)
+                                    {
+                                        gls.Add((pp.Key, pp.Value));
+                                    }
+                                }
+                            }
+                            //处理投票活动结束统计账户信息
+                            List<FMember> idsList = await GroupListService.GetFinishMemberInfo(_coreAPIHttpService, client, _dingDing, vote.school, vote.classes, vote.stuLists, vote.tchLists, gls);
+                            vote.staffIds = idsList;
+
+                            if (string.IsNullOrEmpty(vote.recordUrl))
+                            {
+                                vote.recordUrl = url;
+                                await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<Vote>(vote, vote.id, new Azure.Cosmos.PartitionKey(vote.code));
+                            }
+                            else
+                            {
+                                //异动,且已经有结算记录则不必再继续。
+                                _azureRedis.GetRedisClient(8).KeyDelete($"Vote:Record:{vote.id}");
+                                _azureRedis.GetRedisClient(8).KeyDelete($"Vote:Count:{vote.id}");
+                                break;
+                            }
+                            await Task.WhenAll(tasks);                         
+                            break;
+                    }
+                }
+            }
+            catch (CosmosException e)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-CosmosDB异常{e.Message}\n{e.StackTrace}\n{e.Status}", GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}投票活动异常{ex.Message}\n{ex.StackTrace}\n{input.ToJsonString()}\n{tdata.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+            }
+
+        }
+    }
+}

+ 51 - 0
TEAMModelOS.Function/DI/BackgroundWorkerQueue.cs

@@ -0,0 +1,51 @@
+using Microsoft.Extensions.Hosting;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TEAMModelOS.Function.DI
+{
+    public class BackgroundWorkerQueue
+    {
+        private readonly ConcurrentQueue<Func<CancellationToken, Task>> _workItems = new();
+        private readonly SemaphoreSlim _signal = new(0);
+
+        public async Task<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken)
+        {
+            await _signal.WaitAsync(cancellationToken);
+            _workItems.TryDequeue(out var workItem);
+
+            return workItem;
+        }
+
+        public void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem)
+        {
+            ArgumentNullException.ThrowIfNull(workItem);
+
+            _workItems.Enqueue(workItem);
+            _signal.Release();
+        }
+    }
+    public class LongRunningService : BackgroundService
+    {
+
+        public LongRunningService(BackgroundWorkerQueue queue)
+        {
+            _queue = queue;
+        }
+        private readonly BackgroundWorkerQueue _queue;
+
+        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+        {
+            while (!stoppingToken.IsCancellationRequested)
+            {
+                var workItem = await _queue.DequeueAsync(stoppingToken);
+
+                await workItem(stoppingToken);
+            }
+        }
+    }
+}

+ 135 - 0
TEAMModelOS.Function/IESCosmosDBTrigger.cs

@@ -0,0 +1,135 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK;
+using System.Xml.Linq;
+using Microsoft.Azure.Cosmos.Linq;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.CosmosDBTriggers;
+namespace TEAMModelOS.Function
+{
+    public class IESCosmosDBTrigger
+    {
+        private readonly ILogger _logger;
+        private readonly AzureCosmosFactory _azureCosmos;
+        private readonly AzureServiceBusFactory _serviceBus;
+        private readonly AzureStorageFactory _azureStorage;
+        private readonly DingDing _dingDing;
+        private readonly AzureRedisFactory _azureRedis;
+        private readonly IHttpClientFactory _httpClient;
+        private IConfiguration _configuration { get; set; }
+        private readonly CoreAPIHttpService _coreAPIHttpService;
+        private readonly HttpTrigger _httpTrigger;
+
+        public IESCosmosDBTrigger(ILoggerFactory loggerFactory, CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, AzureServiceBusFactory azureServiceBus, AzureStorageFactory azureStorage, DingDing dingDing, AzureRedisFactory azureRedis
+          , IConfiguration configuration, IHttpClientFactory httpClient, HttpTrigger httpTrigger)
+        {
+            _logger = loggerFactory.CreateLogger<IESCosmosDBTrigger>();
+            _azureCosmos = azureCosmos;
+            _serviceBus = azureServiceBus;
+            _azureStorage = azureStorage;
+            _dingDing = dingDing;
+            _azureRedis = azureRedis;
+            _configuration = configuration;
+            _coreAPIHttpService=coreAPIHttpService;
+            _httpClient = httpClient;
+            _httpTrigger = httpTrigger;
+        }
+
+        [Function("Common")]
+        public async Task Common([CosmosDBTrigger(
+            databaseName: "TEAMModelOS",
+            containerName: "Common",
+            Connection = "Azure:Cosmos:ConnectionString",
+            LeaseContainerName = "leases",
+            CreateLeaseContainerIfNotExists = true)] IReadOnlyList<JsonElement> input)
+        {
+            if (input != null && input.Count > 0)
+            {
+                _logger.LogInformation("Documents modified: " + input.Count);
+                _logger.LogInformation("First document Id: " +JsonSerializer.Serialize(input[0]));
+                var client = _azureCosmos.GetCosmosClient();
+                foreach (var element in input) {
+                    _logger.LogInformation("变化参数 " + element);
+                    element.TryGetProperty("pk", out JsonElement jsond);
+                    if (!string.IsNullOrWhiteSpace($"{jsond}"))
+                    {
+                        if ($"{jsond}".Equals("Receiver", StringComparison.OrdinalIgnoreCase)
+                            || $"{jsond}".Equals("Notice", StringComparison.OrdinalIgnoreCase)
+                            || $"{jsond}".Equals("ExamClassResult", StringComparison.OrdinalIgnoreCase))
+                        {
+                            ///通知接收者的变更
+                            continue;
+                        }
+                        //else if ($"{jsond}".Equals("StatsNotice", StringComparison.OrdinalIgnoreCase)) 
+                        //{
+                        //    var sert = 012;
+                        //}
+                        else
+                        {
+                            TriggerData data = element.ToObject<TriggerData>();
+                            ///活动类型的变更
+#if DEBUG
+                            await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-CosmosDBTrigger,{data.pk}触发变更\n{data.ToJsonString()}",
+                                            GroupNames.醍摩豆服務運維群組);
+#endif
+                            switch (data.pk)
+                            {
+                                case "Exam":
+                                    await TriggerExam.Trigger(_coreAPIHttpService, _azureCosmos, _serviceBus, _azureStorage, _dingDing, client, element, data, _httpClient, _configuration, _httpTrigger, _azureRedis);
+                                    break;
+                                case "Vote":
+                                    await TriggerVote.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis, _configuration);
+                                    break;
+                                case "Survey":
+                                    await TriggerSurvey.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis, _configuration);
+                                    break;
+                                case "Correct":
+                                    await TriggerCorrect.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis);
+                                    break;
+                                case "ExamLite":
+                                    await TriggerExamLite.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis, _configuration);
+                                    break;
+                                case "Study":
+                                    await TriggerStudy.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis, _configuration);
+                                    break;
+                                case "Homework":
+                                    await TriggerHomework.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis, _configuration);
+                                    break;
+                                case "Art":
+                                    await TriggerArt.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis, _configuration, _httpTrigger);
+                                    break;
+                                case "ExamImport":
+                                    await TriggerExamImport.Trigger(_coreAPIHttpService, _azureCosmos, _serviceBus, _azureStorage, _dingDing, client, element, data, _httpClient, _configuration, _azureRedis);
+                                    break;
+                                case "QuotaImport":
+                                    await TriggerQuotaImport.Trigger(_coreAPIHttpService, _azureCosmos, _serviceBus, _azureStorage, _dingDing, client, element, data, _httpClient, _configuration, _azureRedis);
+                                    break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    public class TriggerData
+    {
+        public string pk { get; set; }
+        public int? status { get; set; }
+        public string name { get; set; }
+        public long startTime { get; set; }
+        public long endTime { get; set; }
+        public string school { get; set; }
+        public string code { get; set; }
+        public string creatorId { get; set; }
+        public string progress { get; set; }
+        public string scope { get; set; }
+        public int ttl { get; set; }
+        public string id { get; set; }
+        public int? publish { get; set; }
+    }
+}

+ 24 - 0
TEAMModelOS.Function/IESHttpTrigger.cs

@@ -0,0 +1,24 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Extensions.Logging;
+
+namespace TEAMModelOS.Function
+{
+    public class IESHttpTrigger
+    {
+        private readonly ILogger<IESHttpTrigger> _logger;
+
+        public IESHttpTrigger(ILogger<IESHttpTrigger> logger)
+        {
+            _logger = logger;
+        }
+
+        [Function("IESHttpTrigger")]
+        public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequest req)
+        {
+            _logger.LogInformation("C# HTTP trigger function processed a request.");
+            return new OkObjectResult("Welcome to Azure Functions!");
+        }
+    }
+}

+ 37 - 0
TEAMModelOS.Function/IESServiceBusTrigger.cs

@@ -0,0 +1,37 @@
+using System;
+using System.Threading.Tasks;
+using Azure.Messaging.ServiceBus;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Extensions.Logging;
+
+namespace TEAMModelOS.Function
+{
+    public class IESServiceBusTrigger
+    {
+        private readonly ILogger<IESServiceBusTrigger> _logger;
+
+        public IESServiceBusTrigger(ILogger<IESServiceBusTrigger> logger)
+        {
+            _logger = logger;
+        }
+        /// <summary>
+        /// UseDevelopmentStorage=true
+        /// </summary>
+        /// <param name="message"></param>
+        /// <param name="messageActions"></param>
+        /// <returns></returns>
+        [Function("BlobRoot")]
+        public async Task BlobRoot(
+            [ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "blobroot", Connection = "Azure:ServiceBus:ConnectionString")]
+            ServiceBusReceivedMessage message,
+            ServiceBusMessageActions messageActions)
+        {
+            _logger.LogInformation("Message ID: {id}", message.MessageId);
+            _logger.LogInformation("Message Body: {body}", message.Body);
+            _logger.LogInformation("Message Content-Type: {contentType}", message.ContentType);
+
+             // Complete the message
+            await messageActions.CompleteMessageAsync(message);
+        }
+    }
+}

+ 27 - 0
TEAMModelOS.Function/IESTimerTrigger.cs

@@ -0,0 +1,27 @@
+using System;
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Extensions.Logging;
+
+namespace TEAMModelOS.Function
+{
+    public class IESTimerTrigger
+    {
+        private readonly ILogger _logger;
+
+        public IESTimerTrigger(ILoggerFactory loggerFactory)
+        {
+            _logger = loggerFactory.CreateLogger<IESTimerTrigger>();
+        }
+
+        [Function("IESTimerTrigger")]
+        public void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer)
+        {
+            _logger.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
+            
+            if (myTimer.ScheduleStatus is not null)
+            {
+                _logger.LogInformation($"Next timer schedule at: {myTimer.ScheduleStatus.Next}");
+            }
+        }
+    }
+}

+ 43 - 0
TEAMModelOS.Function/Program.cs

@@ -0,0 +1,43 @@
+
+using Microsoft.Azure.Functions.Worker;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using TEAMModelOS.Function.DI;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.DI.Multiple;
+var host = new HostBuilder()
+    .ConfigureFunctionsWebApplication()
+    .ConfigureServices((context, services) =>
+    {
+        services.AddApplicationInsightsTelemetryWorkerService();
+        services.ConfigureFunctionsApplicationInsights();
+
+
+
+        services.AddHttpClient();
+        services.AddHttpClient<DingDing>();
+        services.AddHttpClient<HttpTrigger>();
+        services.AddHttpClient<CoreAPIHttpService>();
+        List<(string name, string connectionString)> cosmosDBConnects = new();
+        cosmosDBConnects.Add(("Default", context.Configuration.GetSection("Azure:Cosmos:ConnectionString").Get<string>()));
+        cosmosDBConnects.Add(("CoreServiceV1", context.Configuration.GetSection("CoreServiceV1:Cosmos:ConnectionString").Get<string>())); //CoreService V1 read only
+        cosmosDBConnects.Add(("CoreServiceV2", context.Configuration.GetSection("CoreServiceV2:Cosmos:ConnectionString").Get<string>())); //CoreService V2
+        cosmosDBConnects.Add(("CoreServiceV2CnRead", context.Configuration.GetSection("CoreServiceV2:CosmosCnRead:ConnectionString").Get<string>())); //CoreService V2 CN read only
+        services.AddMultipleAzureCosmos(cosmosDBConnects);
+
+        services.AddAzureServiceBus(context.Configuration.GetSection("Azure:ServiceBus:ConnectionString").Get<string>());
+
+        services.AddAzureRedis(context.Configuration.GetSection("Azure:Redis:ConnectionString").Get<string>());
+        services.AddSnowflakeId(Convert.ToInt64(context.Configuration.GetSection("Option:LocationNum").Get<Int32>()), 1);
+        List<(string name, string connectionString)> storageConnects = new();
+        storageConnects.Add(("Default", context.Configuration.GetSection("Azure:Storage:ConnectionString").Get<string>()));
+        services.AddMultipleAzureStorage(storageConnects);
+
+        services.AddSingleton<BackgroundWorkerQueue>();
+        services.AddHostedService<LongRunningService>();
+    })
+    .Build();
+
+host.Run();

+ 9 - 0
TEAMModelOS.Function/Properties/launchSettings.json

@@ -0,0 +1,9 @@
+{
+  "profiles": {
+    "TEAMModelOS.Function": {
+      "commandName": "Project",
+      "commandLineArgs": "--port 7201",
+      "launchBrowser": false
+    }
+  }
+}

+ 12 - 0
TEAMModelOS.Function/Properties/serviceDependencies.json

@@ -0,0 +1,12 @@
+{
+  "dependencies": {
+    "appInsights1": {
+      "type": "appInsights",
+      "connectionId": "APPLICATIONINSIGHTS_CONNECTION_STRING"
+    },
+    "storage1": {
+      "type": "storage",
+      "connectionId": "AzureWebJobsStorage"
+    }
+  }
+}

+ 11 - 0
TEAMModelOS.Function/Properties/serviceDependencies.local.json

@@ -0,0 +1,11 @@
+{
+  "dependencies": {
+    "appInsights1": {
+      "type": "appInsights.sdk"
+    },
+    "storage1": {
+      "type": "storage.emulator",
+      "connectionId": "AzureWebJobsStorage"
+    }
+  }
+}

+ 14 - 0
TEAMModelOS.Function/Properties/serviceDependencies.teammodelosfunction-test - Zip Deploy.json

@@ -0,0 +1,14 @@
+{
+  "dependencies": {
+    "appInsights1": {
+      "resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/microsoft.insights/components/teammodelosfunctiontest",
+      "type": "appInsights.azure",
+      "connectionId": "APPLICATIONINSIGHTS_CONNECTION_STRING"
+    },
+    "storage1": {
+      "resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.Storage/storageAccounts/teammodellog",
+      "type": "storage.azure",
+      "connectionId": "AzureWebJobsStorage"
+    }
+  }
+}

+ 36 - 0
TEAMModelOS.Function/TEAMModelOS.Function.csproj

@@ -0,0 +1,36 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <AzureFunctionsVersion>v4</AzureFunctionsVersion>
+    <OutputType>Exe</OutputType>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+  <ItemGroup>
+    <FrameworkReference Include="Microsoft.AspNetCore.App" />
+    <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.22.0" />
+    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.CosmosDB" Version="4.0.0-preview2" />
+    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
+    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.3.2" />
+    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ServiceBus" Version="5.20.0" />
+    <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" Version="4.3.1" />
+    <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.2" />
+    <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
+    <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\TEAMModelOS.SDK\TEAMModelOS.SDK.csproj" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Update="host.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
+    <None Update="local.settings.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
+  </ItemGroup>
+</Project>

+ 12 - 0
TEAMModelOS.Function/host.json

@@ -0,0 +1,12 @@
+{
+    "version": "2.0",
+    "logging": {
+        "applicationInsights": {
+            "samplingSettings": {
+                "isEnabled": true,
+                "excludedTypes": "Request"
+            },
+            "enableLiveMetricsFilters": true
+        }
+    }
+}

+ 11 - 0
TEAMModelOS.Function/readme.md

@@ -0,0 +1,11 @@
+# TimerTrigger - C<span>#</span>
+
+The `TimerTrigger` makes it incredibly easy to have your functions executed on a schedule. This sample demonstrates a simple use case of calling your function every 5 minutes.
+
+## How it works
+
+For a `TimerTrigger` to work, you provide a schedule in the form of a [cron expression](https://en.wikipedia.org/wiki/Cron#CRON_expression)(See the link for full details). A cron expression is a string with 6 separate expressions which represent a given schedule via patterns. The pattern we use to represent every 5 minutes is `0 */5 * * * *`. This, in plain text, means: "When seconds is equal to 0, minutes is divisible by 5, for any hour, day of the month, month, day of the week, or year".
+
+## Learn more
+
+<TODO> Documentation

+ 0 - 2
TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosExtensions.cs

@@ -1,5 +1,3 @@
-using Microsoft.Azure.Cosmos.Table;
-using Microsoft.Azure.Cosmos.Table.Queryable;
 using System;
 using System;
 using System.Collections;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Generic;

+ 9 - 7
TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosFactory.cs

@@ -1,8 +1,11 @@
 using Azure.Cosmos;
 using Azure.Cosmos;
+using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
 using System;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
 
 
 namespace TEAMModelOS.SDK.DI
 namespace TEAMModelOS.SDK.DI
 {
 {
@@ -16,13 +19,12 @@ namespace TEAMModelOS.SDK.DI
 
 
         //   private CosmosDatabase database { get; set; }
         //   private CosmosDatabase database { get; set; }
 
 
-        public AzureCosmosFactory(IServiceProvider services, IOptionsMonitor<AzureCosmosFactoryOptions> optionsMonitor )
+        public AzureCosmosFactory(IServiceProvider services, IOptionsMonitor<AzureCosmosFactoryOptions> optionsMonitor)
         {
         {
             if (services == null) throw new ArgumentNullException(nameof(services));
             if (services == null) throw new ArgumentNullException(nameof(services));
             if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor));
             if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor));
-
+           _optionsMonitor = optionsMonitor;
             _services = services;
             _services = services;
-            _optionsMonitor = optionsMonitor;            
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -35,14 +37,14 @@ namespace TEAMModelOS.SDK.DI
         {
         {
             try
             try
             {
             {
-                //CosmosClientOptions 的 SerializerOptions = new CosmosSerializationOptions() { PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase } 
+                //CosmosClientOptions 的 SerializerOptions = new CosmosSerializationOptions() { PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase }
                 //需等待官方修正
                 //需等待官方修正
-                var cm = CosmosClients.GetOrAdd(name, x => new CosmosClient(_optionsMonitor.Get(name).CosmosConnectionString, new CosmosClientOptions() {  ApplicationRegion = region }));
-                return cm;
+                var cm = CosmosClients.GetOrAdd(name, x => new CosmosClient(_optionsMonitor.Get(name).CosmosConnectionString, new CosmosClientOptions() { ApplicationRegion = region }));
+                return cm; ;
             }
             }
             catch (Exception e)
             catch (Exception e)
             {
             {
-                return null;
+               throw new Exception($"GetCosmosClient error:{e.Message}{e.StackTrace}");
             }
             }
         }        
         }        
 
 

+ 0 - 2
TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusExtensions.cs

@@ -1,5 +1,3 @@
-using Microsoft.Azure.Cosmos.Table;
-using Microsoft.Azure.Cosmos.Table.Queryable;
 using System;
 using System;
 using System.Collections;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Generic;

+ 0 - 8
TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusFactory.cs

@@ -1,15 +1,7 @@
 
 
-using Microsoft.Azure.Cosmos.Table;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 using System;
 using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.Extensions.DependencyInjection;
-using Azure.Storage.Blobs;
-using Azure.Storage.Blobs.Models;
-using Azure.Storage.Blobs.Specialized;
-using StackExchange.Redis;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 using Azure.Messaging.ServiceBus;
 using Azure.Messaging.ServiceBus;
 
 

+ 0 - 1
TEAMModelOS.SDK/DI/HttpTrigger/WebHookHttpTrigger.cs

@@ -1,6 +1,5 @@
 using Azure.Cosmos;
 using Azure.Cosmos;
 using Azure.Storage.Blobs.Models;
 using Azure.Storage.Blobs.Models;
-using Grpc.Core;
 using HTEXLib.COMM.Helpers;
 using HTEXLib.COMM.Helpers;
 using Microsoft.AspNetCore;
 using Microsoft.AspNetCore;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;

+ 9 - 3
TEAMModelOS.SDK/DI/Multiple/MultipleAzureCosmosFactoryExtensions.cs

@@ -1,5 +1,6 @@
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection.Extensions;
 using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Options;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Text;
 using System.Text;
@@ -20,12 +21,17 @@ namespace TEAMModelOS.SDK.DI.Multiple
         {
         {
             if (services == null) throw new ArgumentNullException(nameof(services));
             if (services == null) throw new ArgumentNullException(nameof(services));
             if (connectionInfo == null) throw new ArgumentNullException(nameof(connectionInfo));
             if (connectionInfo == null) throw new ArgumentNullException(nameof(connectionInfo));
-            services.TryAddSingleton<AzureCosmosFactory>();
+          
             connectionInfo.ForEach(connection =>
             connectionInfo.ForEach(connection =>
             {
             {
                 services.Configure<AzureCosmosFactoryOptions>(connection.name, o => { o.Name = connection.name; o.CosmosConnectionString = connection.connectionString; });
                 services.Configure<AzureCosmosFactoryOptions>(connection.name, o => { o.Name = connection.name; o.CosmosConnectionString = connection.connectionString; });
-            });  //多个数据库注入
-            //services.Configure<AzureCosmosFactoryOptions>(name, o => { o.Name = name; o.CosmosConnectionString = connectionString; });  //单个数据库注入
+               
+            });
+            services.AddSingleton<IOptionsMonitor<AzureCosmosFactoryOptions>, OptionsMonitor<AzureCosmosFactoryOptions>>();
+            services.TryAddSingleton<AzureCosmosFactory>();
+           
+            //多个数据库注入
+           
             return services;
             return services;
         }
         }
     }
     }

+ 0 - 46
TEAMModelOS.SDK/Helper/Common/JsonHelper/JsonPatchHelper.cs

@@ -1,46 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using Microsoft.AspNetCore.JsonPatch;
-using Microsoft.AspNetCore.JsonPatch.Operations;
-namespace System
-{
-    public static class JsonPatchHelper
-    {
-        public static T JsonAdd<T>(this T t, string path, object value) where T : class
-        {
-            JsonPatchDocument<T> jsonPatch = new JsonPatchDocument<T>();
-            jsonPatch.Operations.Add(new Operation<T>("add", path, null, value));
-            jsonPatch.ApplyTo(t);
-            return t;
-        }
-        public static T JsonRemove<T>(this T t, string path) where T : class
-        {
-            JsonPatchDocument<T> jsonPatch = new JsonPatchDocument<T>();
-            jsonPatch.Operations.Add(new Operation<T>("remove", path, null, null));
-            jsonPatch.ApplyTo(t);
-            return t;
-        }
-        public static T JsonReplace<T>(this T t, string path, object value) where T : class
-        {
-            JsonPatchDocument<T> jsonPatch = new JsonPatchDocument<T>();
-            jsonPatch.Operations.Add(new Operation<T>("replace", path, null, value));
-            jsonPatch.ApplyTo(t);
-            return t;
-        }
-        public static T JsonMove<T>(this T t, string from, string path) where T : class
-        {
-            JsonPatchDocument<T> jsonPatch = new JsonPatchDocument<T>();
-            jsonPatch.Operations.Add(new Operation<T>("move", path, from));
-            jsonPatch.ApplyTo(t);
-            return t;
-        }
-        public static T JsonCopy<T>(this T t, string from, string path) where T : class
-        {
-            JsonPatchDocument<T> jsonPatch = new JsonPatchDocument<T>();
-            jsonPatch.Operations.Add(new Operation<T>("copy", path, from));
-            jsonPatch.ApplyTo(t);
-            return t;
-        }
-    }
-}

+ 0 - 3
TEAMModelOS.SDK/Helper/Common/StringHelper/PingYinHelper.cs

@@ -1,8 +1,5 @@
 using Microsoft.International.Converters.PinYinConverter;
 using Microsoft.International.Converters.PinYinConverter;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using NUnit.Framework.Internal;
 using System;
 using System;
-using System.Collections.Generic;
 using System.Text;
 using System.Text;
 
 
 namespace TEAMModelOS.SDK
 namespace TEAMModelOS.SDK

+ 1 - 2
TEAMModelOS.SDK/Models/Cosmos/Common/StudentScoreRecord.cs

@@ -1,5 +1,4 @@
-using NUnit.Framework.Internal.Execution;
-using System;
+using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using System.Text;
 using System.Text;

+ 1 - 5
TEAMModelOS.SDK/Models/Service/BI/BICommonWay.cs

@@ -1,11 +1,7 @@
-using DocumentFormat.OpenXml.Bibliography;
-using MathNet.Numerics.LinearAlgebra.Double;
-using NUnit.Framework;
+using MathNet.Numerics.LinearAlgebra.Double;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Linq;
 using System.Text;
 using System.Text;
-using System.Threading.Tasks;
 
 
 namespace TEAMModelOS.SDK.Models.Service.BI
 namespace TEAMModelOS.SDK.Models.Service.BI
 {
 {

+ 0 - 2
TEAMModelOS.SDK/Models/Service/BI/BIStats.cs

@@ -1,9 +1,7 @@
 using Azure.Cosmos;
 using Azure.Cosmos;
 using Azure.Storage.Blobs;
 using Azure.Storage.Blobs;
-using DocumentFormat.OpenXml.Math;
 using MathNet.Numerics.LinearAlgebra.Double;
 using MathNet.Numerics.LinearAlgebra.Double;
 using Microsoft.Azure.Cosmos.Table;
 using Microsoft.Azure.Cosmos.Table;
-using NUnit.Framework.Constraints;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;

+ 0 - 13
TEAMModelOS.SDK/Models/Service/StudentService.cs

@@ -1,20 +1,8 @@
 using Azure;
 using Azure;
 using Azure.Cosmos;
 using Azure.Cosmos;
 using Azure.Messaging.ServiceBus;
 using Azure.Messaging.ServiceBus;
-using DocumentFormat.OpenXml.Drawing;
-using DocumentFormat.OpenXml.Drawing.Charts;
-using DocumentFormat.OpenXml.Office2010.Excel;
-using DocumentFormat.OpenXml.Office2013.Excel;
-using DocumentFormat.OpenXml.Spreadsheet;
-using DocumentFormat.OpenXml.VariantTypes;
-using DocumentFormat.OpenXml.Vml;
 using HTEXLib.COMM.Helpers;
 using HTEXLib.COMM.Helpers;
-using HTEXLib.Helpers.ShapeHelpers;
-using Microsoft.AspNetCore.Http;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
-using NUnit.Framework;
-using NUnit.Framework.Interfaces;
-using OpenXmlPowerTools;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.IO;
 using System.IO;
@@ -27,7 +15,6 @@ using TEAMModelOS.Models;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models;
-using TEAMModelOS.SDK.Models.Service;
 using Member = TEAMModelOS.SDK.Models.Member;
 using Member = TEAMModelOS.SDK.Models.Member;
 
 
 namespace TEAMModelOS.SDK
 namespace TEAMModelOS.SDK

+ 0 - 14
TEAMModelOS.SDK/Models/Service/SystemService.cs

@@ -1,35 +1,21 @@
 using Azure.Storage.Blobs.Models;
 using Azure.Storage.Blobs.Models;
-using DocumentFormat.OpenXml.Bibliography;
-using DocumentFormat.OpenXml.Drawing.Charts;
-using DocumentFormat.OpenXml.Office2010.Excel;
-using DocumentFormat.OpenXml.Wordprocessing;
-using HTEXLib;
 using HTEXLib.COMM.Helpers;
 using HTEXLib.COMM.Helpers;
-using HTEXLib.PPTX.Models;
-using Microsoft.Azure.Amqp.Framing;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Logging;
 using Newtonsoft.Json.Linq;
 using Newtonsoft.Json.Linq;
-using NUnit.Framework.Internal.Execution;
-using OpenXmlPowerTools;
 using StackExchange.Redis;
 using StackExchange.Redis;
 using System;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Diagnostics.PerformanceData;
 using System.IdentityModel.Tokens.Jwt;
 using System.IdentityModel.Tokens.Jwt;
 using System.Linq;
 using System.Linq;
 using System.Net.Http;
 using System.Net.Http;
 using System.Net.Http.Json;
 using System.Net.Http.Json;
-using System.Security.Policy;
 using System.Text;
 using System.Text;
 using System.Text.Json;
 using System.Text.Json;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI;
-using TEAMModelOS.SDK.DI.Mail;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
-using TEAMModelOS.SDK.Models.Cosmos.Common;
 using TEAMModelOS.SDK.Models.Dtos;
 using TEAMModelOS.SDK.Models.Dtos;
 using static Azure.Core.HttpHeader;
 using static Azure.Core.HttpHeader;
 using static OpenXmlPowerTools.RevisionProcessor;
 using static OpenXmlPowerTools.RevisionProcessor;

+ 12 - 12
TEAMModelOS.SDK/TEAMModelOS.SDK.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
 
 
 	<PropertyGroup>
 	<PropertyGroup>
-		<TargetFramework>net6.0</TargetFramework>
+		<TargetFramework>net8.0</TargetFramework>
 		<Version>5.2406.19</Version>
 		<Version>5.2406.19</Version>
 		<AssemblyVersion>5.2406.19.1</AssemblyVersion>
 		<AssemblyVersion>5.2406.19.1</AssemblyVersion>
 		<FileVersion>5.2406.19.1</FileVersion>
 		<FileVersion>5.2406.19.1</FileVersion>
@@ -12,7 +12,7 @@
 		<PackageReference Include="CHTCHSConv" Version="1.0.0" />
 		<PackageReference Include="CHTCHSConv" Version="1.0.0" />
 		<PackageReference Include="AspectCore.Extensions.Reflection" Version="2.4.0" />
 		<PackageReference Include="AspectCore.Extensions.Reflection" Version="2.4.0" />
 		<PackageReference Include="Azure.Cosmos" Version="4.0.0-preview3" />
 		<PackageReference Include="Azure.Cosmos" Version="4.0.0-preview3" />
-		<PackageReference Include="Azure.Identity" Version="1.12.0" />
+		<!--<PackageReference Include="Azure.Identity" Version="1.12.0" />-->
 		<PackageReference Include="Azure.Messaging.ServiceBus" Version="7.17.5" />
 		<PackageReference Include="Azure.Messaging.ServiceBus" Version="7.17.5" />
 		<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.6.0" />
 		<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.6.0" />
 		<PackageReference Include="Azure.Storage.Blobs.Batch" Version="12.17.0" />
 		<PackageReference Include="Azure.Storage.Blobs.Batch" Version="12.17.0" />
@@ -23,20 +23,20 @@
 		<PackageReference Include="HTEXLib" Version="5.2401.1024" />
 		<PackageReference Include="HTEXLib" Version="5.2401.1024" />
 		<PackageReference Include="HtmlAgilityPack" Version="1.11.61" />
 		<PackageReference Include="HtmlAgilityPack" Version="1.11.61" />
 		<PackageReference Include="Lib.AspNetCore.ServerSentEvents" Version="9.0.0" />
 		<PackageReference Include="Lib.AspNetCore.ServerSentEvents" Version="9.0.0" />
-		<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.31" />
+		<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.6" />
+		<!--<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="8.0.6" />-->
+		<!--<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="8.0.6" />-->
+		<PackageReference Include="System.Drawing.Common" Version="8.0.6" />
 		<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
 		<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
-		<PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="6.0.31" />
 		<PackageReference Include="Microsoft.Azure.SignalR.Management" Version="1.25.2" />
 		<PackageReference Include="Microsoft.Azure.SignalR.Management" Version="1.25.2" />
-		<PackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="6.0.31" />
-		<PackageReference Include="Microsoft.Identity.Client" Version="4.61.3" />
-		<PackageReference Include="MSTest.TestFramework" Version="3.4.3" />
-		<PackageReference Include="NUnit" Version="4.1.0" />
+		<!--<PackageReference Include="Microsoft.Identity.Client" Version="4.61.3" />-->
+		<!--<PackageReference Include="MSTest.TestFramework" Version="3.4.3" />-->
+		<!--<PackageReference Include="NUnit" Version="4.1.0" />-->
 		<PackageReference Include="PinYinConverterCore" Version="1.0.2" />
 		<PackageReference Include="PinYinConverterCore" Version="1.0.2" />
-		<PackageReference Include="StackExchange.Redis" Version="2.7.33" />
-		<PackageReference Include="SvgNet" Version="2.2.2" />
-		<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
+		<PackageReference Include="StackExchange.Redis" Version="2.8.0" />
+		<!--<PackageReference Include="SvgNet" Version="3.3.6" />-->
 		<PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="2.0.0-preview" />
 		<PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="2.0.0-preview" />
-		<PackageReference Include="System.Net.Http.Json" Version="6.0.1" />
+		<!--<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />-->
 		<PackageReference Include="NPinyin.Core" Version="3.0.0" />
 		<PackageReference Include="NPinyin.Core" Version="3.0.0" />
 		<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
 		<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
 		<PackageReference Include="VueCliMiddleware" Version="6.0.0" />
 		<PackageReference Include="VueCliMiddleware" Version="6.0.0" />

+ 1 - 1
TEAMModelOS.TEST/TEAMModelOS.TEST.csproj

@@ -2,7 +2,7 @@
 
 
   <PropertyGroup>
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <OutputType>Exe</OutputType>
-    <TargetFramework>net6.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
     <Nullable>enable</Nullable>
   </PropertyGroup>
   </PropertyGroup>

+ 6 - 0
TEAMModelOS.sln

@@ -19,6 +19,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contest.Server", "TEAMModel
 EndProject
 EndProject
 Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "contest.client", "TEAMModelContest\contest.client\contest.client.esproj", "{84B6D998-91A7-420D-A409-4C7442B91055}"
 Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "contest.client", "TEAMModelContest\contest.client\contest.client.esproj", "{84B6D998-91A7-420D-A409-4C7442B91055}"
 EndProject
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TEAMModelOS.Function", "TEAMModelOS.Function\TEAMModelOS.Function.csproj", "{1C7F42FE-4644-47C6-92BD-594BE22AB0C9}"
+EndProject
 Global
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
 		Debug|Any CPU = Debug|Any CPU
@@ -55,6 +57,10 @@ Global
 		{84B6D998-91A7-420D-A409-4C7442B91055}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{84B6D998-91A7-420D-A409-4C7442B91055}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{84B6D998-91A7-420D-A409-4C7442B91055}.Release|Any CPU.Build.0 = Release|Any CPU
 		{84B6D998-91A7-420D-A409-4C7442B91055}.Release|Any CPU.Build.0 = Release|Any CPU
 		{84B6D998-91A7-420D-A409-4C7442B91055}.Release|Any CPU.Deploy.0 = Release|Any CPU
 		{84B6D998-91A7-420D-A409-4C7442B91055}.Release|Any CPU.Deploy.0 = Release|Any CPU
+		{1C7F42FE-4644-47C6-92BD-594BE22AB0C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1C7F42FE-4644-47C6-92BD-594BE22AB0C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1C7F42FE-4644-47C6-92BD-594BE22AB0C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1C7F42FE-4644-47C6-92BD-594BE22AB0C9}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE

+ 1 - 40
TEAMModelOS/Controllers/Both/ScoreCalcController.cs

@@ -3,69 +3,30 @@ using Azure.Core;
 using Azure.Cosmos;
 using Azure.Cosmos;
 using Azure.Messaging.ServiceBus;
 using Azure.Messaging.ServiceBus;
 using Azure.Storage.Blobs.Models;
 using Azure.Storage.Blobs.Models;
-using DinkToPdf;
-using DinkToPdf.Contracts;
-using DocumentFormat.OpenXml.Bibliography;
-using DocumentFormat.OpenXml.Office2010.Excel;
-using DocumentFormat.OpenXml.Office2016.Excel;
-using DocumentFormat.OpenXml.Presentation;
-using DocumentFormat.OpenXml.Spreadsheet;
-using DocumentFormat.OpenXml.VariantTypes;
-using DocumentFormat.OpenXml.Wordprocessing;
-using FastJSON;
+using DinkToPdf.Contracts; 
 using HTEXLib.COMM.Helpers;
 using HTEXLib.COMM.Helpers;
-using HTEXLib.Helpers.ShapeHelpers;
-using MathNet.Numerics.Distributions;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
-using Microsoft.International.Converters.PinYinConverter;
-using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
-using Microsoft.OData.Edm;
 using Newtonsoft.Json;
 using Newtonsoft.Json;
-using NUnit.Framework;
-using NUnit.Framework.Internal;
-using OpenXmlPowerTools;
 using StackExchange.Redis;
 using StackExchange.Redis;
 using System;
 using System;
-using System.Collections;
-using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Net;
 using System.Net;
 using System.Net.Http;
 using System.Net.Http;
-using System.Net.Http.Json;
-using System.Runtime.Intrinsics.X86;
-using System.Security.Policy;
 using System.Text;
 using System.Text;
 using System.Text.Json;
 using System.Text.Json;
-using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using System.Xml.Linq;
-using TEAMModelOS.Controllers.Analysis;
-using TEAMModelOS.Controllers.Core;
-using TEAMModelOS.Filter;
 using TEAMModelOS.Models;
 using TEAMModelOS.Models;
-using TEAMModelOS.Models.Dto;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models;
-using TEAMModelOS.SDK.Models.Cosmos.Common;
-using TEAMModelOS.SDK.Models.Cosmos.OpenEntity;
 using TEAMModelOS.SDK.Models.Cosmos.School;
 using TEAMModelOS.SDK.Models.Cosmos.School;
-using TEAMModelOS.SDK.Models.Cosmos.Student;
 using TEAMModelOS.SDK.Models.Service;
 using TEAMModelOS.SDK.Models.Service;
-using TEAMModelOS.SDK.Models.Service.BI;
-using TEAMModelOS.SDK.Services;
-using static Azure.Core.HttpHeader;
-using static TEAMModelOS.Controllers.Learn.HomeworkController;
-using static TEAMModelOS.SDK.Models.Teacher;
-using static TEAMModelOS.SDK.SchoolService;
 
 
 namespace TEAMModelOS.Controllers
 namespace TEAMModelOS.Controllers
 {
 {

+ 0 - 1
TEAMModelOS/Controllers/Client/HiTeachController.cs

@@ -33,7 +33,6 @@ using Azure;
 using TEAMModelOS.Controllers.Both;
 using TEAMModelOS.Controllers.Both;
 using TEAMModelOS.SDK.Models.Cosmos.School;
 using TEAMModelOS.SDK.Models.Cosmos.School;
 using Azure.Storage.Blobs;
 using Azure.Storage.Blobs;
-using Json.Path;
 using HtmlAgilityPack;
 using HtmlAgilityPack;
 using System.Diagnostics;
 using System.Diagnostics;
 using TEAMModelOS.Models.Service;
 using TEAMModelOS.Models.Service;

+ 1 - 22
TEAMModelOS/Controllers/Common/ArtController.cs

@@ -1,46 +1,25 @@
-using Azure.Core;
-using Azure.Cosmos;
+using Azure.Cosmos;
 using DinkToPdf.Contracts;
 using DinkToPdf.Contracts;
-using DocumentFormat.OpenXml.Bibliography;
-using DocumentFormat.OpenXml.Office2010.Excel;
-using DocumentFormat.OpenXml.Office2013.Excel;
-using DocumentFormat.OpenXml.Office2016.Excel;
-using DocumentFormat.OpenXml.Presentation;
-using DocumentFormat.OpenXml.Spreadsheet;
-using DocumentFormat.OpenXml.Wordprocessing;
-using HTEXLib.COMM.Helpers;
-using HTEXLib.Helpers.ShapeHelpers;
-using MathNet.Numerics.Distributions;
-using MathNet.Numerics.RootFinding;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
-using NUnit.Framework;
-using OpenXmlPowerTools;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
-using System.Net;
-using System.Reflection;
-using System.Security.Policy;
 using System.Text;
 using System.Text;
 using System.Text.Json;
 using System.Text.Json;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using System.Web;
 using System.Web;
-using System.Xml.Linq;
-using TEAMModelOS.Controllers.Analysis;
 using TEAMModelOS.Filter;
 using TEAMModelOS.Filter;
 using TEAMModelOS.Models;
 using TEAMModelOS.Models;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models;
-using TEAMModelOS.SDK.Models.Cosmos;
 using TEAMModelOS.SDK.Models.Cosmos.Common;
 using TEAMModelOS.SDK.Models.Cosmos.Common;
 using TEAMModelOS.SDK.Models.Cosmos.Student;
 using TEAMModelOS.SDK.Models.Cosmos.Student;
-using Survey = TEAMModelOS.SDK.Models.Survey;
 
 
 namespace TEAMModelOS.Controllers.Common
 namespace TEAMModelOS.Controllers.Common
 {
 {

+ 1 - 10
TEAMModelOS/Controllers/School/ImportExamController.cs

@@ -1,22 +1,13 @@
-using DocumentFormat.OpenXml.Spreadsheet;
-using HTEXLib.COMM.Helpers;
-using Microsoft.AspNetCore.Authorization;
+using HTEXLib.COMM.Helpers;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
-using Microsoft.Azure.Amqp.Framing;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
-using NUnit.Framework;
 using OfficeOpenXml;
 using OfficeOpenXml;
-using OpenXmlPowerTools;
-using StackExchange.Redis;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.ComponentModel;
 using System.Linq;
 using System.Linq;
-using System.Runtime.Intrinsics.Arm;
-using System.Text.Json;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using TEAMModelOS.Filter;
 using TEAMModelOS.Filter;

+ 0 - 31
TEAMModelOS/Controllers/System/BillController.cs

@@ -1,53 +1,22 @@
 using Azure.Storage.Blobs.Models;
 using Azure.Storage.Blobs.Models;
-using Azure.Storage.Blobs.Specialized;
-using DocumentFormat.OpenXml.Bibliography;
-using DocumentFormat.OpenXml.Drawing;
-using DocumentFormat.OpenXml.Office2010.Excel;
-using DocumentFormat.OpenXml.Spreadsheet;
-using DocumentFormat.OpenXml.Wordprocessing;
-using FastJSON;
 using HTEXLib.COMM.Helpers;
 using HTEXLib.COMM.Helpers;
-using IP2Region.Net.Abstractions;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Cors;
 using Microsoft.AspNetCore.Cors;
-using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
-using Microsoft.Azure.Amqp.Framing;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
-using Newtonsoft.Json.Linq;
-using NUnit.Framework;
-using OfficeOpenXml;
-using OpenXmlPowerTools;
-using StackExchange.Redis;
 using System;
 using System;
-using System.Collections;
-using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.ComponentModel;
 using System.IdentityModel.Tokens.Jwt;
 using System.IdentityModel.Tokens.Jwt;
-using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Net.Http;
 using System.Net.Http;
-using System.Runtime.Intrinsics.Arm;
-using System.Text;
 using System.Text.Json;
 using System.Text.Json;
-using System.Text.Json.Nodes;
-using System.Text.RegularExpressions;
-using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using System.Web;
-using TEAMModelOS.Filter;
 using TEAMModelOS.Models;
 using TEAMModelOS.Models;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
-using TEAMModelOS.SDK.IP2Region;
-using TEAMModelOS.SDK.Models.Cosmos.BI.BISchool;
-using TEAMModelOS.SDK.Models.Service;
-using Top.Api;
-using static TEAMModelOS.SDK.Models.Service.SystemService;
 
 
 namespace TEAMModelOS.Controllers
 namespace TEAMModelOS.Controllers
 {
 {

+ 0 - 36
TEAMModelOS/Controllers/XTest/TestController.cs

@@ -1,34 +1,14 @@
 using Azure;
 using Azure;
-using Azure.Core;
 using Azure.Cosmos;
 using Azure.Cosmos;
-using Azure.Messaging.ServiceBus;
-using Azure.Messaging.ServiceBus.Administration;
-using Azure.Storage.Blobs;
 using Azure.Storage.Blobs.Models;
 using Azure.Storage.Blobs.Models;
-using Azure.Storage.Blobs.Specialized;
 using DinkToPdf;
 using DinkToPdf;
 using DinkToPdf.Contracts; 
 using DinkToPdf.Contracts; 
-using DocumentFormat.OpenXml.Drawing.Wordprocessing;
-using DocumentFormat.OpenXml.Office2010.Excel;
-using DocumentFormat.OpenXml.Office2016.Excel;
-using DocumentFormat.OpenXml.Presentation;
-using DocumentFormat.OpenXml.Spreadsheet;
-using DocumentFormat.OpenXml.Wordprocessing;
-using FastJSON;
 using HTEXLib.COMM.Helpers;
 using HTEXLib.COMM.Helpers;
-using HTEXLib.Helpers.ShapeHelpers;
-using Json.Path;
-using MathNet.Numerics.Distributions;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
-using Microsoft.International.Converters.PinYinConverter;
-using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
-using Newtonsoft.Json;
-using OpenXmlPowerTools;
-using StackExchange.Redis;
 using System;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -37,20 +17,11 @@ using System.Linq;
 using System.Net;
 using System.Net;
 using System.Net.Http;
 using System.Net.Http;
 using System.Net.Http.Json;
 using System.Net.Http.Json;
-using System.Runtime.Intrinsics.X86;
-using System.Runtime.Serialization;
-using System.Security.Policy;
 using System.Text;
 using System.Text;
 using System.Text.Json;
 using System.Text.Json;
-using System.Text.Json.Nodes;
-using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using System.Web;
-using TEAMModelOS.Controllers.Analysis;
-using TEAMModelOS.Controllers.Core;
 using TEAMModelOS.Controllers.Third.LePei;
 using TEAMModelOS.Controllers.Third.LePei;
 using TEAMModelOS.Filter;
 using TEAMModelOS.Filter;
-using TEAMModelOS.Helper.Common.FileHelper;
 using TEAMModelOS.Models;
 using TEAMModelOS.Models;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI;
@@ -58,15 +29,8 @@ using TEAMModelOS.SDK.DI.Mail;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models.Cosmos.Common;
 using TEAMModelOS.SDK.Models.Cosmos.Common;
-using TEAMModelOS.SDK.Models.Cosmos.OpenEntity;
-using TEAMModelOS.SDK.Models.Cosmos.School;
-using TEAMModelOS.SDK.Models.Dtos;
 using TEAMModelOS.SDK.Models.Service;
 using TEAMModelOS.SDK.Models.Service;
-using TEAMModelOS.SDK.Models.Service.BI;
 using TEAMModelOS.SDK.Services;
 using TEAMModelOS.SDK.Services;
-using Top.Api;
-using static SKIT.FlurlHttpClient.Wechat.TenpayV3.Models.CreateBrandProfitSharingOrderRequest.Types;
-using static TEAMModelOS.Controllers.FixDataController;
 using static TEAMModelOS.SDK.Models.Teacher;
 using static TEAMModelOS.SDK.Models.Teacher;
 using static TEAMModelOS.SDK.SchoolService;
 using static TEAMModelOS.SDK.SchoolService;
 
 

+ 1 - 11
TEAMModelOS/Filter/RequestAuditFilter.cs

@@ -1,28 +1,18 @@
-using Microsoft.AspNetCore.Mvc.Controllers;
-using Microsoft.AspNetCore.Mvc.Filters;
-using System.Security.Claims;
+using Microsoft.AspNetCore.Mvc.Filters;
 using System;
 using System;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
-using Microsoft.Extensions.Logging;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK;
-using DocumentFormat.OpenXml.Office2010.Excel;
-using DocumentFormat.OpenXml.Wordprocessing;
 using System.IdentityModel.Tokens.Jwt;
 using System.IdentityModel.Tokens.Jwt;
 using System.Linq;
 using System.Linq;
-using Azure.Core;
-using DocumentFormat.OpenXml.Office2016.Excel;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI;
 using Microsoft.Extensions.Primitives;
 using Microsoft.Extensions.Primitives;
 using HTEXLib.Helpers.ShapeHelpers;
 using HTEXLib.Helpers.ShapeHelpers;
-using TEAMModelOS.Controllers;
-using System.Net;
 using System.Net.Http;
 using System.Net.Http;
 using System.Net.Http.Json;
 using System.Net.Http.Json;
 using TEAMModelOS.Models;
 using TEAMModelOS.Models;
 using Microsoft.Extensions.Options;
 using Microsoft.Extensions.Options;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using FastJSON;
 
 
 namespace TEAMModelOS.Filter
 namespace TEAMModelOS.Filter
 {
 {

+ 3 - 3
TEAMModelOS/TEAMModelOS.csproj

@@ -1,17 +1,17 @@
 <Project Sdk="Microsoft.NET.Sdk.Web">
 <Project Sdk="Microsoft.NET.Sdk.Web">
 
 
 	<PropertyGroup>
 	<PropertyGroup>
-		<TargetFramework>net6.0</TargetFramework>
+		<TargetFramework>net8.0</TargetFramework>
 	</PropertyGroup>
 	</PropertyGroup>
 	<ItemGroup>
 	<ItemGroup>
 		<PackageReference Include="DotNetZip" Version="1.16.0" />
 		<PackageReference Include="DotNetZip" Version="1.16.0" />
 		<PackageReference Include="DinkToPdf" Version="1.0.8" />
 		<PackageReference Include="DinkToPdf" Version="1.0.8" />
 		<PackageReference Include="EPPlus" Version="7.2.0" />
 		<PackageReference Include="EPPlus" Version="7.2.0" />
 		<PackageReference Include="IP2Region.Net" Version="2.0.2" />
 		<PackageReference Include="IP2Region.Net" Version="2.0.2" />
-		<PackageReference Include="JsonPath.Net" Version="1.1.2" />
+		<!--<PackageReference Include="JsonPath.Net" Version="1.1.2" />-->
 		<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
 		<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
 		<PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="2.20.0" />
 		<PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="2.20.0" />
-		<PackageReference Include="System.Security.Cryptography.Algorithms" Version="3.5.0" />
+		<!--<PackageReference Include="System.Security.Cryptography.Algorithms" Version="3.5.0" />-->
 	</ItemGroup>
 	</ItemGroup>
 	<ItemGroup>
 	<ItemGroup>
 		<None Remove="ClientApp\src\static\BaseDataDefault.json" />
 		<None Remove="ClientApp\src\static\BaseDataDefault.json" />