main
HuangHai 1 month ago
parent 8081e2004a
commit 27ca716645

@ -2,9 +2,11 @@ package com.dsideal.base.AI.Controller;
import com.dsideal.base.AI.Generator.WordGenerator;
import com.dsideal.base.AI.Generator.HtmlGenerator;
import com.dsideal.base.AI.Generator.PptGenerator;
import com.dsideal.base.AI.Model.YunNanModel;
import com.dsideal.base.Util.CallDeepSeek;
import com.dsideal.base.Util.CommonUtil;
import com.dsideal.base.Util.PptAIKit;
import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.ext.interceptor.GET;
@ -144,4 +146,73 @@ public class AiController extends Controller {
sseEmitter.waiting(100);
renderNull();
}
/**
* PPT
*
* @param shiZhouA A
* @param shiZhouB B
* http://10.10.21.20:9200/dsBase/ai/compareShiZhouPpt?shiZhouA=文山州&shiZhouB=楚雄州
*/
@Before({GET.class})
public void compareShiZhouPpt(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");
// 构建PPT提示词直接生成PPT大纲
String regionName = shiZhouA + "与" + shiZhouB;
String pptPrompt = PptGenerator.buildPptPrompt(content, regionName);
// 调用DeepSeek API生成PPT大纲然后直接生成PPT文件
CallDeepSeek.callDeepSeekStream(pptPrompt, new CallDeepSeek.SSEListener() {
@Override
public void onData(String data) {
// 实时推送PPT大纲生成进度
sseEmitter.sendMessage("data: " + data + "\n\n");
}
@Override
public void onComplete(String fullResponse) {
try {
// PPT大纲生成完成开始生成PPT文件
sseEmitter.sendMessage("data: PPT大纲生成完成正在生成PPT文件...\n\n");
// 直接使用生成的大纲调用PPT生成API不再调用DeepSeek
String token = PptAIKit.createApiToken("dsideal", 1000);
String pptFileUrl = PptGenerator.generatePptFromMarkdown(fullResponse, token);
if (pptFileUrl != null && !pptFileUrl.trim().isEmpty()) {
sseEmitter.sendMessage("data: PPT生成完成文件下载地址" + pptFileUrl + "\n\n");
} else {
sseEmitter.sendMessage("data: PPT生成失败请检查API令牌或网络连接\n\n");
}
sseEmitter.sendMessage("data: [DONE]\n\n");
// 完成SSE连接
sseEmitter.complete();
} catch (Exception e) {
sseEmitter.sendMessage("data: 生成PPT时发生错误" + 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();
}
}

@ -4,12 +4,9 @@ import com.alibaba.fastjson.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* PPT - PPT稿
@ -17,43 +14,47 @@ import java.util.Date;
public class PptGenerator {
private static final String PPT_API_URL = "https://open.docmee.cn/api/ppt/generatePptx";
// 指定保存目录
private static final String SAVE_DIRECTORY = "D:\\dsWork\\YunNanDsBase\\WebRoot\\upload";
/**
* PPT稿
* @param analysisContent Word
* @param regions
* @param token API访
* @return PPT
* PPT
* @param dataContent
* @param regionName
* @return PPT
*/
public static String generatePptPresentation(String analysisContent, String[] regions, String token) {
try {
// 确保保存目录存在
File saveDir = new File(SAVE_DIRECTORY);
if (!saveDir.exists()) {
saveDir.mkdirs();
public static String buildPptPrompt(String dataContent, String regionName) {
return String.format(
"请根据以下数据内容生成一个适合制作PPT的大纲要求\n\n" +
"1. 生成标准的Markdown格式大纲用于PPT制作\n" +
"2. 大纲应该包含清晰的章节结构,每个章节都有明确的标题\n" +
"3. 每个章节下应该有3-5个要点适合在PPT幻灯片中展示\n" +
"4. 重点突出数据对比和分析结论\n" +
"5. 大纲应该逻辑清晰,便于制作专业的演示文稿\n" +
"6. 包含以下主要部分:\n" +
" - 概述与背景\n" +
" - 数据对比分析\n" +
" - 关键发现\n" +
" - 结论与建议\n\n" +
"地区:%s\n\n" +
"数据内容:\n%s",
regionName, dataContent
);
}
// 将分析内容转换为Markdown格式
String markdownContent = convertToMarkdown(analysisContent, regions);
// 调用docmee API生成PPT
/**
* MarkdownPPTDeepSeek
* @param markdownContent PPTMarkdownDeepSeek
* @param token API访
* @return PPTURL
*/
public static String generatePptFromMarkdown(String markdownContent, String token) {
try {
// 直接使用传入的markdown内容调用docmee API生成PPT
String pptFileUrl = callDocmeeApi(markdownContent, token);
if (pptFileUrl != null && !pptFileUrl.trim().isEmpty()) {
System.out.println("PPT生成成功");
System.out.println("PPT文件下载地址: " + pptFileUrl);
// 下载PPT文件到本地
String localFilePath = downloadPptFile(pptFileUrl, regions);
if (localFilePath != null) {
System.out.println("PPT文件已下载到: " + localFilePath);
return localFilePath;
} else {
System.err.println("PPT文件下载失败");
return null;
}
return pptFileUrl;
} else {
System.err.println("PPT生成失败");
return null;
@ -67,117 +68,16 @@ public class PptGenerator {
}
/**
* PPT
* @param fileUrl PPTURL
* @param regions
* @return
*/
private static String downloadPptFile(String fileUrl, String[] regions) {
try {
// 生成本地文件名
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fileName = generateReportTitle(regions).replace("教育资源配置对比分析报告", "教育资源对比分析报告") + "_" + timestamp + ".pptx";
String localFilePath = SAVE_DIRECTORY + File.separator + fileName;
// 下载文件
URL url = new URL(fileUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(30000); // 30秒连接超时
connection.setReadTimeout(60000); // 60秒读取超时
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
try (InputStream inputStream = connection.getInputStream();
FileOutputStream outputStream = new FileOutputStream(localFilePath)) {
byte[] buffer = new byte[4096];
int bytesRead;
long totalBytesRead = 0;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
}
System.out.println("文件下载完成,大小: " + totalBytesRead + " 字节");
return localFilePath;
}
} else {
System.err.println("下载失败HTTP状态码: " + responseCode);
return null;
}
} catch (Exception e) {
System.err.println("下载PPT文件时出错: " + e.getMessage());
e.printStackTrace();
return null;
}
}
/**
* Markdown
* @param analysisContent
* PPT稿
* @param markdownContent PPTMarkdownDeepSeek
* @param regions
* @return Markdown
*/
private static String convertToMarkdown(String analysisContent, String[] regions) {
StringBuilder markdown = new StringBuilder();
// 添加标题
String title = generateReportTitle(regions);
markdown.append("# ").append(title).append("\n\n");
// 处理分析内容
String[] lines = analysisContent.split("\n");
for (String line : lines) {
if (line.trim().isEmpty()) {
markdown.append("\n");
} else if (isTitle(line)) {
// 根据标题级别添加Markdown标题
if (line.matches("^\\d+\\..+")) {
markdown.append("## ").append(line).append("\n\n");
} else if (line.matches("^\\d+\\.\\d+.+")) {
markdown.append("### ").append(line).append("\n\n");
} else if (line.matches("^\\d+\\.\\d+\\.\\d+.+")) {
markdown.append("#### ").append(line).append("\n\n");
} else {
markdown.append("## ").append(line).append("\n\n");
}
} else {
// 普通内容,处理列表项
if (line.trim().startsWith("-") || line.trim().startsWith("•")) {
markdown.append("- ").append(line.trim().substring(1).trim()).append("\n");
} else {
markdown.append(line).append("\n\n");
}
}
}
return markdown.toString();
}
/**
*
* @param token API访
* @return PPTURL
*/
private static String generateReportTitle(String[] regions) {
if (regions != null && regions.length >= 2) {
return String.join("与", regions) + "教育资源配置对比分析报告";
} else {
return "教育资源配置对比分析报告";
}
public static String generatePptPresentation(String markdownContent, String[] regions, String token) {
return generatePptFromMarkdown(markdownContent, token);
}
/**
*
*/
private static boolean isTitle(String line) {
return line.matches("^\\d+\\..+") ||
line.matches("^\\d+\\.\\d+.+") ||
line.matches("^\\d+\\.\\d+\\.\\d+.+") ||
line.trim().matches("^(执行摘要|数据概览|详细对比分析|问题识别|建议与对策|结论).*");
}
/**
* docmee APIPPT

Loading…
Cancel
Save