package com.zy.ai.service; import com.alibaba.fastjson.JSON; import com.zy.ai.entity.ChatCompletionRequest; import com.zy.ai.entity.WcsDiagnosisRequest; import com.zy.ai.utils.AiPromptUtils; import com.zy.ai.utils.AiUtils; import com.zy.common.utils.RedisUtil; import com.zy.core.enums.RedisKeyType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; import java.util.Map; @Service @RequiredArgsConstructor public class WcsDiagnosisService { private static final long CHAT_TTL_SECONDS = 7L * 24 * 3600; @Autowired private LlmChatService llmChatService; @Autowired private RedisUtil redisUtil; @Autowired private AiPromptUtils aiPromptUtils; @Autowired private AiUtils aiUtils; /** * 针对“系统不执行任务 / 不知道哪个设备没在运行”的通用 AI 诊断 */ public String diagnose(WcsDiagnosisRequest request) { List messages = new ArrayList<>(); // 1. system:定义专家身份 + 输出结构 ChatCompletionRequest.Message system = new ChatCompletionRequest.Message(); system.setRole("system"); system.setContent(aiPromptUtils.getAiDiagnosePrompt()); messages.add(system); ChatCompletionRequest.Message user = new ChatCompletionRequest.Message(); user.setRole("user"); user.setContent(aiUtils.buildDiagnosisUserContent(request)); messages.add(user); // 调用大模型 return llmChatService.chat(messages, 0.2, 2048); } public void diagnoseStream(WcsDiagnosisRequest request, SseEmitter emitter) { List messages = new ArrayList<>(); ChatCompletionRequest.Message system = new ChatCompletionRequest.Message(); system.setRole("system"); system.setContent(aiPromptUtils.getAiDiagnosePrompt()); messages.add(system); ChatCompletionRequest.Message user = new ChatCompletionRequest.Message(); user.setRole("user"); user.setContent(aiUtils.buildDiagnosisUserContent(request)); messages.add(user); llmChatService.chatStream(messages, 0.2, 2048, s -> { try { String safe = s == null ? "" : s.replace("\r", "").replace("\n", "\\n"); if (!safe.isEmpty()) { emitter.send(SseEmitter.event().data(safe)); } } catch (Exception ignore) {} }, () -> { try { emitter.complete(); } catch (Exception ignore) {} }, e -> { try { emitter.completeWithError(e); } catch (Exception ignore) {} }); } public void askStream(WcsDiagnosisRequest request, String prompt, String chatId, boolean reset, SseEmitter emitter) { List base = new ArrayList<>(); ChatCompletionRequest.Message system = new ChatCompletionRequest.Message(); system.setRole("system"); system.setContent(aiPromptUtils.getWcsSensorPrompt()); base.add(system); List history = null; String historyKey = null; String metaKey = null; if (chatId != null && !chatId.isEmpty()) { historyKey = RedisKeyType.AI_CHAT_HISTORY.key + chatId; metaKey = RedisKeyType.AI_CHAT_META.key + chatId; if (reset) { redisUtil.del(historyKey, metaKey); } List stored = redisUtil.lGet(historyKey, 0, -1); if (stored != null && !stored.isEmpty()) { history = new ArrayList<>(stored.size()); for (Object o : stored) { ChatCompletionRequest.Message m = convertToMessage(o); if (m != null) history.add(m); } if (!history.isEmpty()) base.addAll(history); } else { history = new ArrayList<>(); } } ChatCompletionRequest.Message contextMsg = new ChatCompletionRequest.Message(); contextMsg.setRole("user"); contextMsg.setContent(aiUtils.buildAskUserContent(request)); base.add(contextMsg); ChatCompletionRequest.Message questionMsg = new ChatCompletionRequest.Message(); questionMsg.setRole("user"); questionMsg.setContent("【用户提问】\n" + (prompt == null ? "" : prompt)); base.add(questionMsg); StringBuilder assistantBuffer = new StringBuilder(); final String finalChatId = chatId; final String finalHistoryKey = historyKey; final String finalMetaKey = metaKey; final String finalPrompt = prompt; llmChatService.chatStream(base, 0.2, 2048, s -> { try { String safe = s == null ? "" : s.replace("\r", "").replace("\n", "\\n"); if (!safe.isEmpty()) { emitter.send(SseEmitter.event().data(safe)); assistantBuffer.append(s); } } catch (Exception ignore) {} }, () -> { try { if (finalChatId != null && !finalChatId.isEmpty()) { ChatCompletionRequest.Message q = new ChatCompletionRequest.Message(); q.setRole("user"); q.setContent(finalPrompt == null ? "" : finalPrompt); ChatCompletionRequest.Message a = new ChatCompletionRequest.Message(); a.setRole("assistant"); a.setContent(assistantBuffer.toString()); redisUtil.lSet(finalHistoryKey, q); redisUtil.lSet(finalHistoryKey, a); redisUtil.expire(finalHistoryKey, CHAT_TTL_SECONDS); Map old = redisUtil.hmget(finalMetaKey); Long createdAt = old != null && old.get("createdAt") != null ? (old.get("createdAt") instanceof Number ? ((Number) old.get("createdAt")).longValue() : Long.valueOf(String.valueOf(old.get("createdAt")))) : System.currentTimeMillis(); Map meta = new java.util.HashMap<>(); meta.put("chatId", finalChatId); meta.put("title", buildTitleFromPrompt(finalPrompt)); meta.put("createdAt", createdAt); meta.put("updatedAt", System.currentTimeMillis()); redisUtil.hmset(finalMetaKey, meta, CHAT_TTL_SECONDS); } emitter.complete(); } catch (Exception ignore) {} }, e -> { try { emitter.completeWithError(e); } catch (Exception ignore) {} }); } public List> listChats() { java.util.Set keys = redisUtil.scanKeys(RedisKeyType.AI_CHAT_META.key, 1000); List> resp = new ArrayList<>(); if (keys != null) { for (String key : keys) { Map m = redisUtil.hmget(key); if (m != null && !m.isEmpty()) { java.util.HashMap item = new java.util.HashMap<>(); for (Map.Entry e : m.entrySet()) { item.put(String.valueOf(e.getKey()), e.getValue()); } String chatId = String.valueOf(item.get("chatId")); String historyKey = RedisKeyType.AI_CHAT_HISTORY.key + chatId; item.put("size", redisUtil.lGetListSize(historyKey)); resp.add(item); } } } return resp; } public boolean deleteChat(String chatId) { if (chatId == null || chatId.isEmpty()) return false; String historyKey = RedisKeyType.AI_CHAT_HISTORY.key + chatId; String metaKey = RedisKeyType.AI_CHAT_META.key + chatId; redisUtil.del(historyKey, metaKey); return true; } public List getChatHistory(String chatId) { if (chatId == null || chatId.isEmpty()) return java.util.Collections.emptyList(); String historyKey = RedisKeyType.AI_CHAT_HISTORY.key + chatId; List stored = redisUtil.lGet(historyKey, 0, -1); List result = new ArrayList<>(); if (stored != null) { for (Object o : stored) { ChatCompletionRequest.Message m = convertToMessage(o); if (m != null) result.add(m); } } return result; } private ChatCompletionRequest.Message convertToMessage(Object o) { if (o instanceof ChatCompletionRequest.Message) { return (ChatCompletionRequest.Message) o; } if (o instanceof Map) { Map map = (Map) o; ChatCompletionRequest.Message m = new ChatCompletionRequest.Message(); Object role = map.get("role"); Object content = map.get("content"); m.setRole(role == null ? null : String.valueOf(role)); m.setContent(content == null ? null : String.valueOf(content)); return m; } return null; } private String buildTitleFromPrompt(String prompt) { if (prompt == null || prompt.isEmpty()) return "未命名会话"; String p = prompt.replaceAll("\n", " ").trim(); return p.length() > 20 ? p.substring(0, 20) : p; } }