Procházet zdrojové kódy

Merge branch 'PL/develop-IES5' into develop

Li před 2 roky
rodič
revize
6dd6d20742

+ 63 - 1
TEAMModelOS.SDK/DI/AzureStorage/AzureStorageBlobExtensions.cs

@@ -21,6 +21,10 @@ using TEAMModelOS.SDK.Models.Table;
 using Microsoft.AspNetCore.Http;
 using TEAMModelOS.Models;
 using Microsoft.Azure.Cosmos.Table;
+using DocumentFormat.OpenXml.Spreadsheet;
+using System.Text.Json;
+using HTEXLib.DOCX.Models;
+using static TEAMModelOS.SDK.CoreAPIHttpService;
 
 namespace TEAMModelOS.SDK.DI
 {
@@ -311,7 +315,7 @@ namespace TEAMModelOS.SDK.DI
                 log.scope = scope;
                 host = !string.IsNullOrWhiteSpace($"{host}") ? $"{host}" : option?.Location != null ? $"{host}" : "Default";
                 log.url =$"{host}{httpContext?.Request.Path}" ;
-                if (!string.IsNullOrWhiteSpace(msg) && msg.Length > 150)
+                if (!string.IsNullOrWhiteSpace(msg) && msg.Length > 256)
                 {
                     log.saveMod = 1;
                     log.jsonfile = $"/0-public/optlog/{log.RowKey}-{log.PartitionKey}.json";
@@ -328,6 +332,64 @@ namespace TEAMModelOS.SDK.DI
                 _ = dingDing.SendBotMsg($"日志保存失败:{ex.Message}\n{ex.StackTrace},,{log.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
             }
         }
+
+        /// <summary>
+        /// 保存日志文件
+        /// </summary>
+        /// <param name="azureStorage"></param>
+        /// <param name="type"></param>
+        /// <param name="rootPath"></param>
+        /// <param name="replaceData"></param>
+        /// <param name="dingDing"></param>
+        /// <param name="scope"></param>
+        /// <param name="bizId"></param>
+        /// <param name="option"></param>
+        /// <param name="httpContext"></param>
+        /// <returns></returns>
+        public static async Task SaveLogLang(this AzureStorageFactory azureStorage, string type,string rootPath,  Dictionary<string, object> replaceData, DingDing dingDing, string scope = null, string bizId = null, Option option = null, HttpContext httpContext = null)
+        {
+            string msg = FileWay.FileValue(rootPath, "zh-cn", type, replaceData);
+            var table = azureStorage.GetCloudTableClient().GetTableReference("IESOptLog");
+            OptLog log = new() { RowKey = Guid.NewGuid().ToString() };
+            try
+            {
+                object id = null, school = null, name = null, website = null;
+                httpContext?.Items.TryGetValue("ID", out id);
+                httpContext?.Items.TryGetValue("School", out school);
+                httpContext?.Items.TryGetValue("Name", out name);
+                httpContext?.Items.TryGetValue("Website", out website);
+                log.tmdId = id != null ? $"{id}" : log.tmdId;
+                log.name = name != null ? $"{name}" : log.name;
+                string host = httpContext?.Request?.Host.Value;
+                log.school = school != null ? $"{school}" : log.school;
+                log.PartitionKey = type != null ? $"Log-{type}" : "Log-Default";
+                log.RowKey = bizId != null ? bizId : log.RowKey;
+                log.platform = website != null ? $"{website}" : "Default";
+                log.msg = msg;
+                log.tmsg = FileWay.FileValue(rootPath, "zh-tw", type, replaceData);
+                log.emsg = FileWay.FileValue(rootPath, "en-us", type, replaceData);
+                log.type = type;
+                log.scope = scope;
+                host = !string.IsNullOrWhiteSpace($"{host}") ? $"{host}" : option?.Location != null ? $"{host}" : "Default";
+                log.url = $"{host}{httpContext?.Request.Path}";
+                if (!string.IsNullOrWhiteSpace(msg) && msg.Length > 256)
+                {
+                    log.saveMod = 1;
+                    log.jsonfile = $"/0-public/optlog/{log.RowKey}-{log.PartitionKey}.json";
+                    await azureStorage.GetBlobContainerClient("0-public").UploadFileByContainer(log.ToJsonString(), "optlog", $"{log.RowKey}-{log.PartitionKey}.json");
+                    log.msg = null;
+                    await table.SaveOrUpdate<OptLog>(log);
+                }
+                else
+                {
+                    await table.SaveOrUpdate<OptLog>(log);
+                }
+            }
+            catch (Exception ex)
+            {
+                _ = dingDing.SendBotMsg($"日志保存失败:{ex.Message}\n{ex.StackTrace},,{log.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+            }
+        }
         /// <summary>
         /// 系统管理员 资源,题目关联,htex关联,学习活动学生上传文件关联,基本信息关联,教室平面图关联,评测冷数据关联
         /// "system": [ "res", "item", "htex", "task", "info", "room", "exam" ],

+ 48 - 0
TEAMModelOS.SDK/Models/Service/BI/FileWay.cs

@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.Extension;
+
+namespace TEAMModelOS.SDK
+{
+
+    /// <summary>
+    /// 文件方法
+    /// </summary>
+    public static class FileWay
+    {
+        /// <summary>
+        /// 读取文件类容替换方法
+        /// </summary>
+        /// <param name="rootPath"></param>
+        /// <param name="fileLang"></param>
+        /// <param name="keyType"></param>
+        /// <param name="replaceData"></param>
+        /// <returns></returns>
+        public static string FileValue(string rootPath, string fileLang, string keyType, Dictionary<string, object> replaceData)
+        {
+            string name = "";
+            string path = Path.Combine(rootPath, $"LogLang/{fileLang}.json");
+            var sampleJson = File.ReadAllBytes(path).AsSpan();
+            Utf8JsonReader reader = new Utf8JsonReader(sampleJson);
+            if (JsonDocument.TryParseValue(ref reader, out JsonDocument jsonDoc) && jsonDoc.RootElement.TryGetProperty(keyType, out JsonElement json))
+            {
+                string msgs = json.ToObject<string>();
+                if (!string.IsNullOrEmpty(msgs))
+                {
+                    replaceData.Keys.ToList().ForEach(x => {
+                        msgs = msgs.Replace("{" + x + "}", $"{replaceData[x]}");
+                    });
+                    name = msgs;
+                    //notifyData.body = msgs[1];
+                }
+            }
+
+            return name;
+        }
+    }
+}

+ 11 - 1
TEAMModelOS.SDK/Models/Table/OptLog.cs

@@ -25,10 +25,20 @@ namespace TEAMModelOS.SDK.Models.Table
         public string name { get; set; }
 
         /// <summary>
-        /// 操作描述
+        /// 操作描述 简体
         /// </summary>
         public string msg { get; set; }
 
+        /// <summary>
+        /// 操作描述  繁体
+        /// </summary>
+        public string tmsg { get; set; }
+
+        /// <summary>
+        /// 操作描述  英文
+        /// </summary>
+        public string emsg { get; set; }
+
         /// <summary>
         /// json文件地址
         /// </summary>

+ 78 - 0
TEAMModelOS/Controllers/Both/TablesLogController.cs

@@ -0,0 +1,78 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.Filter;
+using TEAMModelOS.Models;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Context.Constant;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Models.Table;
+
+namespace TEAMModelOS.Controllers
+{
+    [ProducesResponseType(StatusCodes.Status200OK)]
+    [ProducesResponseType(StatusCodes.Status400BadRequest)]
+    [Route("log")]
+    [ApiController]
+    public class TablesLogController : ControllerBase
+    {
+        private readonly AzureCosmosFactory _azureCosmos;
+        //blob和table容器
+        private readonly AzureStorageFactory _azureStorage;
+        private readonly SnowflakeId _snowflakeId;
+        private readonly DingDing _dingDing;
+        private readonly Option _option;
+        private readonly CoreAPIHttpService _coreAPIHttpService;
+        private readonly IWebHostEnvironment _environment;
+        private readonly IConfiguration _configuration;
+
+        public TablesLogController(IConfiguration configuration, CoreAPIHttpService coreAPIHttpServic, IWebHostEnvironment environment, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage,SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option)
+        {
+            _azureCosmos = azureCosmos;
+            _snowflakeId = snowflakeId;
+            _dingDing = dingDing;
+            _option = option?.Value;
+            _environment = environment;
+            _coreAPIHttpService = coreAPIHttpServic;
+            _configuration = configuration;
+            _azureStorage = azureStorage;
+        }
+
+        /// <summary>
+        /// 获取日志信息
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [AuthToken(Roles = "admin")]
+        [HttpPost("get-lists")]
+        public async Task<IActionResult> GetLog(JsonElement jsonElement)
+        {
+            jsonElement.TryGetProperty("tmdId", out JsonElement tmdId);
+            jsonElement.TryGetProperty("startDate", out JsonElement startDate);
+            jsonElement.TryGetProperty("endDate", out JsonElement endDate);
+            var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOptLog");
+
+            StringBuilder tableSql = new();
+
+            if (!string.IsNullOrEmpty($"{tmdId}"))
+                tableSql.Append($" tmdId eq {tmdId} ");
+            if (!string.IsNullOrEmpty($"{startDate}"))
+                tableSql.Append(!string.IsNullOrEmpty(tableSql.ToString()) ? $" and time ge {startDate}L " : $"time ge {startDate}L ");
+            if (!string.IsNullOrEmpty($"{endDate}"))
+                tableSql.Append(!string.IsNullOrEmpty(tableSql.ToString()) ? $" and time le {endDate}L " : $" time le {endDate}L ");
+
+            var logs = await table.QueryWhereString<OptLog>(tableSql.ToString());
+
+            return Ok(new { state = RespondCode.Ok, logs });
+        }
+    }
+}

+ 112 - 0
TEAMModelOS/Controllers/OpenApi/Business/BizArtController.cs

@@ -0,0 +1,112 @@
+using Azure.Cosmos;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Options;
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Threading.Tasks;
+using TEAMModelOS.Filter;
+using TEAMModelOS.Models;
+using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Context.Constant;
+using TEAMModelOS.SDK.DI;
+using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models;
+using TEAMModelOS.SDK.Models.Cosmos.Common;
+using TEAMModelOS.SDK.Models.Dtos;
+
+namespace TEAMModelOS.Controllers
+{
+    [Route("business")]
+    [ApiController]
+    public class BizArtController : ControllerBase
+    {
+        private readonly AzureCosmosFactory _azureCosmos;
+        private readonly AzureStorageFactory _azureStorage;
+        private readonly AzureRedisFactory _azureRedis;
+        private readonly DingDing _dingDing;
+        private readonly Option _option;
+        private readonly IConfiguration _configuration;
+        private readonly CoreAPIHttpService _coreAPIHttpService;
+        private readonly AzureServiceBusFactory _serviceBus;
+        public BizArtController(CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, DingDing dingDing, IOptionsSnapshot<Option> option, IConfiguration configuration, AzureServiceBusFactory serviceBus)
+        {
+            _azureCosmos = azureCosmos;
+            _azureStorage = azureStorage;
+            _azureRedis = azureRedis;
+            _dingDing = dingDing;
+            _option = option?.Value;
+            _configuration = configuration;
+            _coreAPIHttpService = coreAPIHttpService;
+            _serviceBus = serviceBus;
+        }
+
+        /// <summary>
+        /// 获取艺术评测标准信息
+        /// </summary>
+        /// <param name="jsonElement"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("get-artseting")]
+        [ApiToken(Auth = "2100", Name = "获取艺术评测标准信息", TName = "取得藝術評量標準資訊", EName = "Get art assessment standard", RWN = "R", Limit = false)]
+        public async Task<IActionResult> GetArtSetting(JsonElement jsonElement)
+        {
+            var (id, school) = HttpContext.GetApiTokenInfo();
+            if (!jsonElement.TryGetProperty("artId", out JsonElement artId)) return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.ParamsError, msg = "参数错误" } });
+
+            var cosmosClient = _azureCosmos.GetCosmosClient();
+            string areaId = null;
+            List<MusicZystd> musicScores = new();
+            ArtEvaluation artEvaluation = new();
+
+            var artEva = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{artId}", new PartitionKey($"Art-{school}"));
+            if (artEva.Status == 200)
+            {
+                JsonDocument document = JsonDocument.Parse(artEva.Content);
+                artEvaluation = document.RootElement.Deserialize<ArtEvaluation>();
+                areaId = artEvaluation.areaId;
+            }
+            else
+                return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.NotFound, msg = "未找到艺术评测信息" } });
+
+            if (string.IsNullOrEmpty(areaId))
+            {
+                await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<string>(queryText: $"select value(c.areaId) from c where c.id='{school}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
+                {
+                    areaId = item;
+                }
+            }
+
+            if (!string.IsNullOrEmpty(areaId))
+            {
+                ArtSetting artSetting = new();
+                var resArt = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync(areaId, new PartitionKey("ArtSetting"));
+                if (resArt.Status == 200)
+                {
+                    JsonDocument document = JsonDocument.Parse(resArt.Content);
+                    artSetting = document.RootElement.Deserialize<ArtSetting>();
+                }
+                else
+                    artSetting = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync<ArtSetting>("default", new PartitionKey("ArtSetting"));
+
+                if (artEvaluation.zymusicstds.Count > 0)
+                {
+                    foreach (var item in artEvaluation.zymusicstds)
+                    {
+                        MusicZystd tempMusic = artSetting.musicZystds.Find(f => f.code.Equals(item.code));
+                        MusicZystd musicZystd = new() { code = tempMusic.code, label = tempMusic.label, percent = item.percent, child = tempMusic.child, points = tempMusic.points };
+
+                        musicScores.Add(musicZystd);
+                    }
+                }
+                else
+                    return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.NotFound, msg = "活动中暂未有评分标准" } });
+            }
+
+            return Ok(new { responseData = new ResponseData<dynamic>() { code = RespondCode.Ok, msg = "成功", data = musicScores } });
+        }
+
+
+    }
+}

+ 1 - 1
TEAMModelOS/Controllers/OpenApi/OpenSchool/ScStudentController.cs

@@ -43,7 +43,7 @@ namespace TEAMModelOS.Controllers
         /// <returns></returns>
         [ProducesDefaultResponseType]
         [HttpPost("get-student-info")]
-        [ApiToken(Auth = "2000", Name = "学生详细信息", TName = "學生詳細信息", EName = "Student Details", RWN = "R", Limit = false)]
+        [ApiToken(Auth = "2000", Name = "学生详细信息", TName = "學生詳細資訊", EName = "Student details", RWN = "R", Limit = false)]
         public async Task<IActionResult> GetLoginStuInfo(JsonElement jsonElement)
         {
             var (id, school) = HttpContext.GetApiTokenInfo();

+ 4 - 4
TEAMModelOS/Controllers/Teacher/InitController.cs

@@ -105,8 +105,6 @@ namespace TEAMModelOS.Controllers
 
         }
 
-
-
         /// <summary>
         /// 修改教师信息
         /// </summary>
@@ -278,8 +276,10 @@ namespace TEAMModelOS.Controllers
                                 strMsg.Append($"{targetTeacher.name}[{targetTeacher.id}]");
                                 _coreAPIHttpService.PushNotify(new List<IdNameCode> { new IdNameCode { id= targetTeacher.id,name= targetTeacher.name,code=targetTeacher.lang} }, "transfer-admin_school", Constant.NotifyType_IES5_Management,
                                     new Dictionary<string, object> { { "tmdname", name },{ "schoolName", schoolBase.name }, { "schoolId", $"{school}" } , { "tmdid", userid } }, _option.Location, _configuration, _dingDing, _environment.ContentRootPath);
-                                _ = _azureStorage.SaveLog("transfer-admin-role", new { request, userid, name, school, schoolName = schoolBase.name, targetTecher = _targetTecher, }.ToJsonString(), bizId: $"{userid}-{schoolBase.id}-{_targetTecher}", httpContext: HttpContext, dingDing: _dingDing, scope: "school");
-
+                               // _ = _azureStorage.SaveLog("transfer-admin-role", new { request, userid, name, school, schoolName = schoolBase.name, targetTecher = _targetTecher, }.ToJsonString(), bizId: $"{userid}-{schoolBase.id}-{_targetTecher}", httpContext: HttpContext, dingDing: _dingDing, scope: "school");
+                               //保存日志
+                                Dictionary<string, object> replaceData = new() { { "oName" ,$"{name}" }, { "oId", $"{userid}" }, { "scName", $"{schoolBase.name}" }, { "scId", $"{schoolBase.id}" } , { "tName", $"{targetTeacher.name}" }, { "tId", $"{targetTeacher.id}" } };
+                                _ = _azureStorage.SaveLogLang("transfer-admin-role", _environment.ContentRootPath, replaceData, _dingDing, bizId: $"{userid}-{schoolBase.id}-{_targetTecher}", httpContext: HttpContext, scope: "school");
 
                                 //保存管理员移交至BI
                                 await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "school-transfer-admin", strMsg?.ToString(), _dingDing, twebsite: "IES5", httpContext: HttpContext);

+ 3 - 0
TEAMModelOS/LogLang/en-us.json

@@ -0,0 +1,3 @@
+{
+  "transfer-admin-role": "{oName}[{oId}] Transfer the administration of this {scName}[{scId}] school to {tName}[{tId}]"
+}

+ 3 - 0
TEAMModelOS/LogLang/zh-cn.json

@@ -0,0 +1,3 @@
+{
+  "transfer-admin-role": "{oName}[{oId}]将学校{scName}[{scId}] 的管理员权限移交给{tName}[{tId}]"
+}

+ 3 - 0
TEAMModelOS/LogLang/zh-tw.json

@@ -0,0 +1,3 @@
+{
+  "transfer-admin-role": "{oName}[{oId}]將學校{scName}[{scId}] 的管理員權限移交給{tName}[{tId}]"
+}

+ 9 - 0
TEAMModelOS/TEAMModelOS.csproj

@@ -46,6 +46,15 @@
       <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
       <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
     </Content>
+    <Content Update="LogLang\en-us.json">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Update="LogLang\zh-cn.json">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Update="LogLang\zh-tw.json">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
   </ItemGroup>
 	<ItemGroup>
 		<None Update="JsonFile\Core\ip2region.db">