package com.supervision.controller; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.MD5; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.supervision.exception.BusinessException; import com.supervision.model.AskTemplateQuestionLibrary; import com.supervision.model.ConfigPhysicalTool; import com.supervision.model.DiagnosisAiRecord; import com.supervision.service.AskTemplateQuestionLibraryService; import com.supervision.service.ConfigPhysicalToolService; import com.supervision.service.DiagnosisAiRecordService; import com.supervision.util.MinioUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.ai.chat.ChatResponse; import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.document.Document; import org.springframework.ai.ollama.OllamaChatClient; import org.springframework.ai.vectorstore.RedisVectorStore; import org.springframework.ai.vectorstore.SearchRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; import java.util.*; import java.util.stream.Collectors; @Slf4j @RestController @RequestMapping("test") @RequiredArgsConstructor public class TestController { private final ConfigPhysicalToolService configPhysicalToolService; private final RedisVectorStore redisVectorStore; private final AskTemplateQuestionLibraryService askTemplateQuestionLibraryService; private final DiagnosisAiRecordService diagnosisAiRecordService; private final OllamaChatClient chatClient; @GetMapping("testMatchQuestion") public String test(String question) { String template = """ 现在给定以下问题列表: --- {questionList} --- 给定问题:{question} --- 请先对给定问题列表进行意图分析,然后从中判断给定问题的意图是否出现 --- 以json格式进行返回 {"match":true/false,"matchQuestion":"匹配到的项原文"} """; Set questionList = diagnosisAiRecordService.lambdaQuery().list().stream().map(DiagnosisAiRecord::getQuestion).collect(Collectors.toSet()); List messages = new ArrayList<>(); messages.add(new UserMessage(StrUtil.format(template, Map.of("questionList", JSONUtil.toJsonStr(questionList), "question", question)))); ChatResponse call = chatClient.call(new Prompt(messages)); return call.getResult().getOutput().getContent(); } @GetMapping("testJedis") public void testJedis() { Map stringObjectMap = redisVectorStore.getJedis().ftConfigGet("spring-ai-index", ""); System.out.println(1); } @GetMapping("testRedisVectorStore") public void testRedisVectorStore() { List list = askTemplateQuestionLibraryService.list(); for (AskTemplateQuestionLibrary askTemplateQuestionLibrary : list) { String description = askTemplateQuestionLibrary.getDescription(); redisVectorStore.add(List.of(new Document(description, Map.of("type", "1", "medicalId", "222")))); List question = askTemplateQuestionLibrary.getQuestion(); for (String s : question) { redisVectorStore.add(List.of(new Document(s, Map.of("type", "1", "medicalId", "222")))); } // log.info("处理完成:{}", description); } } @GetMapping("testQuestion") public List testQuestion(String question) { List documents = redisVectorStore.similaritySearch(SearchRequest .query(question) .withTopK(5).withSimilarityThreshold(0.5)); // return documents.stream().map(document -> Map.of("content", document.getContent(), "id", document.getId())).collect(Collectors.toList()); documents.forEach(e -> { double v = Double.parseDouble(String.valueOf(e.getMetadata().get("vector_score"))); // 降序 e.getMetadata().put("originalScore", 1 - (v * 2)); }); return documents; } @GetMapping("testExpireTime") public String testExpireTime() { return "OK"; } @GetMapping("testQueryJSON") public List testQueryJSON() { return configPhysicalToolService.list(); } /** * 数字人获取房间号 * * @param key 数字人ID,张总那边提供 * @param token 前端每打开一个页面,就给一个新的UUID * @return 房间号 */ @GetMapping("queryRoomId") public String queryRoomId(String key, String token) { Map param = new HashMap<>(); param.put("token", token); param.put("key", key); String s = HttpUtil.get("https://digital-human.jd.com/getRoomId", param); JSONObject entries = JSONUtil.parseObj(s); if (200 != entries.getInt("code")) { throw new BusinessException(entries.getStr("data")); } return entries.getStr("data"); } /** * 调用数字人接口进行语音的播放 * * @param text 需要播放的文本 * @param roomId 房间ID */ @GetMapping("shuZiRenSend") public String shuZiRenSend(String text, String roomId) { HashMap param = new HashMap<>(); long timeStamp = System.currentTimeMillis(); param.put("text", text); param.put("roomId", roomId); param.put("action", "-1"); param.put("nonce", UUID.randomUUID().toString()); param.put("timeStamp", String.valueOf(timeStamp)); param.put("sign", getSign(String.valueOf(timeStamp), (String) param.get("nonce"), (String) param.get("text"), (String) param.get("actionId"), (String) param.get("roomId"))); return HttpUtil.get("https://digital-human.jd.com/text_driven", param); } private static String getSign(String timeStamp, String nonce, String text, String actionId, String roomId) { Map paramMap = new TreeMap<>(); paramMap.put("action", actionId); paramMap.put("nonce", nonce); paramMap.put("roomId", roomId); paramMap.put("text", text); paramMap.put("timeStamp", timeStamp); String paramJsonString = JSONUtil.toJsonStr(paramMap); System.out.println(paramJsonString); String signServer = new MD5().digestHex16(paramJsonString); System.out.println("---------> :" + signServer); return signServer; } @PostMapping("testFileUpload") public String testFileUpload(MultipartFile file) throws Exception { return MinioUtil.uploadFile(file.getInputStream()); } @PostMapping("downloadFile") public InputStream downloadFile(String fileId) throws Exception { return MinioUtil.download(fileId); } }