This commit is contained in:
jack ning
2024-06-18 15:28:57 +08:00
parent 212d962371
commit f1fc648dfe
446 changed files with 3989 additions and 4199 deletions

BIN
.DS_Store vendored

Binary file not shown.

2
.vscode/launch.json vendored
View File

@@ -9,7 +9,7 @@
"name": "StarterApplication",
"request": "launch",
"mainClass": "com.bytedesk.starter.StarterApplication",
"projectName": "starter"
"projectName": "bytedesk-starter"
}
]
}

BIN
modules/.DS_Store vendored

Binary file not shown.

BIN
modules/ai/.DS_Store vendored

Binary file not shown.

Binary file not shown.

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:13:38
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-11 11:41:42
* @LastEditTime: 2024-06-14 12:07:30
* @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,6 +16,7 @@ package com.bytedesk.ai.kb;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.enums.LanguageEnum;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@@ -53,7 +54,8 @@ public class Kb extends BaseEntity {
private boolean published = true;
@Builder.Default
private String language = I18Consts.ZH_CN;
// private String language = I18Consts.ZH_CN;
private LanguageEnum language = LanguageEnum.ZH_CN;
/**
* belong to org

View File

@@ -15,6 +15,7 @@
package com.bytedesk.ai.robot;
import com.bytedesk.ai.kb.Kb;
import com.bytedesk.ai.settings.RobotServiceSettings;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.constant.AvatarConsts;
import com.bytedesk.core.constant.I18Consts;

View File

@@ -50,13 +50,13 @@ public class RobotLlm {
private RobotEmbedingEnum embeddings = RobotEmbedingEnum.M3E_BASE;
@Builder.Default
private Float temperature = 0.9f;
private float temperature = 0.9f;
@Builder.Default
private Float topP = 0.7f;
private float topP = 0.7f;
@Builder.Default
private String prompt = I18Consts.I18N_ROBOT_LLM_PROMPT_ZH_CN;
private String prompt = I18Consts.I18N_ROBOT_LLM_PROMPT;
// 默认是true表示使用自定义模型, false表示云服务需要在配置文件中配置相关参数
@Builder.Default

View File

@@ -14,6 +14,7 @@
*/
package com.bytedesk.ai.robot;
import com.bytedesk.ai.settings.RobotServiceSettingsRequest;
import com.bytedesk.core.base.BaseRequest;
import jakarta.validation.constraints.NotBlank;

View File

@@ -14,6 +14,7 @@
*/
package com.bytedesk.ai.robot;
import com.bytedesk.ai.settings.RobotServiceSettings;
import com.bytedesk.core.base.BaseResponse;
import lombok.AllArgsConstructor;

View File

@@ -29,6 +29,7 @@ import org.springframework.stereotype.Service;
import com.bytedesk.ai.kb.Kb;
import com.bytedesk.ai.kb.KbService;
import com.bytedesk.ai.settings.RobotServiceSettings;
import com.bytedesk.core.base.BaseService;
import com.bytedesk.core.constant.AvatarConsts;
import com.bytedesk.core.constant.I18Consts;

View File

@@ -1,91 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-04 17:16:54
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-11 12:29:46
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.ai.robot;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.thread.ThreadTypeEnum;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.FetchType;
import jakarta.persistence.OneToMany;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@Builder
@Embeddable
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class RobotServiceSettingsRequest {
@Builder.Default
private String language = I18Consts.ZH_CN;
@Builder.Default
@Column(name = "is_auto_pop")
private boolean autoPop = false;
/**
* TODO: set different tips for different lang
*/
@Builder.Default
private boolean showTopTip = false;
@Builder.Default
@Column(length = 512)
private String topTip = I18Consts.I18N_TOP_TIP;
@Builder.Default
private String welcomeTip = I18Consts.I18N_WELCOME_TIP;
@Builder.Default
private String leavemsgTip = I18Consts.I18N_LEAVEMSG_TIP;
/** auto close time in min - 默认自动关闭时间,单位分钟 */
@Builder.Default
private Double autoCloseMin = Double.valueOf(25);
@Builder.Default
@OneToMany(fetch = FetchType.LAZY)
private List<String> quickButtonUids = new ArrayList<>();
// 是否允许转人工
@Builder.Default
private boolean allowTransferToAgent = true;
// 限制仅允许workgroup、appointed
@Builder.Default
private ThreadTypeEnum transferType = ThreadTypeEnum.WORKGROUP;
// agentUid or workgroupUid
private String transferToUid;
//
@Builder.Default
private boolean showLogo = true;
// private String logoUrl;
// 有效日期
private Date validateUntil;
}

View File

@@ -1,92 +0,0 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-04 17:16:54
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-12 10:40:36
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.ai.robot;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.quick_button.QuickButton;
import com.bytedesk.core.thread.ThreadTypeEnum;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.FetchType;
import jakarta.persistence.OneToMany;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@Builder
@Embeddable
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class RobotServiceSettingsResponse {
@Builder.Default
private String language = I18Consts.ZH_CN;
@Builder.Default
@Column(name = "is_auto_pop")
private boolean autoPop = false;
/**
* TODO: set different tips for different lang
*/
@Builder.Default
private boolean showTopTip = false;
@Builder.Default
@Column(length = 512)
private String topTip = I18Consts.I18N_TOP_TIP;
@Builder.Default
private String welcomeTip = I18Consts.I18N_WELCOME_TIP;
@Builder.Default
private String leavemsgTip = I18Consts.I18N_LEAVEMSG_TIP;
/** auto close time in min - 默认自动关闭时间,单位分钟 */
@Builder.Default
private Double autoCloseMin = Double.valueOf(25);
@Builder.Default
@OneToMany(fetch = FetchType.LAZY)
private List<QuickButton> quickButtons = new ArrayList<>();
// 是否允许转人工
@Builder.Default
private boolean allowTransferToAgent = true;
// 限制仅允许workgroup、appointed
@Builder.Default
private ThreadTypeEnum transferType = ThreadTypeEnum.WORKGROUP;
// agentUid or workgroupUid
private String transferToUid;
//
@Builder.Default
private boolean showLogo = true;
// private String logoUrl;
// 有效日期
private Date validateUntil;
}

View File

@@ -0,0 +1,89 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-04 17:16:54
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-14 10:57:24
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.ai.settings;
import com.bytedesk.core.service_settings.BaseServiceSettings;
import com.bytedesk.core.thread.ThreadTypeEnum;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@Embeddable
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class RobotServiceSettings extends BaseServiceSettings {
// @Builder.Default
// private String language = I18Consts.ZH_CN;
// @Builder.Default
// @Column(name = "is_auto_pop")
// private boolean autoPop = false;
// /**
// * TODO: set different tips for different lang
// */
// @Builder.Default
// private boolean showTopTip = false;
// @Builder.Default
// @Column(length = 512)
// private String topTip = I18Consts.I18N_TOP_TIP;
// @Builder.Default
// private String welcomeTip = I18Consts.I18N_WELCOME_TIP;
// @Builder.Default
// private String leavemsgTip = I18Consts.I18N_LEAVEMSG_TIP;
// /** auto close time in min - 默认自动关闭时间,单位分钟 */
// @Builder.Default
// private Double autoCloseMin = Double.valueOf(25);
// @Builder.Default
// @ManyToMany(fetch = FetchType.LAZY)
// private List<QuickButton> quickButtons = new ArrayList<>();
// @Builder.Default
// @ManyToMany(fetch = FetchType.LAZY)
// private List<Faq> faqs = new ArrayList<>();
// 是否允许转人工
@Builder.Default
private boolean allowTransferToAgent = true;
// 限制仅允许workgroup、appointed
@Builder.Default
private ThreadTypeEnum transferType = ThreadTypeEnum.WORKGROUP;
// agentUid or workgroupUid
private String transferToUid;
//
// @Builder.Default
// private boolean showLogo = true;
// // 有效日期
// private Date validateUntil;
}

View File

@@ -0,0 +1,87 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-04 17:16:54
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-14 12:14:04
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.ai.settings;
import com.bytedesk.core.service_settings.BaseServiceSettingsRequest;
import com.bytedesk.core.thread.ThreadTypeEnum;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@Embeddable
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class RobotServiceSettingsRequest extends BaseServiceSettingsRequest {
// @Builder.Default
// // private String language = I18Consts.ZH_CN;
// private LanguageEnum language = LanguageEnum.ZH_CN;
// @Builder.Default
// @Column(name = "is_auto_pop")
// private boolean autoPop = false;
// /**
// * TODO: set different tips for different lang
// */
// @Builder.Default
// private boolean showTopTip = false;
// @Builder.Default
// @Column(length = 512)
// private String topTip = I18Consts.I18N_TOP_TIP;
// @Builder.Default
// private String welcomeTip = I18Consts.I18N_WELCOME_TIP;
// @Builder.Default
// private String leavemsgTip = I18Consts.I18N_LEAVEMSG_TIP;
// /** auto close time in min - 默认自动关闭时间,单位分钟 */
// @Builder.Default
// private Double autoCloseMin = Double.valueOf(25);
// @Builder.Default
// @OneToMany(fetch = FetchType.LAZY)
// private List<String> quickButtonUids = new ArrayList<>();
// 是否允许转人工
@Builder.Default
private boolean allowTransferToAgent = true;
// 限制仅允许workgroup、appointed
@Builder.Default
private ThreadTypeEnum transferType = ThreadTypeEnum.WORKGROUP;
// agentUid or workgroupUid
private String transferToUid;
//
// @Builder.Default
// private boolean showLogo = true;
// // private String logoUrl;
// // 有效日期
// private Date validateUntil;
}

View File

@@ -0,0 +1,90 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-04 17:16:54
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-14 12:34:02
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.ai.settings;
import com.bytedesk.core.service_settings.BaseServiceSettingsResponse;
import com.bytedesk.core.thread.ThreadTypeEnum;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@Embeddable
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class RobotServiceSettingsResponse extends BaseServiceSettingsResponse {
// @Builder.Default
// // private String language = I18Consts.ZH_CN;
// private LanguageEnum language = LanguageEnum.ZH_CN;
// @Builder.Default
// @Column(name = "is_auto_pop")
// private boolean autoPop = false;
// /**
// * TODO: set different tips for different lang
// */
// @Builder.Default
// private boolean showTopTip = false;
// @Builder.Default
// @Column(length = 512)
// private String topTip = I18Consts.I18N_TOP_TIP;
// @Builder.Default
// private String welcomeTip = I18Consts.I18N_WELCOME_TIP;
// @Builder.Default
// private String leavemsgTip = I18Consts.I18N_LEAVEMSG_TIP;
// /** auto close time in min - 默认自动关闭时间,单位分钟 */
// @Builder.Default
// private Double autoCloseMin = Double.valueOf(25);
// @Builder.Default
// @OneToMany(fetch = FetchType.LAZY)
// private List<QuickButtonResponse> quickButtons = new ArrayList<>();
// @Builder.Default
// @ManyToMany(fetch = FetchType.LAZY)
// private List<FaqResponse> faqs = new ArrayList<>();
// 是否允许转人工
@Builder.Default
private boolean allowTransferToAgent = true;
// 限制仅允许workgroup、appointed
@Builder.Default
private ThreadTypeEnum transferType = ThreadTypeEnum.WORKGROUP;
// agentUid or workgroupUid
private String transferToUid;
// //
// @Builder.Default
// private boolean showLogo = true;
// // 有效日期
// private Date validateUntil;
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-06 11:28:01
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-06 11:29:36
* @LastEditTime: 2024-06-14 12:30:56
* @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,12 +19,14 @@ import org.modelmapper.ModelMapper;
import com.bytedesk.ai.robot.Robot;
import com.bytedesk.ai.robot.RobotResponse;
import com.bytedesk.ai.robot.RobotResponseSimple;
import com.bytedesk.ai.settings.RobotServiceSettings;
import com.bytedesk.core.service_settings.ServiceSettingsResponseVisitor;
public class ConvertAiUtils {
private ConvertAiUtils() {
}
public static RobotResponse convertToRobotResponse(Robot entity) {
return new ModelMapper().map(entity, RobotResponse.class);
}
@@ -33,4 +35,9 @@ public class ConvertAiUtils {
return new ModelMapper().map(entity, RobotResponseSimple.class);
}
public static ServiceSettingsResponseVisitor convertToServiceSettingsResponseVisitor(RobotServiceSettings serviceSettings) {
return new ModelMapper().map(serviceSettings, ServiceSettingsResponseVisitor.class);
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-31 11:00:20
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-06 10:48:32
* @LastEditTime: 2024-06-14 13:55:30
* @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.
@@ -93,7 +93,6 @@ public class ZhipuAiController {
}
//
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
// http://localhost:9003/visitor/api/v1/zhipuai/sse?uid=&sid=&content=hi

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-05 15:39:22
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-11 11:43:13
* @LastEditTime: 2024-06-14 10:28: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.
@@ -89,7 +89,7 @@ public class ZhipuAiService {
//
String messageUid = uidUtils.getCacheSerialUid();
Message message = Message.builder()
.type(MessageTypeEnum.QA)
.type(MessageTypeEnum.ROBOT_QA)
.status(MessageStatusEnum.SENT)
.client(ClientEnum.SYSTEM)
.orgUid(thread.getOrgUid())

BIN
modules/core/.DS_Store vendored

Binary file not shown.

View File

@@ -22,11 +22,69 @@
<dependencies>
<!--
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<scope>provided</scope>
</dependency>
<!--
https://mvnrepository.com/artifact/org.springframework.security/spring-security-messaging -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-messaging</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.106.Final</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.25.2</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java-util -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.25.2</version>
<scope>provided</scope>
</dependency>
<!--
https://mvnrepository.com/artifact/com.googlecode.protobuf-java-format/protobuf-java-format -->
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.4</version>
<scope>provided</scope>
</dependency>
<!-- https://github.com/redisson/redisson?tab=readme-ov-file -->
<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
<!-- <dependency>
@@ -122,11 +180,74 @@
<build>
<plugins>
<!-- <plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin> -->
<!--自动生成protobuf
java类-->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<extensions>true</extensions>
<configuration>
<!--默认值-->
<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
<!--默认值-->
<!--<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>-->
<!--<outputDirectory>${project.build.sourceDirectory}</outputDirectory>-->
<!--设置是否在生成java文件之前清空outputDirectory的文件默认值为true设置为false时也会覆盖同名文件-->
<clearOutputDirectory>false</clearOutputDirectory>
<!--默认值-->
<temporaryProtoFileDirectory>${project.build.directory}/protoc-dependencies</temporaryProtoFileDirectory>
<!--更多配置信息可以查看https://www.xolstice.org/protobuf-maven-plugin/compile-mojo.html-->
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
<!--也可以设置成局部变量执行compile或test-compile时才执行-->
<!--<configuration>-->
<!--<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>-->
<!--<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>-->
<!--<temporaryProtoFileDirectory>${project.build.directory}/protoc-dependencies</temporaryProtoFileDirectory>-->
<!--</configuration>-->
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-protobuf-generate-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<!--<source>target/generated-sources/protobuf/java</source>-->
<source>src/main/java</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-protobuf-generate-test-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>target/generated-test-sources/protobuf/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -1 +1,44 @@
<!--
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-29 16:24:49
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-15 16:26: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
-->
# core
## socket
```bash
# proxy
export http_proxy=http://127.0.0.1:10818
export https_proxy=http://127.0.0.1:10818
#
# gradle dependencies
# run gradle with hot reload
# 1. open one terminal, run
gradle build --continuous
# 2. open second terminal, run:
gradle bootRun
#
# 生成proto
gradle build
# 或
gradle generateProto
```
## links
- [mqtt](https://mqtt.org/mqtt-specification/)
- [mqtt-v3.1.1](https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html)
- [netty](https://netty.io/wiki/user-guide-for-4.x.html)
- [netty mqtt](https://netty.io/4.1/api/io/netty/handler/codec/mqtt/package-summary.html)
- [netty mqtt github](https://github.com/netty/netty/tree/4.1/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt)
- [spring stomp](https://docs.spring.io/spring-framework/reference/web/websocket/stomp/overview.html)

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-31 12:53:03
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-04 16:18:07
* @LastEditTime: 2024-06-14 10:45:30
* @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,24 +14,18 @@
*/
package com.bytedesk.core.base;
import com.bytedesk.core.constant.AvatarConsts;
// import com.bytedesk.core.constant.AvatarConsts;
import jakarta.persistence.MappedSuperclass;
import lombok.Data;
import lombok.EqualsAndHashCode;
// import jakarta.persistence.MappedSuperclass;
// import lombok.Data;
// import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper=false)
// @Entity
// @Table(name = "core_base_user")
// @Inheritance()
// @DiscriminatorColumn(name = "user_type")
@MappedSuperclass
public abstract class BaseUser extends BaseEntity {
// @Data
// @EqualsAndHashCode(callSuper=false)
// @MappedSuperclass
// public abstract class BaseUser extends BaseEntity {
private String nickname;
// private String nickname;
private String avatar = AvatarConsts.DEFAULT_AVATAR_URL;
}
// private String avatar = AvatarConsts.DEFAULT_AVATAR_URL;
// }

View File

@@ -51,6 +51,7 @@ public class Category extends BaseEntity {
// private String description;
// this category type may be user defined, so it should not be enum
@Column(name = TypeConsts.COLUMN_NAME_TYPE)
private String type;
@@ -59,9 +60,6 @@ public class Category extends BaseEntity {
// @Column(unique = true)
// private String path;
/**
* 排序
*/
@Builder.Default
private int orderNo = 0;

View File

@@ -1,3 +1,17 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-08 14:43:05
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-17 16:45:24
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.category;
public class CategoryConsts {
@@ -11,4 +25,5 @@ public class CategoryConsts {
public static final String CATEGORY_TYPE_ROBOT_KB = "robot_kb";
public static final String CATEGORY_TYPE_BLOG = "blog";
public static final String CATEGORY_TYPE_EMAIL = "email";
//
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-11 18:21:36
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-08 13:29:49
* @LastEditTime: 2024-06-17 17:05:32
* @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.
@@ -23,5 +23,5 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface CategoryRepository extends JpaRepository<Category, Long>, JpaSpecificationExecutor<Category> {
Optional<Category> findByUid(String uid);
List<Category> findByParentAndPlatformOrderByOrderNoAsc(Category parent, String platform);
// Boolean existsByPlatform(String platform);
Optional<Category> findByNameAndTypeAndOrgUidAndPlatform(String name, String type, String orgUid, String platform);
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-11 18:22:04
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-08 16:54:59
* @LastEditTime: 2024-06-17 17:33:00
* @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.
@@ -29,31 +29,35 @@ import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.stereotype.Service;
import com.bytedesk.core.base.BaseService;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.constant.UserConsts;
import com.bytedesk.core.uid.UidUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
// import lombok.extern.slf4j.Slf4j;
@Slf4j
// @Slf4j
@Service
@AllArgsConstructor
public class CategoryService extends BaseService<Category, CategoryRequest, CategoryResponse> {
private final CategoryRepository categoryRepository;
private final ModelMapper modelMapper;
private final UidUtils uidUtils;
public List<CategoryResponse> findByNullParent(String platform) {
// 一级分类
List<Category> firstCategoriesList = categoryRepository.findByParentAndPlatformOrderByOrderNoAsc(null, platform);
List<Category> firstCategoriesList = categoryRepository.findByParentAndPlatformOrderByOrderNoAsc(null,
platform);
Iterator<Category> iterator = firstCategoriesList.iterator();
while (iterator.hasNext()) {
Category category = iterator.next();
// 二级分类
List<Category> secondCategoriesSet = categoryRepository.findByParentAndPlatformOrderByOrderNoAsc(category, platform);
List<Category> secondCategoriesSet = categoryRepository.findByParentAndPlatformOrderByOrderNoAsc(category,
platform);
if (secondCategoriesSet != null && !secondCategoriesSet.isEmpty()) {
category.setChildren(secondCategoriesSet);
}
@@ -61,15 +65,15 @@ public class CategoryService extends BaseService<Category, CategoryRequest, Cate
return convertToResponseList(firstCategoriesList);
}
@Override
public Page<CategoryResponse> queryByOrg(CategoryRequest request) {
Pageable pageable = PageRequest.of(request.getPageNumber(), request.getPageSize(), Sort.Direction.ASC,
"updatedAt");
Specification<Category> specs = CategorySpecification.search(request);
Page<Category> page = categoryRepository.findAll(specs, pageable);
return page.map(this::convertToResponse);
@@ -88,22 +92,29 @@ public class CategoryService extends BaseService<Category, CategoryRequest, Cate
@Override
public CategoryResponse create(CategoryRequest request) {
Category category = modelMapper.map(request, Category.class);
category.setUid(uidUtils.getCacheSerialUid());
Category newCategory = save(category);
if (newCategory == null) {
throw new RuntimeException("category save error");
}
return convertToResponse(newCategory);
}
public Optional<Category> findByNameAndTypeAndOrgUidAndPlatform(String name, String type, String orgUid, String platform) {
return categoryRepository.findByNameAndTypeAndOrgUidAndPlatform(name, type, orgUid, platform);
}
@Override
public CategoryResponse update(CategoryRequest request) {
Optional<Category> category = findByUid(request.getUid());
if (!category.isPresent()) {
throw new RuntimeException("category not found");
}
Category entity = category.get();
// modelMapper.map(request, entity);
entity.setName(request.getName());
@@ -155,11 +166,8 @@ public class CategoryService extends BaseService<Category, CategoryRequest, Cate
@Override
public CategoryResponse convertToResponse(Category entity) {
CategoryResponse response = modelMapper.map(entity, CategoryResponse.class);
log.info("{} children length {}", entity.getName(), entity.getChildren().size());
// log.info("{} children length {}", entity.getName(), entity.getChildren().size());
// response.setChildren(convertToResponseList(entity.getChildren()));
return response;
}
@@ -175,6 +183,44 @@ public class CategoryService extends BaseService<Category, CategoryRequest, Cate
// public Boolean existsByPlatform(String platform) {
// return categoryRepository.existsByPlatform(platform);
// }
//
public void initData() {
if (categoryRepository.count() > 0) {
return;
}
String orgUid = UserConsts.DEFAULT_ORGANIZATION_UID;
// init quick reply categories
CategoryRequest categoryContact = CategoryRequest.builder()
.name(I18Consts.I18N_QUICK_REPLY_CATEGORY_CONTACT)
.orgUid(orgUid)
.build();
categoryContact.setType(CategoryConsts.CATEGORY_TYPE_QUICK_REPLY);
create(categoryContact);
CategoryRequest categoryThanks = CategoryRequest.builder()
.name(I18Consts.I18N_QUICK_REPLY_CATEGORY_THANKS)
.orgUid(orgUid)
.build();
categoryThanks.setType(CategoryConsts.CATEGORY_TYPE_QUICK_REPLY);
create(categoryThanks);
CategoryRequest categoryWelcome = CategoryRequest.builder()
.name(I18Consts.I18N_QUICK_REPLY_CATEGORY_WELCOME)
.orgUid(orgUid)
.build();
categoryWelcome.setType(CategoryConsts.CATEGORY_TYPE_QUICK_REPLY);
create(categoryWelcome);
CategoryRequest categoryBye = CategoryRequest.builder()
.name(I18Consts.I18N_QUICK_REPLY_CATEGORY_BYE)
.orgUid(orgUid)
.build();
categoryBye.setType(CategoryConsts.CATEGORY_TYPE_QUICK_REPLY);
create(categoryBye);
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-26 22:25:47
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-12 07:07:56
* @LastEditTime: 2024-06-17 17:29:38
* @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.
@@ -20,12 +20,12 @@ public class I18Consts {
private I18Consts() {
}
public static final String EN = "en";
// public static final String EN = "en";
// public static final String ZH = "zh";
//
public static final String EN_US = "en-US";
public static final String ZH_CN = "zh-CN";
public static final String ZH_TW = "zh-TW";
//
// public static final String EN_US = "en-US";
// public static final String ZH_CN = "zh-CN";
// public static final String ZH_TW = "zh-TW";
public static final String I18N_PREFIX = "i18n_";
// "文件助手"
@@ -54,18 +54,31 @@ public class I18Consts {
//
public static final String I18N_USER_NICKNAME = I18N_PREFIX + "user_nickname";
public static final String I18N_USER_DESCRIPTION = I18N_PREFIX + "user_description";
//
//
public static final String I18N_DESCRIPTION = I18N_PREFIX + "description";
// "你是一个聪明、对人类有帮助的人工智能,你可以对人类提出的问题给出有用、详细、礼貌的回答"
// "智能问答机器人"
//
public static final String I18N_ROBOT_NICKNAME = I18N_PREFIX + "robot_nickname";
public static final String I18N_ROBOT_DESCRIPTION = I18N_PREFIX + "robot_description";
//
public static final String I18N_ROBOT_LLM_PROMPT_ZH_CN = "你是一个聪明、对人类有帮助的人工智能,你可以对人类提出的问题给出有用、详细、礼貌的回答";
//
public static final String I18N_ROBOT_LLM_PROMPT = I18N_PREFIX + "llm_prompt";
//
public static final String I18N_ADMIN = I18N_PREFIX + "admin";
public static final String I18N_ADMIN_DESCRIPTION = I18N_PREFIX + "admin_description";
// quick reply category
public static final String I18N_QUICK_REPLY_CATEGORY_CONTACT = I18N_PREFIX + "contact"; // 询问联系方式
public static final String I18N_QUICK_REPLY_CATEGORY_THANKS = I18N_PREFIX + "thanks"; // 感谢
public static final String I18N_QUICK_REPLY_CATEGORY_WELCOME = I18N_PREFIX + "welcome"; // 问候
public static final String I18N_QUICK_REPLY_CATEGORY_BYE = I18N_PREFIX + "bye"; // 告别
//
public static final String I18N_QUICK_REPLY_CONTACT_TITLE = I18N_PREFIX + "contact_title";//
public static final String I18N_QUICK_REPLY_CONTACT_CONTENT = I18N_PREFIX + "contact_content";//
//
public static final String I18N_QUICK_REPLY_THANKS_TITLE = I18N_PREFIX + "thanks_title";//
public static final String I18N_QUICK_REPLY_THANKS_CONTENT = I18N_PREFIX + "thanks_content";//
//
public static final String I18N_QUICK_REPLY_WELCOME_TITLE = I18N_PREFIX + "welcome_title";//
public static final String I18N_QUICK_REPLY_WELCOME_CONTENT = I18N_PREFIX + "welcome_content";//
//
public static final String I18N_QUICK_REPLY_BYE_TITLE = I18N_PREFIX + "bye_title";//
public static final String I18N_QUICK_REPLY_BYE_CONTENT = I18N_PREFIX + "bye_content";//
}

View File

@@ -15,27 +15,27 @@
package com.bytedesk.core.enums;
public enum LanguageEnum {
EN("en"),
ZH_CN("zh-cn"),
ZH_TW("zh-tw");
EN,//("en"),
ZH_CN,//("zh-cn"),
ZH_TW,//("zh-tw");
private final String value;
// private final String value;
LanguageEnum(String value) {
this.value = value;
}
// LanguageEnum(String value) {
// this.value = value;
// }
public String getValue() {
return value;
}
// public String getValue() {
// return value;
// }
// 根据字符串查找对应的枚举常量
public static LanguageEnum fromValue(String value) {
for (LanguageEnum type : LanguageEnum.values()) {
if (type.getValue().equalsIgnoreCase(value)) {
return type;
}
}
throw new IllegalArgumentException("No enum constant with value: " + value);
}
// // 根据字符串查找对应的枚举常量
// public static LanguageEnum fromValue(String value) {
// for (LanguageEnum type : LanguageEnum.values()) {
// if (type.getValue().equalsIgnoreCase(value)) {
// return type;
// }
// }
// throw new IllegalArgumentException("No enum constant with value: " + value);
// }
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-26 09:31:29
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-11 16:28:00
* @LastEditTime: 2024-06-12 21:19:37
* @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.
@@ -30,15 +30,20 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@ControllerAdvice
public class GlobalControllerAdvice {
@ExceptionHandler(UsernameExistsException.class)
public ResponseEntity<?> handleUsernameExistsException(UsernameExistsException e) {
return ResponseEntity.ok().body(JsonResult.error(e.getMessage()));
}
@ExceptionHandler(EmailExistsException.class)
public ResponseEntity<?> handleEmailExistsException(EmailExistsException e) {
return ResponseEntity.ok().body(JsonResult.error("Email already exists, please login or use another one"));
return ResponseEntity.ok().body(JsonResult.error(e.getMessage()));
}
@ExceptionHandler(MobileExistsException.class)
public ResponseEntity<?> handleMobileExistsException(MobileExistsException e) {
return ResponseEntity.ok().body(JsonResult.error("Mobile already exists, please login or use another one"));
return ResponseEntity.ok().body(JsonResult.error(e.getMessage()));
}
@ExceptionHandler(UsernameNotFoundException.class)

View File

@@ -0,0 +1,28 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-26 09:28:30
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-12 19:06:55
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.exception;
public class UsernameExistsException extends BaseException {
private static final long serialVersionUID = 1L;
public UsernameExistsException(String message) {
super(message);
//TODO Auto-generated constructor stub
}
}

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.faq;
package com.bytedesk.core.faq;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.category.Category;
@@ -32,7 +32,7 @@ import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 常见问题
* faq: Frequently Asked Questions
*/
@Entity
@Data
@@ -41,7 +41,7 @@ import lombok.experimental.Accessors;
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "service_faq")
@Table(name = "core_faq")
public class Faq extends BaseEntity {
private static final long serialVersionUID = 1L;

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 22:59:07
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-08 19:23:29
* @LastEditTime: 2024-06-14 13:47: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.
@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.faq;
package com.bytedesk.core.faq;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
@@ -76,4 +76,9 @@ public class FaqController extends BaseController<FaqRequest> {
return ResponseEntity.ok(JsonResult.success("delete success", request.getUid()));
}
//
}

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.faq;
package com.bytedesk.core.faq;
import java.util.Optional;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.faq;
package com.bytedesk.core.faq;
import com.bytedesk.core.base.BaseRequest;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.faq;
package com.bytedesk.core.faq;
import java.util.Date;

View File

@@ -0,0 +1,38 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 23:00:00
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-14 10:43:11
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.faq;
import com.bytedesk.core.base.BaseResponse;
import com.bytedesk.core.category.CategoryResponse;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
public class FaqResponseVisitor extends BaseResponse {
private String title;
private String content;
private String type;
private CategoryResponse category;
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 22:59:18
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-08 16:48:36
* @LastEditTime: 2024-06-14 11:39:31
* @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.
@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.faq;
package com.bytedesk.core.faq;
import java.util.Optional;
@@ -37,7 +37,7 @@ import lombok.AllArgsConstructor;
@AllArgsConstructor
public class FaqService extends BaseService<Faq, FaqRequest, FaqResponse> {
private final FaqRepository FaqRepository;
private final FaqRepository faqRepository;
private final ModelMapper modelMapper;
@@ -53,7 +53,7 @@ public class FaqService extends BaseService<Faq, FaqRequest, FaqResponse> {
Specification<Faq> spec = FaqSpecification.search(request);
Page<Faq> page = FaqRepository.findAll(spec, pageable);
Page<Faq> page = faqRepository.findAll(spec, pageable);
return page.map(this::convertToResponse);
}
@@ -66,7 +66,7 @@ public class FaqService extends BaseService<Faq, FaqRequest, FaqResponse> {
@Override
public Optional<Faq> findByUid(String uid) {
return FaqRepository.findByUid(uid);
return faqRepository.findByUid(uid);
}
@Override
@@ -110,7 +110,7 @@ public class FaqService extends BaseService<Faq, FaqRequest, FaqResponse> {
@Override
public Faq save(Faq entity) {
try {
return FaqRepository.save(entity);
return faqRepository.save(entity);
} catch (ObjectOptimisticLockingFailureException e) {
handleOptimisticLockingFailureException(e, entity);
}

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.faq;
package com.bytedesk.core.faq;
import java.util.ArrayList;
import java.util.List;

View File

@@ -46,9 +46,11 @@ public class MessageService {
Pageable pageable = PageRequest.of(request.getPageNumber(), request.getPageSize(), Sort.Direction.DESC,
"createdAt");
Specification<Message> specs = MessageSpecs.search(request);
Specification<Message> specs = MessageSpecification.search(request);
Page<Message> messagePage = messageRepository.findAll(specs, pageable);
// Page<Message> messagePage = messageRepository.findByOrgUidAndDeleted(request.getOrgUid(), false, pageable);
// Page<Message> messagePage =
// messageRepository.findByOrgUidAndDeleted(request.getOrgUid(), false,
// pageable);
return messagePage.map(ConvertUtils::convertToMessageResponse);
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-05 22:53:57
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-06 08:58:36
* @LastEditTime: 2024-06-14 10:22:07
* @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,7 +24,7 @@ import com.bytedesk.core.base.BaseSpecification;
import jakarta.persistence.criteria.Predicate;
public class MessageSpecs extends BaseSpecification {
public class MessageSpecification extends BaseSpecification {
public static Specification<Message> search(MessageRequest request) {
return (root, query, criteriaBuilder) -> {
@@ -36,8 +36,7 @@ public class MessageSpecs extends BaseSpecification {
}
//
// if (StringUtils.hasText(request.getType())) {
// predicates.add(criteriaBuilder.equal(root.get("type"), "%" +
// request.getType() + "%"));
// predicates.add(criteriaBuilder.equal(root.get("type"), request.getType()));
// }
//
if (StringUtils.hasText(request.getClient())) {

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-05 21:50:54
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-05 22:15:10
* @LastEditTime: 2024-06-14 15:13:30
* @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,7 +24,10 @@ public enum MessageTypeEnum {
TYPING("typing"), // 6.正在输入
RECALL("recall"), // 7.撤回
RECEIPT("receipt"), // 8.消息回执
QA("qa"); // 问答
ROBOT_QA("robot_qa"), // 9.机器人问答
QUICKBUTTON_QA("quickbutton_qa"), // 10.快捷按钮问答
QUICKBUTTON_URL("quickbutton_url"), // 11.快捷按钮URL
FAQ_QA("faq_qa"); // 12.常见问题问答
private final String value;

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-02-22 16:13:46
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-07 14:42:19
* @LastEditTime: 2024-06-14 15:11:48
* @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,6 +16,7 @@ package com.bytedesk.core.quick_button;
import com.bytedesk.core.base.BaseEntity;
import com.bytedesk.core.constant.TypeConsts;
import com.bytedesk.core.message.MessageTypeEnum;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
@@ -47,8 +48,10 @@ public class QuickButton extends BaseEntity {
@Column(columnDefinition = TypeConsts.COLUMN_TYPE_TEXT)
private String content;
@Builder.Default
@Column(name = TypeConsts.COLUMN_NAME_TYPE)
private String type;
// private String type;
private MessageTypeEnum type = MessageTypeEnum.TEXT;
private String orgUid;
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 23:02:13
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-07 15:32:49
* @LastEditTime: 2024-06-14 13:46:58
* @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.
@@ -77,5 +77,8 @@ public class QuickButtonController extends BaseController<QuickButtonRequest> {
}
//
}

View File

@@ -0,0 +1,36 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 23:02:56
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-14 10:42: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.quick_button;
import com.bytedesk.core.base.BaseResponse;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
public class QuickButtonResponseVisitor extends BaseResponse {
private String title;
private String content;
private String type;
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 23:02:24
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-08 12:10:12
* @LastEditTime: 2024-06-14 15:12: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.
@@ -26,6 +26,7 @@ import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.stereotype.Service;
import com.bytedesk.core.base.BaseService;
import com.bytedesk.core.message.MessageTypeEnum;
import com.bytedesk.core.uid.UidUtils;
import lombok.AllArgsConstructor;
@@ -86,7 +87,8 @@ public class QuickButtonService extends BaseService<QuickButton, QuickButtonRequ
//
entity.setTitle(request.getTitle());
entity.setContent(request.getContent());
entity.setType(request.getType());
// entity.setType(request.getType());
entity.setType(MessageTypeEnum.fromValue(request.getType()));
entity.setOrgUid(request.getOrgUid());

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-23 07:53:01
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-03 14:55:52
* @LastEditTime: 2024-06-12 17:51: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.
@@ -64,8 +64,7 @@ public class AuthService {
// FIXME: 验证码错误时会报错java.lang.ClassCastException: class java.lang.String cannot be cast to
// class com.bytedesk.core.rbac.user.UserDetailsImpl (java.lang.String is in
// module java.base of loader 'bootstrap';
// com.bytedesk.core.rbac.user.UserDetailsImpl is in unnamed module of loader
// 'app')
// com.bytedesk.core.rbac.user.UserDetailsImpl is in unnamed module of loader 'app')
e.printStackTrace();
}

View File

@@ -0,0 +1,46 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-12 17:59:34
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-12 18:00:36
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.rbac.auth;
import org.modelmapper.ModelMapper;
import org.springframework.security.core.context.SecurityContextHolder;
import com.bytedesk.core.rbac.user.User;
import com.bytedesk.core.rbac.user.UserDetailsImpl;
public class AuthUser {
public static User getCurrentUser() {
// not logged in
if (SecurityContextHolder.getContext().getAuthentication() == null) {
return null;
}
//
try {
UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication()
.getPrincipal();
return new ModelMapper().map(userDetails, User.class);
} catch (Exception e) {
// TODO: handle exception
// FIXME: 验证码错误时会报错java.lang.ClassCastException: class java.lang.String cannot be cast to
// class com.bytedesk.core.rbac.user.UserDetailsImpl (java.lang.String is in
// module java.base of loader 'bootstrap';
// com.bytedesk.core.rbac.user.UserDetailsImpl is in unnamed module of loader 'app')
e.printStackTrace();
}
//
return null;
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-29 16:20:17
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-12 09:55:01
* @LastEditTime: 2024-06-12 22:38:38
* @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.
@@ -136,9 +136,12 @@ public class OrganizationService {
// 获取要更新的组织实体
Organization organization = organizationOptional.get();
// 使用ModelMapper进行属性拷贝避免逐一设置字段
modelMapper.map(organizationRequest, organization);
// modelMapper.map(organizationRequest, organization); // 一些默认值会被清空,待前端支持完善之后再启用
organization.setName(organizationRequest.getName());
organization.setLogo(organizationRequest.getLogo());
organization.setCode(organizationRequest.getCode());
organization.setDescription(organizationRequest.getDescription());
// 保存更新后的组织
Organization updatedOrganization = save(organization);
@@ -206,18 +209,13 @@ public class OrganizationService {
if (adminOptional.isPresent()) {
//
Organization organization = Organization.builder()
// .uid(uidUtils.getCacheSerialUid())
.name(bytedeskProperties.getOrganizationName())
.code(bytedeskProperties.getOrganizationCode())
.description(bytedeskProperties.getOrganizationName() + " Description")
.user(adminOptional.get())
.build();
// organization.setUid(uidUtils.getCacheSerialUid());
organization.setUid(UserConsts.DEFAULT_ORGANIZATION_UID);
save(organization);
//
// adminOptional.get().getOrganizations().add(organization.getUid());
// userService.save(adminOptional.get());
}
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-29 16:21:24
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-04-25 22:46:49
* @LastEditTime: 2024-06-12 17:44:32
* @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,6 +67,15 @@ public class UserController {
return ResponseEntity.ok(JsonResult.success(userResponse));
}
@ActionAnnotation(title = "user", action = "changePassword", description = "changePassword")
@PostMapping("/change/password")
public ResponseEntity<?> changePassword(@RequestBody UserRequest userRequest) {
UserResponse userResponse = userService.changePassword(userRequest);
return ResponseEntity.ok(JsonResult.success(userResponse));
}
/** */
@ActionAnnotation(title = "user", action = "logout", description = "logout")
@PostMapping("/logout")

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-29 16:21:24
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-03 09:58:47
* @LastEditTime: 2024-06-12 17:53:51
* @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.
@@ -45,6 +45,10 @@ public class UserRequest extends BaseRequest {
private String password;
// 专门用于修改密码
private String oldPassword;
private String newPassword;
@Email(message = "email format error")
private String email;

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-29 16:21:24
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-04 15:57:38
* @LastEditTime: 2024-06-12 19: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.
@@ -32,7 +32,8 @@ import com.bytedesk.core.constant.TypeConsts;
import com.bytedesk.core.constant.UserConsts;
import com.bytedesk.core.exception.EmailExistsException;
import com.bytedesk.core.exception.MobileExistsException;
import com.bytedesk.core.exception.NotFoundException;
import com.bytedesk.core.exception.UsernameExistsException;
import com.bytedesk.core.rbac.auth.AuthUser;
import com.bytedesk.core.rbac.organization.Organization;
import com.bytedesk.core.rbac.organization.OrganizationRepository;
import com.bytedesk.core.rbac.role.Role;
@@ -70,10 +71,12 @@ public class UserService {
@Transactional
public UserResponse register(UserRequest userRequest) {
if (StringUtils.hasText(userRequest.getEmail()) && existsByEmailAndPlatform(userRequest.getEmail(), userRequest.getPlatform())) {
if (StringUtils.hasText(userRequest.getEmail())
&& existsByEmailAndPlatform(userRequest.getEmail(), userRequest.getPlatform())) {
throw new EmailExistsException("Email already exists..!!");
}
if (StringUtils.hasText(userRequest.getMobile()) && existsByMobileAndPlatform(userRequest.getMobile(), userRequest.getPlatform())) {
if (StringUtils.hasText(userRequest.getMobile())
&& existsByMobileAndPlatform(userRequest.getMobile(), userRequest.getPlatform())) {
throw new MobileExistsException("Mobile already exists..!!");
}
//
@@ -101,7 +104,8 @@ public class UserService {
if (StringUtils.hasText(userRequest.getEmail())) {
user.setUsername(userRequest.getEmail());
user.setNum(userRequest.getEmail());
user.setEmailVerified(true);
// 默认注册时,仅验证手机号,无需验证邮箱
user.setEmailVerified(false);
}
// 只有经过验证的手机号,才真正执行注册
if (StringUtils.hasText(userRequest.getMobile())) {
@@ -109,6 +113,7 @@ public class UserService {
user.setMobileVerified(true);
}
user.setEnabled(true);
//
// TODO: 设置角色role
//
user = save(user);
@@ -119,10 +124,29 @@ public class UserService {
@Transactional
public UserResponse update(UserRequest userRequest) {
Optional<User> userOptional = findByUid(userRequest.getUid());
if (StringUtils.hasText(userRequest.getUsername())
&& existsByUsernameAndPlatform(userRequest.getUsername(), userRequest.getPlatform())) {
throw new UsernameExistsException("Username already exists..!!");
}
if (StringUtils.hasText(userRequest.getEmail())
&& existsByEmailAndPlatform(userRequest.getEmail(), userRequest.getPlatform())) {
throw new EmailExistsException("Email already exists..!!");
}
if (StringUtils.hasText(userRequest.getMobile())
&& existsByMobileAndPlatform(userRequest.getMobile(), userRequest.getPlatform())) {
throw new MobileExistsException("Mobile already exists..!!");
}
User currentUser = AuthUser.getCurrentUser(); // FIXME: 直接使用此user save会报错
Optional<User> userOptional = findByUid(currentUser.getUid());
if (userOptional.isPresent()) {
User user = userOptional.get();
if (StringUtils.hasText(userRequest.getUsername())) {
user.setUsername(userRequest.getUsername());
}
if (StringUtils.hasText(userRequest.getNickname())) {
user.setNickname(userRequest.getNickname());
}
@@ -131,12 +155,6 @@ public class UserService {
user.setAvatar(userRequest.getAvatar());
}
if (StringUtils.hasText(userRequest.getPassword())) {
String rawPassword = userRequest.getPassword();
String encodedPassword = passwordEncoder.encode(rawPassword);
user.setPassword(encodedPassword);
}
if (StringUtils.hasText(userRequest.getEmail())) {
user.setEmail(userRequest.getEmail());
}
@@ -156,7 +174,35 @@ public class UserService {
return ConvertUtils.convertToUserResponse(user);
} else {
throw new NotFoundException("User not found..!!");
throw new RuntimeException("User not found..!!");
}
}
@Transactional
public UserResponse changePassword(UserRequest userRequest) {
User currentUser = AuthUser.getCurrentUser(); // FIXME: 直接使用此user save会报错
Optional<User> userOptional = findByUid(currentUser.getUid());
if (userOptional.isPresent()) {
User user = userOptional.get();
String oldEncryptedPassword = user.getPassword(); // 假设这是数据库中加密后的密码
String oldRawPassword = userRequest.getOldPassword(); // 用户输入的旧密码
String newRawPassword = userRequest.getNewPassword(); // 用户输入的新密码
// 验证旧密码
if (passwordEncoder.matches(oldRawPassword, oldEncryptedPassword)) {
// 旧密码验证通过,设置新密码
String newEncryptedPassword = passwordEncoder.encode(newRawPassword);
user.setPassword(newEncryptedPassword); // 更新用户密码
user = save(user); // 保存用户信息到数据库假设save方法已经存在
//
return ConvertUtils.convertToUserResponse(user); // 返回更新后的用户信息
} else {
// 旧密码验证失败,抛出异常或返回错误信息
throw new RuntimeException("old password wrong, please try again..!!");
}
} else {
throw new RuntimeException("User not found..!!");
}
}
@@ -194,10 +240,10 @@ public class UserService {
} else {
user.setPassword(passwordEncoder.encode(bytedeskProperties.getPasswordDefault()));
}
// user.getOrganizations().add(userRequest.getOrgUid());
Optional<Organization> orgOptional = organizationRepository.findByUid(UserConsts.DEFAULT_ORGANIZATION_UID);
Optional<Role> roleOptional = roleService.findByNameAndOrgUid(TypeConsts.ROLE_CUSTOMER_SERVICE, UserConsts.DEFAULT_ORGANIZATION_UID);
Optional<Role> roleOptional = roleService.findByNameAndOrgUid(TypeConsts.ROLE_CUSTOMER_SERVICE,
UserConsts.DEFAULT_ORGANIZATION_UID);
if (orgOptional.isPresent() && roleOptional.isPresent()) {
Organization organization = orgOptional.get();
Role role = roleOptional.get();
@@ -243,7 +289,8 @@ public class UserService {
@Cacheable(value = "admin", unless = "#result == null")
public Optional<User> getAdmin() {
return userRepository.findByUsernameAndPlatformAndDeleted(bytedeskProperties.getEmail(), BdConstants.PLATFORM_BYTEDESK, false);
return userRepository.findByUsernameAndPlatformAndDeleted(bytedeskProperties.getEmail(),
BdConstants.PLATFORM_BYTEDESK, false);
}
//
@@ -332,8 +379,10 @@ public class UserService {
public void updateInitData() {
Optional<Organization> orgOptional = organizationRepository.findByUid(UserConsts.DEFAULT_ORGANIZATION_UID);
Optional<Role> roleOptional = roleService.findByNameAndOrgUid(TypeConsts.ROLE_SUPER, UserConsts.DEFAULT_ORGANIZATION_UID);
Optional<User> adminOptional = findByEmailAndPlatform(bytedeskProperties.getEmail(), BdConstants.PLATFORM_BYTEDESK);
Optional<Role> roleOptional = roleService.findByNameAndOrgUid(TypeConsts.ROLE_SUPER,
UserConsts.DEFAULT_ORGANIZATION_UID);
Optional<User> adminOptional = findByEmailAndPlatform(bytedeskProperties.getEmail(),
BdConstants.PLATFORM_BYTEDESK);
if (orgOptional.isPresent() && roleOptional.isPresent() && adminOptional.isPresent()) {
Organization organization = orgOptional.get();
Role role = roleOptional.get();

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-04 17:16:54
* @Date: 2024-06-14 10:45:08
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-12 10:40:16
* @LastEditTime: 2024-06-14 12:21:50
* @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.
@@ -12,80 +12,61 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.ai.robot;
package com.bytedesk.core.service_settings;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.constant.TypeConsts;
import com.bytedesk.core.enums.LanguageEnum;
import com.bytedesk.core.faq.Faq;
import com.bytedesk.core.quick_button.QuickButton;
import com.bytedesk.core.thread.ThreadTypeEnum;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.FetchType;
import jakarta.persistence.OneToMany;
import lombok.AllArgsConstructor;
import lombok.Builder;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.MappedSuperclass;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.EqualsAndHashCode;
@Data
@Builder
@Embeddable
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class RobotServiceSettings {
@EqualsAndHashCode(callSuper = false)
@MappedSuperclass
public class BaseServiceSettings {
@Builder.Default
private String language = I18Consts.ZH_CN;
@NotBlank
// private String language = I18Consts.ZH_CN;
private LanguageEnum language = LanguageEnum.ZH_CN;
@Builder.Default
@Column(name = "is_auto_pop")
private boolean autoPop = false;
/**
* TODO: set different tips for different lang
*/
@Builder.Default
private boolean showTopTip = false;
@Builder.Default
@Column(length = 512)
private String topTip = I18Consts.I18N_TOP_TIP;
@Builder.Default
@Column(columnDefinition = TypeConsts.COLUMN_TYPE_TEXT)
private String welcomeTip = I18Consts.I18N_WELCOME_TIP;
@Builder.Default
private String leavemsgTip = I18Consts.I18N_LEAVEMSG_TIP;
/** auto close time in min - 默认自动关闭时间,单位分钟 */
@Builder.Default
/** auto close time in minutes */
private Double autoCloseMin = Double.valueOf(25);
@Builder.Default
@OneToMany(fetch = FetchType.LAZY)
@ManyToMany(fetch = FetchType.LAZY)
private List<QuickButton> quickButtons = new ArrayList<>();
// 是否允许转人工
@Builder.Default
private boolean allowTransferToAgent = true;
@ManyToMany(fetch = FetchType.LAZY)
private List<Faq> faqs = new ArrayList<>();
// 限制仅允许workgroupappointed
@Builder.Default
private ThreadTypeEnum transferType = ThreadTypeEnum.WORKGROUP;
// agentUid or workgroupUid
private String transferToUid;
//
@Builder.Default
private boolean showLogo = true;
// 有效日期
// validate until date, when expire the service will be disabled
private Date validateUntil;
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-29 13:57:24
* @Date: 2024-06-14 10:45:08
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-12 10:40:44
* @LastEditTime: 2024-06-14 12:13:17
* @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.
@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.common;
package com.bytedesk.core.service_settings;
import java.util.ArrayList;
import java.util.Date;
@@ -20,76 +20,41 @@ import java.util.List;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.enums.LanguageEnum;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import jakarta.persistence.MappedSuperclass;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.EqualsAndHashCode;
@Data
@Builder
@Embeddable
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class ServiceSettingsRequest {
@Builder.Default
@EqualsAndHashCode(callSuper = false)
@MappedSuperclass
public class BaseServiceSettingsRequest {
// private String language = I18Consts.ZH_CN;
private LanguageEnum language = LanguageEnum.ZH_CN;
@Builder.Default
@Column(name = "is_auto_pop")
private Boolean autoPop = false;
/**
* TODO: set different tips for different lang
*/
@Builder.Default
private Boolean showTopTip = false;
@Builder.Default
@Column(length = 512)
private String topTip = I18Consts.I18N_TOP_TIP;
@Builder.Default
private String welcomeTip = I18Consts.I18N_WELCOME_TIP;
@Builder.Default
private String leavemsgTip = I18Consts.I18N_LEAVEMSG_TIP;
/** auto close time in min - 默认自动关闭时间,单位分钟 */
@Builder.Default
private Double autoCloseMin = Double.valueOf(25);
/**
* robot
* 是否默认机器人接待
*/
@Builder.Default
private Boolean defaultRobot = false;
/** 无客服在线时,是否启用机器人接待 */
@Builder.Default
private Boolean offlineRobot = false;
/** 非工作时间段,是否启用机器人接待 */
@Builder.Default
private Boolean nonWorktimeRobot = false;
@Builder.Default
private List<String> worktimeUids = new ArrayList<>();
@Builder.Default
private List<String> quickButtonUids = new ArrayList<>();
private String robotUid;
private List<String> faqUids = new ArrayList<>();
// 访客对话底部页面显示logo
@Builder.Default
private Boolean showLogo = true;
// 有效日期

View File

@@ -0,0 +1,63 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-06-14 10:45:08
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-14 12:17:57
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.service_settings;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.enums.LanguageEnum;
import com.bytedesk.core.faq.FaqResponse;
import com.bytedesk.core.quick_button.QuickButtonResponse;
import jakarta.persistence.MappedSuperclass;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
@MappedSuperclass
public class BaseServiceSettingsResponse {
// private String language = I18Consts.ZH_CN;
private LanguageEnum language = LanguageEnum.ZH_CN;
private Boolean autoPop = false;
/**
* TODO: set different tips for different lang
*/
private Boolean showTopTip = false;
private String topTip = I18Consts.I18N_TOP_TIP;
private String welcomeTip = I18Consts.I18N_WELCOME_TIP;
private String leavemsgTip = I18Consts.I18N_LEAVEMSG_TIP;
/** auto close time in min - 默认自动关闭时间,单位分钟 */
private Double autoCloseMin = Double.valueOf(25);
private List<QuickButtonResponse> quickButtons = new ArrayList<>();
private List<FaqResponse> faqs = new ArrayList<>();
private Boolean showLogo = true;
// 有效日期
private Date validateUntil;
}

View File

@@ -1,8 +1,8 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-05-29 13:57:24
* @Date: 2024-06-14 10:45:08
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-11 12:08:28
* @LastEditTime: 2024-06-14 12:45:18
* @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.
@@ -12,17 +12,16 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.service.common;
package com.bytedesk.core.service_settings;
import java.util.ArrayList;
import java.util.List;
import com.bytedesk.core.constant.I18Consts;
import com.bytedesk.core.enums.LanguageEnum;
import com.bytedesk.core.quick_button.QuickButtonResponse;
import com.bytedesk.core.faq.FaqResponseVisitor;
import com.bytedesk.core.quick_button.QuickButtonResponseVisitor;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -31,18 +30,15 @@ import lombok.experimental.Accessors;
@Data
@Builder
@Embeddable
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class ServiceSettingsResponseVisitor {
@Builder.Default
// private String language = I18Consts.ZH_CN;
private LanguageEnum language = LanguageEnum.ZH_CN;
@Builder.Default
@Column(name = "is_auto_pop")
private Boolean autoPop = false;
/**
@@ -52,13 +48,19 @@ public class ServiceSettingsResponseVisitor {
private Boolean showTopTip = false;
@Builder.Default
@Column(length = 512)
private String topTip = I18Consts.I18N_TOP_TIP;
// 存储到thread_log方便定时关闭会话
/** auto close time in min - 默认自动关闭时间,单位分钟 */
@Builder.Default
private List<QuickButtonResponse> quickButtons = new ArrayList<>();
private Double autoCloseMin = Double.valueOf(25);
@Builder.Default
private List<QuickButtonResponseVisitor> quickButtons = new ArrayList<>();
@Builder.Default
private List<FaqResponseVisitor> faqs = new ArrayList<>();
//
@Builder.Default
private Boolean showLogo = true;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket;
package com.bytedesk.core.socket;
// import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@@ -0,0 +1,60 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-04-27 16:41:32
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-06-14 17:15:35
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.socket.controller;
// import java.util.Map;
// import org.springframework.http.ResponseEntity;
// import org.springframework.web.bind.annotation.PostMapping;
// import org.springframework.web.bind.annotation.RequestBody;
// import org.springframework.web.bind.annotation.RequestMapping;
// import org.springframework.web.bind.annotation.RestController;
// import com.bytedesk.core.utils.JsonResult;
// import com.bytedesk.core.socket.stomp.service.StompMqService;
// import lombok.AllArgsConstructor;
// import lombok.extern.slf4j.Slf4j;
// /**
// *
// * http://localhost:9003/swagger-ui/index.html
// */
// @Slf4j
// @RestController
// @AllArgsConstructor
// @RequestMapping("/api/v1/message/rest")
// public class MessageRestController {
// private final StompMqService stompMqService;
// /**
// * send offline message
// *
// * @param map map
// * @return json
// */
// @PostMapping("/send")
// public ResponseEntity<?> sendOfflineMessage(@RequestBody Map<String, String>
// map) {
// String json = (String) map.get("json");
// log.debug("json {}", json);
// stompMqService.sendMessageToMq(json);
// //
// return ResponseEntity.ok(JsonResult.success(json));
// }
// }

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.controller;
package com.bytedesk.core.socket.controller;
import java.util.List;
@@ -24,7 +24,7 @@ import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
import com.bytedesk.core.uid.utils.NetUtils;
import com.bytedesk.core.utils.JsonResult;
import com.bytedesk.socket.mqtt.service.MqttSessionService;
import com.bytedesk.core.socket.mqtt.service.MqttSessionService;
import lombok.AllArgsConstructor;
@@ -34,7 +34,7 @@ import lombok.AllArgsConstructor;
public class MqttController {
private MqttSessionService mqttSessionService;
/**
* http://localhost:9003/visitor/api/v1/mqtt/clientIds
*
@@ -42,10 +42,10 @@ public class MqttController {
*/
@GetMapping("/clientIds")
public ResponseEntity<?> getAllClientIds() {
//
//
String host = NetUtils.getLocalAddress();
List<String> clientIds = mqttSessionService.getAllClientIds();
//
//
JSONObject json = new JSONObject();
json.put("host", host);
json.put("clientIds", clientIds);
@@ -53,6 +53,4 @@ public class MqttController {
return ResponseEntity.ok(JsonResult.success(json));
}
}

View File

@@ -0,0 +1,106 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-29 16:21:46
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-04-16 09:38: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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.socket.mqtt.cache;
// import com.bytedesk.core.socket.mqtt.model.MqttSubscribe;
// import com.bytedesk.core.socket.mqtt.util.MqttConsts;
// // import org.springframework.data.redis.core.RedisTemplate;
// // import org.springframework.data.redis.core.StringRedisTemplate;
// import org.springframework.stereotype.Service;
// import java.util.*;
// import java.util.concurrent.ConcurrentHashMap;
// /**
// * @author jackning
// */
// @Service
// public class MqttSubscribeNotWildcardCache {
// public static final String CACHE_PRE = MqttConsts.MQTT_PREFIX +
// "subnotwildcard:";
// public static final String CACHE_CLIENT_PRE = MqttConsts.MQTT_PREFIX +
// "client:";
// // @Autowired
// // private StringRedisTemplate stringRedisTemplate;
// // @Autowired
// // private RedisTemplate<String, Serializable> redisTemplate;
// public void put(String topic, String clientId, MqttSubscribe mqttSubscribe) {
// // redisTemplate.opsForHash().put(CACHE_PRE + topic, clientId,
// mqttSubscribe);
// // stringRedisTemplate.opsForSet().add(CACHE_CLIENT_PRE + clientId, topic);
// }
// public MqttSubscribe get(String topic, String clientId) {
// // return (MqttSubscribe) redisTemplate.opsForHash().get(CACHE_PRE + topic,
// clientId);
// return null;
// }
// public boolean containsKey(String topic, String clientId) {
// // return redisTemplate.opsForHash().hasKey(CACHE_PRE + topic, clientId);
// return false;
// }
// public void remove(String topic, String clientId) {
// // stringRedisTemplate.opsForSet().remove(CACHE_CLIENT_PRE + clientId,
// topic);
// // redisTemplate.opsForHash().delete(CACHE_PRE + topic, clientId);
// }
// public void removeForClient(String clientId) {
// // for (String topic :
// stringRedisTemplate.opsForSet().members(CACHE_CLIENT_PRE + clientId)) {
// // redisTemplate.opsForHash().delete(CACHE_PRE + topic, clientId);
// // }
// // stringRedisTemplate.delete(CACHE_CLIENT_PRE + clientId);
// }
// public Map<String, ConcurrentHashMap<String, MqttSubscribe>> all() {
// Map<String, ConcurrentHashMap<String, MqttSubscribe>> map = new HashMap<>();
// // Set<String> set = redisTemplate.keys(CACHE_PRE + "*");
// // if (set != null && !set.isEmpty()) {
// // set.forEach(
// // entry -> {
// // ConcurrentHashMap<String, MqttSubscribe> map1 = new ConcurrentHashMap<>();
// // Map<Object, Object> map2 = redisTemplate.opsForHash().entries(entry);
// // if (map2 != null && !map2.isEmpty()) {
// // map2.forEach((k, v) -> {
// // map1.put((String) k, (MqttSubscribe) v);
// // });
// // map.put(entry.substring(CACHE_PRE.length()), map1);
// // }
// // });
// // }
// return map;
// }
// public List<MqttSubscribe> all(String topic) {
// List<MqttSubscribe> list = new ArrayList<>();
// // Map<Object, Object> map = redisTemplate.opsForHash().entries(CACHE_PRE +
// topic);
// // if (map != null && !map.isEmpty()) {
// // map.forEach((k, v) -> {
// // list.add((MqttSubscribe) v);
// // });
// // }
// return list;
// }
// }

View File

@@ -0,0 +1,111 @@
/*
* @Author: jackning 270580156@qq.com
* @Date: 2024-01-29 16:21:46
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2024-04-16 09:38:32
* @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.
* 仅支持企业内部员工自用严禁私自用于销售、二次销售或者部署SaaS方式销售
* Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE
* contact: 270580156@qq.com
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.core.socket.mqtt.cache;
// import com.bytedesk.core.socket.mqtt.model.MqttSubscribe;
// import com.bytedesk.core.socket.mqtt.util.MqttConsts;
// // import org.springframework.data.redis.core.RedisTemplate;
// // import org.springframework.data.redis.core.StringRedisTemplate;
// import org.springframework.stereotype.Service;
// import java.util.*;
// import java.util.concurrent.ConcurrentHashMap;
// /**
// * topic通配符说明
// * 单层通配符"+":只能匹配一层主题。例如,"aaa/+"可以匹配"aaa/bbb",但不能匹配"aaa/bbb/ccc"。
// *
// 多层通配符"#":可以匹配多层主题。例如,"aaa/#"不但可以匹配"aaa/bbb",还可以匹配"aaa/bbb/ccc/ddd"。它必须作为主题的最后一个级别使用,并且只能出现在最后
// *
// * @author jackning
// */
// @Service
// public class MqttSubscribeWildcardCache {
// public static final String CACHE_PRE = MqttConsts.MQTT_PREFIX +
// "subwildcard:";
// public static final String CACHE_CLIENT_PRE = MqttConsts.MQTT_PREFIX +
// "client:";
// // @Autowired
// // private StringRedisTemplate stringRedisTemplate;
// // @Autowired
// // private RedisTemplate<String, Serializable> redisTemplate;
// public void put(String topic, String clientId, MqttSubscribe subscribeStore)
// {
// // redisTemplate.opsForHash().put(CACHE_PRE + topic, clientId,
// subscribeStore);
// // stringRedisTemplate.opsForSet().add(CACHE_CLIENT_PRE + clientId, topic);
// }
// public MqttSubscribe get(String topic, String clientId) {
// // return (MqttSubscribe) redisTemplate.opsForHash().get(CACHE_PRE + topic,
// clientId);
// return null;
// }
// public boolean containsKey(String topic, String clientId) {
// // return redisTemplate.opsForHash().hasKey(CACHE_PRE + topic, clientId);
// return false;
// }
// public void remove(String topic, String clientId) {
// // stringRedisTemplate.opsForSet().remove(CACHE_CLIENT_PRE + clientId,
// topic);
// // redisTemplate.opsForHash().delete(CACHE_PRE + topic, clientId);
// }
// public void removeForClient(String clientId) {
// // for (String topic :
// stringRedisTemplate.opsForSet().members(CACHE_CLIENT_PRE + clientId)) {
// // redisTemplate.opsForHash().delete(CACHE_PRE + topic, clientId);
// // }
// // stringRedisTemplate.delete(CACHE_CLIENT_PRE + clientId);
// }
// public Map<String, ConcurrentHashMap<String, MqttSubscribe>> all() {
// Map<String, ConcurrentHashMap<String, MqttSubscribe>> map = new HashMap<>();
// // Set<String> set = redisTemplate.keys(CACHE_PRE + "*");
// // if (set != null && !set.isEmpty()) {
// // set.forEach(
// // entry -> {
// // ConcurrentHashMap<String, MqttSubscribe> map1 = new ConcurrentHashMap<>();
// // Map<Object, Object> map2 = redisTemplate.opsForHash().entries(entry);
// // if (map2 != null && !map2.isEmpty()) {
// // map2.forEach((k, v) -> {
// // map1.put((String) k, (MqttSubscribe) v);
// // });
// // map.put(entry.substring(CACHE_PRE.length()), map1);
// // }
// // });
// // }
// return map;
// }
// public List<MqttSubscribe> all(String topic) {
// List<MqttSubscribe> list = new ArrayList<>();
// // Map<Object, Object> map = redisTemplate.opsForHash().entries(CACHE_PRE +
// topic);
// // if (map != null && !map.isEmpty()) {
// // map.forEach((k, v) -> {
// // list.add((MqttSubscribe) v);
// // });
// // }
// return list;
// }
// }

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.config;
package com.bytedesk.core.socket.mqtt.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler;
package com.bytedesk.core.socket.mqtt.handler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleStateEvent;

View File

@@ -1,4 +1,4 @@
package com.bytedesk.socket.mqtt.handler;
package com.bytedesk.core.socket.mqtt.handler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
@@ -9,12 +9,13 @@ import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.AttributeKey;
//
import com.bytedesk.socket.mqtt.model.MqttSession;
import com.bytedesk.socket.mqtt.protocol.ProtocolProcess;
import com.bytedesk.socket.mqtt.util.MqttConsts;
import com.bytedesk.core.socket.mqtt.model.MqttSession;
import com.bytedesk.core.socket.mqtt.protocol.ProtocolProcess;
import com.bytedesk.core.socket.mqtt.util.MqttConsts;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
/**
* 消息处理
*

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.handler.packet;
package com.bytedesk.core.socket.mqtt.handler.packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.initializer;
package com.bytedesk.core.socket.mqtt.initializer;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
@@ -25,8 +25,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import com.bytedesk.socket.mqtt.handler.MqttTransportHandler;
import com.bytedesk.socket.mqtt.protocol.ProtocolProcess;
import com.bytedesk.core.socket.mqtt.handler.MqttTransportHandler;
import com.bytedesk.core.socket.mqtt.protocol.ProtocolProcess;
/**
* @author bytedesk.com on 2019-07-05

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.initializer;
package com.bytedesk.core.socket.mqtt.initializer;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
@@ -26,13 +26,13 @@ import io.netty.handler.codec.mqtt.MqttDecoder;
import io.netty.handler.codec.mqtt.MqttEncoder;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.stream.ChunkedWriteHandler;
import com.bytedesk.socket.mqtt.handler.MqttTransportHandler;
import com.bytedesk.socket.mqtt.protocol.ProtocolProcess;
import com.bytedesk.socket.mqtt.util.MqttConsts;
import com.bytedesk.socket.mqtt.websocket.BinaryWebSocketFrameHandler;
import com.bytedesk.socket.mqtt.websocket.ContinuationWebSocketFrameHandler;
import com.bytedesk.socket.mqtt.websocket.ByteBufToWebSocketFrameEncoder;
import com.bytedesk.socket.mqtt.websocket.TextWebSocketFrameHandler;
import com.bytedesk.core.socket.mqtt.handler.MqttTransportHandler;
import com.bytedesk.core.socket.mqtt.protocol.ProtocolProcess;
import com.bytedesk.core.socket.mqtt.util.MqttConsts;
import com.bytedesk.core.socket.mqtt.websocket.BinaryWebSocketFrameHandler;
import com.bytedesk.core.socket.mqtt.websocket.ContinuationWebSocketFrameHandler;
import com.bytedesk.core.socket.mqtt.websocket.ByteBufToWebSocketFrameEncoder;
import com.bytedesk.core.socket.mqtt.websocket.TextWebSocketFrameHandler;
/**
* @author bytedesk.com on 2019-07-05

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.model;
package com.bytedesk.core.socket.mqtt.model;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.MqttPublishMessage;

View File

@@ -1,4 +1,4 @@
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
@@ -10,10 +10,10 @@ import org.springframework.util.StringUtils;
import com.bytedesk.core.event.BytedeskEventPublisher;
// import com.bytedesk.core.topic.TopicService;
import com.bytedesk.socket.mqtt.handler.MqttIdleStateHandler;
import com.bytedesk.socket.mqtt.model.MqttSession;
import com.bytedesk.socket.mqtt.service.*;
import com.bytedesk.socket.mqtt.util.MqttConsts;
import com.bytedesk.core.socket.mqtt.handler.MqttIdleStateHandler;
import com.bytedesk.core.socket.mqtt.model.MqttSession;
import com.bytedesk.core.socket.mqtt.service.*;
import com.bytedesk.core.socket.mqtt.util.MqttConsts;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

View File

@@ -1,4 +1,4 @@
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
// import java.util.Iterator;
// import java.util.Set;
@@ -21,13 +21,13 @@ import com.bytedesk.core.event.BytedeskEventPublisher;
// import com.bytedesk.core.redis.RedisService;
// import com.bytedesk.core.redis.RedisStatisticService;
// import com.bytedesk.core.redis.RedisUserService;
// import com.bytedesk.socket.mqtt.model.MqttSession;
// import com.bytedesk.socket.mqtt.service.MqttClientIdService;
// import com.bytedesk.socket.mqtt.service.MqttDupPubRelMessageStoreService;
// import com.bytedesk.socket.mqtt.service.MqttDupPublishMessageStoreService;
import com.bytedesk.socket.mqtt.service.MqttSessionService;
// import com.bytedesk.socket.mqtt.service.MqttSubscribeService;
import com.bytedesk.socket.mqtt.util.ChannelUtils;
// import com.bytedesk.core.socket.mqtt.model.MqttSession;
// import com.bytedesk.core.socket.mqtt.service.MqttClientIdService;
// import com.bytedesk.core.socket.mqtt.service.MqttDupPubRelMessageStoreService;
// import com.bytedesk.core.socket.mqtt.service.MqttDupPublishMessageStoreService;
import com.bytedesk.core.socket.mqtt.service.MqttSessionService;
// import com.bytedesk.core.socket.mqtt.service.MqttSubscribeService;
import com.bytedesk.core.socket.mqtt.util.ChannelUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -42,13 +42,15 @@ public class DisConnect {
// private final TopicService topicService;
private final BytedeskEventPublisher bytedeskEventPublisher;
private final BytedeskEventPublisher bytedeskEventPublisher;
// private final MqttSubscribeService mqttSubscribeStoreService;
// private final MqttDupPublishMessageStoreService mqttDupPublishMessageStoreService;
// private final MqttDupPublishMessageStoreService
// mqttDupPublishMessageStoreService;
// private final MqttDupPubRelMessageStoreService mqttDupPubRelMessageStoreService;
// private final MqttDupPubRelMessageStoreService
// mqttDupPubRelMessageStoreService;
// private final MqttClientIdService mqttClientIdStoreService;
@@ -95,7 +97,7 @@ public class DisConnect {
// mqttClientIdStoreService.remove(clientId);
// topicService.removeClientId(clientId);
bytedeskEventPublisher.publishMqttDisconnectedEvent(clientId);
channel.close();
// FIXME:io.netty.channel.DefaultChannelPipeline : An exceptionCaught() event
@@ -112,46 +114,47 @@ public class DisConnect {
// 延迟执行如果客服在此时间段之内重新连接则不执行
// private void updateDisconnectedStatus(String clientId) {
// // 用户离线
// // final String uid = clientId.split("/")[0];
// // log.debug("DisConnect disconnected {}", uid);
// // redisConnectService.setDelayDisconnect(uid);
// //
// // if (redisUserService.isAgent(uid)) {
// // //
// // Set<String> workGroupSet = redisUserService.getWorkGroups(uid);
// // Iterator<String> iterator = workGroupSet.iterator();
// // while (iterator.hasNext()) {
// // String wid = iterator.next();
// // // 将客服从缓存redis中删除
// // redisRoutingRoundRobin.removeRoundRobinAgent(wid, uid);
// // }
// // // 清除客服在线缓存
// // // TODO: 考虑同一个用户登录多个客户端的情况
// // redisConnectService.deleteConnectedAgent(uid);
// // //
// // User user = redisUserService.getAgentInfo(uid);
// // if (user != null) {
// // // 统计数据减少在线客服数量
// // redisStatisticService.removeOnlineAgent(user.getSubDomain(), uid);
// // }
// // // 清空空闲数量
// // // redisService.removeAgentIdleCount(uid);
// // } else {
// // //
// // // deleteConnectedVisitor(user);
// // // TODO: 减少在线访客数量
// // // redisStatisticService.removeOnlineVisitor();
// // // 通知客服端访客离线
// // messageService.notifyDisconnectedUid(uid);
// // }
// // //
// // redisConnectService.disconnected(uid);
// // // 设置连接状态为离线
// // userService.updateConnectionStatusByUid(StatusConsts.USER_STATUS_DISCONNECTED,
// // uid);
// // // 将当前用户长连接从所在服务器删除
// // redisHostService.removeUserHost(uid);
// // 用户离线
// // final String uid = clientId.split("/")[0];
// // log.debug("DisConnect disconnected {}", uid);
// // redisConnectService.setDelayDisconnect(uid);
// //
// // if (redisUserService.isAgent(uid)) {
// // //
// // Set<String> workGroupSet = redisUserService.getWorkGroups(uid);
// // Iterator<String> iterator = workGroupSet.iterator();
// // while (iterator.hasNext()) {
// // String wid = iterator.next();
// // // 将客服从缓存redis中删除
// // redisRoutingRoundRobin.removeRoundRobinAgent(wid, uid);
// // }
// // // 清除客服在线缓存
// // // TODO: 考虑同一个用户登录多个客户端的情况
// // redisConnectService.deleteConnectedAgent(uid);
// // //
// // User user = redisUserService.getAgentInfo(uid);
// // if (user != null) {
// // // 统计数据减少在线客服数量
// // redisStatisticService.removeOnlineAgent(user.getSubDomain(), uid);
// // }
// // // 清空空闲数量
// // // redisService.removeAgentIdleCount(uid);
// // } else {
// // //
// // // deleteConnectedVisitor(user);
// // // TODO: 减少在线访客数量
// // // redisStatisticService.removeOnlineVisitor();
// // // 通知客服端访客离线
// // messageService.notifyDisconnectedUid(uid);
// // }
// // //
// // redisConnectService.disconnected(uid);
// // // 设置连接状态为离线
// //
// userService.updateConnectionStatusByUid(StatusConsts.USER_STATUS_DISCONNECTED,
// // uid);
// // // 将当前用户长连接从所在服务器删除
// // redisHostService.removeUserHost(uid);
// }
}

View File

@@ -13,9 +13,9 @@
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
import com.bytedesk.socket.mqtt.util.ChannelUtils;
import com.bytedesk.core.socket.mqtt.util.ChannelUtils;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.*;
import lombok.extern.slf4j.Slf4j;
@@ -32,7 +32,7 @@ public class PingReq {
//
String clientId = ChannelUtils.getClientId(channel);
log.debug("PINGREQ - clientId: {}", clientId);
MqttMessage pingRespMessage = MqttMessageFactory.newMessage(
new MqttFixedHeader(MqttMessageType.PINGRESP, false, MqttQoS.AT_MOST_ONCE, false, 0),
null,

View File

@@ -1,7 +1,7 @@
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
import com.bytedesk.core.event.BytedeskEventPublisher;
import com.bytedesk.socket.mqtt.service.*;
import com.bytedesk.core.socket.mqtt.service.*;
import lombok.Data;
@@ -83,8 +83,8 @@ public class ProtocolProcess {
// mqttSubscribeStoreService,
// mqttClientIdStoreService,
bytedeskEventPublisher
// topicService
);
// topicService
);
}
return connect;
}
@@ -92,13 +92,12 @@ public class ProtocolProcess {
public Subscribe subscribe() {
if (subscribe == null) {
subscribe = new Subscribe(
// mqttMessageIdService,
// mqttSubscribeStoreService
// mqttRetainMessageStoreService
// redisUserService
// topicService
bytedeskEventPublisher
);
// mqttMessageIdService,
// mqttSubscribeStoreService
// mqttRetainMessageStoreService
// redisUserService
// topicService
bytedeskEventPublisher);
}
return subscribe;
}
@@ -106,10 +105,9 @@ public class ProtocolProcess {
public UnSubscribe unSubscribe() {
if (unSubscribe == null) {
unSubscribe = new UnSubscribe(
// mqttSubscribeStoreService
// topicService
bytedeskEventPublisher
);
// mqttSubscribeStoreService
// topicService
bytedeskEventPublisher);
}
return unSubscribe;
}
@@ -117,11 +115,11 @@ public class ProtocolProcess {
public Publish publish() {
if (publish == null) {
publish = new Publish(
// mqttRetainMessageStoreService,
bytedeskEventPublisher
// mqttMessageIdService,
// mqttClientIdStoreService,
// mqttSessionStoreService
// mqttRetainMessageStoreService,
bytedeskEventPublisher
// mqttMessageIdService,
// mqttClientIdStoreService,
// mqttSessionStoreService
);
}
return publish;
@@ -133,10 +131,10 @@ public class ProtocolProcess {
mqttSessionStoreService,
// topicService,
bytedeskEventPublisher
// mqttSubscribeStoreService,
// mqttDupPublishMessageStoreService,
// mqttDupPubRelMessageStoreService,
// mqttClientIdStoreService
// mqttSubscribeStoreService,
// mqttDupPublishMessageStoreService,
// mqttDupPubRelMessageStoreService,
// mqttClientIdStoreService
);
}
return disConnect;
@@ -159,8 +157,8 @@ public class ProtocolProcess {
public PubAck pubAck() {
if (pubAck == null) {
pubAck = new PubAck(
// mqttDupPublishMessageStoreService
);
// mqttDupPublishMessageStoreService
);
}
return pubAck;
}
@@ -168,8 +166,8 @@ public class ProtocolProcess {
public PubRec pubRec() {
if (pubRec == null) {
pubRec = new PubRec(
// mqttDupPublishMessageStoreService, mqttDupPubRelMessageStoreService
);
// mqttDupPublishMessageStoreService, mqttDupPubRelMessageStoreService
);
}
return pubRec;
}
@@ -177,8 +175,8 @@ public class ProtocolProcess {
public PubComp pubComp() {
if (pubComp == null) {
pubComp = new PubComp(
// mqttDupPubRelMessageStoreService
);
// mqttDupPubRelMessageStoreService
);
}
return pubComp;
}

View File

@@ -12,12 +12,12 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader;
// import com.bytedesk.socket.mqtt.service.MqttDupPublishMessageStoreService;
import com.bytedesk.socket.mqtt.util.ChannelUtils;
// import com.bytedesk.core.socket.mqtt.service.MqttDupPublishMessageStoreService;
import com.bytedesk.core.socket.mqtt.util.ChannelUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -28,14 +28,15 @@ import lombok.extern.slf4j.Slf4j;
@AllArgsConstructor
public class PubAck {
// private final MqttDupPublishMessageStoreService mqttDupPublishMessageStoreService;
// private final MqttDupPublishMessageStoreService
// mqttDupPublishMessageStoreService;
public void processPubAck(Channel channel, MqttMessageIdVariableHeader variableHeader) {
//
//
String clientId = ChannelUtils.getClientId(channel);
int messageId = variableHeader.messageId();
log.debug("PUBACK - clientId: {}, messageId: {}", clientId, messageId);
//
//
// mqttDupPublishMessageStoreService.remove(clientId, messageId);
}
}

View File

@@ -12,12 +12,12 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.MqttMessageIdVariableHeader;
// import com.bytedesk.socket.mqtt.service.MqttDupPubRelMessageStoreService;
import com.bytedesk.socket.mqtt.util.ChannelUtils;
// import com.bytedesk.core.socket.mqtt.service.MqttDupPubRelMessageStoreService;
import com.bytedesk.core.socket.mqtt.util.ChannelUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -30,7 +30,8 @@ import lombok.extern.slf4j.Slf4j;
@AllArgsConstructor
public class PubComp {
// private final MqttDupPubRelMessageStoreService mqttDupPubRelMessageStoreService;
// private final MqttDupPubRelMessageStoreService
// mqttDupPubRelMessageStoreService;
public void processPubComp(Channel channel, MqttMessageIdVariableHeader variableHeader) {
String clientId = ChannelUtils.getClientId(channel);

View File

@@ -12,14 +12,14 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.*;
// import com.bytedesk.socket.mqtt.model.MqttDupPubRelMessage;
// import com.bytedesk.socket.mqtt.service.MqttDupPubRelMessageStoreService;
// import com.bytedesk.socket.mqtt.service.MqttDupPublishMessageStoreService;
import com.bytedesk.socket.mqtt.util.ChannelUtils;
// import com.bytedesk.core.socket.mqtt.model.MqttDupPubRelMessage;
// import com.bytedesk.core.socket.mqtt.service.MqttDupPubRelMessageStoreService;
// import com.bytedesk.core.socket.mqtt.service.MqttDupPublishMessageStoreService;
import com.bytedesk.core.socket.mqtt.util.ChannelUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -27,9 +27,11 @@ import lombok.extern.slf4j.Slf4j;
@AllArgsConstructor
public class PubRec {
// private final MqttDupPublishMessageStoreService mqttDupPublishMessageStoreService;
// private final MqttDupPublishMessageStoreService
// mqttDupPublishMessageStoreService;
// private final MqttDupPubRelMessageStoreService mqttDupPubRelMessageStoreService;
// private final MqttDupPubRelMessageStoreService
// mqttDupPubRelMessageStoreService;
public void processPubRec(Channel channel, MqttMessageIdVariableHeader variableHeader) {
//
@@ -39,7 +41,8 @@ public class PubRec {
//
// mqttDupPublishMessageStoreService.remove(clientId, messageId);
//
// MqttDupPubRelMessage dupPubRelMessageStore = new MqttDupPubRelMessage().setClientId(clientId).setMessageId(messageId);
// MqttDupPubRelMessage dupPubRelMessageStore = new
// MqttDupPubRelMessage().setClientId(clientId).setMessageId(messageId);
// mqttDupPubRelMessageStoreService.put(clientId, dupPubRelMessageStore);
//
MqttMessage pubRelMessage = MqttMessageFactory.newMessage(

View File

@@ -12,9 +12,9 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
import com.bytedesk.socket.mqtt.util.ChannelUtils;
import com.bytedesk.core.socket.mqtt.util.ChannelUtils;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.*;
import lombok.extern.slf4j.Slf4j;

View File

@@ -12,14 +12,14 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.*;
import com.bytedesk.core.event.BytedeskEventPublisher;
// import com.bytedesk.socket.mqtt.service.*;
import com.bytedesk.socket.mqtt.util.ChannelUtils;
// import com.bytedesk.core.socket.mqtt.service.*;
import com.bytedesk.core.socket.mqtt.util.ChannelUtils;
import lombok.AllArgsConstructor;
// import lombok.extern.slf4j.Slf4j;
@@ -37,7 +37,8 @@ public class Publish {
// log.debug("processPublish {}", mqttPublishMessage.toString());
//
// TODO: 发送消息发送成功回执
// String clientId = (String) channel.attr(AttributeKey.valueOf(MqttConsts.MQTT_CLIENT_ID)).get();
// String clientId = (String)
// channel.attr(AttributeKey.valueOf(MqttConsts.MQTT_CLIENT_ID)).get();
byte[] messageBytes = new byte[mqttPublishMessage.payload().readableBytes()];
this.sendMqMessage(mqttPublishMessage, messageBytes);
// QoS=0
@@ -58,15 +59,16 @@ public class Publish {
mqttPublishMessage.payload().getBytes(mqttPublishMessage.payload().readerIndex(), messageBytes);
//
// if (messageBytes.length == 0) {
// mqttRetainMessageStoreService.remove(mqttPublishMessage.variableHeader().topicName());
// mqttRetainMessageStoreService.remove(mqttPublishMessage.variableHeader().topicName());
// } else {
// MqttRetainMessage retainMessageStore = new MqttRetainMessage()
// .setTopic(mqttPublishMessage.variableHeader().topicName())
// .setMqttQoS(mqttPublishMessage.fixedHeader().qosLevel().value()).setMessageBytes(messageBytes);
// mqttRetainMessageStoreService.put(mqttPublishMessage.variableHeader().topicName(), retainMessageStore);
// MqttRetainMessage retainMessageStore = new MqttRetainMessage()
// .setTopic(mqttPublishMessage.variableHeader().topicName())
// .setMqttQoS(mqttPublishMessage.fixedHeader().qosLevel().value()).setMessageBytes(messageBytes);
// mqttRetainMessageStoreService.put(mqttPublishMessage.variableHeader().topicName(),
// retainMessageStore);
// }
}
}
// 下列过滤不能从直接数据库中读取否则会增加数据库压力影响消息发送速度务必从内存或redis中读取

View File

@@ -1,4 +1,4 @@
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.*;
@@ -6,11 +6,11 @@ import io.netty.handler.codec.mqtt.*;
import com.bytedesk.core.event.BytedeskEventPublisher;
// import com.bytedesk.core.topic.TopicService;
// import com.bytedesk.core.redis.RedisUserService;
// import com.bytedesk.socket.mqtt.model.MqttRetainMessage;
// import com.bytedesk.socket.mqtt.model.MqttSubscribe;
// import com.bytedesk.socket.mqtt.service.MqttSubscribeService;
import com.bytedesk.socket.mqtt.util.ChannelUtils;
import com.bytedesk.socket.mqtt.util.MqttUtil;
// import com.bytedesk.core.socket.mqtt.model.MqttRetainMessage;
// import com.bytedesk.core.socket.mqtt.model.MqttSubscribe;
// import com.bytedesk.core.socket.mqtt.service.MqttSubscribeService;
import com.bytedesk.core.socket.mqtt.util.ChannelUtils;
import com.bytedesk.core.socket.mqtt.util.MqttUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -54,14 +54,15 @@ public class Subscribe {
List<Integer> mqttQoSList = new ArrayList<>();
topicSubscriptions.forEach(topicSubscription -> {
String topicFilter = topicSubscription.topicFilter(); //topicSubscription.topicName();
String topicFilter = topicSubscription.topicFilter(); // topicSubscription.topicName();
MqttQoS mqttQoS = topicSubscription.qualityOfService();
// MqttSubscribe subscribeStore = new MqttSubscribe(clientId, topicFilter, mqttQoS.value());
// MqttSubscribe subscribeStore = new MqttSubscribe(clientId, topicFilter,
// mqttQoS.value());
//
// mqttSubscribeStoreService.put(topicFilter, subscribeStore);
// topicService.subscribe(topicFilter, clientId);
bytedeskEventPublisher.publishMqttSubscribeEvent(topicFilter, clientId);
//
//
mqttQoSList.add(mqttQoS.value());
// 添加缓存
// redisUserService.addTopic(uid, topicFilter);
@@ -77,9 +78,9 @@ public class Subscribe {
// 发布当前topic的retain消息给当前客户端
// topicSubscriptions.forEach(topicSubscription -> {
// String topicFilter = topicSubscription.topicName();
// MqttQoS mqttQoS = topicSubscription.qualityOfService();
// this.sendRetainMessage(channel, topicFilter, mqttQoS);
// String topicFilter = topicSubscription.topicName();
// MqttQoS mqttQoS = topicSubscription.qualityOfService();
// this.sendRetainMessage(channel, topicFilter, mqttQoS);
// });
} else {
@@ -88,45 +89,51 @@ public class Subscribe {
}
// 发布当前topic的retain消息给当前客户端
// private void sendRetainMessage(Channel channel, String topicFilter, MqttQoS mqttQoS) {
// //
// // List<MqttRetainMessage> retainMessageStores = mqttRetainMessageStoreService.search(topicFilter);
// // retainMessageStores.forEach(retainMessage -> {
// // //
// // MqttQoS respQoS = retainMessage.getMqttQoS() > mqttQoS.value() ? mqttQoS
// // : MqttQoS.valueOf(retainMessage.getMqttQoS());
// // //
// // String clientId = ChannelUtils.getClientId(channel);
// private void sendRetainMessage(Channel channel, String topicFilter, MqttQoS
// mqttQoS) {
// //
// // List<MqttRetainMessage> retainMessageStores =
// mqttRetainMessageStoreService.search(topicFilter);
// // retainMessageStores.forEach(retainMessage -> {
// // //
// // MqttQoS respQoS = retainMessage.getMqttQoS() > mqttQoS.value() ? mqttQoS
// // : MqttQoS.valueOf(retainMessage.getMqttQoS());
// // //
// // String clientId = ChannelUtils.getClientId(channel);
// // if (respQoS == MqttQoS.AT_MOST_ONCE) {
// // //
// // MqttPublishMessage publishMessage = (MqttPublishMessage) MqttMessageFactory.newMessage(
// // new MqttFixedHeader(MqttMessageType.PUBLISH, false, respQoS, false, 0),
// // new MqttPublishVariableHeader(retainMessage.getTopic(), 0),
// // Unpooled.buffer().writeBytes(retainMessage.getMessageBytes()));
// // //
// // log.debug("PUBLISH - clientId: {}, topic: {}, Qos: {}",
// // clientId, retainMessage.getTopic(),
// // respQoS.value());
// // if (respQoS == MqttQoS.AT_MOST_ONCE) {
// // //
// // MqttPublishMessage publishMessage = (MqttPublishMessage)
// MqttMessageFactory.newMessage(
// // new MqttFixedHeader(MqttMessageType.PUBLISH, false, respQoS, false, 0),
// // new MqttPublishVariableHeader(retainMessage.getTopic(), 0),
// // Unpooled.buffer().writeBytes(retainMessage.getMessageBytes()));
// // //
// // channel.writeAndFlush(publishMessage);
// // log.debug("PUBLISH - clientId: {}, topic: {}, Qos: {}",
// // clientId, retainMessage.getTopic(),
// // respQoS.value());
// // } else if (respQoS == MqttQoS.AT_LEAST_ONCE || respQoS == MqttQoS.EXACTLY_ONCE) {
// // //
// // int messageId = mqttMessageIdService.getNextMessageId();
// // MqttPublishMessage publishMessage = (MqttPublishMessage) MqttMessageFactory.newMessage(
// // new MqttFixedHeader(MqttMessageType.PUBLISH, false, respQoS, false, 0),
// // new MqttPublishVariableHeader(retainMessage.getTopic(), messageId),
// // Unpooled.buffer().writeBytes(retainMessage.getMessageBytes()));
// // //
// // log.debug("PUBLISH - clientId: {}, topic: {}, Qos: {}, messageId: {}", clientId, retainMessage.getTopic(),
// // respQoS.value(), messageId);
// // channel.writeAndFlush(publishMessage);
// // } else if (respQoS == MqttQoS.AT_LEAST_ONCE || respQoS ==
// MqttQoS.EXACTLY_ONCE) {
// // //
// // int messageId = mqttMessageIdService.getNextMessageId();
// // MqttPublishMessage publishMessage = (MqttPublishMessage)
// MqttMessageFactory.newMessage(
// // new MqttFixedHeader(MqttMessageType.PUBLISH, false, respQoS, false, 0),
// // new MqttPublishVariableHeader(retainMessage.getTopic(), messageId),
// // Unpooled.buffer().writeBytes(retainMessage.getMessageBytes()));
// // //
// // log.debug("PUBLISH - clientId: {}, topic: {}, Qos: {}, messageId: {}",
// clientId, retainMessage.getTopic(),
// // respQoS.value(), messageId);
// // channel.writeAndFlush(publishMessage);
// // }
// // });
// // channel.writeAndFlush(publishMessage);
// // }
// // });
// }
}

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.protocol;
package com.bytedesk.core.socket.mqtt.protocol;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.*;
@@ -20,8 +20,8 @@ import io.netty.handler.codec.mqtt.*;
import com.bytedesk.core.event.BytedeskEventPublisher;
// import com.bytedesk.core.topic.TopicService;
// import com.bytedesk.core.redis.RedisUserService;
// import com.bytedesk.socket.mqtt.service.MqttSubscribeService;
import com.bytedesk.socket.mqtt.util.ChannelUtils;
// import com.bytedesk.core.socket.mqtt.service.MqttSubscribeService;
import com.bytedesk.core.socket.mqtt.util.ChannelUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.server;
package com.bytedesk.core.socket.mqtt.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
@@ -24,9 +24,9 @@ import io.netty.util.ResourceLeakDetector;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import com.bytedesk.socket.mqtt.config.MqttProperties;
import com.bytedesk.socket.mqtt.initializer.MqttServerInitializer;
import com.bytedesk.socket.mqtt.protocol.ProtocolProcess;
import com.bytedesk.core.socket.mqtt.config.MqttProperties;
import com.bytedesk.core.socket.mqtt.initializer.MqttServerInitializer;
import com.bytedesk.core.socket.mqtt.protocol.ProtocolProcess;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -34,10 +34,11 @@ import org.springframework.stereotype.Component;
/**
* current version based on 3.1.1
* 当前版本基于 mqtt3.1.1
*
* @see https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
* @see https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html
*
* encrypt/security through nginx proxy
* encrypt/security through nginx proxy
*
* @author jackning
*/
@@ -60,7 +61,8 @@ public class MqttServer {
@PostConstruct
public void init() throws Exception {
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.valueOf(mqttProperties.getLeakDetectorLevel().toUpperCase()));
ResourceLeakDetector
.setLevel(ResourceLeakDetector.Level.valueOf(mqttProperties.getLeakDetectorLevel().toUpperCase()));
parentEventLoopGroup = new NioEventLoopGroup(mqttProperties.getParentEventLoopGroupThreadCount());
@@ -101,5 +103,5 @@ public class MqttServer {
parentEventLoopGroup.shutdownGracefully();
}
}
}

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.server;
package com.bytedesk.core.socket.mqtt.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
@@ -24,9 +24,9 @@ import io.netty.util.ResourceLeakDetector;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import com.bytedesk.socket.mqtt.config.MqttProperties;
import com.bytedesk.socket.mqtt.initializer.MqttWebSocketServerInitializer;
import com.bytedesk.socket.mqtt.protocol.ProtocolProcess;
import com.bytedesk.core.socket.mqtt.config.MqttProperties;
import com.bytedesk.core.socket.mqtt.initializer.MqttWebSocketServerInitializer;
import com.bytedesk.core.socket.mqtt.protocol.ProtocolProcess;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

View File

@@ -12,9 +12,9 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.service;
package com.bytedesk.core.socket.mqtt.service;
import com.bytedesk.socket.mqtt.service.MqttAuthService;
import com.bytedesk.core.socket.mqtt.service.MqttAuthService;
import lombok.AllArgsConstructor;
// import lombok.extern.slf4j.Slf4j;

View File

@@ -12,7 +12,7 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.service;
package com.bytedesk.core.socket.mqtt.service;
import org.springframework.stereotype.Service;

View File

@@ -12,9 +12,9 @@
* 联系270580156@qq.com
* Copyright (c) 2024 by bytedesk.com, All Rights Reserved.
*/
package com.bytedesk.socket.mqtt.service;
package com.bytedesk.core.socket.mqtt.service;
import com.bytedesk.socket.mqtt.model.MqttSession;
import com.bytedesk.core.socket.mqtt.model.MqttSession;
import lombok.AllArgsConstructor;
// import lombok.extern.slf4j.Slf4j;

Some files were not shown because too many files have changed in this diff Show More