diff --git a/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotEntity.java b/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotEntity.java index d6632b1009..07df1b17ee 100644 --- a/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotEntity.java +++ b/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-03-22 16:16:26 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-02-10 08:26:27 + * @LastEditTime: 2025-02-11 17:04:21 * @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. @@ -67,9 +67,9 @@ public class RobotEntity extends BaseEntity { @Builder.Default private RobotLlm llm = new RobotLlm(); - @Embedded - @Builder.Default - private RobotFlow flow = new RobotFlow(); + // @Embedded + // @Builder.Default + // private RobotFlow flow = new RobotFlow(); @Embedded @Builder.Default diff --git a/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotEventListener.java b/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotEventListener.java index 1a941145fc..dd29b30253 100644 --- a/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotEventListener.java +++ b/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotEventListener.java @@ -137,9 +137,11 @@ public class RobotEventListener { // 调用大模型 - } else if (robot.getFlow().isEnabled()) { - // 调用流程引擎 - } else if (robot.isKbEnabled()) { + } + // else if (robot.getFlow().isEnabled()) { + // // 调用流程引擎 + // } + else if (robot.isKbEnabled()) { // 搜索知识库 } else { // 默认回复 diff --git a/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotFlow.java b/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotFlow.java index e31d82626d..2ca536f561 100644 --- a/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotFlow.java +++ b/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotFlow.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-09-06 15:13:07 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2024-12-27 12:02:12 + * @LastEditTime: 2025-02-11 17:01: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. @@ -13,58 +13,58 @@ */ package com.bytedesk.ai.robot; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; +// import org.hibernate.annotations.JdbcTypeCode; +// import org.hibernate.type.SqlTypes; -import com.bytedesk.core.constant.BytedeskConsts; -import com.bytedesk.core.constant.TypeConsts; +// import com.bytedesk.core.constant.BytedeskConsts; +// import com.bytedesk.core.constant.TypeConsts; -import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +// import jakarta.persistence.Column; +// import jakarta.persistence.Embeddable; +// import lombok.AllArgsConstructor; +// import lombok.Builder; +// import lombok.Data; +// import lombok.NoArgsConstructor; -@Embeddable -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class RobotFlow { +// @Embeddable +// @Data +// @Builder +// @NoArgsConstructor +// @AllArgsConstructor +// public class RobotFlow { - @Builder.Default - @Column(name = "is_flow_enabled") - private boolean enabled = false; +// @Builder.Default +// @Column(name = "is_flow_enabled") +// private boolean enabled = false; - @Builder.Default - @Column(name = "flow_groups", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) - private String groups = BytedeskConsts.EMPTY_JSON_STRING; +// @Builder.Default +// @Column(name = "flow_groups", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) +// @JdbcTypeCode(SqlTypes.JSON) +// private String groups = BytedeskConsts.EMPTY_JSON_STRING; - @Builder.Default - @Column(name = "flow_events", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) - private String events = BytedeskConsts.EMPTY_JSON_STRING; +// @Builder.Default +// @Column(name = "flow_events", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) +// @JdbcTypeCode(SqlTypes.JSON) +// private String events = BytedeskConsts.EMPTY_JSON_STRING; - @Builder.Default - @Column(name = "flow_variables", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) - private String variables = BytedeskConsts.EMPTY_JSON_STRING; +// @Builder.Default +// @Column(name = "flow_variables", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) +// @JdbcTypeCode(SqlTypes.JSON) +// private String variables = BytedeskConsts.EMPTY_JSON_STRING; - @Builder.Default - @Column(name = "flow_edges", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) - private String edges = BytedeskConsts.EMPTY_JSON_STRING; +// @Builder.Default +// @Column(name = "flow_edges", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) +// @JdbcTypeCode(SqlTypes.JSON) +// private String edges = BytedeskConsts.EMPTY_JSON_STRING; - @Builder.Default - @Column(name = "flow_themes", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) - private String themes = BytedeskConsts.EMPTY_JSON_STRING; +// @Builder.Default +// @Column(name = "flow_themes", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) +// @JdbcTypeCode(SqlTypes.JSON) +// private String themes = BytedeskConsts.EMPTY_JSON_STRING; - @Builder.Default - @Column(name = "flow_settings", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) - private String settings = BytedeskConsts.EMPTY_JSON_STRING; +// @Builder.Default +// @Column(name = "flow_settings", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) +// @JdbcTypeCode(SqlTypes.JSON) +// private String settings = BytedeskConsts.EMPTY_JSON_STRING; -} +// } diff --git a/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotRequest.java b/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotRequest.java index a020e5363e..46d63a5dff 100644 --- a/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotRequest.java +++ b/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotRequest.java @@ -52,8 +52,8 @@ public class RobotRequest extends BaseRequest { @Builder.Default private Boolean isFlowEnabled = false; - @Builder.Default - private RobotFlow flow = new RobotFlow(); + // @Builder.Default + // private RobotFlow flow = new RobotFlow(); @Builder.Default private String defaultReply = I18Consts.I18N_ROBOT_REPLY; diff --git a/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotResponse.java b/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotResponse.java index 0cb5d6294e..bc76dd7eb7 100644 --- a/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotResponse.java +++ b/modules/ai/src/main/java/com/bytedesk/ai/robot/RobotResponse.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-03-22 16:45:18 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-01-10 15:23:14 + * @LastEditTime: 2025-02-11 17:04:42 * @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. @@ -46,7 +46,7 @@ public class RobotResponse extends BaseResponse { private Boolean isFlowEnabled; - private RobotFlow flow; + // private RobotFlow flow; private String defaultReply; diff --git a/modules/core/src/main/java/com/bytedesk/core/action/ActionEntity.java b/modules/core/src/main/java/com/bytedesk/core/action/ActionEntity.java index fc9ca56815..8be5b20b25 100644 --- a/modules/core/src/main/java/com/bytedesk/core/action/ActionEntity.java +++ b/modules/core/src/main/java/com/bytedesk/core/action/ActionEntity.java @@ -13,12 +13,8 @@ */ package com.bytedesk.core.action; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.BytedeskConsts; -import com.bytedesk.core.constant.TypeConsts; import com.bytedesk.core.enums.PlatformEnum; import com.bytedesk.core.rbac.user.UserEntity; @@ -68,8 +64,9 @@ public class ActionEntity extends BaseEntity { // action failed object @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) private String extra = BytedeskConsts.EMPTY_JSON_STRING; // private String userUid; diff --git a/modules/core/src/main/java/com/bytedesk/core/feature/FeatureEntity.java b/modules/core/src/main/java/com/bytedesk/core/feature/FeatureEntity.java index 915ef044d9..06b0041428 100644 --- a/modules/core/src/main/java/com/bytedesk/core/feature/FeatureEntity.java +++ b/modules/core/src/main/java/com/bytedesk/core/feature/FeatureEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-12-19 10:17:07 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2024-12-19 10:26:29 + * @LastEditTime: 2025-02-11 17:01:26 * @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,9 +13,6 @@ */ package com.bytedesk.core.feature; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.BytedeskConsts; import com.bytedesk.core.constant.TypeConsts; @@ -52,11 +49,11 @@ public class FeatureEntity extends BaseEntity { @Column(name = "min_version") private String minVersion; // 最低支持版本 - @Column(name = "config_schema", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "config_schema", columnDefinition = TypeConsts.COLUMN_TYPE_TEXT) + // @JdbcTypeCode(SqlTypes.JSON) private String configSchema = BytedeskConsts.EMPTY_JSON_STRING; // 配置项schema(JSON) - @Column(name = "default_config", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "default_config", columnDefinition = TypeConsts.COLUMN_TYPE_TEXT) + // @JdbcTypeCode(SqlTypes.JSON) private String defaultConfig = BytedeskConsts.EMPTY_JSON_STRING; // 默认配置(JSON) } \ No newline at end of file diff --git a/modules/core/src/main/java/com/bytedesk/core/message/MessageEntity.java b/modules/core/src/main/java/com/bytedesk/core/message/MessageEntity.java index fbc8b8e94d..05a3b6a2d8 100644 --- a/modules/core/src/main/java/com/bytedesk/core/message/MessageEntity.java +++ b/modules/core/src/main/java/com/bytedesk/core/message/MessageEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-01-29 16:21:24 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2024-10-23 15:22:26 + * @LastEditTime: 2025-02-11 17:06:14 * @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. @@ -14,9 +14,6 @@ */ package com.bytedesk.core.message; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.BytedeskConsts; import com.bytedesk.core.constant.TypeConsts; @@ -57,8 +54,10 @@ public class MessageEntity extends BaseEntity { private String content; @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(length = 1024) private String extra = BytedeskConsts.EMPTY_JSON_STRING; @Builder.Default @@ -78,8 +77,10 @@ public class MessageEntity extends BaseEntity { // private User user; // h2 db 不能使用 user, 所以重定义为 message_user @Builder.Default - @Column(name = "message_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(name = "message_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "message_user") private String user = BytedeskConsts.EMPTY_JSON_STRING; } diff --git a/modules/core/src/main/java/com/bytedesk/core/message_unread/MessageUnread.java b/modules/core/src/main/java/com/bytedesk/core/message_unread/MessageUnread.java index a58bbd6f65..6fea5c7d82 100644 --- a/modules/core/src/main/java/com/bytedesk/core/message_unread/MessageUnread.java +++ b/modules/core/src/main/java/com/bytedesk/core/message_unread/MessageUnread.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-06-28 17:15:48 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2024-11-07 16:16:01 + * @LastEditTime: 2025-02-11 17:06:33 * @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. @@ -16,8 +16,6 @@ package com.bytedesk.core.message_unread; import java.io.Serializable; import java.time.LocalDateTime; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; @@ -86,8 +84,10 @@ public class MessageUnread implements Serializable { private String content; @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(length = 1024) private String extra = BytedeskConsts.EMPTY_JSON_STRING; @Builder.Default @@ -99,8 +99,8 @@ public class MessageUnread implements Serializable { // h2 db 不能使用 user, 所以重定义为 message_user @Builder.Default - @Column(name = "message_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "message_user", length = 512) + // @JdbcTypeCode(SqlTypes.JSON) private String user = BytedeskConsts.EMPTY_JSON_STRING; // 乐观锁版本字段,每次更新时版本号加1 diff --git a/modules/core/src/main/java/com/bytedesk/core/notification/NotificationEntity.java b/modules/core/src/main/java/com/bytedesk/core/notification/NotificationEntity.java index a231c67ec2..db7716122b 100644 --- a/modules/core/src/main/java/com/bytedesk/core/notification/NotificationEntity.java +++ b/modules/core/src/main/java/com/bytedesk/core/notification/NotificationEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-09-01 09:27:49 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2024-12-04 17:30:02 + * @LastEditTime: 2025-02-11 17:08: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. @@ -13,12 +13,8 @@ */ package com.bytedesk.core.notification; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.BytedeskConsts; -import com.bytedesk.core.constant.TypeConsts; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -55,7 +51,9 @@ public class NotificationEntity extends BaseEntity { private String status = NotificationStatusEnum.UNREAD.name(); @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(length = 1024) private String extra = BytedeskConsts.EMPTY_JSON_STRING; } diff --git a/modules/core/src/main/java/com/bytedesk/core/rbac/auth/ldap/readme.md b/modules/core/src/main/java/com/bytedesk/core/rbac/auth/ldap/readme.md new file mode 100644 index 0000000000..46aab1bbb9 --- /dev/null +++ b/modules/core/src/main/java/com/bytedesk/core/rbac/auth/ldap/readme.md @@ -0,0 +1,16 @@ + +# LDAP + +## Overview diff --git a/modules/core/src/main/java/com/bytedesk/core/rbac/auth/ldap/readme.zh.md b/modules/core/src/main/java/com/bytedesk/core/rbac/auth/ldap/readme.zh.md new file mode 100644 index 0000000000..0b3c628c83 --- /dev/null +++ b/modules/core/src/main/java/com/bytedesk/core/rbac/auth/ldap/readme.zh.md @@ -0,0 +1,16 @@ + +# LDAP + +## Overview diff --git a/modules/core/src/main/java/com/bytedesk/core/rbac/auth/sso/readme.md b/modules/core/src/main/java/com/bytedesk/core/rbac/auth/sso/readme.md new file mode 100644 index 0000000000..feb0e8c695 --- /dev/null +++ b/modules/core/src/main/java/com/bytedesk/core/rbac/auth/sso/readme.md @@ -0,0 +1,16 @@ + +# Single Sign-On + +## Overview diff --git a/modules/core/src/main/java/com/bytedesk/core/rbac/auth/sso/readme.zh.md b/modules/core/src/main/java/com/bytedesk/core/rbac/auth/sso/readme.zh.md new file mode 100644 index 0000000000..ce029f3936 --- /dev/null +++ b/modules/core/src/main/java/com/bytedesk/core/rbac/auth/sso/readme.zh.md @@ -0,0 +1,16 @@ + +# 单点登录 + +## Overview diff --git a/modules/core/src/main/java/com/bytedesk/core/rbac/user/UserEntity.java b/modules/core/src/main/java/com/bytedesk/core/rbac/user/UserEntity.java index f6cbb637b5..cba655e3e3 100644 --- a/modules/core/src/main/java/com/bytedesk/core/rbac/user/UserEntity.java +++ b/modules/core/src/main/java/com/bytedesk/core/rbac/user/UserEntity.java @@ -6,9 +6,6 @@ import java.util.Iterator; import java.util.Set; import java.util.stream.Collectors; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntityNoOrg; import com.bytedesk.core.constant.AvatarConsts; import com.bytedesk.core.constant.BytedeskConsts; @@ -219,10 +216,12 @@ public class UserEntity extends BaseEntityNoOrg { // } @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) // 用于兼容postgreSQL,否则会报错,[ERROR: column "extra" is of type json but expression is // of type character varying - @JdbcTypeCode(SqlTypes.JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(columnDefinition = TypeConsts.COLUMN_TYPE_TEXT) private String extra = BytedeskConsts.EMPTY_JSON_STRING; // return the first organization oid diff --git a/modules/core/src/main/java/com/bytedesk/core/thread/ThreadEntity.java b/modules/core/src/main/java/com/bytedesk/core/thread/ThreadEntity.java index 368003b5eb..906d0f456c 100644 --- a/modules/core/src/main/java/com/bytedesk/core/thread/ThreadEntity.java +++ b/modules/core/src/main/java/com/bytedesk/core/thread/ThreadEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-01-29 16:21:24 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-02-11 15:24:14 + * @LastEditTime: 2025-02-11 17:06:52 * @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. @@ -14,13 +14,9 @@ */ package com.bytedesk.core.thread; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.alibaba.fastjson2.JSON; import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.BytedeskConsts; -import com.bytedesk.core.constant.TypeConsts; import com.bytedesk.core.enums.ClientEnum; import com.bytedesk.core.rbac.user.UserEntity; import com.bytedesk.core.rbac.user.UserProtobuf; @@ -130,9 +126,11 @@ public class ThreadEntity extends BaseEntity { private String client = ClientEnum.WEB.name(); @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) // for postgres compatibility,[ERROR: column "extra" is of type json but expression is of type character varying - @JdbcTypeCode(SqlTypes.JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(length = 1024) private String extra = BytedeskConsts.EMPTY_JSON_STRING; /** @@ -145,8 +143,10 @@ public class ThreadEntity extends BaseEntity { * @{UserProtobuf} */ @Builder.Default - @Column(name = "thread_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(name = "thread_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "thread_user") private String user = BytedeskConsts.EMPTY_JSON_STRING; /** @@ -157,14 +157,16 @@ public class ThreadEntity extends BaseEntity { * @{UserProtobuf} */ @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) private String agent = BytedeskConsts.EMPTY_JSON_STRING; // multi agent assistants: monitoring agent、quality check agent、robot agent @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) private String multiAgents = BytedeskConsts.EMPTY_JSON_STRING; // belongs to user diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/article/ArticleEntity.java b/modules/kbase/src/main/java/com/bytedesk/kbase/article/ArticleEntity.java index a296303dbb..479debc81b 100644 --- a/modules/kbase/src/main/java/com/bytedesk/kbase/article/ArticleEntity.java +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/article/ArticleEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-02-22 16:16:42 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-02-06 15:24:55 + * @LastEditTime: 2025-02-11 17:02: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. @@ -17,8 +17,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; import org.springframework.ai.document.Document; import org.springframework.lang.NonNull; @@ -118,8 +116,8 @@ public class ArticleEntity extends BaseEntity { private String kbUid; // 对应知识库 @Builder.Default - @Column(name = "create_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "create_user", length = 512) + // @JdbcTypeCode(SqlTypes.JSON) private String user = BytedeskConsts.EMPTY_JSON_STRING; // diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/notebase/NotebaseEntity.java b/modules/kbase/src/main/java/com/bytedesk/kbase/notebase/NotebaseEntity.java index 8e506c8011..c690623f59 100644 --- a/modules/kbase/src/main/java/com/bytedesk/kbase/notebase/NotebaseEntity.java +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/notebase/NotebaseEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-02-22 16:16:42 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-01-21 10:43:05 + * @LastEditTime: 2025-02-11 17:03:54 * @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. @@ -17,8 +17,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; import org.springframework.ai.document.Document; import org.springframework.lang.NonNull; @@ -100,8 +98,8 @@ public class NotebaseEntity extends BaseEntity { private String kbUid; // 对应知识库 @Builder.Default - @Column(name = "create_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "create_user", length = 512) + // @JdbcTypeCode(SqlTypes.JSON) private String user = BytedeskConsts.EMPTY_JSON_STRING; // diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/service_settings/ServiceSettings.java b/modules/kbase/src/main/java/com/bytedesk/kbase/service_settings/ServiceSettings.java index bbc94a1f52..6685430b9f 100644 --- a/modules/kbase/src/main/java/com/bytedesk/kbase/service_settings/ServiceSettings.java +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/service_settings/ServiceSettings.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-06-14 10:45:08 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-01-13 12:53:01 + * @LastEditTime: 2025-02-11 16:47:47 * @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. @@ -19,9 +19,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.constant.BytedeskConsts; import com.bytedesk.core.constant.I18Consts; import com.bytedesk.core.constant.TypeConsts; @@ -91,8 +88,8 @@ public class ServiceSettings implements Serializable { private boolean showPreForm = false; @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) private String preForm = BytedeskConsts.EMPTY_JSON_STRING; // show history message or not diff --git a/modules/kbase/src/main/java/com/bytedesk/kbase/upload/UploadEntity.java b/modules/kbase/src/main/java/com/bytedesk/kbase/upload/UploadEntity.java index 67d5cceeb5..f8518167e7 100644 --- a/modules/kbase/src/main/java/com/bytedesk/kbase/upload/UploadEntity.java +++ b/modules/kbase/src/main/java/com/bytedesk/kbase/upload/UploadEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-03-16 10:46:55 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2024-11-22 16:05:22 + * @LastEditTime: 2025-02-11 17:02:59 * @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. @@ -16,9 +16,6 @@ package com.bytedesk.kbase.upload; import java.util.ArrayList; import java.util.List; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.BytedeskConsts; import com.bytedesk.core.constant.TypeConsts; @@ -81,8 +78,8 @@ public class UploadEntity extends BaseEntity { // 上传用户 @Builder.Default - @Column(name = "upload_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "upload_user", length = 512) + // @JdbcTypeCode(SqlTypes.JSON) private String user = BytedeskConsts.EMPTY_JSON_STRING; // vector store id diff --git a/modules/service/src/main/java/com/bytedesk/service/agent/AgentEntity.java b/modules/service/src/main/java/com/bytedesk/service/agent/AgentEntity.java index d726ba67e8..48f5ecbfd0 100644 --- a/modules/service/src/main/java/com/bytedesk/service/agent/AgentEntity.java +++ b/modules/service/src/main/java/com/bytedesk/service/agent/AgentEntity.java @@ -18,7 +18,6 @@ import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.AvatarConsts; import com.bytedesk.core.constant.BytedeskConsts; import com.bytedesk.core.constant.I18Consts; -import com.bytedesk.core.constant.TypeConsts; import com.bytedesk.kbase.auto_reply.settings.AutoReplySettings; import com.bytedesk.kbase.service_settings.InviteSettings; import com.bytedesk.kbase.service_settings.ServiceSettings; @@ -129,7 +128,7 @@ public class AgentEntity extends BaseEntity { /** 存储当前接待数量等 */ @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) // 用于兼容postgreSQL,否则会报错,[ERROR: column "extra" is of type json but expression is // of type character varying private String extra = BytedeskConsts.EMPTY_JSON_STRING; diff --git a/modules/service/src/main/java/com/bytedesk/service/leave_msg/LeaveMsgEntity.java b/modules/service/src/main/java/com/bytedesk/service/leave_msg/LeaveMsgEntity.java index cb20bbd174..350054aad2 100644 --- a/modules/service/src/main/java/com/bytedesk/service/leave_msg/LeaveMsgEntity.java +++ b/modules/service/src/main/java/com/bytedesk/service/leave_msg/LeaveMsgEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-02-22 16:11:42 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2024-10-22 12:19:09 + * @LastEditTime: 2025-02-11 17:04:08 * @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. @@ -16,9 +16,6 @@ package com.bytedesk.service.leave_msg; import java.util.ArrayList; import java.util.List; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.BytedeskConsts; import com.bytedesk.core.constant.TypeConsts; @@ -68,7 +65,7 @@ public class LeaveMsgEntity extends BaseEntity { private String status = LeaveMsgStatusEnum.UNREAD.name(); @Builder.Default - @Column(name = "leavemsg_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "leavemsg_user", length = 512) + // @JdbcTypeCode(SqlTypes.JSON) private String user = BytedeskConsts.EMPTY_JSON_STRING; } diff --git a/modules/service/src/main/java/com/bytedesk/service/leave_msg/settings/LeaveMsgSettings.java b/modules/service/src/main/java/com/bytedesk/service/leave_msg/settings/LeaveMsgSettings.java index 10c7836e49..7220edf5f4 100644 --- a/modules/service/src/main/java/com/bytedesk/service/leave_msg/settings/LeaveMsgSettings.java +++ b/modules/service/src/main/java/com/bytedesk/service/leave_msg/settings/LeaveMsgSettings.java @@ -17,12 +17,8 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.constant.BytedeskConsts; import com.bytedesk.core.constant.I18Consts; -import com.bytedesk.core.constant.TypeConsts; import com.bytedesk.service.leave_msg.LeaveMsgNotifyTypeEnum; import com.bytedesk.service.worktime.WorktimeEntity; @@ -82,8 +78,8 @@ public class LeaveMsgSettings implements Serializable { // 留言表单 @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) private String leaveMsgForm = BytedeskConsts.EMPTY_JSON_STRING; /** work time */ diff --git a/modules/service/src/main/java/com/bytedesk/service/rating/RatingEntity.java b/modules/service/src/main/java/com/bytedesk/service/rating/RatingEntity.java index b685e10390..01d597d939 100644 --- a/modules/service/src/main/java/com/bytedesk/service/rating/RatingEntity.java +++ b/modules/service/src/main/java/com/bytedesk/service/rating/RatingEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-12-07 11:37:48 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-01-09 23:12:36 + * @LastEditTime: 2025-02-11 17:03:16 * @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,12 +13,8 @@ */ package com.bytedesk.service.rating; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.BytedeskConsts; -import com.bytedesk.core.constant.TypeConsts; import com.bytedesk.core.message.MessageEntity; import com.bytedesk.core.thread.ThreadEntity; @@ -94,7 +90,7 @@ public class RatingEntity extends BaseEntity { private ThreadEntity thread; @Builder.Default - @Column(name = "rate_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "rate_user", length = 512) + // @JdbcTypeCode(SqlTypes.JSON) private String user = BytedeskConsts.EMPTY_JSON_STRING; } \ No newline at end of file diff --git a/modules/service/src/main/java/com/bytedesk/service/visitor/VisitorEntity.java b/modules/service/src/main/java/com/bytedesk/service/visitor/VisitorEntity.java index 28b042333f..851d4b0b4e 100644 --- a/modules/service/src/main/java/com/bytedesk/service/visitor/VisitorEntity.java +++ b/modules/service/src/main/java/com/bytedesk/service/visitor/VisitorEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-01-29 16:21:24 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-02-08 10:39:47 + * @LastEditTime: 2025-02-11 16:59:52 * @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,9 +13,6 @@ */ package com.bytedesk.service.visitor; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.AvatarConsts; import com.bytedesk.core.constant.BytedeskConsts; @@ -80,8 +77,9 @@ public class VisitorEntity extends BaseEntity { // extra info,开发者自定义URL参数,使用json格式存储,便于扩展 @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(columnDefinition = TypeConsts.COLUMN_TYPE_TEXT) private String extra = BytedeskConsts.EMPTY_JSON_STRING; // 方便后续扩展,比如用户被拉黑的时候,暂存于此 diff --git a/modules/service/src/main/java/com/bytedesk/service/visitor_thread/VisitorThreadEntity.java b/modules/service/src/main/java/com/bytedesk/service/visitor_thread/VisitorThreadEntity.java index b3dee9a02f..46aa679b14 100644 --- a/modules/service/src/main/java/com/bytedesk/service/visitor_thread/VisitorThreadEntity.java +++ b/modules/service/src/main/java/com/bytedesk/service/visitor_thread/VisitorThreadEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-06-29 13:00:33 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2024-12-25 14:05:51 + * @LastEditTime: 2025-02-11 17:07:20 * @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. @@ -24,12 +24,8 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.BytedeskConsts; -import com.bytedesk.core.constant.TypeConsts; import com.bytedesk.core.enums.ClientEnum; import com.bytedesk.core.thread.ThreadStateEnum; import com.bytedesk.core.thread.ThreadTypeEnum; @@ -112,10 +108,12 @@ public class VisitorThreadEntity extends BaseEntity { private String client = ClientEnum.WEB.name(); @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) // 用于兼容postgreSQL,否则会报错,[ERROR: column "extra" is of type json but expression is // of type character varying - @JdbcTypeCode(SqlTypes.JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(length = 1024) private String extra = BytedeskConsts.EMPTY_JSON_STRING; /** @@ -128,8 +126,10 @@ public class VisitorThreadEntity extends BaseEntity { * 注意:h2 db 不能使用 user, 所以重定义为 thread_user */ @Builder.Default - @Column(name = "thread_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(name = "thread_user", columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "thread_user") private String user = BytedeskConsts.EMPTY_JSON_STRING; /** @@ -140,8 +140,10 @@ public class VisitorThreadEntity extends BaseEntity { * FIXME: 头像、昵称和机器人大模型中参数修改之后,不能及时同步更新 */ @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "thread_agent") private String agent = BytedeskConsts.EMPTY_JSON_STRING; // 机器人和agent可以同时存在,人工接待的时候,机器人可以同时给出答案,客服可以选用 diff --git a/modules/service/src/main/java/com/bytedesk/service/visitor_thread/VisitorThreadService.java b/modules/service/src/main/java/com/bytedesk/service/visitor_thread/VisitorThreadService.java index f765c241dc..1b6a2da614 100644 --- a/modules/service/src/main/java/com/bytedesk/service/visitor_thread/VisitorThreadService.java +++ b/modules/service/src/main/java/com/bytedesk/service/visitor_thread/VisitorThreadService.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-06-29 13:08:52 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-02-11 11:18:08 + * @LastEditTime: 2025-02-11 16:55:41 * @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. @@ -121,6 +121,7 @@ public class VisitorThreadService // String visitor = ConvertServiceUtils.convertToUserProtobufJSONString(visitorRequest); thread.setUser(visitor); + threadService.save(thread); // return thread; } @@ -135,7 +136,9 @@ public class VisitorThreadService .convertToServiceSettingsResponseVisitorJSONString(workgroup.getServiceSettings()); thread.setExtra(extra); } - // + // 保存 + threadService.save(thread); + // return thread; } @@ -153,6 +156,7 @@ public class VisitorThreadService // thread.setOwner(agent.getMember().getUser()); thread.setOrgUid(agent.getOrgUid()); + threadService.save(thread); // return thread; } @@ -165,6 +169,8 @@ public class VisitorThreadService // 考虑到客服信息发生变化,更新客服信息 String agentString = ConvertServiceUtils.convertToUserProtobufJSONString(agent); thread.setAgent(agentString); + // 保存 + threadService.save(thread); // return thread; } @@ -182,6 +188,7 @@ public class VisitorThreadService // UserProtobuf visitor = ConvertServiceUtils.convertToUserProtobuf(visitorRequest); thread.setUser(JSON.toJSONString(visitor)); + threadService.save(thread); // return thread; } @@ -194,6 +201,8 @@ public class VisitorThreadService // 使用agent的serviceSettings配置 String robotString = ConvertAiUtils.convertToUserProtobufString(robot); thread.setAgent(robotString); + // 保存 + threadService.save(thread); // return thread; } diff --git a/modules/service/src/main/java/com/bytedesk/service/workgroup/WorkgroupEntity.java b/modules/service/src/main/java/com/bytedesk/service/workgroup/WorkgroupEntity.java index ce5c7e17a8..d1042e94f4 100644 --- a/modules/service/src/main/java/com/bytedesk/service/workgroup/WorkgroupEntity.java +++ b/modules/service/src/main/java/com/bytedesk/service/workgroup/WorkgroupEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-01-29 16:19:51 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-02-08 10:27:28 + * @LastEditTime: 2025-02-11 17:05:22 * @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,14 +18,10 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.AvatarConsts; import com.bytedesk.core.constant.BytedeskConsts; import com.bytedesk.core.constant.I18Consts; -import com.bytedesk.core.constant.TypeConsts; import com.bytedesk.kbase.service_settings.InviteSettings; import com.bytedesk.kbase.service_settings.ServiceSettings; import com.bytedesk.service.agent.AgentEntity; @@ -111,10 +107,11 @@ public class WorkgroupEntity extends BaseEntity { /** 存储下一个待分配的客服等信息 */ @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) // 用于兼容postgreSQL,否则会报错,[ERROR: column "extra" is of type json but expression is // of type character varying - @JdbcTypeCode(SqlTypes.JSON) + // @JdbcTypeCode(SqlTypes.JSON) + @Column(length = 1024) private String extra = BytedeskConsts.EMPTY_JSON_STRING; diff --git a/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketCaseListener.java b/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketCaseListener.java index 9724b936b6..59d8bd9ace 100644 --- a/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketCaseListener.java +++ b/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketCaseListener.java @@ -18,6 +18,8 @@ import org.flowable.cmmn.api.runtime.CaseInstance; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import com.alibaba.fastjson2.JSON; +import com.bytedesk.core.rbac.user.UserProtobuf; import com.bytedesk.ticket.service.TicketNotificationService; import com.bytedesk.ticket.sla.TicketSLAService; import com.bytedesk.ticket.ticket.TicketRestService; @@ -84,8 +86,10 @@ public class TicketCaseListener implements CaseInstanceLifecycleListener { private void handleCaseTerminated(CaseInstance caseInstance) { // 通知相关人员工单被终止 ticketService.findByUid(caseInstance.getId()).ifPresent(ticket -> { + String assigneeUid = JSON.parseObject(ticket.getAssignee(), UserProtobuf.class).getUid(); + // notificationService.notifyManager( - ticket.getAssignee().getUid(), + assigneeUid, String.format("工单 #%d 已被终止", ticket.getId()) ); }); diff --git a/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketEventListener.java b/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketEventListener.java index effa95a40d..3ec6497550 100644 --- a/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketEventListener.java +++ b/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketEventListener.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2025-01-23 14:52:45 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-02-05 12:13:48 + * @LastEditTime: 2025-02-11 15:58:22 * @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. @@ -22,6 +22,8 @@ import org.flowable.engine.runtime.ProcessInstance; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; +import com.alibaba.fastjson2.JSON; +import com.bytedesk.core.rbac.user.UserProtobuf; import com.bytedesk.ticket.consts.TicketConsts; import com.bytedesk.ticket.event.TicketCreateEvent; import com.bytedesk.ticket.event.TicketUpdateEvent; @@ -50,14 +52,14 @@ public class TicketEventListener { Map variables = new HashMap<>(); variables.put("ticketUid", ticket.getUid()); variables.put("orgUid", ticket.getOrgUid()); - variables.put("userUid", ticket.getReporter().getUid()); + variables.put("userUid", JSON.parseObject(ticket.getReporter(), UserProtobuf.class).getUid()); String processKey = null; if (ticket.getType().equals(TicketTypeEnum.AGENT.name())) { processKey = TicketConsts.TICKET_PROCESS_KEY_AGENT; - variables.put("agentUid", ticket.getAssignee().getUid()); + variables.put("agentUid", JSON.parseObject(ticket.getAssignee(), UserProtobuf.class).getUid()); } else { processKey = TicketConsts.TICKET_PROCESS_KEY_GROUP; - variables.put("workgroupUid", ticket.getWorkgroup().getUid()); + variables.put("workgroupUid", JSON.parseObject(ticket.getWorkgroup(), UserProtobuf.class).getUid()); } // 根据不同优先级设置不同的SLA时间 switch (ticket.getPriority()) { diff --git a/modules/ticket/src/main/java/com/bytedesk/ticket/sla/TicketSLAService.java b/modules/ticket/src/main/java/com/bytedesk/ticket/sla/TicketSLAService.java index 1c5fb9d8b9..d41e01d62c 100644 --- a/modules/ticket/src/main/java/com/bytedesk/ticket/sla/TicketSLAService.java +++ b/modules/ticket/src/main/java/com/bytedesk/ticket/sla/TicketSLAService.java @@ -1,8 +1,8 @@ /* * @Author: jackning 270580156@qq.com * @Date: 2025-01-21 13:06:07 - * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-02-05 14:57:46 + * @LastEditors: jackning 270580156@qq.com + * @LastEditTime: 2025-02-11 15:58:44 * @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. @@ -17,6 +17,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.alibaba.fastjson2.JSON; +import com.bytedesk.core.rbac.user.UserProtobuf; import com.bytedesk.ticket.service.TicketNotificationService; import com.bytedesk.ticket.ticket.TicketEntity; @@ -55,7 +57,7 @@ public class TicketSLAService { * 检查工单是否违反 SLA */ public boolean isSLABreached(TicketEntity ticket) { - Map sla = determineSLA(ticket.getCategory().getUid(), ticket.getPriority()); + Map sla = determineSLA(ticket.getCategoryUid(), ticket.getPriority()); LocalDateTime now = LocalDateTime.now(); LocalDateTime createdAt = ticket.getCreatedAt(); @@ -112,6 +114,6 @@ public class TicketSLAService { ticket.getId(), ticket.getCreatedAt() ); - notificationService.notifyManager(ticket.getAssignee().getUid(), message); + notificationService.notifyManager(JSON.parseObject(ticket.getAssignee(), UserProtobuf.class).getUid(), message); } } \ No newline at end of file diff --git a/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketEntity.java b/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketEntity.java index ddbe9bff99..7a849a5c74 100644 --- a/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketEntity.java +++ b/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketEntity.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2025-01-16 14:56:11 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-02-11 15:47:18 + * @LastEditTime: 2025-02-11 16:40:53 * @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. @@ -15,12 +15,8 @@ package com.bytedesk.ticket.ticket; import java.util.List; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import com.bytedesk.core.base.BaseEntity; import com.bytedesk.core.constant.BytedeskConsts; -import com.bytedesk.core.constant.TypeConsts; import com.bytedesk.ticket.attachment.TicketAttachmentEntity; import com.bytedesk.ticket.comment.TicketCommentEntity; import com.bytedesk.ticket.listener.TicketEntityListener; @@ -49,8 +45,16 @@ public class TicketEntity extends BaseEntity { @Column(nullable = false) private String title; // 工单标题(必填) + // 非结构化内容 private String description; // 工单描述(选填) + // 结构化内容 + @Builder.Default + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) + private String form = BytedeskConsts.EMPTY_JSON_STRING; + @Builder.Default private String status = TicketStatusEnum.NEW.name(); // 状态(新建/处理中/已解决/已关闭) @@ -79,8 +83,9 @@ public class TicketEntity extends BaseEntity { // @ManyToOne(fetch = FetchType.LAZY) // private WorkgroupEntity workgroup; @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) private String workgroup = BytedeskConsts.EMPTY_JSON_STRING; // 使用UserProtobuf json格式化 @@ -88,8 +93,9 @@ public class TicketEntity extends BaseEntity { // @ManyToOne(fetch = FetchType.LAZY) // private AgentEntity assignee; // 处理人 @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) private String assignee = BytedeskConsts.EMPTY_JSON_STRING; // 使用UserProtobuf json格式化 @@ -97,8 +103,9 @@ public class TicketEntity extends BaseEntity { // @ManyToOne(fetch = FetchType.LAZY) // private UserEntity reporter; // 报告人 @Builder.Default - @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) - @JdbcTypeCode(SqlTypes.JSON) + // json字段格式,搜索时,对数据库有依赖,不方便迁移 + // @Column(columnDefinition = TypeConsts.COLUMN_TYPE_JSON) + // @JdbcTypeCode(SqlTypes.JSON) private String reporter = BytedeskConsts.EMPTY_JSON_STRING; // 工单评论 diff --git a/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketRestService.java b/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketRestService.java index 2bd6b01c79..8b83e792c2 100644 --- a/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketRestService.java +++ b/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketRestService.java @@ -11,7 +11,6 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.orm.ObjectOptimisticLockingFailureException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; @@ -22,8 +21,6 @@ import java.time.LocalDateTime; import com.alibaba.fastjson2.JSON; import com.bytedesk.core.base.BaseRestService; -import com.bytedesk.core.category.CategoryEntity; -import com.bytedesk.core.category.CategoryRestService; import com.bytedesk.core.rbac.auth.AuthService; import com.bytedesk.core.rbac.user.UserEntity; import com.bytedesk.core.rbac.user.UserProtobuf; @@ -75,7 +72,7 @@ public class TicketRestService extends BaseRestService threadOptional = threadRestService.findFirstByTopic(request.getServiceThreadTopic()); - if (threadOptional.isPresent()) { - ticket.setServiceThread(threadOptional.get()); - } - } - // - if (StringUtils.hasText(request.getCategoryUid())) { - Optional categoryOptional = categoryRestService.findByUid(request.getCategoryUid()); - if (categoryOptional.isPresent()) { - ticket.setCategory(categoryOptional.get()); - } - } - // Optional workgroupOptional = workgroupRestService.findByUid(request.getWorkgroupUid()); if (workgroupOptional.isPresent()) { - ticket.setWorkgroup(workgroupOptional.get()); + UserProtobuf workgroupProtobuf = UserProtobuf.builder() + .nickname(workgroupOptional.get().getNickname()) + .avatar(workgroupOptional.get().getAvatar()) + .build(); + workgroupProtobuf.setUid(workgroupOptional.get().getUid()); + workgroupProtobuf.setType(UserTypeEnum.WORKGROUP.name()); + String workgroupJson = JSON.toJSONString(workgroupProtobuf); + ticket.setWorkgroup(workgroupJson); } else { throw new RuntimeException("workgroup not found"); } // Optional assigneeOptional = agentRestService.findByUid(request.getAssigneeUid()); if (assigneeOptional.isPresent()) { - ticket.setAssignee(assigneeOptional.get()); + UserProtobuf assigneeProtobuf = UserProtobuf.builder() + .nickname(assigneeOptional.get().getNickname()) + .avatar(assigneeOptional.get().getAvatar()) + .build(); + assigneeProtobuf.setUid(assigneeOptional.get().getUid()); + assigneeProtobuf.setType(UserTypeEnum.AGENT.name()); + String assigneeJson = JSON.toJSONString(assigneeProtobuf); + ticket.setAssignee(assigneeJson); ticket.setType(TicketTypeEnum.AGENT.name()); ticket.setStatus(TicketStatusEnum.ASSIGNED.name()); // @@ -163,7 +160,7 @@ public class TicketRestService extends BaseRestService reporterOptional = userRestService.findByUid(request.getReporterUid()); if (reporterOptional.isPresent()) { - ticket.setReporter(reporterOptional.get()); + UserProtobuf reporterProtobuf = UserProtobuf.builder() + .nickname(reporterOptional.get().getNickname()) + .avatar(reporterOptional.get().getAvatar()) + .build(); + reporterProtobuf.setUid(reporterOptional.get().getUid()); + reporterProtobuf.setType(UserTypeEnum.USER.name()); + ticket.setReporter(JSON.toJSONString(reporterProtobuf)); } // 先保存工单 TicketEntity savedTicket = save(ticket); @@ -224,24 +227,26 @@ public class TicketRestService extends BaseRestService threadOptional = threadRestService.findFirstByTopic(request.getThreadTopic()); - if (threadOptional.isPresent()) { - ticket.setThread(threadOptional.get()); - } - // - Optional categoryOptional = categoryRestService.findByUid(request.getCategoryUid()); - if (categoryOptional.isPresent()) { - ticket.setCategory(categoryOptional.get()); - } - // Optional assigneeOptional = agentRestService.findByUid(request.getAssigneeUid()); if (assigneeOptional.isPresent()) { - ticket.setAssignee(assigneeOptional.get()); + UserProtobuf assigneeProtobuf = UserProtobuf.builder() + .nickname(assigneeOptional.get().getNickname()) + .avatar(assigneeOptional.get().getAvatar()) + .build(); + assigneeProtobuf.setUid(assigneeOptional.get().getUid()); + assigneeProtobuf.setType(UserTypeEnum.AGENT.name()); + ticket.setAssignee(JSON.toJSONString(assigneeProtobuf)); } // Optional workgroupOptional = workgroupRestService.findByUid(request.getWorkgroupUid()); if (workgroupOptional.isPresent()) { - ticket.setWorkgroup(workgroupOptional.get()); + UserProtobuf workgroupProtobuf = UserProtobuf.builder() + .nickname(workgroupOptional.get().getNickname()) + .avatar(workgroupOptional.get().getAvatar()) + .build(); + workgroupProtobuf.setUid(workgroupOptional.get().getUid()); + workgroupProtobuf.setType(UserTypeEnum.WORKGROUP.name()); + ticket.setWorkgroup(JSON.toJSONString(workgroupProtobuf)); } // 先保存工单 TicketEntity savedTicket = save(ticket); @@ -317,7 +322,13 @@ public class TicketRestService extends BaseRestService +# ticket + +```java +public static Specification search(TicketRequest request) { + return (root, query, criteriaBuilder) -> { + query.distinct(true); + + List predicates = new ArrayList<>(); + predicates.addAll(getBasicPredicates(root, criteriaBuilder, request.getOrgUid())); + + if (StringUtils.hasText(request.getTitle())) { + predicates.add(criteriaBuilder.like(root.get("title"), "%" + request.getTitle() + "%")); + } + if (StringUtils.hasText(request.getDescription())) { + predicates.add(criteriaBuilder.like(root.get("description"), "%" + request.getDescription() + "%")); + } + if (StringUtils.hasText(request.getSearchText())) { + predicates.add(criteriaBuilder.or( + criteriaBuilder.like(root.get("uid"), "%" + request.getSearchText() + "%"), + criteriaBuilder.like(root.get("title"), "%" + request.getSearchText() + "%"), + criteriaBuilder.like(root.get("description"), "%" + request.getSearchText() + "%") + )); + } + if (StringUtils.hasText(request.getStatus())) { + predicates.add(criteriaBuilder.equal(root.get("status"), request.getStatus())); + } + if (StringUtils.hasText(request.getPriority())) { + predicates.add(criteriaBuilder.equal(root.get("priority"), request.getPriority())); + } + if (StringUtils.hasText(request.getCategoryUid())) { + predicates.add(criteriaBuilder.equal(root.get("category").get("uid"), request.getCategoryUid())); + } + if (StringUtils.hasText(request.getThreadTopic())) { + predicates.add(criteriaBuilder.equal(root.get("thread").get("topic"), request.getThreadTopic())); + } + if (StringUtils.hasText(request.getWorkgroupUid())) { + predicates.add(criteriaBuilder.equal(root.get("workgroup").get("uid"), request.getWorkgroupUid())); + } + // 处理 ALL 查询 - 我创建的或待我处理的 + if (StringUtils.hasText(request.getReporterUid()) || StringUtils.hasText(request.getAssigneeUid())) { + if (Boolean.TRUE.equals(request.getAssignmentAll())) { + List orPredicates = new ArrayList<>(); + + // 处理 reporter 条件 + if (StringUtils.hasText(request.getReporterUid())) { + var reporterJoin = root.join("reporter", JoinType.LEFT); + orPredicates.add(criteriaBuilder.equal(reporterJoin.get("uid"), request.getReporterUid())); + } + + // 处理 assignee 条件 + if (StringUtils.hasText(request.getAssigneeUid())) { + var assigneeJoin = root.join("assignee", JoinType.LEFT); + orPredicates.add(criteriaBuilder.equal(assigneeJoin.get("uid"), request.getAssigneeUid())); + } + + // 组合 OR 条件 + if (!orPredicates.isEmpty()) { + predicates.add(criteriaBuilder.or(orPredicates.toArray(new Predicate[0]))); + } + } else { + + if (TicketConsts.TICKET_FILTER_UNASSIGNED.equals(request.getAssigneeUid())) { + predicates.add(criteriaBuilder.isNull(root.get("assignee"))); + } else { + // 单一条件查询 + if (StringUtils.hasText(request.getReporterUid())) { + var reporterJoin = root.join("reporter"); + predicates.add(criteriaBuilder.equal(reporterJoin.get("uid"), request.getReporterUid())); + } + if (StringUtils.hasText(request.getAssigneeUid())) { + var assigneeJoin = root.join("assignee"); + predicates.add(criteriaBuilder.equal(assigneeJoin.get("uid"), request.getAssigneeUid())); + } + } + } + } + // 处理日期范围查询 + if (StringUtils.hasText(request.getStartDate())) { + LocalDateTime startDate = LocalDateTime.parse(request.getStartDate(), formatter); + predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createdAt"), startDate)); + } + if (StringUtils.hasText(request.getEndDate())) { + LocalDateTime endDate = LocalDateTime.parse(request.getEndDate(), formatter); + predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createdAt"), endDate)); + } + + // 添加排序 + query.orderBy(criteriaBuilder.desc(root.get("updatedAt"))); + + return criteriaBuilder.and(predicates.toArray(new Predicate[0])); + }; +} +``` + +```java +// 字段为 json 格式 +if (StringUtils.hasText(request.getWorkgroupUid())) { + predicates.add(criteriaBuilder.equal( + criteriaBuilder.function( + "JSON_CONTAINS", + Integer.class, + root.get("workgroup"), + criteriaBuilder.literal("{\"uid\":\"" + request.getWorkgroupUid() + "\"}") + ), + 1 + )); +} +// 处理 ALL 查询 - 我创建的或待我处理的 +if (StringUtils.hasText(request.getReporterUid()) || StringUtils.hasText(request.getAssigneeUid())) { + if (Boolean.TRUE.equals(request.getAssignmentAll())) { + List orPredicates = new ArrayList<>(); + + // 处理 reporter 条件 + if (StringUtils.hasText(request.getReporterUid())) { + orPredicates.add(criteriaBuilder.equal( + criteriaBuilder.function( + "JSON_CONTAINS", + Integer.class, + root.get("reporter"), + criteriaBuilder.literal("{\"uid\":\"" + request.getReporterUid() + "\"}") + ), + 1 + )); + } + + // 处理 assignee 条件 + if (StringUtils.hasText(request.getAssigneeUid())) { + if (TicketConsts.TICKET_FILTER_UNASSIGNED.equals(request.getAssigneeUid())) { + orPredicates.add(criteriaBuilder.or( + criteriaBuilder.isNull(root.get("assignee")), + criteriaBuilder.equal(root.get("assignee"), BytedeskConsts.EMPTY_JSON_STRING) + )); + } else { + orPredicates.add(criteriaBuilder.equal( + criteriaBuilder.function( + "JSON_CONTAINS", + Integer.class, + root.get("assignee"), + criteriaBuilder.literal("{\"uid\":\"" + request.getAssigneeUid() + "\"}") + ), + 1 + )); + } + } + + // 组合 OR 条件 + if (!orPredicates.isEmpty()) { + predicates.add(criteriaBuilder.or(orPredicates.toArray(new Predicate[0]))); + } + } else { + // 单一条件查询 + if (StringUtils.hasText(request.getReporterUid())) { + predicates.add(criteriaBuilder.equal( + criteriaBuilder.function( + "JSON_CONTAINS", + Integer.class, + root.get("reporter"), + criteriaBuilder.literal("{\"uid\":\"" + request.getReporterUid() + "\"}") + ), + 1 + )); + } + if (StringUtils.hasText(request.getAssigneeUid())) { + if (TicketConsts.TICKET_FILTER_UNASSIGNED.equals(request.getAssigneeUid())) { + predicates.add(criteriaBuilder.or( + criteriaBuilder.isNull(root.get("assignee")), + criteriaBuilder.equal(root.get("assignee"), BytedeskConsts.EMPTY_JSON_STRING) + )); + } else { + predicates.add(criteriaBuilder.equal( + criteriaBuilder.function( + "JSON_CONTAINS", + Integer.class, + root.get("assignee"), + criteriaBuilder.literal("{\"uid\":\"" + request.getAssigneeUid() + "\"}") + ), + 1 + )); + } + } + } +} +```