【功能新增】AI:对接文多多 v2 接口

This commit is contained in:
xiaoxin 2025-03-15 22:38:09 +08:00
parent ea1d9f0075
commit a82abed2b5
1 changed files with 217 additions and 293 deletions

View File

@ -1,17 +1,26 @@
package cn.iocoder.yudao.framework.ai.core.model.wenduoduo.api;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
@ -47,26 +56,24 @@ public class WddApi {
.build();
}
/**
* 创建API令牌
* 创建 token
*
* @param apiKey API密钥
* @param uid 用户ID
* @param limit 限制
* @return API令牌
* @param request 请求信息
* @return token
*/
public String createApiToken(String apiKey, String uid, Integer limit) {
CreateApiTokenRequest request = new CreateApiTokenRequest(uid, limit);
public String createApiToken(CreateTokenRequest request) {
return this.webClient.post()
.uri("/api/user/createApiToken")
.header("Api-Key", apiKey)
.body(Mono.just(request), CreateApiTokenRequest.class)
.header("Api-Key", request.apiKey)
.body(Mono.just(request), CreateTokenRequest.class)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.bodyToMono(ApiResponse.class)
.<String>handle((response, sink) -> {
if (response.code != 0) {
sink.error(new IllegalStateException("创建apiToken异常," + response.message));
sink.error(new IllegalStateException("创建 token 异常," + response.message));
return;
}
sink.next(response.data.get("token").toString());
@ -74,259 +81,159 @@ public class WddApi {
.block();
}
/**
* 解析文件数据
* 创建任务
*
* @param apiToken API令牌
* @param content 内容
* @param fileUrl 文件URL
* @return 数据URL
* @param type 类型
* @param content 内容
* @param files 文件列表
* @return 任务ID
*/
public String parseFileData(String apiToken, String content, String fileUrl) {
ParseFileDataRequest request = new ParseFileDataRequest(content, fileUrl);
public ApiResponse createTask(String token, Integer type, String content, List<MultipartFile> files) {
MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
formData.add("type", type);
if (content != null) {
formData.add("content", content);
}
if (files != null) {
for (MultipartFile file : files) {
formData.add("file", file.getResource());
}
}
return this.webClient.post()
.uri("/api/ppt/parseFileData")
.header("token", apiToken)
.body(Mono.just(request), ParseFileDataRequest.class)
.uri("/api/ppt/v2/createTask")
.header("token", token)
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(formData))
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(formData))
.bodyToMono(ApiResponse.class)
.<String>handle((response, sink) -> {
if (response.code != 0) {
sink.error(new IllegalStateException("解析文件或内容异常," + response.message));
return;
}
sink.next(response.data.get("dataUrl").toString());
})
.block();
}
/**
* 生成大纲
* 获取生成选项
*
* @param apiToken API令牌
* @param subject 主题
* @param dataUrl 数据URL
* @param prompt 提示词
* @return 大纲内容
* @param lang 语种
* @return 生成选项
*/
public String generateOutline(String apiToken, String subject, String dataUrl, String prompt) {
GenerateOutlineRequest request = new GenerateOutlineRequest(subject, dataUrl, prompt);
return this.webClient.post()
.uri("/api/ppt/generateOutline")
.header("token", apiToken)
.body(Mono.just(request), GenerateOutlineRequest.class)
public Map<String, Object> getOptions(String lang) {
String uri = "/api/ppt/v2/options";
if (lang != null) {
uri += "?lang=" + lang;
}
return this.webClient.get()
.uri(uri)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.bodyToMono(String.class)
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(null))
.bodyToMono(new ParameterizedTypeReference<ApiResponse>() {
})
.<Map<String, Object>>handle((response, sink) -> {
if (response.code != 0) {
sink.error(new IllegalStateException("获取生成选项异常," + response.message));
return;
}
sink.next(response.data);
})
.block();
}
/**
* 生成大纲内容
*
* @param apiToken API令牌
* @param outlineMarkdown 大纲Markdown
* @param dataUrl 数据URL
* @param prompt 提示词
* @return 大纲内容
* @return 大纲内容流
*/
public String generateContent(String apiToken, String outlineMarkdown, String dataUrl, String prompt) {
GenerateContentRequest request = new GenerateContentRequest(outlineMarkdown, dataUrl, prompt);
public Flux<Map<String, Object>> generateOutlineContent(String token, GenerateOutlineRequest request) {
return this.webClient.post()
.uri("/api/ppt/generateContent")
.header("token", apiToken)
.body(Mono.just(request), GenerateContentRequest.class)
.uri("/api/ppt/v2/generateContent")
.header("token", token)
.body(Mono.just(request), GenerateOutlineRequest.class)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.bodyToMono(String.class)
.block();
.bodyToFlux(new ParameterizedTypeReference<>() {
});
}
/**
* 异步生成大纲内容
* 修改大纲内容
*
* @param apiToken API令牌
* @param outlineMarkdown 大纲Markdown
* @param dataUrl 数据URL
* @param templateId 模板ID
* @param prompt 提示词
* @return 大纲内容和PPT ID
* @param id 任务ID
* @param markdown 大纲内容markdown
* @param question 用户修改建议
* @return 大纲内容流
*/
public Map<String, Object> asyncGenerateContent(String apiToken, String outlineMarkdown, String dataUrl, String templateId, String prompt) {
AsyncGenerateContentRequest request = new AsyncGenerateContentRequest(outlineMarkdown, dataUrl, templateId, prompt);
public Flux<Map<String, Object>> updateOutlineContent(String token, String id, String markdown, String question) {
UpdateOutlineRequest request = new UpdateOutlineRequest(id, markdown, question);
return this.webClient.post()
.uri("/api/ppt/generateContent")
.header("token", apiToken)
.body(Mono.just(request), AsyncGenerateContentRequest.class)
.uri("/api/ppt/v2/updateContent")
.header("token", token)
.body(Mono.just(request), UpdateOutlineRequest.class)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {
})
.block();
.bodyToFlux(new ParameterizedTypeReference<Map<String, Object>>() {
});
}
/**
* 随机获取一个模板ID
*
* @param apiToken API令牌
* @return 模板ID
*/
public String randomOneTemplateId(String apiToken) {
RandomTemplateRequest request = new RandomTemplateRequest(1, new TemplateFilter(1));
return this.webClient.post()
.uri("/api/ppt/randomTemplates")
.header("token", apiToken)
.body(Mono.just(request), RandomTemplateRequest.class)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.bodyToMono(ApiResponse.class)
.<String>handle((response, sink) -> {
if (response.code != 0) {
sink.error(new IllegalStateException("获取模板异常," + response.message));
return;
}
sink.next(((Map<String, Object>) ((Object[]) response.data.get("data"))[0]).get("id").toString());
})
.block();
}
/**
* 生成PPT
*
* @param apiToken API令牌
* @param templateId 模板ID
* @param markdown Markdown内容
* @param pptxProperty PPT属性
* @return PPT信息
*/
public Map<String, Object> generatePptx(String apiToken, String templateId, String markdown, boolean pptxProperty) {
GeneratePptxRequest request = new GeneratePptxRequest(templateId, markdown, pptxProperty);
return this.webClient.post()
.uri("/api/ppt/generatePptx")
.header("token", apiToken)
.body(Mono.just(request), GeneratePptxRequest.class)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.bodyToMono(ApiResponse.class)
.<Map<String, Object>>handle((response, sink) -> {
if (response.code != 0) {
sink.error(new IllegalStateException("生成PPT异常" + response.message));
return;
}
sink.next((Map<String, Object>) response.data.get("pptInfo"));
})
.block();
}
/**
* 下载PPT
*
* @param apiToken API令牌
* @param id PPT ID
* @return 下载信息
*/
public Map<String, Object> downloadPptx(String apiToken, String id) {
DownloadPptxRequest request = new DownloadPptxRequest(id);
return this.webClient.post()
.uri("/api/ppt/downloadPptx")
.header("token", apiToken)
.body(Mono.just(request), DownloadPptxRequest.class)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.bodyToMono(ApiResponse.class)
.<Map<String, Object>>handle((response, sink) -> {
if (response.code != 0) {
sink.error(new IllegalStateException("下载PPT异常" + response.message));
return;
}
sink.next(response.data);
})
.block();
}
/**
* 直接生成PPT
*
* @param apiToken API令牌
* @param templateId 模板ID
* @param subject 主题
* @param dataUrl 数据URL
* @param prompt 提示词
* @param pptxProperty PPT属性
* @return PPT信息
*/
public Map<String, Object> directGeneratePptx(String apiToken, String templateId, String subject, String dataUrl, String prompt, boolean pptxProperty) {
DirectGeneratePptxRequest request = new DirectGeneratePptxRequest(false, templateId, subject, dataUrl, prompt, pptxProperty);
return this.webClient.post()
.uri("/api/ppt/directGeneratePptx")
.header("token", apiToken)
.body(Mono.just(request), DirectGeneratePptxRequest.class)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.bodyToMono(ApiResponse.class)
.<Map<String, Object>>handle((response, sink) -> {
if (response.code != 0) {
sink.error(new IllegalStateException("生成PPT异常" + response.message));
return;
}
sink.next((Map<String, Object>) response.data.get("pptInfo"));
})
.block();
}
/**
* 查询所有PPT列表
*
* @param apiToken API令牌
* @param body 请求体
* @return PPT列表
*/
public Map<String, Object> listAllPptx(String apiToken, String body) {
return this.webClient.post()
.uri("/api/ppt/listAllPptx")
.header("token", apiToken)
.bodyValue(body)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(body))
.bodyToMono(ApiResponse.class)
.<Map<String, Object>>handle((response, sink) -> {
if (response.code != 0) {
sink.error(new IllegalStateException("查询所有PPT列表异常" + response.message));
return;
}
sink.next(response.data);
})
.block();
}
/**
* 分页查询PPT模板
*
* @param apiToken API令牌
* @param body 请求体
* @param token 令牌
* @param request 请求体
* @return 模板列表
*/
public Map<String, Object> getPptTemplates(String apiToken, String body) {
public PagePptTemplateInfo getPptTemplatePage(String token, TemplateQueryRequest request) {
return this.webClient.post()
.uri("/api/ppt/templates")
.header("token", apiToken)
.bodyValue(body)
.header("token", token)
.bodyValue(request)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(body))
.bodyToMono(ApiResponse.class)
.<Map<String, Object>>handle((response, sink) -> {
if (response.code != 0) {
sink.error(new IllegalStateException("分页查询PPT模板异常" + response.message));
return;
}
sink.next(response.data);
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.bodyToMono(new ParameterizedTypeReference<PagePptTemplateInfo>() {
})
.block();
}
/**
* API响应
* 生成PPT
*
* @return PPT信息
*/
public PptInfo generatePptx(String token, GeneratePptxRequest request) {
return this.webClient.post()
.uri("/api/ppt/v2/generatePptx")
.header("token", token)
.body(Mono.just(request), GeneratePptxRequest.class)
.retrieve()
.onStatus(STATUS_PREDICATE, EXCEPTION_FUNCTION.apply(request))
.bodyToMono(ApiResponse.class)
.<PptInfo>handle((response, sink) -> {
if (response.code != 0) {
sink.error(new IllegalStateException("生成 PPT 异常," + response.message));
return;
}
sink.next(Objects.requireNonNull(JsonUtils.parseObject(JsonUtils.toJsonString(response.data.get("pptInfo")), PptInfo.class)));
})
.block();
}
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record CreateTokenRequest(
String apiKey,
String uid,
Integer limit
) {
public CreateTokenRequest(String apiKey) {
this(apiKey, null, null);
}
}
/**
* API 通用响应
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record ApiResponse(
@ -337,33 +244,13 @@ public class WddApi {
}
/**
* 创建API令牌请求
* 创建任务
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record CreateApiTokenRequest(
String uid,
Integer limit
) {
}
/**
* 解析文件数据请求
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record ParseFileDataRequest(
public record CreateTaskRequest(
Integer type,
String content,
String fileUrl
) {
}
/**
* 生成大纲请求
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record GenerateOutlineRequest(
String subject,
String dataUrl,
String prompt
List<MultipartFile> files
) {
}
@ -371,45 +258,24 @@ public class WddApi {
* 生成大纲内容请求
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record GenerateContentRequest(
String outlineMarkdown,
String dataUrl,
public record GenerateOutlineRequest(
String id,
String length,
String scene,
String audience,
String lang,
String prompt
) {
}
/**
* 异步生成大纲内容请求
* 修改大纲内容请求
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record AsyncGenerateContentRequest(
String outlineMarkdown,
String dataUrl,
String templateId,
String prompt,
@JsonProperty("asyncGenPptx") boolean asyncGenPptx
) {
public AsyncGenerateContentRequest(String outlineMarkdown, String dataUrl, String templateId, String prompt) {
this(outlineMarkdown, dataUrl, templateId, prompt, true);
}
}
/**
* 随机模板请求
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record RandomTemplateRequest(
Integer size,
TemplateFilter filters
) {
}
/**
* 模板过滤器
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record TemplateFilter(
Integer type
public record UpdateOutlineRequest(
String id,
String markdown,
String question
) {
}
@ -418,32 +284,90 @@ public class WddApi {
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record GeneratePptxRequest(
String id,
String templateId,
@JsonProperty("outlineContentMarkdown") String outlineContentMarkdown,
boolean pptxProperty
String markdown
) {
}
/**
* 下载PPT请求
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record DownloadPptxRequest(
String id
) {
}
/**
* 直接生成PPT请求
*/
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record DirectGeneratePptxRequest(
boolean stream,
String templateId,
public record PptInfo(
String id,
String name,
String subject,
String dataUrl,
String prompt,
boolean pptxProperty
String coverUrl,
String fileUrl,
String templateId,
String pptxProperty,
String userId,
String userName,
int companyId,
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime updateTime,
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime createTime,
String createUser,
String updateUser
) {
}
}
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record TemplateQueryRequest(
int page,
int size,
Filter filters
) {
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record Filter(
int type,
String category,
String style,
String themeColor
) {
}
}
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record PagePptTemplateInfo(
List<PptTemplateInfo> data,
String total
) {
}
@JsonInclude(value = JsonInclude.Include.NON_NULL)
public record PptTemplateInfo(
String id,
int type,
Integer subType,
String layout,
String category,
String style,
String themeColor,
String lang,
boolean animation,
String subject,
String coverUrl,
String fileUrl,
List<String> pageCoverUrls,
String pptxProperty,
int sort,
int num,
Integer imgNum,
int isDeleted,
String userId,
int companyId,
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime updateTime,
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
LocalDateTime createTime,
String createUser,
String updateUser
) {
}
}