Browse Source

完善豆包多模态Api

yuanrf 2 days ago
parent
commit
b30c399f99

+ 176 - 3
OASystem/OASystem.Api/Controllers/AITestController.cs

@@ -1,4 +1,6 @@
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
+using System.IO;
+using OASystem.API.OAMethodLib.DoubaoAPI;
 using OASystem.API.OAMethodLib.HunYuanAPI;
 using OASystem.API.OAMethodLib.QiYeWeChatAPI;
 using OASystem.Domain.ViewModels.QiYeWeChat;
@@ -13,12 +15,14 @@ namespace OASystem.API.Controllers
     public class AITestController : ControllerBase
     {
         private readonly IHunyuanService _hunyuanService;
+        private readonly IDoubaoService _doubaoService;
         private readonly ILogger<AITestController> _logger;
         private readonly IQiYeWeChatApiService _qiYeWeChatApiService;
 
-        public AITestController(IHunyuanService hunyuanService, ILogger<AITestController> logger, IQiYeWeChatApiService qiYeWeChatApiService)
+        public AITestController(IHunyuanService hunyuanService, IDoubaoService doubaoService, ILogger<AITestController> logger, IQiYeWeChatApiService qiYeWeChatApiService)
         {
             _hunyuanService = hunyuanService;
+            _doubaoService = doubaoService;
             _logger = logger;
             _qiYeWeChatApiService = qiYeWeChatApiService;
         }
@@ -33,7 +37,8 @@ namespace OASystem.API.Controllers
         {
             try
             {
-                var req = new EmailRequestDto() {
+                var req = new EmailRequestDto()
+                {
                     ToEmails = new List<string> { "johnny.yang@pan-american-intl.com" },
                     CcEmails = new List<string> { "Roy.lei@pan-american-intl.com" },
                     BccEmails = new List<string> { "Roy.lei@pan-american-intl.com" },
@@ -52,6 +57,163 @@ namespace OASystem.API.Controllers
         }
         #endregion
 
+        #region 豆包 AI
+
+        /// <summary>
+        /// 豆包基础对话
+        /// </summary>
+        [HttpPost("doubao-chat")]
+        public async Task<ActionResult<string>> DoubaoChat(string question, bool isThinking = false)
+        {
+            try
+            {
+                var messages = new List<DouBaoChatMessage>
+                {
+                    new DouBaoChatMessage { Role = DouBaoRole.user, Content = question }
+                };
+                var options = new CompleteChatOptions
+                {
+                    ThinkingOptions = new thinkingOptions { IsThinking = isThinking }
+                };
+                var response = await _doubaoService.CompleteChatAsync(messages, options);
+                return Ok(response);
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "调用豆包API失败。");
+                return StatusCode(500, new { Message = "调用豆包API失败", Detail = ex.Message });
+            }
+        }
+
+
+        /// <summary>
+        /// 豆包上传文件
+        /// </summary>
+        [HttpPost("doubao-upload")]
+        public async Task<ActionResult<DoubaoFileResponse>> DoubaoUpload(IFormFile file, string purpose = "fine-tune")
+        {
+            if (file == null || file.Length == 0)
+                return BadRequest("请选择要上传的文件");
+
+            try
+            {
+                using var stream = file.OpenReadStream();
+                var response = await _doubaoService.UploadFileAsync(stream, file.FileName, purpose);
+                return Ok(response);
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "豆包上传文件失败");
+                return StatusCode(500, new { Message = "上传失败", Detail = ex.Message });
+            }
+        }
+
+        /// <summary>
+        /// 豆包获取文件列表
+        /// </summary>
+        [HttpGet("doubao-files")]
+        public async Task<ActionResult<DoubaoFileListResponse>> DoubaoListFiles()
+        {
+            try
+            {
+                var response = await _doubaoService.ListFilesAsync();
+                return Ok(response);
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "获取豆包文件列表失败");
+                return StatusCode(500, new { Message = "获取失败", Detail = ex.Message });
+            }
+        }
+
+        /// <summary>
+        /// 豆包删除文件
+        /// </summary>
+        [HttpDelete("doubao-file/{fileId}")]
+        public async Task<ActionResult<bool>> DoubaoDeleteFile(string fileId)
+        {
+            try
+            {
+                var response = await _doubaoService.DeleteFileAsync(fileId);
+                return Ok(response);
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "删除豆包文件失败");
+                return StatusCode(500, new { Message = "删除失败", Detail = ex.Message });
+            }
+        }
+
+        /// <summary>
+        /// 豆包多模态对话(支持文本+图片)
+        /// </summary>
+        /// <param name="request">表单请求参数</param>
+        [HttpPost("doubao-multimodal-chat")]
+        public async Task<ActionResult<string>> DoubaoMultimodalChat([FromForm] DoubaoMultimodalChatRequest request)
+        {
+            if (string.IsNullOrWhiteSpace(request.Question))
+                return BadRequest("问题不能为空");
+
+            try
+            {
+                var contentItems = new List<DoubaoMultimodalContentItem>
+                {
+                    new DoubaoMultimodalContentItem { Type = "text", Text = request.Question.Trim() }
+                };
+
+                if (!string.IsNullOrWhiteSpace(request.FileId))
+                {
+                    contentItems.Add(new DoubaoMultimodalContentItem
+                    {
+                        Type = "file",
+                        FileId = request.FileId.Trim(),
+                    });
+                }
+
+                if (request.Image != null && request.Image.Length > 0)
+                {
+                    using var ms = new MemoryStream();
+                    await request.Image.CopyToAsync(ms);
+                    var base64 = Convert.ToBase64String(ms.ToArray());
+                    var mimeType = request.Image.ContentType ?? "image/jpeg";
+                    var dataUrl = $"data:{mimeType};base64,{base64}";
+                    contentItems.Add(new DoubaoMultimodalContentItem
+                    {
+                        Type = "image_url",
+                        ImageUrl = new DoubaoMultimodalImageUrl { Url = dataUrl }
+                    });
+                }
+
+                var messages = new List<DoubaoMultimodalChatMessage>
+                {
+                    new DoubaoMultimodalChatMessage
+                    {
+                        Role = "user",
+                        Content = contentItems
+                    }
+                };
+
+                var options = new CompleteMultimodalChatOptions
+                {
+                    ThinkingOptions = new DoubaoMultimodalThinkingOptions
+                    {
+                        IsThinking = request.IsThinking,
+                        ReasoningEffort = "medium"
+                    }
+                };
+
+                var response = await _doubaoService.CompleteMultimodalChatAsync(messages, options);
+                return Ok(response ?? string.Empty);
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "调用豆包多模态API失败。");
+                return StatusCode(500, new { Message = "调用豆包多模态API失败", Detail = ex.Message });
+            }
+        }
+
+        #endregion
+
         #region 混元 AI
         /// <summary>
         /// 基础对话示例
@@ -128,6 +290,17 @@ namespace OASystem.API.Controllers
             public string Question { get; set; } = string.Empty;
             public string Model { get; set; } = "hunyuan-lite";
         }
+
+        /// <summary>
+        /// 豆包多模态对话请求体(form-data)
+        /// </summary>
+        public class DoubaoMultimodalChatRequest
+        {
+            public string Question { get; set; } = string.Empty;
+            public IFormFile? Image { get; set; }
+            public bool IsThinking { get; set; } = false;
+            public string FileId { get; set; } = string.Empty;
+        }
         #endregion
 
     }

+ 47 - 4
OASystem/OASystem.Api/Controllers/GroupsController.cs

@@ -12267,6 +12267,49 @@ FROM
 
         #endregion
 
+        #region 商邀Ai
+
+        /// <summary>
+        /// 请示文件生成
+        /// </summary>
+        /// <param name="dto"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [ProducesResponseType(typeof(JsonView), StatusCodes.Status200OK)]
+        public async Task<IActionResult> BusinessInvitationInstructionsFile(BusinessInvitationInstructionsFileDto dto)
+        {
+            var jw = JsonView(false);
+            if (dto.Diid < 1)
+            {
+                jw.Msg = "团组Id不能为空!";
+                return Ok(jw);
+            }
+
+            var groupInfo = await _sqlSugar.Queryable<Grp_DelegationInfo>().FirstAsync(x => x.IsDel == 0 && x.Id == dto.Diid);
+            if (groupInfo == null)
+            {
+                jw.Msg = "团组信息不存在!";
+                return Ok(jw);
+            }
+
+            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, "请示文件生成成功!"));
+        }
+
+        #endregion
+
         #region 票据上传
 
         /// <summary>
@@ -17243,7 +17286,7 @@ FROM
                         }
                         else dic.Add("SubGZF", "0.00");
 
-                        if (table3 != null && table3.Rows.Count > 0) 
+                        if (table3 != null && table3.Rows.Count > 0)
                         {
                             //删除多余行
                             while (table3.Rows.Count > table3Row)
@@ -17251,7 +17294,7 @@ FROM
                                 table3.Rows.RemoveAt(table3Row);
                             }
                         }
-                            
+
 
                         //培训费
                         Aspose.Words.Tables.Table table4 = allTables[3] as Aspose.Words.Tables.Table;
@@ -17299,14 +17342,14 @@ FROM
                         }
                         //else dic.Add("SubPX", $"六、培训费合计:  0    元/人");
                         //删除多余行
-                        if (table4 != null && table4.Rows.Count > 0) 
+                        if (table4 != null && table4.Rows.Count > 0)
                         {
                             while (table4.Rows.Count > table4Row)
                             {
                                 table4.Rows.RemoveAt(table4Row);
                             }
                         }
-                       
+
                         //其他费用
                         Aspose.Words.Tables.Table table5 = allTables[4] as Aspose.Words.Tables.Table;
                         if (_EnterExitCosts.OtherExpenses_Checked == 1)

+ 198 - 6
OASystem/OASystem.Api/OAMethodLib/DoubaoAPI/DoubaoService.cs

@@ -1,4 +1,5 @@
 using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
 using System.Net.Http.Headers;
 using System.Text;
 
@@ -26,10 +27,13 @@ namespace OASystem.API.OAMethodLib.DoubaoAPI
                 return null;
             }
 
-            if(!messages.Any(x => x.Role == DouBaoRole.system)){
-                messages.Insert(0, 
-                new DouBaoChatMessage() { 
-                    Role = DouBaoRole.system, Content = "你是一个专业的AI助手,请根据用户的问题给出回答" 
+            if (!messages.Any(x => x.Role == DouBaoRole.system))
+            {
+                messages.Insert(0,
+                new DouBaoChatMessage()
+                {
+                    Role = DouBaoRole.system,
+                    Content = "你是一个专业的AI助手,请根据用户的问题给出回答"
                 });
             }
 
@@ -46,14 +50,15 @@ namespace OASystem.API.OAMethodLib.DoubaoAPI
             if (options.ThinkingOptions.IsThinking)
             {
                 body["reasoning_effort"] = options.ThinkingOptions.ReasoningEffort.ToString().ToLower();
-                body["thinking"] = new {
+                body["thinking"] = new
+                {
                     type = "enabled",
                 };
             }
 
             var json = JsonConvert.SerializeObject(body);
             var response = await httpClient.PostAsync(
-                _doubaoSetting.BaseAddress,
+                "chat/completions",
                 new StringContent(json, Encoding.UTF8, "application/json")
             );
 
@@ -62,5 +67,192 @@ namespace OASystem.API.OAMethodLib.DoubaoAPI
             var doubaoResponse = JsonConvert.DeserializeObject<DoubaoResponse>(responseContent);
             return doubaoResponse.choices[0].message.content;
         }
+
+        /// <summary>
+        /// 多模态实现
+        /// </summary>
+        /// <param name="messages"></param>
+        /// <param name="options"></param>
+        /// <returns></returns>
+        public async Task<string> CompleteMultimodalChatAsync(List<DoubaoMultimodalChatMessage> messages, CompleteMultimodalChatOptions? options)
+        {
+            // 1. 入参校验
+            if (messages == null || !messages.Any())
+            {
+                _logger.LogError("多模态消息不能为空");
+                return null;
+            }
+            if (string.IsNullOrWhiteSpace(_doubaoSetting.ApiKey) || string.IsNullOrWhiteSpace(_doubaoSetting.EndpointId) || string.IsNullOrWhiteSpace(_doubaoSetting.BaseAddress))
+            {
+                _logger.LogError("Doubao多模态配置不完整(ApiKey/EndpointId/BaseAddress)");
+                return null;
+            }
+
+            options ??= new CompleteMultimodalChatOptions();
+            var httpClient = _httpClientFactory.CreateClient("Doubao");
+            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _doubaoSetting.ApiKey);
+            httpClient.Timeout = TimeSpan.FromSeconds(60); // 超时控制
+
+            // 2. 构建请求体(核心:修正type值)
+            var requestBody = new
+            {
+                model = _doubaoSetting.EndpointId,
+                input = messages.Select(msg => new
+                {
+                    role = msg.Role.ToLower(), // 接口要求小写
+                    type = "message", // 接口必传的消息类型(固定值)
+                    content = msg.Content.Select(contentItem =>
+                    {
+                        // 自动修正type值,避免传入text/image_url
+                        var correctedType = contentItem.Type.ToLower() switch
+                        {
+                            "text" => "input_text", // 把text修正为input_text
+                            "image_url" => "input_image", // 把image_url修正为input_image
+                            "file" => "input_file", // 文件类型
+                            _ => contentItem.Type // 其他合法值直接使用
+                        };
+
+                        // 构建内容项(根据类型补充字段)
+                        var contentObj = new Dictionary<string, object>
+                        {
+                            ["type"] = correctedType
+                        };
+
+                        if (correctedType == "input_text" && !string.IsNullOrWhiteSpace(contentItem.Text))
+                        {
+                            contentObj["text"] = contentItem.Text;
+                        }
+                        else if (correctedType == "input_image" && contentItem.ImageUrl != null && !string.IsNullOrWhiteSpace(contentItem.ImageUrl.Url))
+                        {
+                            // Responses API 要求 image_url 为字符串,而不是对象 { url: ... }
+                            contentObj["image_url"] = contentItem.ImageUrl.Url;
+                        }
+                        else if (correctedType == "input_file" && !string.IsNullOrWhiteSpace(contentItem.FileId))
+                        {
+                            contentObj["file_id"] = contentItem.FileId;
+                        }
+
+                        return contentObj;
+                    }).ToArray()
+                }).ToArray(),
+                temperature = options.Temperature,
+                thinking = options.ThinkingOptions.IsThinking ? new { type = "enabled" } : null,
+                reasoning = options.ThinkingOptions.IsThinking ? new { effort = options.ThinkingOptions.ReasoningEffort.ToLower() } : null,
+                max_output_tokens = options.MaxOutputTokens,
+                previous_response_id = options.PreviousResponseId,
+                expire_at = options.ExpireAt
+            };
+
+            try
+            {
+                // 3. 发送请求
+                var json = JsonConvert.SerializeObject(requestBody, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
+                _logger.LogDebug($"Doubao多模态请求体:{json}");
+
+                var response = await httpClient.PostAsync(
+                    "responses",
+                    new StringContent(json, Encoding.UTF8, "application/json")
+                );
+
+                var responseContent = await response.Content.ReadAsStringAsync();
+                _logger.LogDebug($"Doubao多模态响应:{response.StatusCode} {responseContent}");
+
+                if (!response.IsSuccessStatusCode)
+                {
+                    _logger.LogError($"多模态对话调用失败: {response.StatusCode}, {responseContent}");
+                    return null;
+                }
+
+                // 4. 解析响应(优先兼容 Responses API 的 output 结构)
+                var parsed = JObject.Parse(responseContent);
+
+                // 新结构:output -> type=message -> content -> type=output_text -> text
+                var outputText = parsed["output"]?
+                    .FirstOrDefault(x => string.Equals(x?["type"]?.ToString(), "message", StringComparison.OrdinalIgnoreCase))?["content"]?
+                    .FirstOrDefault(x => string.Equals(x?["type"]?.ToString(), "output_text", StringComparison.OrdinalIgnoreCase))?["text"]?
+                    .ToString();
+
+                if (!string.IsNullOrWhiteSpace(outputText))
+                {
+                    return outputText;
+                }
+
+                // 旧结构兜底:choices -> message -> content -> input_text
+                var doubaoResponse = JsonConvert.DeserializeObject<DoubaoMultimodalResponse>(responseContent);
+                var textContent = doubaoResponse?.Choices?.FirstOrDefault()
+                    ?.Message?.Content?
+                    .FirstOrDefault(c =>
+                        string.Equals(c.Type, "input_text", StringComparison.OrdinalIgnoreCase) ||
+                        string.Equals(c.Type, "output_text", StringComparison.OrdinalIgnoreCase))?
+                    .Text;
+
+                if (string.IsNullOrWhiteSpace(textContent))
+                {
+                    _logger.LogError("Doubao多模态响应无有效结果");
+                    return null;
+                }
+
+                return textContent;
+            }
+            catch (TaskCanceledException ex)
+            {
+                _logger.LogError(ex, "Doubao多模态接口调用超时");
+                return null;
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError(ex, "Doubao多模态对话调用异常");
+                return null;
+            }
+        }
+
+        public async Task<DoubaoFileResponse> UploadFileAsync(Stream fileStream, string fileName, string purpose = "fine-tune")
+        {
+            var httpClient = _httpClientFactory.CreateClient("Doubao");
+            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _doubaoSetting.ApiKey);
+
+            using var content = new MultipartFormDataContent();
+
+            // 添加 purpose 参数
+            content.Add(new StringContent(purpose), "purpose");
+
+            // 添加文件流
+            var fileContent = new StreamContent(fileStream);
+            fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
+            content.Add(fileContent, "file", fileName);
+
+            var response = await httpClient.PostAsync("files", content);
+
+            if (!response.IsSuccessStatusCode)
+            {
+                var errorContent = await response.Content.ReadAsStringAsync();
+                _logger.LogError($"上传文件失败: {response.StatusCode}, {errorContent}");
+                response.EnsureSuccessStatusCode();
+            }
+
+            var responseContent = await response.Content.ReadAsStringAsync();
+            return JsonConvert.DeserializeObject<DoubaoFileResponse>(responseContent);
+        }
+
+        public async Task<DoubaoFileListResponse> ListFilesAsync()
+        {
+            var httpClient = _httpClientFactory.CreateClient("Doubao");
+            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _doubaoSetting.ApiKey);
+
+            var response = await httpClient.GetAsync("files");
+            response.EnsureSuccessStatusCode();
+
+            var responseContent = await response.Content.ReadAsStringAsync();
+            return JsonConvert.DeserializeObject<DoubaoFileListResponse>(responseContent);
+        }
+
+        public async Task<bool> DeleteFileAsync(string fileId)
+        {
+            var httpClient = _httpClientFactory.CreateClient("Doubao");
+            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _doubaoSetting.ApiKey);
+
+            var response = await httpClient.DeleteAsync($"files/{fileId}");
+            return response.IsSuccessStatusCode;
+        }
     }
 }

+ 103 - 2
OASystem/OASystem.Api/OAMethodLib/DoubaoAPI/IDoubaoService.cs

@@ -76,12 +76,113 @@ namespace OASystem.API.OAMethodLib.DoubaoAPI
     {
         public int reasoning_tokens { get; set; }
     }
-    
+
+
+    public class DoubaoFileResponse
+    {
+        public string id { get; set; }
+        public string @object { get; set; }
+        public long bytes { get; set; }
+        public long created_at { get; set; }
+        public string filename { get; set; }
+        public string purpose { get; set; }
+    }
 
     public interface IDoubaoService
     {
         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<DoubaoFileListResponse> ListFilesAsync();
+        Task<bool> DeleteFileAsync(string fileId);
+    }
+
+    public class DoubaoFileListResponse
+    {
+        public string @object { get; set; }
+        public List<DoubaoFileResponse> data { get; set; }
+    }
+
+
+    #region 多模态
+    // 重命名:DoubaoContentItem → DoubaoMultimodalContentItem
+    public class DoubaoMultimodalContentItem
+    {
+        [JsonProperty("type")]
+        // 合法值:input_text(文本)/ input_image(图片)/ input_file(文件)
+        public string Type { get; set; }
+
+        [JsonProperty("text", NullValueHandling = NullValueHandling.Ignore)]
+        public string Text { get; set; }
+
+        [JsonProperty("image_url", NullValueHandling = NullValueHandling.Ignore)]
+        public DoubaoMultimodalImageUrl ImageUrl { get; set; }
+
+        // 补充:文件类型需要的file_id字段
+        [JsonProperty("file_id", NullValueHandling = NullValueHandling.Ignore)]
+        public string FileId { get; set; }
+    }
+
+    // 重命名:DoubaoImageUrl → DoubaoMultimodalImageUrl
+    public class DoubaoMultimodalImageUrl
+    {
+        [JsonProperty("url")]
+        public string Url { get; set; }
+    }
+
+    // 重命名:DoubaoMultimodalChatMessage(原已带Multimodal,保持但字段适配新类)
+    public class DoubaoMultimodalChatMessage
+    {
+        public string Role { get; set; } // 值必须是 user/system/assistant(小写)
+        public List<DoubaoMultimodalContentItem> Content { get; set; } = new List<DoubaoMultimodalContentItem>();
+    }
+
+    // 重命名:CompleteChatOptions → CompleteMultimodalChatOptions
+    public class CompleteMultimodalChatOptions
+    {
+        public DoubaoMultimodalThinkingOptions ThinkingOptions { get; set; } = new DoubaoMultimodalThinkingOptions();
+        public float Temperature { get; set; } = 0.7f;
+        public int? MaxOutputTokens { get; set; }
+        public string PreviousResponseId { get; set; }
+        public long? ExpireAt { get; set; }
+    }
+
+    // 重命名:ThinkingOptions → DoubaoMultimodalThinkingOptions
+    public class DoubaoMultimodalThinkingOptions
+    {
+        public bool IsThinking { get; set; }
+        public string ReasoningEffort { get; set; } = "medium";
+    }
+
+    // 重命名:DoubaoSetting → DoubaoMultimodalSetting
+    public class DoubaoMultimodalSetting
+    {
+        public string ApiKey { get; set; }
+        public string EndpointId { get; set; }
+        public string BaseAddress { get; set; }
     }
 
-    
+    // 重命名:DoubaoResponse → DoubaoMultimodalResponse
+    public class DoubaoMultimodalResponse
+    {
+        [JsonProperty("choices")]
+        public List<DoubaoMultimodalChoice> Choices { get; set; } = new List<DoubaoMultimodalChoice>();
+    }
+
+    // 重命名:DoubaoChoice → DoubaoMultimodalChoice
+    public class DoubaoMultimodalChoice
+    {
+        [JsonProperty("message")]
+        public DoubaoMultimodalResponseMessage Message { get; set; }
+    }
+
+    // 重命名:DoubaoResponseMessage → DoubaoMultimodalResponseMessage
+    public class DoubaoMultimodalResponseMessage
+    {
+        [JsonProperty("content")]
+        public List<DoubaoMultimodalContentItem> Content { get; set; }
+    }
+
+
+    #endregion
 }

+ 1 - 1
OASystem/OASystem.Api/appsettings.json

@@ -479,7 +479,7 @@
     "ApiKey": "sk-a0415069ef56478aaa3028d779d1ace9"
   },
   "DouBao": {
-    "BaseAddress": "https://ark.cn-beijing.volces.com/api/v3/chat/completions",
+    "BaseAddress": "https://ark.cn-beijing.volces.com/api/v3/",
     "ApiKey": "df7914ea-578d-4545-8f3e-9fd8a1e61cb5",
     "endpointId": "ep-20260224163259-4bvfq"
   },

+ 9 - 4
OASystem/OASystem.Domain/Dtos/Groups/InvitationOfficialActivitiesListDto.cs

@@ -26,7 +26,7 @@ namespace OASystem.Domain.Dtos.Groups
     /// <summary>
     /// 根据id查询C表数据和商邀费用数据
     /// </summary>
-    public class InvitationOfficialActivitiesByIdDto: PortDtoBase
+    public class InvitationOfficialActivitiesByIdDto : PortDtoBase
     {
         public int Id { get; set; }
     }
@@ -34,9 +34,9 @@ namespace OASystem.Domain.Dtos.Groups
     public class EncryptionMatching
     {
         [Encrypted]
-        public string InviterArea { get;set; }
+        public string InviterArea { get; set; }
         [Encrypted]
-        public string Inviter { get;set; }
+        public string Inviter { get; set; }
     }
 
     /// <summary>
@@ -198,7 +198,7 @@ namespace OASystem.Domain.Dtos.Groups
         /// </summary>
         public string Remark { get; set; }
         //-----------------------邀请方资料----------
-       
+
         /// 邀请方地址
         public string Address { get; set; }
         /// <summary>
@@ -226,4 +226,9 @@ namespace OASystem.Domain.Dtos.Groups
         /// </summary>
         public string OtherInformation { get; set; }
     }
+
+    public class BusinessInvitationInstructionsFileDto
+    {
+        public int Diid { get; set; }
+    }
 }