办学质量监测教学评价系统
ageerle
2025-06-05 baa664ac4fd1bf72888a59f1099edcf20f22b74f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package org.ruoyi.chat.service.chat.impl;
 
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.chat.config.ChatConfig;
import org.ruoyi.chat.enums.ChatModeType;
import org.ruoyi.chat.listener.SSEEventSourceListener;
import org.ruoyi.chat.service.chat.IChatService;
import org.ruoyi.common.chat.entity.chat.ChatCompletion;
import org.ruoyi.common.chat.entity.chat.Message;
import org.ruoyi.common.chat.openai.OpenAiStreamClient;
import org.ruoyi.common.chat.request.ChatRequest;
import org.ruoyi.domain.vo.ChatModelVo;
import org.ruoyi.service.IChatModelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
import java.util.*;
 
/**
 * 图片识别模型
 */
@Service
@Slf4j
public class ImageServiceImpl implements IChatService {
 
    @Autowired
    private IChatModelService chatModelService;
 
    @SneakyThrows
//    @Override
//    public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
//        ChatModelVo chatModelVo = chatModelService.selectModelByCategory("image");
//
//        // 发送流式消息
//
//            MultiModalConversation conv = new MultiModalConversation();
//            MultiModalMessage systemMessage = MultiModalMessage.builder().role(Role.SYSTEM.getValue())
//                    .content(Arrays.asList(
//                            Collections.singletonMap("text",chatRequest.getSysPrompt()))).build();
//            // 获取用户消息内容
//            List<Message> messages = chatRequest.getMessages();
//            MultiModalMessage userMessage = null;
//            //漫长的格式转换
//            // 遍历消息列表,提取文本内容
//        if (messages != null && !messages.isEmpty()) {
//            Object content = messages.get(messages.size() - 1).getContent();
//            List<Map<String, Object>> contentList = new ArrayList<>();
//            StringBuilder textContent = new StringBuilder();
//            if (content instanceof List<?>) {
//                for (Object item : (List<?>) content) {
//                    if (item instanceof Map<?, ?> mapItem) {
//                        String type = (String) mapItem.get("type");
//                        if ("text".equals(type)) {
//                            String text = (String) mapItem.get("text");
//                            if (text != null) {
//                                textContent.append(text).append(" ");
//                            }
//                        } else if ("image_url".equals(type)) {
//                            Map<String, String> imageUrl  = (Map<String, String>) mapItem.get("image_url");
//                                contentList.add(Collections.singletonMap("image", imageUrl.get("url")));
//                        }
//                    }
//                }
//            }
//            // 将拼接后的文本内容添加到 contentList
//            if (textContent.length() > 0) {
//                contentList.add(Collections.singletonMap("text", textContent.toString().trim()));
//            }
//            userMessage = MultiModalMessage.builder()
//                    .role(Role.USER.getValue())
//                    .content(contentList)
//                    .build();
//        }
//            MultiModalConversationParam param = MultiModalConversationParam.builder()
//                    .apiKey(chatModelVo.getApiKey())
//                    .model(chatModelVo.getModelName())
//                    .messages(Arrays.asList(systemMessage, userMessage))
//                    .incrementalOutput(true)
//                    .build();
//
//
//        try {
//            final QwenStreamingResponseBuilder responseBuilder = new QwenStreamingResponseBuilder(param.getModel(),param.getIncrementalOutput() );
//            conv.streamCall(param, new ResultCallback<>() {
//                @SneakyThrows
//                public void onEvent(MultiModalConversationResult result) {
//
//                    String delta = responseBuilder.append(result);
//                    if (Utils.isNotNullOrEmpty(delta)) {
//
//                        emitter.send(delta);
//                        log.info("收到消息片段: {}", delta);
//                    }
//                }
//                public void onComplete() {
//                    emitter.complete();
//                    log.info("消息结束", responseBuilder.build());
//                }
//                public void onError(Exception e) {
//                    log.info("请求失败", e.getMessage());
//                }
//            });
//        } catch (NoApiKeyException e) {
//            emitter.send("请先配置API密钥");
//            throw new RuntimeException(e);
//        } catch (UploadFileException e) {
//            throw new RuntimeException(e);
//        }
//
//
//        return emitter;
//    }
 
    @Override
    public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) {
        // 从数据库获取 image 类型的模型配置
        ChatModelVo chatModelVo = chatModelService.selectModelByCategory(ChatModeType.IMAGE.getCode());
        if (chatModelVo == null) {
            log.error("未找到 image 类型的模型配置");
            emitter.completeWithError(new IllegalStateException("未找到 image 类型的模型配置"));
            return emitter;
        }
 
        // 创建 OpenAI 流客户端
        OpenAiStreamClient openAiStreamClient = ChatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey());
        List<Message> messages = chatRequest.getMessages();
 
        // 创建 SSE 事件源监听器
        SSEEventSourceListener listener = new SSEEventSourceListener(emitter, chatRequest.getUserId(), chatRequest.getSessionId());
 
        // 构建聊天完成请求
        ChatCompletion completion = ChatCompletion
                .builder()
                .messages(messages)
                .model(chatModelVo.getModelName()) // 使用数据库中配置的模型名称
                .stream(true)
                .build();
 
        // 发起流式聊天完成请求
        openAiStreamClient.streamChatCompletion(completion, listener);
 
        return emitter;
    }
 
    @Override
    public String getCategory() {
        return ChatModeType.IMAGE.getCode();
    }
}