xf 3 ヶ月 前
コミット
f35f1f6ce3

+ 7 - 0
Hotline.sln

@@ -59,6 +59,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hotline.Logger", "src\Hotli
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hotline.WeChat", "src\Hotline.WeChat\Hotline.WeChat.csproj", "{75215667-65AF-4B7B-85E7-3140239B30CC}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hotline.Pdf", "src\Hotline.Pdf\Hotline.Pdf.csproj", "{3AB75B51-A69D-4145-A564-1D9D1695992E}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -153,6 +155,10 @@ Global
 		{75215667-65AF-4B7B-85E7-3140239B30CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{75215667-65AF-4B7B-85E7-3140239B30CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{75215667-65AF-4B7B-85E7-3140239B30CC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3AB75B51-A69D-4145-A564-1D9D1695992E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3AB75B51-A69D-4145-A564-1D9D1695992E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3AB75B51-A69D-4145-A564-1D9D1695992E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3AB75B51-A69D-4145-A564-1D9D1695992E}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -183,6 +189,7 @@ Global
 		{9F99C272-5BC2-452C-9D97-BC756AF04669} = {D041C554-B78E-4AAF-B597-E309DC8EEF4F}
 		{37784861-ABC0-41F4-87B4-2E08A89A2C42} = {D041C554-B78E-4AAF-B597-E309DC8EEF4F}
 		{75215667-65AF-4B7B-85E7-3140239B30CC} = {D041C554-B78E-4AAF-B597-E309DC8EEF4F}
+		{3AB75B51-A69D-4145-A564-1D9D1695992E} = {D041C554-B78E-4AAF-B597-E309DC8EEF4F}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {4B8EA790-BD13-4422-8D63-D6DBB77B823F}

+ 46 - 2
src/Hotline.Api/Controllers/KnowledgeController.cs

@@ -45,6 +45,9 @@ using Hotline.Import;
 using Hotline.Caching.Services;
 using Hotline.Share.Enums.Order;
 using MiniExcelLibs;
+using DocumentFormat.OpenXml.Wordprocessing;
+using Hotline.Pdf;
+using Microsoft.AspNetCore.Authorization;
 
 namespace Hotline.Api.Controllers
 {
@@ -56,6 +59,7 @@ namespace Hotline.Api.Controllers
         private readonly IRepository<KnowledgeHotWord> _knowledgeHotWordRepository;
         private readonly IRepository<KnowledgeApprove> _knowledgeApproRepository;
         private readonly ISystemSettingCacheManager _systemSettingCacheManager;
+        private readonly IPdfManager _pdfManager;
         private readonly IRepository<KnowledgeWord> _knowledgeWordRepository;
         private readonly IWordHelperService _wordHelperService;
         private readonly BaseDataApplication _baseDataApplication;
@@ -121,7 +125,8 @@ namespace Hotline.Api.Controllers
             IOptionsSnapshot<AppConfiguration> appOptions,
             IRepository<KnowledgeHotWord> knowledgeHotWordRepository,
             IRepository<KnowledgeApprove> knowledgeApproRepository,
-            ISystemSettingCacheManager _systemSettingCacheManager)
+            ISystemSettingCacheManager _systemSettingCacheManager,
+            IPdfManager pdfManager)
         {
             _knowledgeRepository = knowledgeRepository;
             _sessionContext = sessionContext;
@@ -155,6 +160,7 @@ namespace Hotline.Api.Controllers
             _knowledgeHotWordRepository = knowledgeHotWordRepository;
             _knowledgeApproRepository = knowledgeApproRepository;
             this._systemSettingCacheManager = _systemSettingCacheManager;
+            _pdfManager = pdfManager;
             _appOptions = appOptions;
         }
 
@@ -962,7 +968,7 @@ namespace Hotline.Api.Controllers
         /// </summary>
         /// <returns></returns>
         [HttpGet("dl-template")]
-        public object DownLoadKnowledgeTemplate()
+        public IActionResult DownLoadKnowledgeTemplate()
         {
             return _exportApplication.ExportData(new List<KnowledgeImportTemplate>
             {
@@ -1033,6 +1039,44 @@ namespace Hotline.Api.Controllers
                 : $"导入{items.Count}条,成功{kns.Count}条,{err}";
         }
 
+        /// <summary>
+        /// 导出知识(new)
+        /// </summary>
+        [HttpGet("export-knowledge")]
+        public async Task<IActionResult> ExportKnowledge([FromQuery] ExportKnowledgeRequest request)
+        {
+            if (string.IsNullOrEmpty(request.Id))
+                throw new UserFriendlyException("无效知识编号");
+            var kn = await _knowledgeRepository.GetAsync(request.Id, HttpContext.RequestAborted);
+            if (kn is null)
+                throw new UserFriendlyException("无效知识编号");
+            var content = kn.Content
+                  .Replace("&nbsp;", " ")
+                  .Replace("&amp;", "&")
+                  .Replace("&quot;", "\"")
+                  .Replace("&gt;", ">")
+                  .Replace("&lt;", "<")
+                  ;
+
+
+            switch (request.ExportType)
+            {
+                case "pdf":
+                    var fileName = $"{kn.Title}.pdf";
+                    var stream = new MemoryStream();
+                    _pdfManager.GeneratePdf(kn.Title, content, stream);
+                    stream.Seek(0, SeekOrigin.Begin);
+                    return new FileStreamResult(stream, "application/pdf")
+                    {
+                        FileDownloadName = fileName ?? DateTime.Now.ToString("yyyyMMddhhmmss") + ".pdf"
+                    };
+
+                    break;
+            }
+
+
+            return null;
+        }
 
         #endregion
 

+ 4 - 1
src/Hotline.Api/StartupExtensions.cs

@@ -43,6 +43,7 @@ using Hotline.WeChat;
 using Hotline.Orders;
 using XF.Domain.Repository.Events;
 using Hotline.Orders.DatabaseEventHandler;
+using Hotline.Pdf;
 
 
 namespace Hotline.Api;
@@ -205,7 +206,9 @@ internal static class StartupExtensions
 
         //job
         services.RegisterJob(appConfiguration);
-        
+
+        services.AddPdfManager();
+
         //compression
         services.RejisterCompression();
 

+ 1 - 1
src/Hotline.Application/ExportWord/WordHelper.cs

@@ -11,7 +11,7 @@ namespace Hotline.Application.ExportWord
     {
         public static Stream ConvertHtmlToPdf(string htmlContent)
         {
-            var pdf = Pdf
+            var pdf = OpenHtmlToPdf.Pdf
                 .From(htmlContent)
                 .WithObjectSetting("web.defaultEncoding", "utf-8")
                 .Content();

+ 1 - 0
src/Hotline.Application/Hotline.Application.csproj

@@ -19,6 +19,7 @@
     <ProjectReference Include="..\Hotline.Ai.Jths\Hotline.Ai.Jths.csproj" />
     <ProjectReference Include="..\Hotline.Application.Contracts\Hotline.Application.Contracts.csproj" />
     <ProjectReference Include="..\Hotline.NewRock\Hotline.NewRock.csproj" />
+    <ProjectReference Include="..\Hotline.Pdf\Hotline.Pdf.csproj" />
     <ProjectReference Include="..\Hotline.Repository.SqlSugar\Hotline.Repository.SqlSugar.csproj" />
     <ProjectReference Include="..\Hotline.WeChat\Hotline.WeChat.csproj" />
     <ProjectReference Include="..\Hotline.Wex\Hotline.Wex.csproj" />

+ 17 - 0
src/Hotline.Pdf/Hotline.Pdf.csproj

@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="QuestPDF" Version="2024.12.2" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\Hotline\Hotline.csproj" />
+  </ItemGroup>
+
+</Project>

+ 52 - 0
src/Hotline.Pdf/QuestPdfManager.cs

@@ -0,0 +1,52 @@
+using Hotline.Ai.Quality;
+using QuestPDF.Fluent;
+using QuestPDF.Helpers;
+using QuestPDF.Infrastructure;
+
+namespace Hotline.Pdf
+{
+    public class QuestPdfManager : IPdfManager
+    {
+        public void GeneratePdf(string title, string content, Stream stream) => CreateDocument(title, content).GeneratePdf(stream);
+
+        public void GeneratePdf(string title, string content, string path) => CreateDocument(title, content).GeneratePdf(path);
+
+
+        private Document CreateDocument(string title, string content)
+        {
+            return Document.Create(container =>
+            {
+                container.Page(page =>
+                {
+                    page.Size(PageSizes.A4);
+                    page.Margin(2, Unit.Centimetre);
+                    page.PageColor(Colors.White);
+                    page.DefaultTextStyle(x => x.FontSize(20));
+
+                    page.Header()
+                        .Text(title)
+                        .SemiBold().FontSize(36).FontColor(Colors.Blue.Medium);
+
+                    page.Content()
+                        .PaddingVertical(1, Unit.Centimetre)
+                        .Column(x =>
+                        {
+                            x.Spacing(20);
+
+                            //x.Item().Text(Placeholders.LoremIpsum());
+                            //x.Item().Image(Placeholders.Image(200, 100));
+                            x.Item().Text(content);
+                        });
+
+                    page.Footer()
+                        .AlignCenter()
+                        .Text(x =>
+                        {
+                            x.Span("Page ");
+                            x.CurrentPageNumber();
+                        });
+                });
+            });
+        }
+    }
+}

+ 16 - 0
src/Hotline.Pdf/QuestPdfManagerStartupExtensions.cs

@@ -0,0 +1,16 @@
+using Microsoft.Extensions.DependencyInjection;
+using QuestPDF.Infrastructure;
+
+namespace Hotline.Pdf;
+
+public static class QuestPdfManagerStartupExtensions
+{
+    public static IServiceCollection AddPdfManager(this IServiceCollection services)
+    {
+        services.AddSingleton<IPdfManager, QuestPdfManager>();
+
+        QuestPDF.Settings.License = LicenseType.Community;
+
+        return services;
+    }
+}

+ 15 - 0
src/Hotline.Share/Dtos/Knowledge/ExportKnowledgeRequest.cs

@@ -0,0 +1,15 @@
+namespace Hotline.Share.Dtos.Knowledge;
+
+public class ExportKnowledgeRequest
+{
+    /// <summary>
+    /// 知识id
+    /// </summary>
+    public string Id { get; set; }
+
+    /// <summary>
+    /// pdf(暂只支持)
+    /// </summary>
+    public string ExportType { get; set; }
+
+}

+ 14 - 0
src/Hotline/Pdf/IPdfManager.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Hotline.Pdf
+{
+    public interface IPdfManager
+    {
+        void GeneratePdf(string title, string content, Stream stream);
+        void GeneratePdf(string title, string content, string path);
+    }
+}