优化
This commit is contained in:
@@ -3,11 +3,13 @@ package cn.iocoder.yudao.module.tik.dify.controller;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.iocoder.yudao.module.tik.dify.service.DifyService;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyBenchmarkReqVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyChatReqVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyChatRespVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyConversationListRespVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyMessageListRespVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.ForecastRewriteReqVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.PromptAnalysisReqVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -51,6 +53,20 @@ public class AppDifyController {
|
||||
.map(CommonResult::success);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/benchmark/analyze", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
@Operation(summary = "对标分析(流式)")
|
||||
public Flux<CommonResult<DifyChatRespVO>> benchmarkAnalyzeStream(@Valid @RequestBody DifyBenchmarkReqVO reqVO) {
|
||||
return difyService.benchmarkAnalyzeStream(reqVO, getCurrentUserId())
|
||||
.map(CommonResult::success);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/prompt/analysis", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
@Operation(summary = "提示词分析(流式)")
|
||||
public Flux<CommonResult<DifyChatRespVO>> promptAnalysisStream(@Valid @RequestBody PromptAnalysisReqVO reqVO) {
|
||||
return difyService.promptAnalysisStream(reqVO, getCurrentUserId())
|
||||
.map(CommonResult::success);
|
||||
}
|
||||
|
||||
@GetMapping("/conversations")
|
||||
@Operation(summary = "获取会话列表")
|
||||
@Parameter(name = "agentId", description = "智能体ID", required = true)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package cn.iocoder.yudao.module.tik.dify.service;
|
||||
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyBenchmarkReqVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyChatReqVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.PromptAnalysisReqVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyChatRespVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyConversationListRespVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyMessageListRespVO;
|
||||
@@ -32,6 +34,24 @@ public interface DifyService {
|
||||
*/
|
||||
Flux<DifyChatRespVO> rewriteStream(ForecastRewriteReqVO reqVO, String userId);
|
||||
|
||||
/**
|
||||
* 对标分析(流式)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @param userId 用户ID
|
||||
* @return 流式响应
|
||||
*/
|
||||
Flux<DifyChatRespVO> benchmarkAnalyzeStream(DifyBenchmarkReqVO reqVO, String userId);
|
||||
|
||||
/**
|
||||
* 提示词分析(流式)
|
||||
*
|
||||
* @param reqVO 请求参数
|
||||
* @param userId 用户ID
|
||||
* @return 流式响应
|
||||
*/
|
||||
Flux<DifyChatRespVO> promptAnalysisStream(PromptAnalysisReqVO reqVO, String userId);
|
||||
|
||||
/**
|
||||
* 获取会话列表
|
||||
*
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package cn.iocoder.yudao.module.tik.dify.service;
|
||||
|
||||
import cn.iocoder.yudao.module.tik.dify.client.DifyClient;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyBenchmarkReqVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyChatReqVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.PromptAnalysisReqVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyChatRespVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyConversationListRespVO;
|
||||
import cn.iocoder.yudao.module.tik.dify.vo.DifyMessageListRespVO;
|
||||
@@ -181,10 +183,23 @@ public class DifyServiceImpl implements DifyService {
|
||||
String difyUserId = "user-" + userId;
|
||||
|
||||
return Mono.fromCallable(() -> {
|
||||
// 1. 获取智能体配置(通过 agentId 获取 systemPrompt)
|
||||
AiAgentDO agent = aiAgentService.getAiAgent(reqVO.getAgentId());
|
||||
if (agent == null) {
|
||||
throw new RuntimeException("智能体不存在");
|
||||
// 1. 获取系统提示词
|
||||
String systemPrompt;
|
||||
if (reqVO.getCustomSystemPrompt() != null && !reqVO.getCustomSystemPrompt().isEmpty()) {
|
||||
// 使用自定义系统提示词(用户风格)
|
||||
systemPrompt = reqVO.getCustomSystemPrompt();
|
||||
log.info("[rewriteStream] 使用自定义系统提示词,长度: {}", systemPrompt.length());
|
||||
} else if (reqVO.getAgentId() != null) {
|
||||
// 从智能体获取系统提示词
|
||||
AiAgentDO agent = aiAgentService.getAiAgent(reqVO.getAgentId());
|
||||
if (agent == null) {
|
||||
throw new RuntimeException("智能体不存在");
|
||||
}
|
||||
systemPrompt = agent.getSystemPrompt();
|
||||
log.info("[rewriteStream] 使用智能体系统提示词,agentId: {}, 长度: {}",
|
||||
reqVO.getAgentId(), systemPrompt != null ? systemPrompt.length() : 0);
|
||||
} else {
|
||||
throw new RuntimeException("必须提供 agentId 或 customSystemPrompt");
|
||||
}
|
||||
|
||||
// 2. 根据 modelType 获取对应的积分配置
|
||||
@@ -208,17 +223,14 @@ public class DifyServiceImpl implements DifyService {
|
||||
);
|
||||
pendingRecordId.set(recordId);
|
||||
|
||||
// 5. 构建 inputs 参数(使用 agent 的 systemPrompt)
|
||||
// 5. 构建 inputs 参数
|
||||
Map<String, Object> inputs = new HashMap<>();
|
||||
inputs.put("sysPrompt", agent.getSystemPrompt());
|
||||
inputs.put("sysPrompt", systemPrompt);
|
||||
inputs.put("userText", reqVO.getUserText());
|
||||
inputs.put("level", reqVO.getLevel());
|
||||
|
||||
// 调试日志
|
||||
log.info("[rewriteStream] 请求参数 - agentId: {}, modelType: {}", reqVO.getAgentId(), reqVO.getModelType());
|
||||
log.info("[rewriteStream] Agent信息 - id: {}, name: {}, systemPrompt长度: {}",
|
||||
agent.getId(), agent.getAgentName(),
|
||||
agent.getSystemPrompt() != null ? agent.getSystemPrompt().length() : 0);
|
||||
log.info("[rewriteStream] inputs参数 - userText长度: {}, level: {}",
|
||||
reqVO.getUserText() != null ? reqVO.getUserText().length() : 0,
|
||||
reqVO.getLevel());
|
||||
@@ -324,6 +336,323 @@ public class DifyServiceImpl implements DifyService {
|
||||
*/
|
||||
private record ForecastRewriteContext(Map<String, Object> inputs, String apiKey, Integer consumePoints) {}
|
||||
|
||||
@Override
|
||||
public Flux<DifyChatRespVO> benchmarkAnalyzeStream(DifyBenchmarkReqVO reqVO, String userId) {
|
||||
// 用于存储预扣记录ID
|
||||
AtomicLong pendingRecordId = new AtomicLong();
|
||||
// 用于存储会话ID
|
||||
AtomicReference<String> conversationIdRef = new AtomicReference<>("");
|
||||
// 用于存储 token 使用信息
|
||||
AtomicReference<DifyChatRespVO> tokenUsageRef = new AtomicReference<>();
|
||||
// Dify 用户标识(固定格式)
|
||||
String difyUserId = "user-" + userId;
|
||||
|
||||
return Mono.fromCallable(() -> {
|
||||
// 1. 获取积分配置
|
||||
AiServiceConfigDO config = pointsService.getConfig(
|
||||
AiPlatformEnum.DIFY.getPlatform(),
|
||||
AiModelTypeEnum.BENCHMARK_ANALYZE.getModelCode());
|
||||
|
||||
// 2. 预检积分
|
||||
pointsService.checkPoints(userId, config.getConsumePoints());
|
||||
|
||||
// 3. 创建预扣记录(带 serviceCode)
|
||||
Long recordId = pointsService.createPendingDeduct(
|
||||
userId,
|
||||
config.getConsumePoints(),
|
||||
"benchmark_analyze",
|
||||
String.valueOf(reqVO.getVideoCount()),
|
||||
config.getServiceCode()
|
||||
);
|
||||
pendingRecordId.set(recordId);
|
||||
|
||||
// 4. 构建对标分析提示词
|
||||
String benchmarkPrompt = buildBenchmarkPrompt(reqVO.getContent(), reqVO.getVideoCount());
|
||||
|
||||
log.info("[benchmarkAnalyzeStream] 请求参数 - videoCount: {}", reqVO.getVideoCount());
|
||||
log.info("[benchmarkAnalyzeStream] 提示词长度: {}", benchmarkPrompt.length());
|
||||
log.info("[benchmarkAnalyzeStream] API配置 - apiKey前缀: {}..., consumePoints: {}",
|
||||
config.getApiKey() != null && config.getApiKey().length() > 10
|
||||
? config.getApiKey().substring(0, 10) + "***"
|
||||
: "null",
|
||||
config.getConsumePoints());
|
||||
|
||||
// 5. 返回调用参数
|
||||
return new BenchmarkAnalyzeContext(benchmarkPrompt, config.getApiKey(), config.getConsumePoints());
|
||||
})
|
||||
.flatMapMany(context -> {
|
||||
// 6. 调用 Dify 流式 API
|
||||
return difyClient.chatStream(
|
||||
context.apiKey(),
|
||||
context.prompt(),
|
||||
null, // systemPrompt 为空,使用 Dify 工作流中的配置
|
||||
null, // conversationId 为空,新会话
|
||||
difyUserId
|
||||
)
|
||||
.doOnNext(resp -> {
|
||||
if (resp.getConversationId() != null) {
|
||||
conversationIdRef.set(resp.getConversationId());
|
||||
}
|
||||
// 捕获 token 使用信息
|
||||
if (resp.getTotalTokens() != null && resp.getTotalTokens() > 0) {
|
||||
tokenUsageRef.set(resp);
|
||||
}
|
||||
})
|
||||
// 7. 流结束时确认扣费(带 token)
|
||||
.doOnComplete(() -> {
|
||||
if (pendingRecordId.get() > 0) {
|
||||
try {
|
||||
DifyChatRespVO tokenUsage = tokenUsageRef.get();
|
||||
if (tokenUsage != null) {
|
||||
pointsService.confirmPendingDeductWithTokens(
|
||||
pendingRecordId.get(),
|
||||
tokenUsage.getInputTokens(),
|
||||
tokenUsage.getOutputTokens(),
|
||||
tokenUsage.getTotalTokens()
|
||||
);
|
||||
log.info("[benchmarkAnalyzeStream] 流结束,确认扣费(带token),记录ID: {}, tokens: {}",
|
||||
pendingRecordId.get(), tokenUsage.getTotalTokens());
|
||||
} else {
|
||||
pointsService.confirmPendingDeduct(pendingRecordId.get());
|
||||
log.info("[benchmarkAnalyzeStream] 流结束,确认扣费(无token),记录ID: {}", pendingRecordId.get());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[benchmarkAnalyzeStream] 确认扣费失败", e);
|
||||
}
|
||||
}
|
||||
})
|
||||
// 8. 流出错时取消预扣
|
||||
.doOnError(e -> {
|
||||
if (pendingRecordId.get() > 0) {
|
||||
try {
|
||||
pointsService.cancelPendingDeduct(pendingRecordId.get());
|
||||
log.info("[benchmarkAnalyzeStream] 流出错,取消预扣,记录ID: {}", pendingRecordId.get());
|
||||
} catch (Exception ex) {
|
||||
log.error("[benchmarkAnalyzeStream] 取消预扣失败", ex);
|
||||
}
|
||||
}
|
||||
})
|
||||
// 9. 用户取消时确认扣费(已消费的部分)
|
||||
.doOnCancel(() -> {
|
||||
if (pendingRecordId.get() > 0) {
|
||||
try {
|
||||
// 用户主动取消,仍然扣费(按最低消费)
|
||||
pointsService.confirmPendingDeduct(pendingRecordId.get());
|
||||
log.info("[benchmarkAnalyzeStream] 用户取消,确认扣费,记录ID: {}", pendingRecordId.get());
|
||||
} catch (Exception e) {
|
||||
log.error("[benchmarkAnalyzeStream] 用户取消后扣费失败", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
// 10. 在最后添加 done 事件
|
||||
.concatWith(Mono.defer(() -> {
|
||||
DifyChatRespVO tokenUsage = tokenUsageRef.get();
|
||||
if (tokenUsage != null) {
|
||||
return Mono.just(DifyChatRespVO.doneWithTokens(
|
||||
conversationIdRef.get(), null,
|
||||
tokenUsage.getInputTokens(),
|
||||
tokenUsage.getOutputTokens(),
|
||||
tokenUsage.getTotalTokens()
|
||||
));
|
||||
}
|
||||
return Mono.just(DifyChatRespVO.done(conversationIdRef.get(), null));
|
||||
}))
|
||||
.onErrorResume(e -> {
|
||||
log.error("[benchmarkAnalyzeStream] 对标分析异常", e);
|
||||
return Flux.just(DifyChatRespVO.error(e.getMessage()));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建对标分析提示词
|
||||
*/
|
||||
private String buildBenchmarkPrompt(String content, Integer videoCount) {
|
||||
return String.format("""
|
||||
请分析以下 %d 个爆款视频的文案,提取出它们的共同特点和创作风格,生成一个综合的文案创作提示词。
|
||||
|
||||
文案内容:
|
||||
%s
|
||||
|
||||
请从以下维度进行分析:
|
||||
1. 文案结构和节奏
|
||||
2. 常用的表达方式和句式
|
||||
3. 情感调动技巧
|
||||
4. 互动引导方式
|
||||
5. 关键词和热词使用
|
||||
|
||||
请生成一个可以直接用于文案创作的提示词,格式要求:
|
||||
- 清晰描述这种文案风格的核心特点
|
||||
- 包含具体的写作指导
|
||||
- 适合作为 AI 写作的 system prompt
|
||||
""", videoCount, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对标分析上下文
|
||||
*/
|
||||
private record BenchmarkAnalyzeContext(String prompt, String apiKey, Integer consumePoints) {}
|
||||
|
||||
@Override
|
||||
public Flux<DifyChatRespVO> promptAnalysisStream(PromptAnalysisReqVO reqVO, String userId) {
|
||||
// 用于存储预扣记录ID
|
||||
AtomicLong pendingRecordId = new AtomicLong();
|
||||
// 用于存储会话ID
|
||||
AtomicReference<String> conversationIdRef = new AtomicReference<>("");
|
||||
// 用于存储 token 使用信息
|
||||
AtomicReference<DifyChatRespVO> tokenUsageRef = new AtomicReference<>();
|
||||
// Dify 用户标识(固定格式)
|
||||
String difyUserId = "user-" + userId;
|
||||
|
||||
return Mono.fromCallable(() -> {
|
||||
// 1. 获取积分配置
|
||||
AiServiceConfigDO config = pointsService.getConfig(
|
||||
AiPlatformEnum.DIFY.getPlatform(),
|
||||
AiModelTypeEnum.PROMPT_ANALYSIS.getModelCode());
|
||||
|
||||
// 2. 预检积分
|
||||
pointsService.checkPoints(userId, config.getConsumePoints());
|
||||
|
||||
// 3. 创建预扣记录(带 serviceCode)
|
||||
Long recordId = pointsService.createPendingDeduct(
|
||||
userId,
|
||||
config.getConsumePoints(),
|
||||
"prompt_analysis",
|
||||
String.valueOf(reqVO.getVideoCount()),
|
||||
config.getServiceCode()
|
||||
);
|
||||
pendingRecordId.set(recordId);
|
||||
|
||||
// 4. 构建提示词分析 prompt
|
||||
String analysisPrompt = buildPromptAnalysisPrompt(reqVO.getContent(), reqVO.getVideoCount());
|
||||
|
||||
log.info("[promptAnalysisStream] 请求参数 - videoCount: {}", reqVO.getVideoCount());
|
||||
log.info("[promptAnalysisStream] 提示词长度: {}", analysisPrompt.length());
|
||||
log.info("[promptAnalysisStream] API配置 - apiKey前缀: {}..., consumePoints: {}",
|
||||
config.getApiKey() != null && config.getApiKey().length() > 10
|
||||
? config.getApiKey().substring(0, 10) + "***"
|
||||
: "null",
|
||||
config.getConsumePoints());
|
||||
|
||||
// 5. 返回调用参数
|
||||
return new PromptAnalysisContext(analysisPrompt, config.getApiKey(), config.getConsumePoints());
|
||||
})
|
||||
.flatMapMany(context -> {
|
||||
// 6. 调用 Dify 流式 API
|
||||
return difyClient.chatStream(
|
||||
context.apiKey(),
|
||||
context.prompt(),
|
||||
null, // systemPrompt 为空,使用 Dify 工作流中的配置
|
||||
null, // conversationId 为空,新会话
|
||||
difyUserId
|
||||
)
|
||||
.doOnNext(resp -> {
|
||||
if (resp.getConversationId() != null) {
|
||||
conversationIdRef.set(resp.getConversationId());
|
||||
}
|
||||
// 捕获 token 使用信息
|
||||
if (resp.getTotalTokens() != null && resp.getTotalTokens() > 0) {
|
||||
tokenUsageRef.set(resp);
|
||||
}
|
||||
})
|
||||
// 7. 流结束时确认扣费(带 token)
|
||||
.doOnComplete(() -> {
|
||||
if (pendingRecordId.get() > 0) {
|
||||
try {
|
||||
DifyChatRespVO tokenUsage = tokenUsageRef.get();
|
||||
if (tokenUsage != null) {
|
||||
pointsService.confirmPendingDeductWithTokens(
|
||||
pendingRecordId.get(),
|
||||
tokenUsage.getInputTokens(),
|
||||
tokenUsage.getOutputTokens(),
|
||||
tokenUsage.getTotalTokens()
|
||||
);
|
||||
log.info("[promptAnalysisStream] 流结束,确认扣费(带token),记录ID: {}, tokens: {}",
|
||||
pendingRecordId.get(), tokenUsage.getTotalTokens());
|
||||
} else {
|
||||
pointsService.confirmPendingDeduct(pendingRecordId.get());
|
||||
log.info("[promptAnalysisStream] 流结束,确认扣费(无token),记录ID: {}", pendingRecordId.get());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[promptAnalysisStream] 确认扣费失败", e);
|
||||
}
|
||||
}
|
||||
})
|
||||
// 8. 流出错时取消预扣
|
||||
.doOnError(e -> {
|
||||
if (pendingRecordId.get() > 0) {
|
||||
try {
|
||||
pointsService.cancelPendingDeduct(pendingRecordId.get());
|
||||
log.info("[promptAnalysisStream] 流出错,取消预扣,记录ID: {}", pendingRecordId.get());
|
||||
} catch (Exception ex) {
|
||||
log.error("[promptAnalysisStream] 取消预扣失败", ex);
|
||||
}
|
||||
}
|
||||
})
|
||||
// 9. 用户取消时确认扣费(已消费的部分)
|
||||
.doOnCancel(() -> {
|
||||
if (pendingRecordId.get() > 0) {
|
||||
try {
|
||||
// 用户主动取消,仍然扣费(按最低消费)
|
||||
pointsService.confirmPendingDeduct(pendingRecordId.get());
|
||||
log.info("[promptAnalysisStream] 用户取消,确认扣费,记录ID: {}", pendingRecordId.get());
|
||||
} catch (Exception e) {
|
||||
log.error("[promptAnalysisStream] 用户取消后扣费失败", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
// 10. 在最后添加 done 事件
|
||||
.concatWith(Mono.defer(() -> {
|
||||
DifyChatRespVO tokenUsage = tokenUsageRef.get();
|
||||
if (tokenUsage != null) {
|
||||
return Mono.just(DifyChatRespVO.doneWithTokens(
|
||||
conversationIdRef.get(), null,
|
||||
tokenUsage.getInputTokens(),
|
||||
tokenUsage.getOutputTokens(),
|
||||
tokenUsage.getTotalTokens()
|
||||
));
|
||||
}
|
||||
return Mono.just(DifyChatRespVO.done(conversationIdRef.get(), null));
|
||||
}))
|
||||
.onErrorResume(e -> {
|
||||
log.error("[promptAnalysisStream] 提示词分析异常", e);
|
||||
return Flux.just(DifyChatRespVO.error(e.getMessage()));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建提示词分析 prompt
|
||||
*/
|
||||
private String buildPromptAnalysisPrompt(String content, Integer videoCount) {
|
||||
return String.format("""
|
||||
请分析以下 %d 个爆款视频的文案,提取出它们的共同特点和创作风格,生成一个可以直接用于 AI 写作的系统提示词。
|
||||
|
||||
文案内容:
|
||||
%s
|
||||
|
||||
请从以下维度进行深度分析:
|
||||
1. 文案结构和节奏特点
|
||||
2. 常用的表达方式和句式模板
|
||||
3. 情感调动和共鸣技巧
|
||||
4. 互动引导和行动号召
|
||||
5. 关键词、热词和流行语使用
|
||||
6. 开头和结尾的特点
|
||||
|
||||
输出要求:
|
||||
- 生成一个完整的系统提示词(System Prompt)
|
||||
- 提示词应该清晰描述这种文案风格的核心特点
|
||||
- 包含具体的写作指导和格式要求
|
||||
- 适合直接作为 AI 写作的系统指令
|
||||
- 使用专业但易懂的语言
|
||||
""", videoCount != null ? videoCount : 1, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提示词分析上下文
|
||||
*/
|
||||
private record PromptAnalysisContext(String prompt, String apiKey, Integer consumePoints) {}
|
||||
|
||||
@Override
|
||||
public DifyConversationListRespVO getConversations(Long agentId, String userId, String lastId, Integer limit) {
|
||||
// 获取智能体配置
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.module.tik.dify.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 对标分析请求 VO
|
||||
*/
|
||||
@Schema(description = "对标分析请求")
|
||||
@Data
|
||||
public class DifyBenchmarkReqVO {
|
||||
|
||||
@Schema(description = "合并后的文案内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "文案内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "视频数量", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "视频数量不能为空")
|
||||
private Integer videoCount;
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.tik.dify.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
@@ -12,8 +11,7 @@ import lombok.Data;
|
||||
@Data
|
||||
public class ForecastRewriteReqVO {
|
||||
|
||||
@Schema(description = "智能体ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "智能体ID不能为空")
|
||||
@Schema(description = "智能体ID(使用用户风格时可为空)")
|
||||
private Long agentId;
|
||||
|
||||
@Schema(description = "用户输入文案", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@@ -26,4 +24,7 @@ public class ForecastRewriteReqVO {
|
||||
@Schema(description = "模型类型:forecast_standard-标准版 forecast_pro-pro版", example = "forecast_standard")
|
||||
private String modelType = "forecast_standard";
|
||||
|
||||
@Schema(description = "自定义系统提示词(使用用户风格时传入)")
|
||||
private String customSystemPrompt;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.tik.dify.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 提示词分析请求 VO
|
||||
*/
|
||||
@Schema(description = "提示词分析请求")
|
||||
@Data
|
||||
public class PromptAnalysisReqVO {
|
||||
|
||||
@Schema(description = "合并后的文案内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "文案内容不能为空")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "视频数量", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer videoCount;
|
||||
|
||||
}
|
||||
@@ -24,6 +24,12 @@ public enum AiModelTypeEnum implements ArrayValuable<String> {
|
||||
FORECAST_STANDARD("forecast_standard", "文案改写-标准版", AiPlatformEnum.DIFY, "text"),
|
||||
FORECAST_PRO("forecast_pro", "文案改写-Pro版", AiPlatformEnum.DIFY, "text"),
|
||||
|
||||
// ========== 对标分析 ==========
|
||||
BENCHMARK_ANALYZE("benchmark_analyze", "对标分析", AiPlatformEnum.DIFY, "text"),
|
||||
|
||||
// ========== 提示词分析 ==========
|
||||
PROMPT_ANALYSIS("prompt_analysis", "提示词分析", AiPlatformEnum.DIFY, "text"),
|
||||
|
||||
// ========== 数字人模型 ==========
|
||||
DIGITAL_HUMAN_LATENTSYNC("latentsync", "LatentSync", AiPlatformEnum.DIGITAL_HUMAN, "video"),
|
||||
DIGITAL_HUMAN_KLING("kling", "可灵", AiPlatformEnum.DIGITAL_HUMAN, "video"),
|
||||
|
||||
@@ -107,5 +107,13 @@ public class AppUserPromptController {
|
||||
PageResult<UserPromptDO> pageResult = userPromptService.getUserPromptPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, UserPromptRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获得用户提示词列表(简化版)")
|
||||
public CommonResult<java.util.List<UserPromptRespVO>> getUserPromptList() {
|
||||
// 只查询当前用户的提示词
|
||||
java.util.List<UserPromptDO> list = userPromptService.getUserPromptListByUserId(getLoginUserId());
|
||||
return success(BeanUtils.toBean(list, UserPromptRespVO.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.tik.userprompt.vo.UserPromptDO;
|
||||
import cn.iocoder.yudao.module.tik.userprompt.vo.UserPromptPageReqVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户提示词 Mapper
|
||||
*
|
||||
@@ -30,4 +32,12 @@ public interface UserPromptMapper extends BaseMapperX<UserPromptDO> {
|
||||
.orderByDesc(UserPromptDO::getId));
|
||||
}
|
||||
|
||||
default List<UserPromptDO> selectList(Long userId) {
|
||||
return selectList(new LambdaQueryWrapperX<UserPromptDO>()
|
||||
.eq(UserPromptDO::getUserId, userId)
|
||||
.eq(UserPromptDO::getStatus, 1)
|
||||
.orderByDesc(UserPromptDO::getSort)
|
||||
.orderByDesc(UserPromptDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -60,4 +60,12 @@ public interface UserPromptService {
|
||||
*/
|
||||
PageResult<UserPromptDO> getUserPromptPage(UserPromptPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 根据用户ID获取用户提示词列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return 用户提示词列表
|
||||
*/
|
||||
List<UserPromptDO> getUserPromptListByUserId(Long userId);
|
||||
|
||||
}
|
||||
|
||||
@@ -92,4 +92,9 @@ public class UserPromptServiceImpl implements UserPromptService {
|
||||
public PageResult<UserPromptDO> getUserPromptPage(UserPromptPageReqVO pageReqVO) {
|
||||
return userPromptMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserPromptDO> getUserPromptListByUserId(Long userId) {
|
||||
return userPromptMapper.selectList(userId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user