diff --git a/src/main/java/com/dsideal/base/AI/Controller/YunNanAiController.java b/src/main/java/com/dsideal/base/AI/Controller/YunNanAiController.java index 77ec2453..515b7a55 100644 --- a/src/main/java/com/dsideal/base/AI/Controller/YunNanAiController.java +++ b/src/main/java/com/dsideal/base/AI/Controller/YunNanAiController.java @@ -27,12 +27,69 @@ public class YunNanAiController extends Controller { * http://10.10.21.20:9200/dsBase/ai/compareShiZhou?shiZhouA=文山州&shiZhouB=楚雄州 */ @Before({GET.class}) - public void compareShiZhou(String shiZhouA, String shiZhouB) throws InterruptedException { + public void compareShiZhou(String shiZhouA, String shiZhouB) throws Exception { + String content = ym.collectEducationData(new String[]{shiZhouA, shiZhouB}); + + //创建sse + final SseEmitter sseEmitter = new SseEmitter(getResponse()); + + // 发送开始分析的消息 + sseEmitter.sendMessage("data: 开始数据分析...\n\n"); + + // 调用DeepSeek API进行流式分析 + CallDeepSeek.callDeepSeekStream(content, new CallDeepSeek.SSEListener() { + @Override + public void onData(String data) { + // 将DeepSeek返回的数据实时推送给前端 + sseEmitter.sendMessage("data: " + data + "\n\n"); + } + + @Override + public void onComplete(String fullResponse) { + try { + // AI分析完成,开始生成Word文档 + sseEmitter.sendMessage("data: AI深度分析完成,正在生成报告文档...\n\n"); + + String filePath = PathKit.getWebRootPath() + "/upload/" + shiZhouA + "与" + shiZhouB + "_教育分析报告_" + + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".docx"; + WordGenerator.generateWordDocument(fullResponse, filePath, new String[]{shiZhouA, shiZhouB}); + + sseEmitter.sendMessage("data: 报告生成完成!文件路径:" + filePath + "\n\n"); + sseEmitter.sendMessage("data: [DONE]\n\n"); + + // 完成SSE连接 + sseEmitter.complete(); + } catch (Exception e) { + sseEmitter.sendMessage("data: 生成报告时发生错误:" + e.getMessage() + "\n\n"); + sseEmitter.sendMessage("data: [DONE]\n\n"); + sseEmitter.complete(); + } + } + + @Override + public void onError(String error) { + // 发送错误信息给前端 + sseEmitter.sendMessage("data: 调用DeepSeek API异常:" + error + "\n\n"); + sseEmitter.sendMessage("data: [DONE]\n\n"); + sseEmitter.complete(); + } + }); + + //锁住等待子线程推送完成 + sseEmitter.waiting(100); + renderNull(); + } + + /** + * 主线程里 + * 测试本地发送文本打字机 + */ + public void sse1() throws InterruptedException { + String msg = "111 222 333 444 555 666 777"; //创建sse SseEmitter sseEmitter = new SseEmitter(getResponse()); //主线程里拿到数据推送消息 - String msg = "111 222 333 444 555 666 777"; - String[] datas = msg.split(" "); + String[] datas = msg.split(""); for (String data : datas) { //推送 sseEmitter.sendMessage(data); @@ -47,28 +104,26 @@ public class YunNanAiController extends Controller { /** * 异步子线程模拟 * 测试本地发送文本打字机 - * http://10.10.21.20:9200/dsBase/ai/sse2 + * http://10.10.21.20:9200/dsBase/ai/sse2 */ - public void sse2(){ + public void sse2() { //创建sse final SseEmitter sseEmitter = new SseEmitter(getResponse()); String msg = "111 222 333 444 555 666 777"; //模拟chatgptapi 异步调用返回 - new Thread(new Runnable() { - public void run() { - String[] datas = msg.split(""); - for(String data:datas){ - //推送 异步子线程里推送数据给客户端 - sseEmitter.sendMessage(data); - try { - Thread.sleep(50); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + new Thread(() -> { + String[] datas = msg.split(""); + for (String data : datas) { + //推送 异步子线程里推送数据给客户端 + sseEmitter.sendMessage(data); + try { + Thread.sleep(50); + } catch (InterruptedException e) { + throw new RuntimeException(e); } - //完成sse 告知主线程已经完成 - sseEmitter.complete(); } + //完成sse 告知主线程已经完成 + sseEmitter.complete(); }).start(); //锁住等待子线程推送完成 sseEmitter.waiting(100); diff --git a/src/main/java/com/dsideal/base/AI/Generator/WordGenerator.java b/src/main/java/com/dsideal/base/AI/Generator/WordGenerator.java index 6df770ee..e98fbadc 100644 --- a/src/main/java/com/dsideal/base/AI/Generator/WordGenerator.java +++ b/src/main/java/com/dsideal/base/AI/Generator/WordGenerator.java @@ -15,27 +15,16 @@ import java.util.Date; */ public class WordGenerator { - // 指定保存目录 - private static final String SAVE_DIRECTORY = "D:\\dsWork\\YunNanDsBase\\WebRoot\\upload"; - + /** * 生成Word分析报告 * @param analysisResult AI分析结果 * @param fileName 文件名(不包含路径) * @param regions 对比地区 - * @return 完整的文件路径 * @throws Exception 文件操作异常 */ - public static String generateWordDocument(String analysisResult, String fileName, String[] regions) throws Exception { - // 确保保存目录存在 - File saveDir = new File(SAVE_DIRECTORY); - if (!saveDir.exists()) { - saveDir.mkdirs(); - } - - + public static void generateWordDocument(String analysisResult, String fileName, String[] regions) throws Exception { XWPFDocument document = new XWPFDocument(); - try { // 动态生成标题 String reportTitle = generateReportTitle(regions); @@ -56,8 +45,6 @@ public class WordGenerator { try (FileOutputStream out = new FileOutputStream(fileName)) { document.write(out); } - - return fileName; } finally { document.close(); diff --git a/src/main/java/com/dsideal/base/AI/Model/YunNanModel.java b/src/main/java/com/dsideal/base/AI/Model/YunNanModel.java index 0bc33893..a4ecbb61 100644 --- a/src/main/java/com/dsideal/base/AI/Model/YunNanModel.java +++ b/src/main/java/com/dsideal/base/AI/Model/YunNanModel.java @@ -114,8 +114,8 @@ public class YunNanModel { // 生成Word文档 String wordOutputPath = path + "/" + regionName + "_教育分析报告_" + timestamp + ".docx"; - String wordFilePath = WordGenerator.generateWordDocument(analysisResult, wordOutputPath, regions); - System.out.println("Word文档生成完成: " + wordFilePath); + WordGenerator.generateWordDocument(analysisResult, wordOutputPath, regions); + System.out.println("Word文档生成完成: " + wordOutputPath); // 生成HTML报告 // String htmlOutputPath = path + "/" + regionName + "_教育分析报告_" + timestamp + ".html";