瀏覽代碼

合并冲突

XW 3 年之前
父節點
當前提交
914ea2f51b

+ 4 - 1
TEAMModelOS.FunctionV4/Program.cs

@@ -1,4 +1,6 @@
-using Microsoft.Extensions.Configuration;
+using DinkToPdf;
+using DinkToPdf.Contracts;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection.Extensions;
 using Microsoft.Extensions.Hosting;
@@ -44,6 +46,7 @@ namespace TEAMModelOS.FunctionV4
                services.AddAzureServiceBus(context.Configuration.GetSection("Azure:ServiceBus:ConnectionString").Get<string>());
                services.AddAzureStorage(context.Configuration.GetSection("Azure:Storage:ConnectionString").Get<string>());
                services.AddAzureRedis(context.Configuration.GetSection("Azure:Redis:ConnectionString").Get<string>());
+               services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
            })
            .Build();
             await host.RunAsync();

+ 193 - 21
TEAMModelOS.FunctionV4/ServiceBus/ActiveTaskTopic.cs

@@ -26,6 +26,8 @@ using Azure.Storage.Blobs.Models;
 using System.IO;
 using Azure;
 using static TEAMModelOS.SDK.Models.Service.LessonService;
+using DinkToPdf.Contracts;
+using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
 
 namespace TEAMModelOS.FunctionV4.ServiceBus
 {
@@ -40,7 +42,8 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
         private readonly NotificationService _notificationService;
         private readonly CoreAPIHttpService _coreAPIHttpService;
         private readonly IConfiguration _configuration;
-        public ActiveTaskTopic(CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, IOptionsSnapshot<Option> option, NotificationService notificationService, IConfiguration configuration)
+        private readonly IConverter _converter;
+        public ActiveTaskTopic(IConverter converter, CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, IOptionsSnapshot<Option> option, NotificationService notificationService, IConfiguration configuration)
         {
             _azureCosmos = azureCosmos;
             _dingDing = dingDing;
@@ -51,6 +54,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
             _notificationService = notificationService;
             _configuration = configuration;
             _coreAPIHttpService = coreAPIHttpService;
+            _converter = converter;
         }
         [Function("Exam")]
         public async Task ExamFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "exam", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
@@ -601,7 +605,175 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                 await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,ItemCond()\n{ex.Message}\n{ex.StackTrace}\n\n{msg}", GroupNames.醍摩豆服務運維群組);
             }
         }
+        [Function("GenPdf")]
+        public async Task GenPdfFunc([ServiceBusTrigger("%Azure:ServiceBus:GenPdfQueue%", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
+        {
+            try
+            {
+                var client = _azureCosmos.GetCosmosClient();
+                /*                var jsonMsg = JsonDocument.Parse(msg);
+                                jsonMsg.RootElement.TryGetProperty("id", out JsonElement id);
+                                //jsonMsg.RootElement.TryGetProperty("code", out JsonElement code);*/
+                List<Study> studies = new();
+                JsonElement element = msg.ToObject<JsonElement>();
+                element.TryGetProperty("id", out JsonElement ids);
+                List<string> tIds = ids.ToObject<List<string>>();
+                element.TryGetProperty("school", out JsonElement code);
+                string sname = string.Empty;
+                var scquery = $"SELECT c.name from c where c.id = '{code}'";
+                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: scquery, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
+                {
+
+                    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;
+                            sname = account.GetProperty("name").ToString();
+                        }
+                    }
+                }
+                foreach (string id in tIds)
+                {
+                    List<(List<string> tch, List<Dictionary<string, List<string>>> groupLists)> tchInfo = new();
+                    var query = $"SELECT  top 1  c.tchLists,c.groupLists FROM c where array_contains(c.teacIds, '{id}') order by c.createTime desc";
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{code}") }))
+                    {
+
+                        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<string> tchId = new();
+                                List<Dictionary<string, List<string>>> groupLists = new();
+                                if (account.TryGetProperty("tchLists", out JsonElement tchLists))
+                                {
+                                    tchId = tchLists.ToObject<List<string>>();
+                                };
+                                if (account.TryGetProperty("groupLists", out JsonElement group))
+                                {
+                                    groupLists = group.ToObject<List<Dictionary<string, List<string>>>>();
+                                };
+                                tchInfo.Add((tchId, groupLists));
+                            }
+                        }
+                    }
+                    string cname = string.Empty;
+                    string gname = string.Empty;
+                    foreach (var (tch, groupLists) in tchInfo)
+                    {
+                        List<(string pId, List<string> gid)> ps = new List<(string pId, List<string> gid)>();
+                        if (groupLists.Count > 0)
+                        {
+                            var group = 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.GetStutmdidListids(_coreAPIHttpService, client, _dingDing, tch, code.GetString(), ps);
+                        gname = tchList.Where(c => c.id == id).FirstOrDefault().groupName;
+                        cname = tchList.Where(c => c.id == id).FirstOrDefault().name;
+                    }
+
+                    var queryInfo = $"select c.id,c.name,c.type,c.hour,c.startTime,c.endTime,c.presenter,c.topic,c.settings,c.desc from c where (c.status<>404 or IS_DEFINED(c.status) = false and array_contains(c.teacIds, '{id}') )";
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<Study>(queryText: queryInfo, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{code}") }))
+                    {
+                        studies.Add(item);
+
+                    }
+                    List<string> details = new();
+                    StringBuilder stringBuilder = new StringBuilder();
+                    foreach (Study study in studies)
+                    {
 
+                        var start = DateTimeHelper.FromUnixTimestamp(study.startTime).ToString("yyyy/MM/dd HH:mm:ss");
+                        var end = DateTimeHelper.FromUnixTimestamp(study.endTime).ToString("yyyy/MM/dd HH:mm:ss");
+                        string tname = string.Empty;
+                        List<string> setName = new();
+                        foreach (string setting in study.settings)
+                        {
+                            if (setting.Equals("sign"))
+                            {
+                                setName.Add("扫码签到");
+                            }
+                            else if (setting.Equals("hw"))
+                            {
+                                setName.Add("作业提交");
+                            }
+                            else if (setting.Equals("survey"))
+                            {
+                                setName.Add("问卷反馈");
+                            }
+                            else if (setting.Equals("exam"))
+                            {
+                                setName.Add("评测活动");
+                            }
+                        }
+                        switch (study.type)
+                        {
+                            case 1:
+                                tname = "信息化教学案例展示与分享";
+                                break;
+                            case 2:
+                                tname = "专家专题培训";
+                                break;
+                            case 3:
+                                tname = "同课同构";
+                                break;
+                            case 4:
+                                tname = "同课异构";
+                                break;
+                            case 5:
+                                tname = "校本2.0培训";
+                                break;
+                            case 6:
+                                tname = "自定义活动";
+                                break;
+                        };
+                        stringBuilder.Append($@"<tr>
+                                                        <td> {study.topic} </td>
+                                                        <td> {tname} </td >
+                                                        <td> {study.hour} </td >
+                                                        <td> 1 </td >
+                                                        <td> {start} 到 {end} </td>
+                                                        <td>{study.desc}</td>
+                                                        <td> {string.Join("、", setName.Select(x => $"{x}\n"))} </td>
+                                                        <td> 已完成 </td >
+                                                    </tr> ");
+                    }
+                    string blob = await StudyService.GenPdf(cname, sname, gname, stringBuilder.ToString(), _converter);
+                }
+
+
+                /*var query = $"select c.id,c.name,c.type,c.hour,c.startTime,c.endTime,c.presenter,c.topic from c where (c.status<>404 or IS_DEFINED(c.status) = false and array_contains(c.teacIds, '{id}') )";
+                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<Study>(queryText: query, requestOptions: new QueryRequestOptions() {PartitionKey = new PartitionKey($"Study-{code}") }))
+                {
+                    studies.Add(item);
+
+                }*/
+                //(List<StuActivity> datas, string continuationToken) = await ActivityStudentService.FindActivity(element, null, null, _azureCosmos, _azureRedis);
+
+                // string blob =  await StudyService.GenPdf(cname,sname,gname,"", _converter);
+
+            }
+            catch (CosmosException ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,GenPdfFunc()\n{ex.Message}\n{ex.StackTrace}\n\n{msg}", GroupNames.醍摩豆服務運維群組);
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,GenPdfFunc()\n{ex.Message}\n{ex.StackTrace}\n\n{msg}", GroupNames.醍摩豆服務運維群組);
+            }
+        }
         //更新學校產品一覽表
         //處理內容:取得所有序號購買紀錄,服務週期、硬體購買紀錄後,更新ProductSum
         [Function("Product")]
@@ -682,7 +854,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                             }
                         }
                     }
-                    
+
                 }
                 ////服務產品特別對應項
                 School school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>($"{schoolId}", new PartitionKey("Base")); //學校基本資料取得
@@ -874,7 +1046,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
             }
 
             var client = _azureCosmos.GetCosmosClient();
-           
+
             if ($"{scope}".Equals("school") && !string.IsNullOrEmpty($"{school}"))
             {
                 blobname = $"{school}";
@@ -1006,18 +1178,18 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                             tmdid = lessonRecord.tmdid,
                                             code = "LessonStudentRecord",
                                             pk = "LessonStudentRecord",
-                                            courseId =lessonRecord.courseId,
-                                            groupIds= lessonRecord.groupIds,
+                                            courseId = lessonRecord.courseId,
+                                            groupIds = lessonRecord.groupIds,
                                             periodId = lessonRecord.periodId,
                                             subjectId = lessonRecord.subjectId,
                                         };
-                                        await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS,Constant.Student).UpsertItemAsync<LessonStudentRecord>(lessonStudentRecord, new PartitionKey("LessonStudentRecord"));
+                                        await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync<LessonStudentRecord>(lessonStudentRecord, new PartitionKey("LessonStudentRecord"));
                                     }
                                     //有上传 base.josn.
-                                    lessonRecord.upload =1;
+                                    lessonRecord.upload = 1;
                                     // await _dingDing.SendBotMsg($"{_option.Location},课堂id:{_lessonId} 更新完成", GroupNames.醍摩豆服務運維群組);
 
-                                    LessonService.DoAutoDeleteSchoolLessonRecord(lessonRecord, scope, client, school, tmdid,   teacher, _notificationService, _serviceBus, _azureStorage, _configuration);
+                                    LessonService.DoAutoDeleteSchoolLessonRecord(lessonRecord, scope, client, school, tmdid, teacher, _notificationService, _serviceBus, _azureStorage, _configuration);
                                     long? size = await _azureStorage.GetBlobContainerClient(blobname).GetBlobsSize($"records/{_lessonId}");
                                     Bloblog bloblog = new Bloblog
                                     {
@@ -1124,7 +1296,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                             case "create":
                                 oldlessonRecord = null;
                                 //处理课堂选用的课程信息
-                              
+
                                 lessonRecord.show = teacher.lessonShow;
                                 lessonRecord.upload = 0;
                                 if (!string.IsNullOrEmpty(lessonRecord.courseId))
@@ -1279,7 +1451,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                                 //var day3= now.AddDays(Constant.private_lesson_expire - 3).ToUnixTimeMilliseconds();
                                                 //result.Add(3, day3);
                                                 //剩余1天的通知
-                                                var day1 = now.AddDays(Constant.private_lesson_expire - (Constant.private_lesson_expire-1)).ToUnixTimeMilliseconds();
+                                                var day1 = now.AddDays(Constant.private_lesson_expire - (Constant.private_lesson_expire - 1)).ToUnixTimeMilliseconds();
                                                 result.Add(1, new ExpireTag { expire = day1, tag = "notification" });
                                                 //到期通知
 
@@ -1291,7 +1463,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                                     addSecond = Constant.private_lesson_expire * 86400 + (24 - now.Hour) * 3600;
                                                     //再加 00到05小时内的 随机秒数
                                                     Random rand = new Random();
-                                                    int randInt= rand.Next(0 , 18000);
+                                                    int randInt = rand.Next(0, 18000);
                                                     addSecond += randInt;
                                                 }
                                                 else
@@ -1307,7 +1479,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                                 {
                                                     hubName = "hita",
                                                     type = "msg",
-                                                    from = $"ies5:{ Environment.GetEnvironmentVariable("Option:Location")}:private",
+                                                    from = $"ies5:{Environment.GetEnvironmentVariable("Option:Location")}:private",
                                                     to = new List<string> { tmdid },
                                                     label = $"{biz}_lessonRecord",
                                                     body = new
@@ -1318,7 +1490,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                                         tmdname = teacher.name,
                                                         sid = lessonRecord.id,
                                                         sname = lessonRecord.name,
-                                                        scope=scope,
+                                                        scope = scope,
                                                         stime = lessonRecord.startTime,
                                                         expire = lessonRecord.expire,
                                                         status = 1,
@@ -1426,7 +1598,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                 jsonMsg.TryGetProperty("tag", out JsonElement _tag);
                 var client = _azureCosmos.GetCosmosClient();
                 //处理到期删除
-                if (_tag.ValueKind.Equals(JsonValueKind.String) && $"{_tag}".Equals("delete") )
+                if (_tag.ValueKind.Equals(JsonValueKind.String) && $"{_tag}".Equals("delete"))
                 {
                     string lessonId = $"{id}";
                     string tbname;
@@ -1559,7 +1731,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                             else
                             {
 
-                                await _dingDing.SendBotMsg($"OS,{ Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                                await _dingDing.SendBotMsg($"OS,{Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                             }
                         }
                     }
@@ -1596,7 +1768,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                             else
                             {
 
-                                await _dingDing.SendBotMsg($"OS,{ Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                                await _dingDing.SendBotMsg($"OS,{Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                             }
                         }
                     }
@@ -1640,7 +1812,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                             else
                             {
 
-                                await _dingDing.SendBotMsg($"OS,{ Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                                await _dingDing.SendBotMsg($"OS,{Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                             }
                         }
                     }
@@ -1678,7 +1850,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                             else
                             {
 
-                                await _dingDing.SendBotMsg($"OS,{ Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                                await _dingDing.SendBotMsg($"OS,{Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                             }
                         }
                     }
@@ -1740,7 +1912,7 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                         }
                         catch (CosmosException ex)
                         {
-                            await _dingDing.SendBotMsg($"OS,{ Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                            await _dingDing.SendBotMsg($"OS,{Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                         }
                     }
                 }
@@ -1800,14 +1972,14 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                         }
                         catch (CosmosException ex)
                         {
-                            await _dingDing.SendBotMsg($"OS,{ Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                            await _dingDing.SendBotMsg($"OS,{Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -CosmosDB异常\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                         }
                     }
                 }
             }
             catch (Exception ex)
             {
-                await _dingDing.SendBotMsg($"OS,{ Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -Course\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                await _dingDing.SendBotMsg($"OS,{Environment.GetEnvironmentVariable("Option:Location")},CourseServiceBus -Course\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
             }
         }
     }

+ 1 - 0
TEAMModelOS.FunctionV4/local.settings.json

@@ -9,6 +9,7 @@
     "Azure:Redis:ConnectionString": "52.130.252.100:6379,password=habook,ssl=false,abortConnect=False,writeBuffer=10240",
     "Azure:ServiceBus:ActiveTask": "dep-active-task",
     "Azure:ServiceBus:ItemCondQueue": "dep-itemcond",
+    "Azure:ServiceBus:GenPdfQueue": "dep-genpdf",
     "Option:Location": "China-Dep",
     "HaBookAuth:CoreService:sendnotification": "https://api2.teammodel.cn/service/sendnotification",
     "HaBookAuth:CoreAPI": "https://api2.teammodel.cn",

+ 106 - 2
TEAMModelOS.SDK/Context/Constant/Constant.cs

@@ -7,7 +7,7 @@ namespace TEAMModelOS.SDK.DI
     public class Constant
     {
         public static readonly List<string> BlobPrefix = new List<string> { "exam", "vote", "survey", "item", "paper", "syllabus", "records", "doc", "image", "res", "video", "audio", "other", "thum", "train", "temp", "jyzx" };
-        public static readonly List<string> ContentPrefix = new List<string> { "doc", "image", "res", "video", "audio", "other"};
+        public static readonly List<string> ContentPrefix = new List<string> { "doc", "image", "res", "video", "audio", "other" };
         public static readonly string TEAMModelOS = "TEAMModelOS";
         public static readonly string ScopeTeacher = "teacher";
         public static readonly string ScopeTmdUser = "tmduser";
@@ -19,8 +19,112 @@ namespace TEAMModelOS.SDK.DI
         public static readonly string Common = "Common";
         public static readonly string Teacher = "Teacher";
         public static readonly string Student = "Student";
-        public static readonly int private_lesson_limit =50;
+        public static readonly int private_lesson_limit = 50;
         public static readonly int private_lesson_expire = 7;
         public static readonly int school_lesson_expire = 7;
+        public static readonly string html = @"
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset=""UTF-8"">
+    <meta http-equiv=""X-UA-Compatible"" content=""IE=edge"">
+    <meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
+    <title>校本研修活动完成情况</title>
+    <style>
+        body {
+            font-family: ""fangsong"";
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+        }
+
+        .tch-table,
+        .details-table {
+            width: 100%;
+        }
+
+        .tch-table table {
+            width: 100%;
+            margin: 15px 0;
+            border: 0;
+        }
+
+        .tch-table th {
+            background-color: #c5c5c5;
+            color: #222222;
+             
+        }
+
+
+        .tch-table,
+        .tch-table th,
+        .tch-table td {
+            font-size: 0.95em;
+            text-align: center;
+            padding: 4px;
+            border-collapse: collapse;
+            font-weight: bolder;
+        }
+
+        .tch-table th,
+        .tch-table td {
+            border-bottom: 1px solid #918b8c;
+            border-width: 1px 0 1px 0;
+        }
+
+        .tch-table tr {
+            border: 1px solid #ffffff;
+            height: 3.2em;
+        }
+
+        .title {
+            font-weight: bold;
+            align-self: flex-start;
+            margin: 30px 5px;
+        }
+
+        .title::before {
+            content: """";
+            width: 10px;
+            height: 10px;
+            background: #3a3a3a;
+            display: inline-block;
+            margin-right: 10px;
+        }
+    </style>
+</head>
+
+<body>
+    <h1 style=""text-align:center;font-weight: bold;"">校本研修活动完成情况</h1>
+    <p class=""title"">教师信息</p>
+    <table class=""tch-table"" id=""tchTable"">
+        <tr>
+            <th style=""width: 33.3%;"">教师姓名</th>
+            <th style=""width: 33.3%;"">机构</th>
+            <th style=""width: 33.3%;"">教研组</th>
+        </tr>
+        <tr>
+            <td>{c.cname}</td>
+            <td>{c.sname}</td>
+            <td>{c.gname}</td>
+        </tr>
+    </table>
+    <p class=""title"">活动明细</p>
+    <table class=""tch-table"" id=""acTable"">
+        <tr>
+            <th style=""width: 25%;"">活动主题</th>
+            <th style=""width: 15%;"">活动类型</th>
+            <th style=""width: 5%;"">任务学时</th>
+            <th style=""width: 5%;"">完成学时</th>
+            <th style=""width: 20%;"">活动时间</th>
+            <th style=""width: 10%;"">活动内容</th>
+            <th style=""width: 10%;"">活动任务</th>
+            <th style=""width: 10%;"">状态</th>
+        </tr>
+        {c.details}
+    </table>
+</body>
+</html>
+";
     }
 }

+ 89 - 0
TEAMModelOS.SDK/Models/Service/StudyService.cs

@@ -0,0 +1,89 @@
+using DinkToPdf;
+using DinkToPdf.Contracts;
+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.DI;
+
+namespace TEAMModelOS.SDK.Models.Service
+{
+    public static class StudyService
+    {
+        public static async Task<string> GenPdf(string cname,string sname,string gname,string details, IConverter _converter)
+        {
+            //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
+
+            try
+            {
+                var html = Constant.html.Replace("{c.cname}", cname).Replace("{c.sname}", sname).Replace("{c.gname}", gname).Replace("{c.details}", details);
+                GlobalSettings globalSettings = new GlobalSettings();
+                globalSettings.ColorMode = ColorMode.Color;
+                globalSettings.Orientation = Orientation.Portrait;
+                globalSettings.PaperSize = PaperKind.A4;
+                globalSettings.Margins = new MarginSettings { Top = 25, Bottom = 25 };
+                globalSettings.Out = @"E:\pdf\test.pdf";
+                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 = "fangsong";
+                headerSettings.Right = "";
+                // headerSettings.Line = true;
+                FooterSettings footerSettings = new FooterSettings();
+                footerSettings.FontSize = 12;
+                footerSettings.FontName = "Ariel";
+                footerSettings.Center = "校本研修活动完成情况([page]/[toPage])页";
+                // 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);
+                string aa = "";
+                return aa;
+                /* FileStream fs = new FileStream("F:\\1111111111111\\SimplePdf1.pdf", FileMode.Create, FileAccess.Write, FileShare.Read);
+                 m.WriteTo(fs);
+                 m.Close();
+                 fs.Close();*/
+
+                //var doc = new HtmlToPdfDocument()
+                //{
+                //    GlobalSettings = {
+                //        ColorMode = ColorMode.Color,
+                //        Orientation = Orientation.Portrait,
+                //        PaperSize = PaperKind.A4,
+                //        Margins = new MarginSettings() { Top = 10 },
+                //        Out = @"F:\test.pdf",
+                //    },
+                //    Objects = {
+                //        new ObjectSettings()
+                //        {
+                //            Page = "https://zhidao.baidu.com/question/175696719173618004.html",
+                //        },
+                //    }
+                //};
+                //_converter.Convert(doc);
+                // return Ok(File(a, "application/octet-stream", "SimplePdf.pdf"));
+            }
+            catch (Exception ex)
+            {
+                return "";
+            }
+        }
+    }
+}

+ 1 - 0
TEAMModelOS.SDK/TEAMModelOS.SDK.csproj

@@ -20,6 +20,7 @@
     <PackageReference Include="Azure.Storage.Blobs.Batch" Version="12.8.0" />
     <PackageReference Include="Azure.Storage.Queues" Version="12.9.0" />
     <PackageReference Include="ClouDASLibx" Version="1.2.7" />
+    <PackageReference Include="DinkToPdf" Version="1.0.8" />
     <PackageReference Include="DocumentFormat.OpenXml" Version="2.15.0" />
     <PackageReference Include="HTEXLib" Version="5.2203.232" />
     <PackageReference Include="HtmlAgilityPack" Version="1.11.42" />

+ 2 - 3
TEAMModelOS/ClientApp/src/view/auth/Product.vue

@@ -1,4 +1,4 @@
-<template>
+<template>
     <div class="product-container">
         <Loading v-show="isLoading"></Loading>
         <!-- 模组列表 -->
@@ -57,7 +57,7 @@
                     </span>
                 </div>
                 <Alert show-icon v-if="spaceStatus == 2" type="warning">
-                    <p style="font-size:12px">
+                    <p s tyle="font-size:12px">
                         {{$t('auth.spaceWarning')}}
                     </p>
                 </Alert>
@@ -218,7 +218,6 @@ export default {
                     item.time = svc.time //目前暂定取time字段,后续确认返回格式
                 }
             })
-
             //获取学校规模授权数量
             let scaleInfo = services.find(item => item.prodCode === '3CLYJ6NP')
             if (scaleInfo) this.scaleCount = scaleInfo.avaliable || 0

+ 95 - 2
TEAMModelOS/Controllers/Common/StudyController.cs

@@ -1,4 +1,7 @@
 using Azure.Cosmos;
+using Azure.Messaging.ServiceBus;
+using DinkToPdf;
+using DinkToPdf.Contracts;
 using HTEXLib.COMM.Helpers;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Http;
@@ -7,6 +10,7 @@ using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Options;
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Net;
 using System.Net.Http;
@@ -37,10 +41,10 @@ namespace TEAMModelOS.Controllers.Common
         private readonly Option _option;
         private readonly AzureStorageFactory _azureStorage;
         private readonly AzureRedisFactory _azureRedis;
-
+        private readonly IConverter _converter;
         public IConfiguration _configuration { get; set; }
         private readonly CoreAPIHttpService _coreAPIHttpService;
-        public StudyController(CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing,
+        public StudyController(IConverter converter,CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing,
            IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, IConfiguration configuration)
         {
             _coreAPIHttpService = coreAPIHttpService;
@@ -52,6 +56,7 @@ namespace TEAMModelOS.Controllers.Common
             _azureStorage = azureStorage;
             _azureRedis = azureRedis;
             _configuration = configuration;
+            _converter = converter;
         }
         /// <summary>
         /// 保存研修信息
@@ -685,6 +690,9 @@ namespace TEAMModelOS.Controllers.Common
                 }
                 list.tmdid = new List<string>(tch);
                 await tasky.TaskPage(10);
+                var messageBlobItemCond = new ServiceBusMessage(new { id = tch, school, userType = "tmdid" }.ToJsonString());
+                var ItemCondQueue = _configuration.GetValue<string>("Azure:ServiceBus:GenPdfQueue");
+                await _serviceBus.GetServiceBusClient().SendMessageAsync(ItemCondQueue, messageBlobItemCond);
                 await StatisticsService.SendServiceBus(list, _configuration, _serviceBus, client);
                 return Ok(new { code = HttpStatusCode.OK });
             }
@@ -784,5 +792,90 @@ namespace TEAMModelOS.Controllers.Common
             }
             await Task.WhenAll(tasks);
         }
+
+
+        [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
+            
+            try
+            {
+                var html = Constant.html.Replace("{c.stuname}", "黄总");
+                html = html.Replace("{c.details}", @"<tr>
+                                                        <td> 语文学科如何在A1技术支持下进行学情分析 </td>
+                                                        <td> 信息化教学案例展示与分享 </td >
+                                                        <td> 1 </td >
+                                                        <td> 1 </td >
+                                                        <td> 2022 - 04 - 07 到 2022 - 04 - 14 </td>
+                                                        <td></td>
+                                                        <td> 扫码签到、作业提交、问卷反馈、评测活动 </td>
+                                                        <td> 已完成 </td >
+                                                    </tr> ");
+                GlobalSettings globalSettings = new GlobalSettings();
+                globalSettings.ColorMode = ColorMode.Color;
+                globalSettings.Orientation = Orientation.Portrait;
+                globalSettings.PaperSize = PaperKind.A4;
+                globalSettings.Margins = new MarginSettings { Top = 25, Bottom = 25 };
+                globalSettings.Out = @"E:\pdf\test.pdf";
+                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 = "fangsong";
+                headerSettings.Right = "";
+                // headerSettings.Line = true;
+                FooterSettings footerSettings = new FooterSettings();
+                footerSettings.FontSize = 12;
+                footerSettings.FontName = "Ariel";
+                footerSettings.Center = "校本研修活动完成情况([page]/[toPage])页";
+                // 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();*/
+
+                //var doc = new HtmlToPdfDocument()
+                //{
+                //    GlobalSettings = {
+                //        ColorMode = ColorMode.Color,
+                //        Orientation = Orientation.Portrait,
+                //        PaperSize = PaperKind.A4,
+                //        Margins = new MarginSettings() { Top = 10 },
+                //        Out = @"F:\test.pdf",
+                //    },
+                //    Objects = {
+                //        new ObjectSettings()
+                //        {
+                //            Page = "https://zhidao.baidu.com/question/175696719173618004.html",
+                //        },
+                //    }
+                //};
+                //_converter.Convert(doc);
+                return Ok();
+                // return Ok(File(a, "application/octet-stream", "SimplePdf.pdf"));
+            }
+            catch (Exception ex)
+            {
+                return BadRequest(new { ex = ex.StackTrace, exmsg = ex.Message });
+            }
+        }
     }
 }