- 为聊天历史面板添加加载更多功能,支持分页加载会话列表 - 优化会话列表按时间降序排序和日期分组逻辑 - 统一复制功能使用工具函数,改进错误处理 - 修复兑换码管理菜单路径缺少斜杠的问题 - 优化Dify服务用户标识生成,按agentId隔离会话 - 重构Dify服务扣费逻辑,提取通用处理方法
This commit is contained in:
@@ -25,6 +25,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Dify 服务实现类
|
||||
@@ -53,8 +54,8 @@ public class DifyServiceImpl implements DifyService {
|
||||
AtomicReference<String> conversationIdRef = new AtomicReference<>(reqVO.getConversationId());
|
||||
// 用于存储 token 使用信息
|
||||
AtomicReference<DifyChatRespVO> tokenUsageRef = new AtomicReference<>();
|
||||
// Dify 用户标识(固定格式)
|
||||
String difyUserId = "user-" + userId;
|
||||
// Dify 用户标识(按 agentId 隔离会话)
|
||||
String difyUserId = "user-" + userId + "-agent-" + reqVO.getAgentId();
|
||||
|
||||
return Mono.fromCallable(() -> {
|
||||
// 1. 获取智能体配置
|
||||
@@ -179,8 +180,10 @@ public class DifyServiceImpl implements DifyService {
|
||||
AtomicReference<String> conversationIdRef = new AtomicReference<>("");
|
||||
// 用于存储 token 使用信息
|
||||
AtomicReference<DifyChatRespVO> tokenUsageRef = new AtomicReference<>();
|
||||
// Dify 用户标识(固定格式)
|
||||
String difyUserId = "user-" + userId;
|
||||
// Dify 用户标识(按 agentId 隔离会话,无 agentId 时使用默认)
|
||||
String difyUserId = reqVO.getAgentId() != null
|
||||
? "user-" + userId + "-agent-" + reqVO.getAgentId()
|
||||
: "user-" + userId;
|
||||
|
||||
return Mono.fromCallable(() -> {
|
||||
// 1. 获取系统提示词
|
||||
@@ -653,6 +656,78 @@ public class DifyServiceImpl implements DifyService {
|
||||
*/
|
||||
private record PromptAnalysisContext(String prompt, String apiKey, Integer consumePoints) {}
|
||||
|
||||
/**
|
||||
* 通用的流式响应扣费处理
|
||||
*/
|
||||
private void handlePointsDeduction(AtomicLong pendingRecordId,
|
||||
AtomicReference<DifyChatRespVO> tokenUsageRef,
|
||||
String logPrefix) {
|
||||
if (pendingRecordId.get() <= 0) return;
|
||||
try {
|
||||
DifyChatRespVO tokenUsage = tokenUsageRef.get();
|
||||
if (tokenUsage != null) {
|
||||
pointsService.confirmPendingDeductWithTokens(
|
||||
pendingRecordId.get(),
|
||||
tokenUsage.getInputTokens(),
|
||||
tokenUsage.getOutputTokens(),
|
||||
tokenUsage.getTotalTokens()
|
||||
);
|
||||
log.info("[{}] 流结束,确认扣费(带token),记录ID: {}, tokens: {}",
|
||||
logPrefix, pendingRecordId.get(), tokenUsage.getTotalTokens());
|
||||
} else {
|
||||
pointsService.confirmPendingDeduct(pendingRecordId.get());
|
||||
log.info("[{}] 流结束,确认扣费(无token),记录ID: {}", logPrefix, pendingRecordId.get());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[{}] 确认扣费失败", logPrefix, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用的取消预扣处理
|
||||
*/
|
||||
private void handlePointsCancellation(AtomicLong pendingRecordId, String logPrefix) {
|
||||
if (pendingRecordId.get() <= 0) return;
|
||||
try {
|
||||
pointsService.cancelPendingDeduct(pendingRecordId.get());
|
||||
log.info("[{}] 流出错,取消预扣,记录ID: {}", logPrefix, pendingRecordId.get());
|
||||
} catch (Exception e) {
|
||||
log.error("[{}] 取消预扣失败", logPrefix, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用的用户取消扣费处理
|
||||
*/
|
||||
private void handleUserCancellation(AtomicLong pendingRecordId, String logPrefix) {
|
||||
if (pendingRecordId.get() <= 0) return;
|
||||
try {
|
||||
pointsService.confirmPendingDeduct(pendingRecordId.get());
|
||||
log.info("[{}] 用户取消,确认扣费,记录ID: {}", logPrefix, pendingRecordId.get());
|
||||
} catch (Exception e) {
|
||||
log.error("[{}] 用户取消后扣费失败", logPrefix, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 done 事件 Mono
|
||||
*/
|
||||
private Mono<DifyChatRespVO> buildDoneMono(AtomicReference<String> conversationIdRef,
|
||||
AtomicReference<DifyChatRespVO> tokenUsageRef) {
|
||||
return 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));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public DifyConversationListRespVO getConversations(Long agentId, String userId, String lastId, Integer limit) {
|
||||
// 获取智能体配置
|
||||
@@ -666,8 +741,8 @@ public class DifyServiceImpl implements DifyService {
|
||||
AiPlatformEnum.DIFY.getPlatform(),
|
||||
AiModelTypeEnum.DIFY_WRITING_STANDARD.getModelCode());
|
||||
|
||||
// Dify 用户标识
|
||||
String difyUserId = "user-" + userId;
|
||||
// Dify 用户标识(按 agentId 隔离会话)
|
||||
String difyUserId = "user-" + userId + "-agent-" + agentId;
|
||||
|
||||
DifyConversationListRespVO result = difyClient.getConversations(config.getApiKey(), difyUserId, lastId, limit);
|
||||
|
||||
@@ -696,8 +771,8 @@ public class DifyServiceImpl implements DifyService {
|
||||
AiPlatformEnum.DIFY.getPlatform(),
|
||||
AiModelTypeEnum.DIFY_WRITING_STANDARD.getModelCode());
|
||||
|
||||
// Dify 用户标识
|
||||
String difyUserId = "user-" + userId;
|
||||
// Dify 用户标识(按 agentId 隔离会话)
|
||||
String difyUserId = "user-" + userId + "-agent-" + agentId;
|
||||
|
||||
DifyMessageListRespVO result = difyClient.getMessages(config.getApiKey(), conversationId, difyUserId, firstId, limit);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user