我对接讯飞的ppt生成,整个对接流程非常简单,我这里是把他接入到系统中所以业务代码隐藏了部分
1.下载相关demo文档进行参考
2.根据自己的业务写代码
java
public static final String appid = ""; //这里填写APPID
public static final String apiSecret = ""; //这里填写Secret
public static final String apiKey = ""; //这里填写Key
@Value("${file.upload}")
private String filePath;
public void getPPT(AiSetDto aiSetDto, HttpServletRequest request, HttpServletResponse response) throws Exception {
AsyncContext asyncContext = request.startAsync(request, response);
asyncContext.setTimeout(0); // 设置超时时间为0,表示无限期等待
long timestamp = System.currentTimeMillis() / 1000;
String ts = String.valueOf(timestamp);
ApiAuthAlgorithm auth = new ApiAuthAlgorithm();
String signature = auth.getSignature(appid, apiSecret, timestamp);
// 建立链接
ApiClient client = new ApiClient("https://zwapi.xfyun.cn/api/ppt/v2");
asyncContext.start(() -> {
try (OutputStream outputStream = response.getOutputStream()) {
//用户输入的内容
String content = aiSetDto.getMessages().get(aiSetDto.getMessages().size() - 1).getContent();
String resp;
if (content.length() < 200) {//小于200字,通过大纲生成。
//用户输入的字太少就根据内容生成大纲在生成PPT
String outlineResp = client.createOutline(appid, ts, signature, content);
System.out.println("大纲" + outlineResp);
XFPPTResponseDto outlineResponse = JSON.parseObject(outlineResp, XFPPTResponseDto.class);
String outline = outlineResponse.getData().getOutline();
//PPT生成 (通过大纲生成PPT)
resp = client.createPptByOutline(appid, ts, signature, outline);
} else {
//PPT生成 (直接生成PPT)
resp = client.createPptByOutline(appid, ts, signature, content);
}
System.out.println("ppt返回信息" + resp);
// 解析返回结果
XFPPTResponseDto pptResponse = JSON.parseObject(resp, XFPPTResponseDto.class);
String sid = pptResponse.getData().getSid();
System.out.println("sid=" + sid);//sid用于获取下载连接
// 检查进度
String progressResult = client.checkProgress(appid, ts, signature, sid);
XFPPTURLDto urlDto = JSON.parseObject(progressResult, XFPPTURLDto.class);
if (!"成功".equals(urlDto.getDesc())) { // 生成失败
outputStream.write(urlDto.getDesc().getBytes(StandardCharsets.UTF_8));
outputStream.flush();
return;
}
while ("building".equals(urlDto.getData().getPptStatus())) {//加载完成后出来
if (isStopped.get()) { // 如果用户停止生成
break;
}
Thread.sleep(3000); //注:该接口设置限流,三秒访问一次 (因为是异步里面所以让它等应该没事)
progressResult = client.checkProgress(appid, ts, signature, sid);
double v = CommonUtil.calculateCompletionPercentage(urlDto.getData().getTotalPages(), urlDto.getData().getDonePages());//计算百分比
// System.out.println("生成进度:" + v + "%");
outputStream.write(("生成进度:" + v + "%").getBytes(StandardCharsets.UTF_8));
outputStream.flush();
urlDto = JSON.parseObject(progressResult, XFPPTURLDto.class);
}
if (isStopped.get()) { // 如果用户停止生成
outputStream.write("用户已停止生成".getBytes(StandardCharsets.UTF_8));
outputStream.flush();
return;
}
if ("build_failed".equals(urlDto.getData().getPptStatus())) {
outputStream.write("PPT生成失败".getBytes(StandardCharsets.UTF_8));
outputStream.flush();
return;
}
System.out.println(progressResult);
String pptUrl = urlDto.getData().getPptUrl();
String savePath = filePath + "generate";//生成ppt路径
String fileName = CommonUtil.GenerateRandomName() + ".ppt";//生成ppt名称
String saveFilePath = savePath + File.separator + fileName;
try (InputStream in = new URL(pptUrl).openStream()) {
Files.copy(in, Paths.get(saveFilePath), StandardCopyOption.REPLACE_EXISTING);
System.out.println("文件成功下载到:" + saveFilePath);
outputStream.write(("generate/" + fileName).getBytes(StandardCharsets.UTF_8));
outputStream.flush();
} catch (Exception e) {
outputStream.write("PPT传输异常".getBytes(StandardCharsets.UTF_8));
outputStream.flush();
System.err.println("下载过程中出现错误: " + e.getMessage());
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
asyncContext.complete();
StopGeneratingUtil.remove(requestId); // 移除停止标志
}
});
}
计算百分比方法
java
/**
* 计算完成百分比
*
* @param totalPages 总页数
* @param donePages 已完成页数
* @return 完成百分比
*/
public static double calculateCompletionPercentage(int totalPages, int donePages) {
if (totalPages == 0) {
return 0.0;
}
double percentage = ((double) donePages / totalPages) * 100;
// 使用 BigDecimal 设置保留两位小数并四舍五入
BigDecimal bd = new BigDecimal(percentage);
bd = bd.setScale(2, RoundingMode.HALF_UP); // 四舍五入到两位小数
return bd.doubleValue();
}
添加讯飞的两个工具类
java
import org.apache.hc.client5.http.utils.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class ApiAuthAlgorithm {
/**
* Gets the signature for the given appId and secret.
*
* @param appId The appId used as a key for the signature.
* @param apiSecret The secret key used for the signature.
* @param ts The timestamp.
* @return The generated signature.
*/
public String getSignature(String appId, String apiSecret, long ts) {
try {
String auth = md5(appId + ts);
return hmacSHA1Encrypt(auth, apiSecret);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
// Log the exception for debugging
e.printStackTrace();
return null;
}
}
/**
* HMAC SHA1 encryption.
*
* @param encryptText The text to be encrypted.
* @param encryptKey The encryption key.
* @return The encrypted string.
* @throws NoSuchAlgorithmException If the algorithm is not available.
* @throws InvalidKeyException If the key is invalid.
*/
private String hmacSHA1Encrypt(String encryptText, String encryptKey)
throws NoSuchAlgorithmException, InvalidKeyException {
SecretKeySpec keySpec = new SecretKeySpec(
encryptKey.getBytes(StandardCharsets.UTF_8), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(keySpec);
byte[] result = mac.doFinal(encryptText.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(result);
}
/**
* Generates MD5 hash of the given text.
*
* @param text The text to be hashed.
* @return The MD5 hash of the text.
* @throws NoSuchAlgorithmException If the MD5 algorithm is not available.
*/
private String md5(String text) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(text.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
java
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class ApiClient {
private static final String MEDIA_TYPE_JSON = "application/json; charset=utf-8";
private final static OkHttpClient client = new OkHttpClient().newBuilder()
.connectionPool(new ConnectionPool(100, 5, TimeUnit.MINUTES))
.readTimeout(60 * 10, TimeUnit.SECONDS)
.build();
private static final String ERROR_MESSAGE = "Unexpected code: ";
private final String baseUrl;
public ApiClient(String baseUrl) {
this.baseUrl = baseUrl;
}
public String getTemplateList(String appId, String timestamp, String signature) throws IOException {
validateParameters(appId, timestamp, signature);
//注意:请求体不能为空,至少有一项
JSONObject jsonObject = new JSONObject();
jsonObject.put("style", "商务");
jsonObject.put("pageSize", "10");
RequestBody body = RequestBody.create(jsonObject.toString(), MediaType.get(MEDIA_TYPE_JSON));
Request request = buildPostRequest(baseUrl + "/template/list", appId, timestamp, signature, body);
return executeRequest(request);
}
public String createOutline(String appId, String timestamp, String signature, String query) throws IOException {
validateParameters(appId, timestamp, signature, query);
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("query", query);
RequestBody body = builder.build();
Request request = buildPostRequest(baseUrl + "/createOutline", appId, timestamp, signature, body);
return executeRequest(request);
}
public String createOutlineByDoc(String appId, String timestamp, String signature, File file) throws IOException {
validateParameters(appId, timestamp, signature);
MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM);
try {
body.addFormDataPart("file", file.getName(), RequestBody.create(null, file));
body.addFormDataPart("fileName", file.getName());
} catch (Exception e) {
e.printStackTrace();
}
RequestBody requestBody = body.build();
Request request = new Request.Builder()
.url(baseUrl + "/createOutlineByDoc")
.addHeader("appId", appId)
.addHeader("timestamp", timestamp)
.addHeader("signature", signature)
//.addHeader("Content-Type", "multipart/form-data")
.post(requestBody)
.build();
return executeRequest(request);
}
public String create(String appId, String timestamp, String signature,File file) throws IOException {
validateParameters(appId, timestamp, signature);
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse("multipart/form-data"), file));
builder.addFormDataPart("fileName", file.getName());
RequestBody body = builder.build();
Request request = buildPostRequest(baseUrl + "/create", appId, timestamp, signature, body);
return executeRequest(request);
}
public String createPptByOutline(String appId, String ts, String signature,String outline) throws IOException {
validateParameters(appId, ts, signature);
JSONObject jsonObject = new JSONObject();
JSONObject outlineJson = JSONObject.parseObject(outline);
jsonObject.put("outline", outlineJson);
jsonObject.put("query", "test");
RequestBody body = RequestBody.create(jsonObject.toString(), MediaType.get(MEDIA_TYPE_JSON));
Request request = buildPostRequest(baseUrl + "/createPptByOutline", appId, ts, signature, body);
return executeRequest(request);
}
public String checkProgress(String appId, String timestamp, String signature, String sid) throws IOException {
validateParameters(appId, timestamp, signature, sid);
HttpUrl url = HttpUrl.parse(baseUrl+"/progress").newBuilder()
.addQueryParameter("sid", sid)
.build();
Request request = buildGetRequest(url.toString(), appId, timestamp, signature);
return executeRequest(request);
}
private Request buildPostRequest(String url, String appId, String timestamp, String signature, RequestBody body) {
return new Request.Builder()
.url(url)
.addHeader("appId", appId)
.addHeader("timestamp", timestamp)
.addHeader("signature", signature)
.post(body)
.build();
}
private Request buildGetRequest(String url, String appId, String timestamp, String signature) {
return new Request.Builder()
.url(url)
.addHeader("appId", appId)
.addHeader("timestamp", timestamp)
.addHeader("signature", signature)
.get()
.build();
}
private String executeRequest(Request request) throws IOException {
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
System.out.println(response.body().string());
throw new IOException(ERROR_MESSAGE + response);
}
return response.body().string();
}
}
private void validateParameters(String... params) {
for (String param : params) {
if (param == null || param.isEmpty()) {
throw new IllegalArgumentException("Parameter cannot be null or empty");
}
}
}
}