CrazyIter_Bin 3 роки тому
батько
коміт
f0f5e89f96

+ 22 - 3
TEAMModelAPI/Startup.cs

@@ -20,6 +20,7 @@ using TEAMModelOS.SDK.Helper.Common.ReflectorExtensions;
 using System.Reflection;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK;
+using TEAMModelOS.SDK.Models;
 
 namespace TEAMModelAPI
 {
@@ -98,7 +99,7 @@ namespace TEAMModelAPI
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
-        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env,AzureStorageFactory azureStorage)
         {
             if (env.IsDevelopment())
             {
@@ -116,14 +117,32 @@ namespace TEAMModelAPI
                 endpoints.MapControllers();
             });
 #if DEBUG
-            //在开发模式时,自检 [ApiToken(Auth = "1")] 有重复的接口
+            //在开发模式时,自检 [ApiToken(Auth = "1")] 有重复的接口 https://teammodelos.table.core.chinacloudapi.cn/IESOpenApi
             List<ApiTokenAttribute> auths = new List<ApiTokenAttribute>();
             List<Attribute> attributes = ReflectorExtensions.GetMethodCustomAttribute<ApiTokenAttribute>(new string[] { "TEAMModelAPI" });
+            List<OpenApi> openApis = new List<OpenApi>();
             attributes.ForEach(x => {
                 ApiTokenAttribute attribute = (ApiTokenAttribute)x;
+                openApis.Add(new OpenApi { 
+                    PartitionKey="IES5-API",
+                    RowKey= attribute.Auth,
+                    auth=int.Parse(attribute.Auth),
+                   // descr=attribute.Name,
+                   method="POST",
+                   name=attribute.Name,
+                    
+                });
                 auths.Add(attribute);
             });
-            auths.GroupBy(x => x.Auth).ToList().ForEach(x => { if (x.Count() > 1) { throw new Exception($"接口Auth重复定义{x.ToList()}"); } });
+          
+            auths.GroupBy(x => x.Auth).ToList().ForEach(x => {
+                if (x.Count() > 1) 
+                { 
+                    throw new Exception($"接口Auth重复定义{x.ToList()}"); 
+                } 
+            });
+
+            var table =  azureStorage.GetCloudTableClient().GetTableReference("IESOpenApi");
 #endif
         }
     }

+ 39 - 0
TEAMModelOS.SDK/Helper/Common/ReflectorExtensions/ReflectorExtensions.cs

@@ -53,6 +53,14 @@ namespace TEAMModelOS.SDK.Helper.Common.ReflectorExtensions
                 foreach (var model in ScanModel)
                 {
                     Assembly assembly = Assembly.LoadFrom(currentDirectory + "\\" + model + ".dll");
+                    var TypeInModelS = assembly.GetTypes().SelectMany(x => x.GetMethods()).GroupBy(z=>z.Name).ToList();
+                    TypeInModelS.ForEach(x => {
+                        if (x.Key.Equals("GetTeacherInfo"))
+                        {
+                            var at = x.ToList().SelectMany(z => z.GetCustomAttributes()).Where(m=>m.GetType().Equals(attr));
+                            string ke = x.Key;
+                        }
+                    });
                     var  TypeInModel = assembly.GetTypes().Select(x => x.GetMethods()).SelectMany(y => y).Select(z=>z.GetCustomAttribute(attr,true)).Where(n=>n!=null);
                     attributes.AddRange(TypeInModel);
                 }
@@ -60,6 +68,37 @@ namespace TEAMModelOS.SDK.Helper.Common.ReflectorExtensions
             return attributes;
         }
 
+        /// <summary>
+        /// 获取T类型的属性标记的类的方法集合
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <returns></returns>
+        public static List<Attribute> GetMethodCustomAttribute<T,V>(string[] ScanModel)
+        {
+            Type attrT = typeof(T);
+            Type attrV = typeof(V);
+            string currentDirectory = Path.GetDirectoryName(attrT.Assembly.Location);
+            List<Attribute> attributes = new List<Attribute>();
+            if (ScanModel != null)
+            {
+                foreach (var model in ScanModel)
+                {
+                    Assembly assembly = Assembly.LoadFrom(currentDirectory + "\\" + model + ".dll");
+                    var TypeInModelS = assembly.GetTypes().SelectMany(x => x.GetMethods()).GroupBy(z => z.Name).ToList();
+                  //  var TypeInModelSS = assembly.GetTypes().SelectMany(x => x.GetMethods()).Where(x=>);
+                    TypeInModelS.ForEach(x => {
+                        if (x.Key.Equals("GetTeacherInfo"))
+                        {
+                            var at = x.ToList().SelectMany(z => z.GetCustomAttributes()).Where(m => m.GetType().Equals(attrT));
+                            string ke = x.Key;
+                        }
+                    });
+                    var TypeInModel = assembly.GetTypes().Select(x => x.GetMethods()).SelectMany(y => y).Select(z => z.GetCustomAttribute(attrT, true)).Where(n => n != null);
+                    attributes.AddRange(TypeInModel);
+                }
+            }
+            return attributes;
+        }
         /// <summary>
         /// 获取T类型属性标记的类集合
         /// </summary>

+ 2 - 2
TEAMModelOS.SDK/Models/Table/OpenApi.cs

@@ -21,7 +21,7 @@ namespace TEAMModelOS.SDK.Models
     /// 限流方案  漏斗、令牌桶、sentinel
     /// 平台开放的OpenAIPs
     /// </summary>
-    [TableName(Name = "OpenApi")]
+    [TableName(Name = "IESOpenApi")]
     public class OpenApi : TableEntity
     {
         public OpenApi() {
@@ -72,7 +72,7 @@ namespace TEAMModelOS.SDK.Models
         /// </summary>
         ///public decimal cost { get; set; }
     }
-    [TableName(Name = "OpenApi")]
+    [TableName(Name = "IESOpenApi")]
     public class Webhook : TableEntity
     {
         public Webhook()

+ 66 - 48
TEAMModelOS/Controllers/School/ClassController.cs

@@ -312,72 +312,90 @@ namespace TEAMModelOS.Controllers
 
         [ProducesDefaultResponseType]
         //[AuthToken(Roles = "teacher")]
-        [HttpPost("hiteach-link")]
+        [HttpPost("hiteach-link-unlink")]
         public async Task<IActionResult> HiteachLink(JsonElement request)
         {
             // 必要檢查            
-            if (!request.TryGetProperty("school_code", out JsonElement code)) return BadRequest();
-            // if (!request.TryGetProperty("linkList", out JsonElement links)) return BadRequest();
-
-            if (!request.TryGetProperty("uuid", out JsonElement a)) return BadRequest();
-            if (!request.TryGetProperty("uuid2", out JsonElement b)) return BadRequest();
-            if (!request.TryGetProperty("pid", out JsonElement d)) return BadRequest();
-            if (!request.TryGetProperty("action", out JsonElement e)) return BadRequest();
-            if (!request.TryGetProperty("classId", out JsonElement c)) return BadRequest();
-
+            if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
+            if (!request.TryGetProperty("serial_id", out JsonElement serial_id)) return BadRequest();
+            if (!request.TryGetProperty("opt", out JsonElement opt)) return BadRequest();
+            request.TryGetProperty("uuid", out JsonElement uuid);
+            request.TryGetProperty("uuid2", out JsonElement uuid2);
+            if (!request.TryGetProperty("classId", out JsonElement classId)) return BadRequest();
             // 如果是link classId 必填
-            string action = e.ToString();
-            if (action != "link" && action != "unLink") return BadRequest();
+            if (!$"{opt}".Equals("link") &&!$"{opt}".Equals("unlink")) return BadRequest();
             try
             {
-                // [變數宣告]
-                string school_code = code.GetString(); // 學校簡碼
-                string uuid = a.GetString(); // uuid
-                string uuid2 = b.GetString(); // uuid2                    
-                string pid = d.GetString(); // id
-                string classId = c.GetString(); // classId
-
-
                 // [取得DB資料]
                 var client = _azureCosmos.GetCosmosClient();
-                var response = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(school_code, new PartitionKey("Product"));
-                var error = 0;
-
+                var response = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync($"{serial_id}", new PartitionKey($"Product-{school_code}"));
+                int status = 200;
                 if (response.Status == 200)
                 {
-                    var json = await JsonDocument.ParseAsync(response.ContentStream);
-
-                    //軟體
-                    SchoolProduct schoolProductItem = json.ToObject<SchoolProduct>();
-
-                    SerialInfoBaseWithdeviceBound updSerialInfo = schoolProductItem.serial.Where(s => s.id == pid).FirstOrDefault();
-                    if (updSerialInfo != null)
+                    deviceBound bound = null;
+                    var serial = JsonDocument.Parse(response.ContentStream).RootElement.Deserialize<SchoolProductSerial>();
+                    if ($"{opt}".Equals("link"))
                     {
-                        deviceBound updDeviceBound = updSerialInfo.deviceBound.Where(d => d.uuid == uuid && d.uuid2 == uuid2).FirstOrDefault();
-                        if (updDeviceBound != null)
+                        if (!string.IsNullOrWhiteSpace($"{uuid}") && !string.IsNullOrWhiteSpace($"{uuid2}"))
                         {
-                            if (action.Equals("link"))
+                            bound = serial.deviceBound.Find(x => $"{uuid}".Equals(x.uuid) && $"{uuid2}".Equals(x.uuid2));
+                            if (bound != null)
                             {
-                                if (updDeviceBound.classId != null)
-                                {
-                                    error = 1;
-                                }
-                                else
-                                {
-                                    updDeviceBound.classId = classId;
-                                }
+                                bound.classId = $"{classId}";
                             }
-                            else if (action.Equals("unLink"))
+                        }
+                        else if (!string.IsNullOrWhiteSpace($"{uuid}") && string.IsNullOrWhiteSpace($"{uuid2}"))
+                        {
+                            bound = serial.deviceBound.Find(x => $"{uuid}".Equals(x.uuid));
+                            if (bound != null)
                             {
-                                updDeviceBound.classId = null;
+                                bound.classId = $"{classId}";
                             }
-                            if (error == 0) await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<SchoolProduct>(schoolProductItem, school_code, new PartitionKey("Product"));
                         }
-
+                        else if (string.IsNullOrWhiteSpace($"{uuid}") && !string.IsNullOrWhiteSpace($"{uuid2}"))
+                        {
+                            bound = serial.deviceBound.Find(x => $"{uuid2}".Equals(x.uuid2));
+                            if (bound != null)
+                            {
+                                bound.classId = $"{classId}";
+                            }
+                        }
+                    }
+                    else if ($"{opt}".Equals("unlink")) {
+                        if (!string.IsNullOrWhiteSpace($"{uuid}") && !string.IsNullOrWhiteSpace($"{uuid2}"))
+                        {
+                            bound = serial.deviceBound.Find(x => $"{uuid}".Equals(x.uuid) && $"{uuid2}".Equals(x.uuid2) && $"{classId}".Equals(x.classId));
+                            if (bound != null)
+                            {
+                                bound.classId = null;
+                            }
+                        }
+                        else if (!string.IsNullOrWhiteSpace($"{uuid}") && string.IsNullOrWhiteSpace($"{uuid2}") )
+                        {
+                            bound = serial.deviceBound.Find(x => $"{uuid}".Equals(x.uuid) && $"{classId}".Equals(x.classId));
+                            if (bound != null)
+                            {
+                                bound.classId = null;
+                            }
+                        }
+                        else if (string.IsNullOrWhiteSpace($"{uuid}") && !string.IsNullOrWhiteSpace($"{uuid2}") )
+                        {
+                            bound = serial.deviceBound.Find(x => $"{uuid2}".Equals(x.uuid2) && $"{classId}".Equals(x.classId));
+                            if (bound != null)
+                            {
+                                bound.classId = null;
+                            }
+                        }
+                    }
+                    if (bound == null) {
+                        status = 404;
                     }
+                    await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<SchoolProductSerial>(serial, $"{serial_id}", new PartitionKey($"Product-{school_code}"));
                 }
-
-                return Ok(new { error });
+                else {
+                    status = 404;
+                }
+                return Ok(new { status });
             }
             catch (Exception ex)
             {
@@ -389,7 +407,7 @@ namespace TEAMModelOS.Controllers
         [ProducesDefaultResponseType]
         //[AuthToken(Roles = "teacher")]
         [HttpPost("hiteach-unlink-classId")]
-        public async Task<IActionResult> HiteachUnlinkByClassId(JsonElement request)
+        public async Task<IActionResult> HiteachunlinkByClassId(JsonElement request)
         {
             // 必要檢查
             if (!request.TryGetProperty("school_code", out JsonElement code)) return BadRequest();

+ 0 - 1
TEAMModelOS/Controllers/School/SchoolController.cs

@@ -294,7 +294,6 @@ namespace TEAMModelOS.Controllers
             }
             return Ok(new { periods, grades, classes });
         }
-
         /// <summary>
         /// 取得某學校產品購買紀錄
         /// </summary>

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

@@ -578,16 +578,16 @@ namespace TEAMModelOS.Controllers
                         }
                     }
                 }
-                List<SchoolProductSumData> serials = new List<SchoolProductSumData>();
+                //List<SchoolProductSumData> serials = new List<SchoolProductSumData>();
                 List<SchoolProductSumData> services = new List<SchoolProductSumData>();
                 Azure.Response productSumResponse = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(school_code, new PartitionKey("ProductSum"));
                 if (productSumResponse.Status == 200)
                 {
                     var doc = JsonDocument.Parse(productSumResponse.Content);
-                    if (doc.RootElement.TryGetProperty("serial", out JsonElement serial))
-                    {
-                        serials = serial.ToObject<List<SchoolProductSumData>>();
-                    }
+                    //if (doc.RootElement.TryGetProperty("serial", out JsonElement serial))
+                    //{
+                    //    serials = serial.ToObject<List<SchoolProductSumData>>();
+                    //}
                     if (doc.RootElement.TryGetProperty("service", out JsonElement service))
                     {
                         services = service.ToObject<List<SchoolProductSumData>>();
@@ -659,7 +659,7 @@ namespace TEAMModelOS.Controllers
                     teacher.lessonShow,
                     productSum = new
                     {
-                        serial = serials,
+                        //serial = serials,
                         service = services
                     }
                 });

+ 71 - 1
TEAMModelOS/Controllers/XTest/TestController.cs

@@ -2,6 +2,8 @@ using Azure;
 using Azure.Cosmos;
 using Azure.Messaging.ServiceBus;
 using Azure.Storage.Blobs.Models;
+using DinkToPdf;
+using DinkToPdf.Contracts;
 using HTEXLib.COMM.Helpers;
 using HTEXLib.Helpers.ShapeHelpers;
 using Microsoft.AspNetCore.Hosting;
@@ -53,8 +55,10 @@ namespace TEAMModelOS.Controllers
         private readonly Option _option;
         private readonly IPSearcher _searcher;
         public IConfiguration _configuration { get; set; }
-        public TestController(IPSearcher searcher, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService, HttpClient httpClient, IWebHostEnvironment environment, AzureCosmosFactory azureCosmos, AzureRedisFactory azureRedis, AzureStorageFactory azureStorage, IConfiguration configuration, AzureServiceBusFactory serviceBus, DingDing dingDing)
+        private readonly IConverter _converter;
+        public TestController(IConverter converter,IPSearcher searcher, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService, HttpClient httpClient, IWebHostEnvironment environment, AzureCosmosFactory azureCosmos, AzureRedisFactory azureRedis, AzureStorageFactory azureStorage, IConfiguration configuration, AzureServiceBusFactory serviceBus, DingDing dingDing)
         {
+            _converter = converter;
             _azureCosmos = azureCosmos;
             _azureRedis = azureRedis;
             _azureStorage = azureStorage;
@@ -1092,5 +1096,71 @@ namespace TEAMModelOS.Controllers
             }
             return Ok(new { dict });
         }
+
+        /// <summary>
+        /// 随机获取三个不同类型的题目
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [HttpPost("gen-pdf")]
+        //[Authorize(Roles = Constant.Role_Root)]
+        public IActionResult GenPdf(JsonElement json) {
+            //https://article.itxueyuan.com/JAxOnG
+            //http://t.zoukankan.com/hsiang-p-14608694.html
+            //https://github.com/rdvojmoc/DinkToPdf
+            //https://blog.csdn.net/u011966339/article/details/114964016?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-114964016-blog-118609642.pc_relevant_antiscanv2&spm=1001.2101.3001.4242.1&utm_relevant_index=3
+            var html = $@"
+                           <!DOCTYPE html>
+                           <html lang=""en"">
+                           <head>
+                               This is the header of this document.
+                           </head>
+                          <body>
+                          <h1>This is the heading for demonstration purposes only111111111111111111111111111111111111111111111111111111.</h1>
+                          <p>This is a line of text for demonstration purposes only.</p>
+<p>This is a line of text for demonstration purposes only.</p>
+                          </body>
+                          </html>
+                          ";
+            try {
+                GlobalSettings globalSettings = new GlobalSettings();
+                globalSettings.ColorMode = ColorMode.Color;
+                globalSettings.Orientation = Orientation.Portrait;
+                globalSettings.PaperSize = PaperKind.A4;
+                globalSettings.Margins = new MarginSettings { Top = 25, Bottom = 25 };
+                ObjectSettings objectSettings = new ObjectSettings();
+                objectSettings.PagesCount = true;
+                objectSettings.HtmlContent = html;
+                WebSettings webSettings = new WebSettings();
+                webSettings.DefaultEncoding = "utf-8";
+                HeaderSettings headerSettings = new HeaderSettings();
+                headerSettings.FontSize = 15;
+                headerSettings.FontName = "Ariel";
+                headerSettings.Right = "页 [page] of [toPage]";
+                headerSettings.Line = true;
+                FooterSettings footerSettings = new FooterSettings();
+                footerSettings.FontSize = 12;
+                footerSettings.FontName = "Ariel";
+                footerSettings.Center = "This is for demonstration purposes only.";
+                footerSettings.Line = true;
+                objectSettings.HeaderSettings = headerSettings;
+                objectSettings.FooterSettings = footerSettings;
+                objectSettings.WebSettings = webSettings;
+                HtmlToPdfDocument htmlToPdfDocument = new HtmlToPdfDocument()
+                {
+                    GlobalSettings = globalSettings,
+                    Objects = { objectSettings },
+                };
+                var a = _converter.Convert(htmlToPdfDocument);
+                //MemoryStream m = new MemoryStream(a);
+                //FileStream fs = new FileStream("F:\\1111111111111\\SimplePdf1.pdf", FileMode.Create, FileAccess.Write, FileShare.Read);
+                //m.WriteTo(fs);
+                //m.Close();
+                //fs.Close();
+                return Ok(File(a, "application/octet-stream", "SimplePdf.pdf"));
+            } catch (Exception ex) {
+                return BadRequest(new { ex = ex.StackTrace, exmsg = ex.Message });
+            }
+        }
     }
 }

+ 4 - 1
TEAMModelOS/Startup.cs

@@ -8,6 +8,8 @@ using System.Text.Json;
 using System.Threading;
 using System.Threading.Tasks;
 using Azure.Storage.Blobs.Models;
+using DinkToPdf;
+using DinkToPdf.Contracts;
 using HTEXLib.Builders;
 using HTEXLib.Translator;   
 using Lib.AspNetCore.ServerSentEvents;
@@ -150,7 +152,8 @@ namespace TEAMModelOS
                 };
             });
             //等保安全性验证。
-          //  services.AddScoped<SecurityHeadersAttribute>();
+            //  services.AddScoped<SecurityHeadersAttribute>();
+            services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

+ 1 - 0
TEAMModelOS/TEAMModelOS.csproj

@@ -5,6 +5,7 @@
   </PropertyGroup>
   <ItemGroup>
     <PackageReference Include="DotNetZip" Version="1.16.0" />
+	  <PackageReference Include="DinkToPdf" Version="1.0.8" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
   </ItemGroup>
   <ItemGroup>