yuanrf 2 天之前
父節點
當前提交
3d889c7841

+ 19 - 2
OASystem/OASystem.Api/Controllers/AITestController.cs

@@ -90,15 +90,32 @@ namespace OASystem.API.Controllers
         /// 豆包上传文件
         /// </summary>
         [HttpPost("doubao-upload")]
-        public async Task<ActionResult<DoubaoFileResponse>> DoubaoUpload(IFormFile file, string purpose = "fine-tune")
+        public async Task<ActionResult<DoubaoFileResponse>> DoubaoUpload(IFormFile file, string purpose = "user_data")
         {
             if (file == null || file.Length == 0)
                 return BadRequest("请选择要上传的文件");
 
             try
             {
-                using var stream = file.OpenReadStream();
+                var stream = file.OpenReadStream();
+
+                var existsFileExpand = new List<string> { "pdf", "docx" };
+
+                if (!existsFileExpand.Contains(file.FileName.Split('.').Last().ToLower()))
+                {
+                    return BadRequest("请上传pdf、docx文件!不支持其他文件");
+                }
+
+                if (file.FileName.Split('.').Last().ToLower() == "docx")
+                {
+                    using var docxStream = file.OpenReadStream();
+                    var pdfStream = DoubaoService.ConvertDocxStreamToPdfStream(docxStream);
+                    stream = pdfStream;
+                }
+
                 var response = await _doubaoService.UploadFileAsync(stream, file.FileName, purpose);
+                stream.Dispose();
+
                 return Ok(response);
             }
             catch (Exception ex)

+ 13 - 8
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -12292,18 +12292,23 @@ FROM
                 return Ok(jw);
             }
 
-            var clients = await _sqlSugar.Queryable<Grp_TourClientList>()
-            .Where(x => x.IsDel == 0 && x.DiId == dto.Diid)
-            .ToListAsync();
-
-            if (!clients.Any())
+            if (dto.isFileClient)
             {
-                jw.Msg = "团组客户信息不存在!";
-                return Ok(jw);
-            }
 
+            }
+            else
+            {
 
+                var clients = await _sqlSugar.Queryable<Grp_TourClientList>()
+                           .Where(x => x.IsDel == 0 && x.DiId == dto.Diid)
+                           .ToListAsync();
 
+                if (!clients.Any())
+                {
+                    jw.Msg = "团组客户信息不存在!";
+                    return Ok(jw);
+                }
+            }
 
             return Ok(JsonView(true, "请示文件生成成功!"));
         }

+ 60 - 5
OASystem/OASystem.Api/OAMethodLib/DoubaoAPI/DoubaoService.cs

@@ -1,5 +1,5 @@
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
+using Aspose.Words;
+using OASystem.API.OAMethodLib.File;
 using System.Net.Http.Headers;
 using System.Text;
 
@@ -91,7 +91,7 @@ namespace OASystem.API.OAMethodLib.DoubaoAPI
             options ??= new CompleteMultimodalChatOptions();
             var httpClient = _httpClientFactory.CreateClient("Doubao");
             httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _doubaoSetting.ApiKey);
-            httpClient.Timeout = TimeSpan.FromSeconds(60); // 超时控制
+            httpClient.Timeout = TimeSpan.FromMinutes(10); // 超时控制
 
             // 2. 构建请求体(核心:修正type值)
             var requestBody = new
@@ -177,7 +177,6 @@ namespace OASystem.API.OAMethodLib.DoubaoAPI
                     return outputText;
                 }
 
-                // 旧结构兜底:choices -> message -> content -> input_text
                 var doubaoResponse = JsonConvert.DeserializeObject<DoubaoMultimodalResponse>(responseContent);
                 var textContent = doubaoResponse?.Choices?.FirstOrDefault()
                     ?.Message?.Content?
@@ -206,7 +205,7 @@ namespace OASystem.API.OAMethodLib.DoubaoAPI
             }
         }
 
-        public async Task<DoubaoFileResponse> UploadFileAsync(Stream fileStream, string fileName, string purpose = "fine-tune")
+        public async Task<DoubaoFileResponse> UploadFileAsync(Stream fileStream, string fileName, string purpose = "user_data")
         {
             var httpClient = _httpClientFactory.CreateClient("Doubao");
             httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _doubaoSetting.ApiKey);
@@ -254,5 +253,61 @@ namespace OASystem.API.OAMethodLib.DoubaoAPI
             var response = await httpClient.DeleteAsync($"files/{fileId}");
             return response.IsSuccessStatusCode;
         }
+
+        /// <summary>
+        /// Word(.docx)二进制流转PDF二进制流。
+        /// </summary>
+        /// <param name="docxStream">Word二进制流(仅支持.docx)</param>
+        /// <param name="saveDirectory">PDF保存目录,空则使用程序目录下 temp/pdf</param>
+        /// <param name="outputFileName">输出PDF文件名(可不带后缀)</param>
+        /// <returns>PDF二进制流(MemoryStream)</returns>
+        public static MemoryStream ConvertDocxStreamToPdfStream(
+            Stream docxStream,
+            string? saveDirectory = null,
+            string? outputFileName = null)
+        {
+            if (docxStream == null || !docxStream.CanRead)
+            {
+                throw new ArgumentException("Word二进制流不可读或为空", nameof(docxStream));
+            }
+
+            if (docxStream.CanSeek)
+            {
+                docxStream.Position = 0;
+            }
+
+            try
+            {
+                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+
+                AsposeHelper.removewatermark_v2180();
+
+                var wordDoc = new Document(docxStream);
+                using var pdfStream = new MemoryStream();
+                wordDoc.Save(pdfStream, SaveFormat.Pdf);
+                pdfStream.Position = 0;
+
+                var pdfBytes = pdfStream.ToArray();
+                // var finalSaveDirectory = string.IsNullOrWhiteSpace(saveDirectory)
+                //     ? global::System.IO.Path.Combine(AppContext.BaseDirectory, "temp", "pdf")
+                //     : saveDirectory;
+                //
+                // global::System.IO.Directory.CreateDirectory(finalSaveDirectory);
+                //
+                // var finalFileName = string.IsNullOrWhiteSpace(outputFileName)
+                //     ? $"docx_to_pdf_{DateTime.Now:yyyyMMdd_HHmmss_fff}.pdf"
+                //     : (outputFileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase) ? outputFileName : $"{outputFileName}.pdf");
+                //
+                // var savePath = global::System.IO.Path.Combine(finalSaveDirectory, finalFileName);
+                // global::System.IO.File.WriteAllBytes(savePath, pdfBytes);
+
+                return new MemoryStream(pdfBytes);
+            }
+            catch (Exception ex)
+            {
+                var rootMessage = ex.InnerException?.Message ?? ex.Message;
+                throw new InvalidOperationException($"Aspose文档转换失败: {rootMessage}", ex);
+            }
+        }
     }
 }

+ 1 - 1
OASystem/OASystem.Api/OAMethodLib/DoubaoAPI/IDoubaoService.cs

@@ -92,7 +92,7 @@ namespace OASystem.API.OAMethodLib.DoubaoAPI
     {
         Task<string> CompleteChatAsync(List<DouBaoChatMessage> messages, CompleteChatOptions? options = null);
         Task<string> CompleteMultimodalChatAsync(List<DoubaoMultimodalChatMessage> messages, CompleteMultimodalChatOptions? options);
-        Task<DoubaoFileResponse> UploadFileAsync(Stream fileStream, string fileName, string purpose = "fine-tune");
+        Task<DoubaoFileResponse> UploadFileAsync(Stream fileStream, string fileName, string purpose = "user_data");
         Task<DoubaoFileListResponse> ListFilesAsync();
         Task<bool> DeleteFileAsync(string fileId);
     }

+ 2 - 0
OASystem/OASystem.Domain/Dtos/Groups/InvitationOfficialActivitiesListDto.cs

@@ -230,5 +230,7 @@ namespace OASystem.Domain.Dtos.Groups
     public class BusinessInvitationInstructionsFileDto
     {
         public int Diid { get; set; }
+
+        public bool isFileClient { get; set; } = false;
     }
 }