|
@@ -2,11 +2,13 @@ package cn.iocoder.yudao.module.promotion.service.kefu;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.util.ObjUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.extra.spring.SpringUtil;
|
|
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
|
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
|
|
import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
|
|
|
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
|
|
+import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
|
|
import cn.iocoder.yudao.module.infra.api.ai.AiApi;
|
|
|
import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
|
|
|
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
|
@@ -127,21 +129,57 @@ public class KeFuMessageServiceImpl implements KeFuMessageService {
|
|
|
KeFuMessageRespVO message =
|
|
|
BeanUtils.toBean(kefuMessage, KeFuMessageRespVO.class).setSenderAvatar(user.getAvatar());
|
|
|
getSelf().sendAsyncMessageToMember(sendReqVO.getRelUserId(), KEFU_MESSAGE_IM, message);
|
|
|
+
|
|
|
+
|
|
|
+ return kefuMessage.getId();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ //@Async
|
|
|
+ public Flux<String> sendStream(AppKeFuMessageSendReqVO sendReqVO) {
|
|
|
+ // 1.1 设置会话编号
|
|
|
String apiKey = DictFrameworkUtils.parseDictDataValue("ai_key", "多轮对话");
|
|
|
Map<String, Object> inputs = new HashMap<>();
|
|
|
inputs.put("type", "活林木");
|
|
|
- aiApi.getDifyMessageStreaming(inputs,
|
|
|
+ sendMessage(sendReqVO);
|
|
|
+
|
|
|
+ AppKeFuMessageSendReqVO aiSendReqVO = sendReqVO;
|
|
|
+ aiSendReqVO.setRelUserId(SecurityFrameworkUtils.getLoginUserId());
|
|
|
+ aiSendReqVO.setSenderId(aiSendReqVO.getRelUserId());
|
|
|
+ aiSendReqVO.setContentType(11);
|
|
|
+ Long aiId = sendMessage(aiSendReqVO);
|
|
|
+ StringBuffer contentBuffer = new StringBuffer();
|
|
|
+ return aiApi.getDifyMessageStreaming(inputs,
|
|
|
SecurityFrameworkUtils.getLoginUserId().toString(),
|
|
|
- apiKey, sendReqVO.getContent(), "123")
|
|
|
+ apiKey, sendReqVO.getContent(), "132")
|
|
|
.flatMap(response -> {
|
|
|
- log.info("流式结果:" + response.toString());
|
|
|
- message.setContent(response);
|
|
|
- getSelf().sendAsyncMessageToMember(sendReqVO.getRelUserId(), KEFU_MESSAGE_IM, message);
|
|
|
- return Flux.empty();
|
|
|
+ log.info("流式结果:" + response.toString());
|
|
|
+ if (response.getEvent().equals("message")) {
|
|
|
+ String answer = response.getAnswer(); // 完整答案
|
|
|
+ log.info("进入workflow_finished阶段:" + answer);
|
|
|
+ if (StrUtil.isNotBlank(answer)) {
|
|
|
+ contentBuffer.append(answer);
|
|
|
+ return Flux.just(answer);
|
|
|
}
|
|
|
-
|
|
|
- );
|
|
|
- return kefuMessage.getId();
|
|
|
+ }
|
|
|
+ if (response.getEvent().equals("message_end")) {
|
|
|
+ log.info("进入message_end");
|
|
|
+ }
|
|
|
+ return Flux.empty(); // 如果不是 workflow_finished 或 message_end,返回空 Flux
|
|
|
+ }).doOnComplete(() -> {
|
|
|
+ KeFuMessageDO aiMessage = new KeFuMessageDO();
|
|
|
+ aiMessage.setId(aiId);
|
|
|
+ aiMessage.setContent(contentBuffer.toString());
|
|
|
+ // 1.2 保存消息
|
|
|
+ TenantUtils.executeIgnore(() ->
|
|
|
+ keFuMessageMapper.updateById(aiMessage));
|
|
|
+
|
|
|
+ })
|
|
|
+ .onErrorResume(e -> {
|
|
|
+ log.error("流式处理出错:", e);
|
|
|
+ return Flux.error(new RuntimeException("流式处理失败,请稍后再试"));
|
|
|
+ });
|
|
|
+
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -223,7 +261,12 @@ public class KeFuMessageServiceImpl implements KeFuMessageService {
|
|
|
pageReqVO.setConversationId(conversation.getId());
|
|
|
return keFuMessageMapper.selectList(BeanUtils.toBean(pageReqVO, KeFuMessageListReqVO.class));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean checkUserId(Long userId) {
|
|
|
+ return webSocketSenderApi.checKSession(null, UserTypeEnum.MEMBER.getValue(), userId);
|
|
|
+ }
|
|
|
+
|
|
|
private KeFuMessageServiceImpl getSelf() {
|
|
|
return SpringUtil.getBean(getClass());
|
|
|
}
|