From 637dd7f48434ebbc07b6f158c53949500dc0b51f Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Sun, 1 Jun 2025 16:12:56 +0800 Subject: [PATCH] 'commit' --- .../com/dsideal/Res/Test/CallDeepSeek.java | 200 ++++++++++-------- dsAi/src/main/resources/XueYuan.sql | 5 +- dsAi/target/classes/XueYuan.sql | 5 +- 3 files changed, 122 insertions(+), 88 deletions(-) diff --git a/dsAi/src/main/java/com/dsideal/Res/Test/CallDeepSeek.java b/dsAi/src/main/java/com/dsideal/Res/Test/CallDeepSeek.java index fd7b5488..25d9a771 100644 --- a/dsAi/src/main/java/com/dsideal/Res/Test/CallDeepSeek.java +++ b/dsAi/src/main/java/com/dsideal/Res/Test/CallDeepSeek.java @@ -1,16 +1,19 @@ package com.dsideal.Res.Test; import cn.hutool.core.io.FileUtil; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; +import cn.hutool.core.util.CharsetUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONArray; import com.jfinal.kit.PathKit; -import java.io.BufferedReader; +import org.apache.commons.codec.digest.DigestUtils; import java.io.File; -import java.io.InputStreamReader; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpResponse; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.CompletableFuture; public class CallDeepSeek { private static final String API_KEY = "sk-44ae895eeb614aa1a9c6460579e322f1"; // 请替换为您的API KEY @@ -20,101 +23,131 @@ public class CallDeepSeek { new Thread(() -> { StringBuilder fullResponse = new StringBuilder(); try { - // 修改提示词确保只返回HTML - String htmlPrompt = prompt + "请严格按照以下HTML模板格式输出SQL血缘关系图,只返回HTML代码:\n" + - "\n" + - "\n" + - "\n" + - " SQL血缘关系图\n" + - " \n" + - " \n" + - "\n" + - "\n" + - "

SQL血缘关系图

\n" + - "
\n" + - " [请在此处插入mermaid格式的血缘关系图]\n" + - "
\n" + - " \n" + - "\n" + - ""; - - JSONObject json = new JSONObject(); - json.set("model", "deepseek-chat"); - // 修改为对象形式构建messages + // 修改htmlPrompt变量,在提示词中明确要求输出格式 + String htmlPrompt = prompt + "请严格按照以下mermaid配置输出SQL血缘关系图:\n" + + "1. 使用以下固定样式配置:\n" + + " graph TD\n" + + " classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px\n" + + " classDef input fill:#D6EAF8,stroke:#333\n" + + " classDef output fill:#D5F5E3,stroke:#333\n" + + " linkStyle default stroke:#333,stroke-width:2px\n" + + "2. 按照以下HTML模板格式输出,不要生成html以外的其它文字:\n" + + "\n" + + "\n" + + "\n" + + " SQL血缘关系图\n" + + " \n" + + " \n" + + "\n" + + "\n" + + "

SQL血缘关系图

\n" + + "
\n" + + " graph TD\n" + + " classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px\n" + + " classDef input fill:#D6EAF8,stroke:#333\n" + + " classDef output fill:#D5F5E3,stroke:#333\n" + + " linkStyle default stroke:#333,stroke-width:2px\n" + + " [请在此处插入mermaid格式的血缘关系图]\n" + + "
\n" + + " \n" + + "\n" + + "\n"; + + JSONObject jsonPayload = new JSONObject(); + jsonPayload.set("model", "deepseek-chat"); JSONObject message = new JSONObject(); message.set("role", "user"); message.set("content", htmlPrompt); JSONArray messages = new JSONArray(); messages.add(message); - json.set("messages", messages); - - json.set("stream", true); - System.out.println(json); // 打印最终请求体 - HttpRequest request = HttpRequest.post(API_URL) + jsonPayload.set("messages", messages); + jsonPayload.set("stream", true); + + HttpClient client = HttpClient.newBuilder() + .version(HttpClient.Version.HTTP_1_1) // 明确指定HTTP版本 + .build(); + + java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder() + .uri(URI.create(API_URL)) .header("Content-Type", "application/json") .header("Authorization", "Bearer " + API_KEY) - .header("Accept", "text/event-stream") - .body(json.toString()); - - HttpResponse response = request.execute(); - if (response.isOk()) { - try (BufferedReader reader = new BufferedReader( - new InputStreamReader(response.bodyStream(), "UTF-8"))) { - - String line; - while ((line = reader.readLine()) != null) { - if (line.startsWith("data:")) { - String data = line.substring(5).trim(); - if (!data.equals("[DONE]")) { - try { - JSONObject jsonData = JSONUtil.parseObj(data); - if (jsonData.containsKey("choices")) { - String content = jsonData.getJSONArray("choices") - .getJSONObject(0) - .getJSONObject("delta") - .getStr("content", ""); - if (content != null && !content.isEmpty()) { - fullResponse.append(content); - // 实时输出到控制台 - System.out.print(content); - System.out.flush(); - listener.onData(content); + .header("Accept", "text/event-stream") // 确保Accept头正确 + .POST(java.net.http.HttpRequest.BodyPublishers.ofString(jsonPayload.toString(), StandardCharsets.UTF_8)) + .build(); + + // 使用 BodyHandlers.ofLines() 来处理流式响应 + CompletableFuture future = client.sendAsync(request, HttpResponse.BodyHandlers.ofLines()) + .thenAccept(response -> { + if (response.statusCode() == 200) { + response.body().forEach(line -> { + if (line.startsWith("data:")) { + String data = line.substring(5).trim(); + if (!data.equals("[DONE]")) { + try { + JSONObject jsonData = JSONUtil.parseObj(data); + if (jsonData.containsKey("choices")) { + String content = jsonData.getJSONArray("choices") + .getJSONObject(0) + .getJSONObject("delta") + .getStr("content", ""); + if (content != null && !content.isEmpty()) { + fullResponse.append(content); + listener.onData(content); // 回调监听器 + } + } + } catch (Exception e) { + System.err.println("解析SSE JSON数据错误: " + data + " \nError: " + e.getMessage()); } } - } catch (Exception e) { - System.err.println("解析SSE数据错误: " + e.getMessage()); } + }); + // 流结束后的处理 + String htmlContent = fullResponse.toString(); + if (htmlContent.contains("") && htmlContent.contains("")) { + FileUtil.writeString(htmlContent, new File("C:\\1.html"), "UTF-8"); + listener.onComplete("HTML已成功保存到C:\\1.html"); + } else { + listener.onError("最终返回内容不是有效的HTML: " + htmlContent.substring(0, Math.min(htmlContent.length(), 200)) + "..."); } + } else { + listener.onError("API请求失败: " + response.statusCode() + " Body: " + response.body().toString()); } - } - } - } - - // 保存HTML到文件 - String htmlContent = fullResponse.toString(); - if (htmlContent.contains("") && htmlContent.contains("")) { - FileUtil.writeString(htmlContent, new File("C:\\1.html"), "UTF-8"); - listener.onComplete("HTML已成功保存到C:\\1.html"); - } else { - listener.onError("返回内容不是有效的HTML"); - } + }).exceptionally(e -> { + listener.onError("请求或处理异常: " + e.getMessage()); + e.printStackTrace(); + return null; + }); + + future.join(); // 等待异步操作完成,对于main线程的简单示例是必要的 + } catch (Exception e) { - listener.onError(e.getMessage()); + listener.onError("发生意外错误: " + e.getMessage()); + e.printStackTrace(); } }).start(); } public static void main(String[] args) { - String sql = FileUtil.readUtf8String(new File(PathKit.getRootClassPath()+"/XueYuan.sql")); - String prompt = "你是一个数据库SQL的血缘关系分析专家,我将提供SQL语句给你,帮我整理数据血缘关系,并且绘制HTML页面,以展示最终的可视化形式展现。"; - - callDeepSeekStream(prompt + "\n" + sql, new SSEListener() { + + String sqlContent = FileUtil.readString("XueYuan.sql", CharsetUtil.CHARSET_UTF_8); + String md5 = DigestUtils.md5Hex(sqlContent); + String outputPath = "C:\\" + md5 + ".html"; + + File outputFile = new File(outputPath); + if (outputFile.exists()) { + System.out.println("文件已存在,跳过生成:" + outputPath); + return; + } + String prompt = "你是一个数据库SQL的血缘关系分析专家,我将提供SQL语句给你,帮我整理数据血缘关系,并且绘制HTML页面,以展示最终的可视化展现。"; + + callDeepSeekStream(prompt + "\n" + sqlContent, new SSEListener() { @Override public void onData(String data) { - System.out.print(data); + System.out.print(data); // 实时打印 + System.out.flush(); // 确保立即刷新到控制台 } @Override @@ -128,11 +161,10 @@ public class CallDeepSeek { } }); - try { - Thread.sleep(30000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + // 移除 Thread.sleep(30000); + // 如果主线程需要等待SSE完成,可以考虑使用更优雅的同步机制, + // 例如 CountDownLatch,或者让 callDeepSeekStream 方法返回一个 Future。 + // 但对于简单的控制台流式输出演示,移除休眠即可观察到流式效果。 } public interface SSEListener { diff --git a/dsAi/src/main/resources/XueYuan.sql b/dsAi/src/main/resources/XueYuan.sql index a2af0cba..68290b93 100644 --- a/dsAi/src/main/resources/XueYuan.sql +++ b/dsAi/src/main/resources/XueYuan.sql @@ -1,2 +1,3 @@ -select tsl.person_id,tsl.person_name,tsl.mz,tdm.mz_name,tsl.xb,tdx.xb_name from t_sys_loginperson as tsl inner join t_dm_mz as tdm on tsl.mz=tdm.mz_id - inner join t_dm_xb as tdx on tsl.xb=tdx.xb_id \ No newline at end of file +select tsl.person_id,tsl.person_name,tsl.mz,tdm.mz_name,tsl.xb,tdx.xb_name from t_sys_loginperson as tsl +inner join t_dm_mz as tdm on tsl.mz=tdm.mz_id +inner join t_dm_xb as tdx on tsl.xb=tdx.xb_id; \ No newline at end of file diff --git a/dsAi/target/classes/XueYuan.sql b/dsAi/target/classes/XueYuan.sql index a2af0cba..68290b93 100644 --- a/dsAi/target/classes/XueYuan.sql +++ b/dsAi/target/classes/XueYuan.sql @@ -1,2 +1,3 @@ -select tsl.person_id,tsl.person_name,tsl.mz,tdm.mz_name,tsl.xb,tdx.xb_name from t_sys_loginperson as tsl inner join t_dm_mz as tdm on tsl.mz=tdm.mz_id - inner join t_dm_xb as tdx on tsl.xb=tdx.xb_id \ No newline at end of file +select tsl.person_id,tsl.person_name,tsl.mz,tdm.mz_name,tsl.xb,tdx.xb_name from t_sys_loginperson as tsl +inner join t_dm_mz as tdm on tsl.mz=tdm.mz_id +inner join t_dm_xb as tdx on tsl.xb=tdx.xb_id; \ No newline at end of file