diff --git a/modules/core/src/main/java/com/bytedesk/core/message/MessageExtra.java b/modules/core/src/main/java/com/bytedesk/core/message/MessageExtra.java index f332def3e7..8d2d609ba5 100644 --- a/modules/core/src/main/java/com/bytedesk/core/message/MessageExtra.java +++ b/modules/core/src/main/java/com/bytedesk/core/message/MessageExtra.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-01-29 16:21:24 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-04-27 13:10:02 + * @LastEditTime: 2025-04-28 16:59:05 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -18,7 +18,6 @@ import com.alibaba.fastjson2.JSON; import com.bytedesk.core.base.BaseExtra; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -48,10 +47,10 @@ public class MessageExtra extends BaseExtra { // private String feedback = BytedeskConsts.EMPTY_JSON_STRING; // 自动回复 - @Builder.Default - private Boolean isAutoReply = false; + // @Builder.Default + // private Boolean isAutoReply = false; - private String autoReplyType; + // private String autoReplyType; // 翻译 // private String translation; diff --git a/modules/core/src/main/java/com/bytedesk/core/message/MessagePersistService.java b/modules/core/src/main/java/com/bytedesk/core/message/MessagePersistService.java index ab9f7e2ba1..d92e3c448d 100644 --- a/modules/core/src/main/java/com/bytedesk/core/message/MessagePersistService.java +++ b/modules/core/src/main/java/com/bytedesk/core/message/MessagePersistService.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-04-16 18:04:37 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-04-27 13:26:33 + * @LastEditTime: 2025-04-28 16:28:49 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -154,14 +154,14 @@ public class MessagePersistService { // FAQ // - if (type.equals(MessageTypeEnum.FAQ_UP) - || type.equals(MessageTypeEnum.FAQ_DOWN)) { - // content为被评价的faq消息的uid - if (StringUtils.hasText(messageProtobuf.getContent())) { - dealWithFaqRateMessage(type, messageProtobuf); - return true; - } - } + // if (type.equals(MessageTypeEnum.FAQ_UP) + // || type.equals(MessageTypeEnum.FAQ_DOWN)) { + // // content为被评价的faq消息的uid + // if (StringUtils.hasText(messageProtobuf.getContent())) { + // dealWithFaqRateMessage(type, messageProtobuf); + // return true; + // } + // } // QA // if (type.equals(MessageTypeEnum.QA)) { @@ -253,19 +253,19 @@ public class MessagePersistService { // } // } - private void dealWithFaqRateMessage(MessageTypeEnum type, MessageProtobuf message) { - // log.info("dealWithFaqRateMessage"); - Optional messageOpt = messageRestService.findByUid(message.getContent()); - if (messageOpt.isPresent()) { - MessageEntity messageEntity = messageOpt.get(); - if (type.equals(MessageTypeEnum.FAQ_UP)) { - messageEntity.setStatus(MessageStatusEnum.RATE_UP.name()); - } else if (type.equals(MessageTypeEnum.FAQ_DOWN)) { - messageEntity.setStatus(MessageStatusEnum.RATE_DOWN.name()); - } - messageRestService.save(messageEntity); - } - } + // private void dealWithFaqRateMessage(MessageTypeEnum type, MessageProtobuf message) { + // // log.info("dealWithFaqRateMessage"); + // Optional messageOpt = messageRestService.findByUid(message.getContent()); + // if (messageOpt.isPresent()) { + // MessageEntity messageEntity = messageOpt.get(); + // if (type.equals(MessageTypeEnum.FAQ_UP)) { + // messageEntity.setStatus(MessageStatusEnum.RATE_UP.name()); + // } else if (type.equals(MessageTypeEnum.FAQ_DOWN)) { + // messageEntity.setStatus(MessageStatusEnum.RATE_DOWN.name()); + // } + // messageRestService.save(messageEntity); + // } + // } private void dealWithRobotRateMessage(MessageTypeEnum type, MessageProtobuf message) { // log.info("dealWithRobotRateMessage"); diff --git a/modules/core/src/main/java/com/bytedesk/core/message/MessageUtils.java b/modules/core/src/main/java/com/bytedesk/core/message/MessageUtils.java index b1c9fa0a21..bf8475870b 100644 --- a/modules/core/src/main/java/com/bytedesk/core/message/MessageUtils.java +++ b/modules/core/src/main/java/com/bytedesk/core/message/MessageUtils.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-08-31 16:23:54 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-04-28 14:17:15 + * @LastEditTime: 2025-04-28 17:14:13 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -109,5 +109,26 @@ public class MessageUtils { BytedeskEventPublisher bytedeskEventPublisher = ApplicationContextHolder.getBean(BytedeskEventPublisher.class); bytedeskEventPublisher.publishMessageJsonEvent(messageProtobuf.toJson()); } + + public static MessageEntity getThreadMessage(String content, String type, String extra, String user, ThreadEntity thread) { + // UserProtobuf system = UserProtobuf.getSystemUser(); + // MessageExtra extra = MessageUtils.getMessageExtra(thread.getOrgUid()); + + MessageEntity message = MessageEntity.builder() + .uid(UidUtils.getInstance().getUid()) + .content(content) + .type(type) + .status(MessageStatusEnum.READ.name()) + .client(ClientEnum.SYSTEM.name()) + .user(user) + .orgUid(thread.getOrgUid()) + .createdAt(LocalDateTime.now()) + .updatedAt(LocalDateTime.now()) + .thread(thread) + .extra(extra) + .build(); + + return message; + } } diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqEventListener.java b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqEventListener.java index 1908bc6926..1ee1fe2b66 100644 --- a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqEventListener.java +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqEventListener.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-09-07 15:42:23 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-04-24 16:12:21 + * @LastEditTime: 2025-04-28 16:29:12 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -18,10 +18,6 @@ import org.springframework.core.io.Resource; import org.springframework.stereotype.Component; import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson2.JSON; -import com.bytedesk.core.message.MessageEntity; -import com.bytedesk.core.message.MessageStatusEnum; -import com.bytedesk.core.message.event.MessageUpdateEvent; import com.bytedesk.core.upload.UploadEntity; import com.bytedesk.core.upload.UploadRestService; import com.bytedesk.core.upload.UploadTypeEnum; @@ -40,33 +36,25 @@ public class FaqEventListener { private final UploadRestService uploadRestService; - // @Order(3) // @EventListener - // public void onOrganizationCreateEvent(OrganizationCreateEvent event) { - // OrganizationEntity organization = (OrganizationEntity) event.getSource(); - // // String orgUid = organization.getUid(); - // log.info("faq - organization created: {}", organization.getName()); + // public void onMessageUpdateEvent(MessageUpdateEvent event) { + // MessageEntity message = event.getMessage(); + // // + // if (message.getStatus().equals(MessageStatusEnum.RATE_UP.name()) + // || message.getStatus().equals(MessageStatusEnum.RATE_DOWN.name())) { + // log.info("message faq update event: {}", message); + // // + // FaqMessageExtra extra = JSON.parseObject(message.getExtra(), FaqMessageExtra.class); + // log.info("faq rate extra faqUid {}, rate {}", extra.getFaqUid(), extra.getRate()); + // // + // if (message.getStatus().equals(MessageStatusEnum.RATE_UP.name())) { + // faqRestService.rateUp(extra.getFaqUid()); + // } else if (message.getStatus().equals(MessageStatusEnum.RATE_DOWN.name())) { + // faqRestService.rateDown(extra.getFaqUid()); + // } + // } // } - @EventListener - public void onMessageUpdateEvent(MessageUpdateEvent event) { - MessageEntity message = event.getMessage(); - // - if (message.getStatus().equals(MessageStatusEnum.RATE_UP.name()) - || message.getStatus().equals(MessageStatusEnum.RATE_DOWN.name())) { - log.info("message faq update event: {}", message); - // - FaqMessageExtra extra = JSON.parseObject(message.getExtra(), FaqMessageExtra.class); - log.info("faq rate extra faqUid {}, rate {}", extra.getFaqUid(), extra.getRate()); - // - if (message.getStatus().equals(MessageStatusEnum.RATE_UP.name())) { - faqRestService.rateUp(extra.getFaqUid()); - } else if (message.getStatus().equals(MessageStatusEnum.RATE_DOWN.name())) { - faqRestService.rateDown(extra.getFaqUid()); - } - } - } - @EventListener public void onUploadCreateEvent(UploadCreateEvent event) { UploadEntity upload = event.getUpload(); diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqMessageExtra.java b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqMessageExtra.java index 29639407bb..91b46d2086 100644 --- a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqMessageExtra.java +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqMessageExtra.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-07-18 18:09:59 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-04-27 13:15:43 + * @LastEditTime: 2025-04-28 16:40:03 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -13,6 +13,9 @@ */ package com.bytedesk.kbase.faq; +import java.util.List; + +import com.alibaba.fastjson2.JSON; import com.bytedesk.core.message.MessageExtra; import lombok.AllArgsConstructor; @@ -30,8 +33,16 @@ public class FaqMessageExtra extends MessageExtra { private static final long serialVersionUID = 1L; - private String uid; + // private String uid; + // private String faqUid; + // private String rate; + // private String orgUid; + + // private String faqUid; - private String rate; - private String orgUid; + private List relatedFaqs; + + public static FaqMessageExtra fromJson(String json) { + return JSON.parseObject(json, FaqMessageExtra.class); + } } diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRequest.java b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRequest.java index ae68aae2b8..3da3ea2bda 100644 --- a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRequest.java +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRequest.java @@ -130,4 +130,7 @@ public class FaqRequest extends BaseRequest { @Builder.Default private List docIdList = new ArrayList<>(); + + // 用于客户端点击uid + private String threadUid; // 对应会话 } diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqResponse.java b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqResponse.java index 8168b0f682..aed9ef4823 100644 --- a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqResponse.java +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqResponse.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-03-22 23:00:00 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-04-27 17:52:56 + * @LastEditTime: 2025-04-28 16:37:09 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; import com.bytedesk.core.base.BaseResponse; +import com.bytedesk.core.message.MessageResponse; import lombok.AllArgsConstructor; import lombok.Builder; @@ -52,10 +53,7 @@ public class FaqResponse extends BaseResponse { private List answerList; // 修改这里,使用简化版的响应对象避免循环依赖 - private List relatedFaqs; - - // 是否是llm问答 - // private Boolean isLlmQa; + private List relatedFaqs; private String type; @@ -107,16 +105,20 @@ public class FaqResponse extends BaseResponse { /** * 简化版FAQ响应,用于相关问题展示,避免循环依赖 */ - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - public static class SimpleFaqResponse { - private String uid; - private String question; - private String answer; - private String type; - private String status; - } + // @Data + // @Builder + // @NoArgsConstructor + // @AllArgsConstructor + // public static class SimpleFaqResponse { + // private String uid; + // private String question; + // private String answer; + // private String type; + // private String status; + // } + + // + private MessageResponse questionMessage; + private MessageResponse answerMessage; } diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqResponseSimple.java b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqResponseSimple.java new file mode 100644 index 0000000000..8186e5f5d1 --- /dev/null +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqResponseSimple.java @@ -0,0 +1,34 @@ +/* + * @Author: jackning 270580156@qq.com + * @Date: 2025-04-28 16:31:15 + * @LastEditors: jackning 270580156@qq.com + * @LastEditTime: 2025-04-28 16:36:03 + * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk + * Please be aware of the BSL license restrictions before installing Bytedesk IM – + * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. + * Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE + * contact: 270580156@qq.com + * + * Copyright (c) 2025 by bytedesk.com, All Rights Reserved. + */ +package com.bytedesk.kbase.faq; + +import java.io.Serializable; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FaqResponseSimple implements Serializable { + + private static final long serialVersionUID = 1L; + + private String uid; + private String question; + private String answer; +} diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRestControllerVisitor.java b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRestControllerVisitor.java index 37f854581f..b53325d067 100644 --- a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRestControllerVisitor.java +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRestControllerVisitor.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2025-01-13 11:16:32 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-04-17 17:16:44 + * @LastEditTime: 2025-04-28 15:35:06 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -63,11 +63,11 @@ public class FaqRestControllerVisitor { return ResponseEntity.ok(JsonResult.success(page)); } - // query by uid - @GetMapping("/query/uid") - public ResponseEntity queryByUid(FaqRequest request) { + // 点击faq + @GetMapping("/click/uid") + public ResponseEntity clickFaq(FaqRequest request) { - FaqResponse faq = faqRestService.queryByUid(request); + FaqResponse faq = faqRestService.clickFaq(request); if (faq == null) { return ResponseEntity.ok(JsonResult.error("faq not found")); } diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRestService.java b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRestService.java index cfcd2d3cc1..e5b277c4ac 100644 --- a/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRestService.java +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/faq/FaqRestService.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-03-22 22:59:18 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-04-28 13:17:20 + * @LastEditTime: 2025-04-28 17:15:09 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -13,6 +13,7 @@ */ package com.bytedesk.kbase.faq; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -36,10 +37,17 @@ import com.bytedesk.core.category.CategoryRequest; import com.bytedesk.core.category.CategoryResponse; import com.bytedesk.core.category.CategoryRestService; import com.bytedesk.core.constant.BytedeskConsts; +import com.bytedesk.core.enums.ClientEnum; +import com.bytedesk.core.message.MessageEntity; +import com.bytedesk.core.message.MessageRestService; +import com.bytedesk.core.message.MessageStatusEnum; import com.bytedesk.core.message.MessageTypeEnum; import com.bytedesk.core.rbac.auth.AuthService; import com.bytedesk.core.rbac.user.UserEntity; +import com.bytedesk.core.thread.ThreadEntity; +import com.bytedesk.core.thread.ThreadRestService; import com.bytedesk.core.uid.UidUtils; +import com.bytedesk.core.utils.ConvertUtils; import com.bytedesk.core.utils.Utils; import com.bytedesk.kbase.faq.FaqJsonLoader.Faq; import com.bytedesk.kbase.faq.FaqJsonLoader.FaqConfiguration; @@ -73,6 +81,10 @@ public class FaqRestService extends BaseRestServiceWithExcel queryByOrgEntity(FaqRequest request) { Pageable pageable = request.getPageable(); @@ -109,14 +121,51 @@ public class FaqRestService extends BaseRestServiceWithExcel optionalEntity = findByUid(request.getUid()); + if (optionalEntity.isPresent()) { + FaqEntity entity = optionalEntity.get(); + entity.increaseClickCount(); + // + FaqEntity savedEntity = faqRepository.save(entity); + if (savedEntity == null) { + throw new RuntimeException("Failed to update click count"); + } + FaqResponse faqResponse = convertToResponse(savedEntity); + + // 插入问题 + 答案 两条消息记录,目前放到发送消息里面 + // 插入问题消息 + Optional thread = threadRestService.findByUid(request.getThreadUid()); + if (thread.isPresent()) { + ThreadEntity threadEntity = thread.get(); + // 插入问题消息 + MessageEntity questionMessage = getFaqQuestionMessage(faqResponse, threadEntity); + MessageEntity savedQuestionMessage = messageRestService.save(questionMessage); + if (savedQuestionMessage == null) { + throw new RuntimeException("Failed to insert question message"); + } + faqResponse.setQuestionMessage(ConvertUtils.convertToMessageResponse(savedQuestionMessage)); + // + MessageEntity answerMessage = getFaqAnswerMessage(faqResponse, threadEntity); + MessageEntity savedAnswerMessage = messageRestService.save(answerMessage); + if (savedAnswerMessage == null) { + throw new RuntimeException("Failed to insert answer message"); + } + faqResponse.setAnswerMessage(ConvertUtils.convertToMessageResponse(savedAnswerMessage)); + } + // + return faqResponse; + } + return null; + } + @Cacheable(value = "faq", key = "#uid", unless = "#result == null") @Override public Optional findByUid(String uid) { @@ -248,7 +297,6 @@ public class FaqRestService extends BaseRestServiceWithExcel optional = findByUid(request.getUid()); if (optional.isPresent()) { @@ -377,40 +425,14 @@ public class FaqRestService extends BaseRestServiceWithExcel simpleFaqs = entity.getRelatedFaqs().stream() - .map(relatedFaq -> FaqResponse.SimpleFaqResponse.builder() + List simpleFaqs = entity.getRelatedFaqs().stream() + .map(relatedFaq -> FaqResponseSimple.builder() .uid(relatedFaq.getUid()) .question(relatedFaq.getQuestion()) .answer(relatedFaq.getAnswer()) - .type(relatedFaq.getType()) - .status(relatedFaq.getStatus()) .build()) .collect(Collectors.toList()); response.setRelatedFaqs(simpleFaqs); @@ -582,13 +604,13 @@ public class FaqRestService extends BaseRestServiceWithExcel docIdList = new ArrayList<>(); + + // 用于客户端点击uid + private String threadUid; // 对应会话 }