diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/ContentTypeUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/ContentTypeUtil.java new file mode 100644 index 00000000..59677502 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/file/ContentTypeUtil.java @@ -0,0 +1,61 @@ +package org.ruoyi.common.core.utils.file; + +import java.util.HashMap; +import java.util.Map; + +/** + * @Author: xiaoen + * @Description: Content-Type 映射工具 + * @Date: Created in 18:50 2026/3/17 + */ +public class ContentTypeUtil { + + private static final Map CONTENT_TYPE_MAP = new HashMap<>(); + + static { + // 文本文件 + CONTENT_TYPE_MAP.put(".txt", "text/plain; charset=UTF-8"); + CONTENT_TYPE_MAP.put(".html", "text/html; charset=UTF-8"); + CONTENT_TYPE_MAP.put(".htm", "text/html; charset=UTF-8"); + CONTENT_TYPE_MAP.put(".css", "text/css; charset=UTF-8"); + CONTENT_TYPE_MAP.put(".js", "application/javascript; charset=UTF-8"); + CONTENT_TYPE_MAP.put(".json", "application/json; charset=UTF-8"); + CONTENT_TYPE_MAP.put(".xml", "application/xml; charset=UTF-8"); + CONTENT_TYPE_MAP.put(".csv", "text/csv; charset=UTF-8"); + + // 图片文件 + CONTENT_TYPE_MAP.put(".jpg", "image/jpeg"); + CONTENT_TYPE_MAP.put(".jpeg", "image/jpeg"); + CONTENT_TYPE_MAP.put(".png", "image/png"); + CONTENT_TYPE_MAP.put(".gif", "image/gif"); + CONTENT_TYPE_MAP.put(".bmp", "image/bmp"); + CONTENT_TYPE_MAP.put(".webp", "image/webp"); + CONTENT_TYPE_MAP.put(".svg", "image/svg+xml"); + + // 应用文件 + CONTENT_TYPE_MAP.put(".pdf", "application/pdf"); + CONTENT_TYPE_MAP.put(".doc", "application/msword"); + CONTENT_TYPE_MAP.put(".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"); + CONTENT_TYPE_MAP.put(".xls", "application/vnd.ms-excel"); + CONTENT_TYPE_MAP.put(".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + CONTENT_TYPE_MAP.put(".ppt", "application/vnd.ms-powerpoint"); + CONTENT_TYPE_MAP.put(".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"); + + // 其他 + CONTENT_TYPE_MAP.put(".mp3", "audio/mpeg"); + CONTENT_TYPE_MAP.put(".mp4", "video/mp4"); + CONTENT_TYPE_MAP.put(".zip", "application/zip"); + CONTENT_TYPE_MAP.put(".rar", "application/x-rar-compressed"); + } + + /** + * 根据后缀返回对应的 content-type + * @param suffix + * @param defaultContentType + * @return + */ + public static String getContentType(String suffix, String defaultContentType) { + String contentType = CONTENT_TYPE_MAP.get(suffix.toLowerCase()); + return contentType != null ? contentType : defaultContentType; + } +} diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/impl/provider/DeepseekServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/impl/provider/DeepseekServiceImpl.java new file mode 100644 index 00000000..b79831b8 --- /dev/null +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/impl/provider/DeepseekServiceImpl.java @@ -0,0 +1,46 @@ +package org.ruoyi.service.chat.impl.provider; + +import dev.langchain4j.data.message.ChatMessage; +import dev.langchain4j.model.chat.StreamingChatModel; +import dev.langchain4j.model.chat.response.StreamingChatResponseHandler; +import dev.langchain4j.model.openai.OpenAiStreamingChatModel; +import lombok.extern.slf4j.Slf4j; +import org.ruoyi.common.chat.domain.dto.request.ChatRequest; +import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo; +import org.ruoyi.enums.ChatModeType; +import org.ruoyi.service.chat.impl.AbstractStreamingChatService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @Author: xiaoen + * @Description: deepseek 服务调用 + * @Date: Created in 19:12 2026/3/17 + */ +@Service +@Slf4j +public class DeepseekServiceImpl extends AbstractStreamingChatService { + + @Override + public StreamingChatModel buildStreamingChatModel(ChatModelVo chatModelVo, ChatRequest chatRequest) { + return OpenAiStreamingChatModel.builder() + .baseUrl(chatModelVo.getApiHost()) + .apiKey(chatModelVo.getApiKey()) + .modelName(chatModelVo.getModelName()) + .returnThinking(chatRequest.getEnableThinking()) + .build(); + } + + @Override + public void doChat(ChatModelVo chatModelVo, ChatRequest chatRequest, List messagesWithMemory, StreamingChatResponseHandler handler) { + StreamingChatModel streamingChatModel = buildStreamingChatModel(chatModelVo, chatRequest); + streamingChatModel.chat(messagesWithMemory, handler); + } + + @Override + public String getProviderName() { + return ChatModeType.DEEP_SEEK.getCode(); + } + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SysOssServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SysOssServiceImpl.java index 8ca967ea..61accdb8 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SysOssServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/impl/SysOssServiceImpl.java @@ -17,6 +17,7 @@ import org.ruoyi.common.core.utils.MapstructUtils; import org.ruoyi.common.core.utils.SpringUtils; import org.ruoyi.common.core.utils.StreamUtils; import org.ruoyi.common.core.utils.StringUtils; +import org.ruoyi.common.core.utils.file.ContentTypeUtil; import org.ruoyi.common.core.utils.file.FileUtils; import org.ruoyi.common.json.utils.JsonUtils; import org.ruoyi.common.mybatis.core.page.PageQuery; @@ -218,7 +219,7 @@ public class SysOssServiceImpl implements ISysOssService, OssService { OssClient storage = OssFactory.instance(); UploadResult uploadResult; try { - uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType()); + uploadResult = storage.uploadSuffix(file.getBytes(), suffix, ContentTypeUtil.getContentType(suffix, file.getContentType())); } catch (IOException e) { throw new ServiceException(e.getMessage()); }